uorb/listener: add new api: orb_open and orb_close

don't using subscriber to get state to avoid rpmsg access

Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
Jiuzhu Dong 2022-04-28 23:17:57 +08:00 committed by Alan Carvalho de Assis
parent d44dd1c426
commit 53ee04ba3c
3 changed files with 124 additions and 96 deletions

View File

@ -33,6 +33,7 @@
#include <string.h> #include <string.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h>
#include <uORB/uORB.h> #include <uORB/uORB.h>
@ -139,21 +140,15 @@ static int listener_get_state(FAR struct orb_object *object,
int ret; int ret;
int fd; int fd;
fd = orb_subscribe_multi(object->meta, object->instance); fd = orb_open(object->meta->o_name, object->instance, 0);
if (fd < 0) if (fd < 0)
{ {
return fd; return fd;
} }
ret = orb_get_state(fd, state); ret = orb_get_state(fd, state);
orb_unsubscribe(fd); orb_close(fd);
if (ret < 0) return ret;
{
return ret;
}
state->nsubscribers--; /* Ignore temp subscriber */
return 0;
} }
/**************************************************************************** /****************************************************************************
@ -174,8 +169,6 @@ static int listener_add_object(FAR struct list_node *objlist,
FAR struct orb_object *object) FAR struct orb_object *object)
{ {
FAR struct listen_object_s *tmp; FAR struct listen_object_s *tmp;
struct orb_state state;
int ret;
tmp = malloc(sizeof(struct listen_object_s)); tmp = malloc(sizeof(struct listen_object_s));
if (tmp == NULL) if (tmp == NULL)
@ -183,20 +176,10 @@ static int listener_add_object(FAR struct list_node *objlist,
return -ENOMEM; return -ENOMEM;
} }
ret = listener_get_state(object, &state);
if (ret < 0)
{
free(tmp);
return ret;
}
tmp->object.meta = object->meta; tmp->object.meta = object->meta;
tmp->object.instance = object->instance; tmp->object.instance = object->instance;
tmp->timestamp = orb_absolute_time(); tmp->timestamp = 0;
tmp->generation = state.generation;
list_add_tail(objlist, &tmp->node); list_add_tail(objlist, &tmp->node);
return 0; return 0;
} }
@ -249,6 +232,13 @@ static int listener_update(FAR struct list_node *objlist,
return ret; return ret;
} }
if (old->timestamp == 0)
{
old->timestamp = orb_absolute_time();
old->generation = state.generation;
return 0;
}
delta_time = now_time - old->timestamp; delta_time = now_time - old->timestamp;
delta_generation = state.generation - old->generation; delta_generation = state.generation - old->generation;
if (delta_generation && delta_time) if (delta_generation && delta_time)

View File

@ -37,7 +37,7 @@
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: orb_open * Name: orb_advsub_open
* *
* Description: * Description:
* Open device node as advertiser / subscriber, regist node and save meta * Open device node as advertiser / subscriber, regist node and save meta
@ -45,7 +45,7 @@
* *
* Input Parameters: * Input Parameters:
* meta The uORB metadata (usually from the ORB_ID() macro) * meta The uORB metadata (usually from the ORB_ID() macro)
* advertiser Whether advertiser or subscriber. * flag The open flag.
* instance Instance number to open. * instance Instance number to open.
* queue_size Maximum number of buffered elements. * queue_size Maximum number of buffered elements.
* *
@ -53,11 +53,10 @@
* fd on success, otherwise returns negative value and set errno. * fd on success, otherwise returns negative value and set errno.
****************************************************************************/ ****************************************************************************/
static int orb_open(FAR const struct orb_metadata *meta, bool advertiser, static int orb_advsub_open(FAR const struct orb_metadata *meta, int flags,
int instance, unsigned int queue_size) int instance, unsigned int queue_size)
{ {
char path[ORB_PATH_MAX]; char path[ORB_PATH_MAX];
bool first_open = false;
int fd; int fd;
int ret; int ret;
@ -66,11 +65,11 @@ static int orb_open(FAR const struct orb_metadata *meta, bool advertiser,
/* Check existance before open */ /* Check existance before open */
ret = access(path, F_OK); flags |= O_CLOEXEC;
if (ret < 0) fd = open(path, flags);
if (fd < 0)
{ {
struct sensor_reginfo_s reginfo; struct sensor_reginfo_s reginfo;
reginfo.path = path; reginfo.path = path;
reginfo.esize = meta->o_size; reginfo.esize = meta->o_size;
reginfo.nbuffer = queue_size; reginfo.nbuffer = queue_size;
@ -90,18 +89,16 @@ static int orb_open(FAR const struct orb_metadata *meta, bool advertiser,
return ret; return ret;
} }
first_open = true; fd = open(path, flags);
} if (fd < 0)
{
return fd;
}
fd = open(path, O_CLOEXEC | (advertiser ? O_WRONLY : O_RDONLY)); if (ret != -EEXIST)
if (fd < 0) {
{ ioctl(fd, SNIOC_SET_USERPRIV, (unsigned long)(uintptr_t)meta);
return fd; }
}
if (first_open)
{
ioctl(fd, SNIOC_SET_USERPRIV, (unsigned long)(uintptr_t)meta);
} }
/* Only first advertiser can successfully set buffer number */ /* Only first advertiser can successfully set buffer number */
@ -118,6 +115,19 @@ static int orb_open(FAR const struct orb_metadata *meta, bool advertiser,
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
int orb_open(FAR const char *name, int instance, int flags)
{
char path[ORB_PATH_MAX];
snprintf(path, ORB_PATH_MAX, ORB_SENSOR_PATH"%s%d", name, instance);
return open(path, O_CLOEXEC | flags);
}
int orb_close(int fd)
{
return close(fd);
}
int orb_advertise_multi_queue(FAR const struct orb_metadata *meta, int orb_advertise_multi_queue(FAR const struct orb_metadata *meta,
FAR const void *data, FAR int *instance, FAR const void *data, FAR int *instance,
unsigned int queue_size) unsigned int queue_size)
@ -129,7 +139,7 @@ int orb_advertise_multi_queue(FAR const struct orb_metadata *meta,
inst = instance ? *instance : orb_group_count(meta); inst = instance ? *instance : orb_group_count(meta);
fd = orb_open(meta, true, inst, queue_size); fd = orb_advsub_open(meta, O_WRONLY, inst, queue_size);
if (fd < 0) if (fd < 0)
{ {
uorberr("%s advertise failed (%i)", meta->o_name, fd); uorberr("%s advertise failed (%i)", meta->o_name, fd);
@ -155,11 +165,6 @@ int orb_advertise_multi_queue(FAR const struct orb_metadata *meta,
return fd; return fd;
} }
int orb_unadvertise(int fd)
{
return close(fd);
}
ssize_t orb_publish_multi(int fd, const void *data, size_t len) ssize_t orb_publish_multi(int fd, const void *data, size_t len)
{ {
return write(fd, data, len); return write(fd, data, len);
@ -168,12 +173,7 @@ ssize_t orb_publish_multi(int fd, const void *data, size_t len)
int orb_subscribe_multi(FAR const struct orb_metadata *meta, int orb_subscribe_multi(FAR const struct orb_metadata *meta,
unsigned instance) unsigned instance)
{ {
return orb_open(meta, false, instance, 0); return orb_advsub_open(meta, O_RDONLY, instance, 0);
}
int orb_unsubscribe(int fd)
{
return close(fd);
} }
ssize_t orb_copy_multi(int fd, FAR void *buffer, size_t len) ssize_t orb_copy_multi(int fd, FAR void *buffer, size_t len)
@ -225,9 +225,9 @@ int orb_check(int fd, FAR bool *updated)
return 0; return 0;
} }
int orb_ioctl(int handle, int cmd, unsigned long arg) int orb_ioctl(int fd, int cmd, unsigned long arg)
{ {
return ioctl(handle, cmd, arg); return ioctl(fd, cmd, arg);
} }
int orb_set_interval(int fd, unsigned interval) int orb_set_interval(int fd, unsigned interval)

View File

@ -173,6 +173,38 @@ extern "C"
* Public Function Prototypes * Public Function Prototypes
****************************************************************************/ ****************************************************************************/
/****************************************************************************
* Name: orb_open
*
* Description:
* Open device exist node with name, instance and flags.
*
* Input Parameters:
* name The topic name.
* instance Instance number to open.
* flags The open flags.
*
* Returned Value:
* fd on success, otherwise returns negative value and set errno.
****************************************************************************/
int orb_open(FAR const char *name, int instance, int flags);
/****************************************************************************
* Name: orb_close
*
* Description:
* Close fd.
*
* Input Parameters:
* fd A fd returned by orb_open.
*
* Returned Value:
* 0 on success.
****************************************************************************/
int orb_close(int fd);
/**************************************************************************** /****************************************************************************
* Name: orb_advertise_multi_queue * Name: orb_advertise_multi_queue
* *
@ -227,13 +259,16 @@ static inline int orb_advertise_multi(FAR const struct orb_metadata *meta,
* Unadvertise a topic. * Unadvertise a topic.
* *
* Input Parameters: * Input Parameters:
* handle A handle returned by orb_advertise or orb_advertise_multi. * fd A fd returned by orb_advertise or orb_advertise_multi.
* *
* Returned Value: * Returned Value:
* 0 on success. * 0 on success.
****************************************************************************/ ****************************************************************************/
int orb_unadvertise(int handle); static inline int orb_unadvertise(int fd)
{
return orb_close(fd);
}
/**************************************************************************** /****************************************************************************
* Name: orb_publish_multi * Name: orb_publish_multi
@ -246,7 +281,7 @@ int orb_unadvertise(int handle);
* updates using orb_check. * updates using orb_check.
* *
* Input Parameters: * Input Parameters:
* handle The handle returned from orb_advertise. * fd The fd returned from orb_advertise.
* data A pointer to the data to be published. * data A pointer to the data to be published.
* len The length of the data to be published. * len The length of the data to be published.
* *
@ -254,24 +289,24 @@ int orb_unadvertise(int handle);
* 0 on success, -1 otherwise with errno set accordingly. * 0 on success, -1 otherwise with errno set accordingly.
****************************************************************************/ ****************************************************************************/
ssize_t orb_publish_multi(int handle, FAR const void *data, size_t len); ssize_t orb_publish_multi(int fd, FAR const void *data, size_t len);
static inline int orb_publish(FAR const struct orb_metadata *meta, static inline int orb_publish(FAR const struct orb_metadata *meta,
int handle, FAR const void *data) int fd, FAR const void *data)
{ {
int ret; int ret;
ret = orb_publish_multi(handle, data, meta->o_size); ret = orb_publish_multi(fd, data, meta->o_size);
return ret == meta->o_size ? 0 : -1; return ret == meta->o_size ? 0 : -1;
} }
static inline int orb_publish_auto(FAR const struct orb_metadata *meta, static inline int orb_publish_auto(FAR const struct orb_metadata *meta,
FAR int *handle, FAR const void *data, FAR int *fd, FAR const void *data,
FAR int *instance) FAR int *instance)
{ {
if (handle && *handle) if (fd && *fd)
{ {
return orb_publish(meta, *handle, data); return orb_publish(meta, *fd, data);
} }
else else
{ {
@ -283,9 +318,9 @@ static inline int orb_publish_auto(FAR const struct orb_metadata *meta,
return tmp; return tmp;
} }
if (handle) if (fd)
{ {
*handle = tmp; *fd = tmp;
return tmp; return tmp;
} }
else else
@ -319,7 +354,7 @@ static inline int orb_publish_auto(FAR const struct orb_metadata *meta,
* the orb_subscribe() call. * the orb_subscribe() call.
* *
* Returned Value: * Returned Value:
* -1 on error, otherwise returns a handle * -1 on error, otherwise returns a fd
* that can be used to read and update the topic. * that can be used to read and update the topic.
* If the topic in question is not known (due to an * If the topic in question is not known (due to an
* ORB_DEFINE_OPTIONAL with no corresponding ORB_DECLARE) * ORB_DEFINE_OPTIONAL with no corresponding ORB_DECLARE)
@ -341,13 +376,16 @@ static inline int orb_subscribe(FAR const struct orb_metadata *meta)
* Unsubscribe from a topic. * Unsubscribe from a topic.
* *
* Input Parameters: * Input Parameters:
* handle A handle returned from orb_subscribe. * fd A fd returned from orb_subscribe.
* *
* Returned Value: * Returned Value:
* 0 on success. * 0 on success.
****************************************************************************/ ****************************************************************************/
int orb_unsubscribe(int handle); static inline int orb_unsubscribe(int fd)
{
return orb_close(fd);
}
/**************************************************************************** /****************************************************************************
* Name: orb_copy_multi * Name: orb_copy_multi
@ -361,7 +399,7 @@ int orb_unsubscribe(int handle);
* must be used to update the subscription. * must be used to update the subscription.
* *
* Input Parameters: * Input Parameters:
* handle A handle returned from orb_subscribe. * fd A fd returned from orb_subscribe.
* buffer Pointer to the buffer receiving the data, or NULL if the * buffer Pointer to the buffer receiving the data, or NULL if the
* caller wants to clear the updated flag without. * caller wants to clear the updated flag without.
* len The length to the buffer receiving the data. * len The length to the buffer receiving the data.
@ -372,14 +410,14 @@ int orb_unsubscribe(int handle);
* -1 otherwise with errno set accordingly. * -1 otherwise with errno set accordingly.
****************************************************************************/ ****************************************************************************/
ssize_t orb_copy_multi(int handle, FAR void *buffer, size_t len); ssize_t orb_copy_multi(int fd, FAR void *buffer, size_t len);
static inline int orb_copy(FAR const struct orb_metadata *meta, static inline int orb_copy(FAR const struct orb_metadata *meta,
int handle, FAR void *buffer) int fd, FAR void *buffer)
{ {
int ret; int ret;
ret = orb_copy_multi(handle, buffer, meta->o_size); ret = orb_copy_multi(fd, buffer, meta->o_size);
return ret == meta->o_size ? 0 : -1; return ret == meta->o_size ? 0 : -1;
} }
@ -397,7 +435,7 @@ static inline int orb_copy(FAR const struct orb_metadata *meta,
* max_frequency to 0. min_batch_interval to 0, enable to false. * max_frequency to 0. min_batch_interval to 0, enable to false.
* *
* Input Parameters: * Input Parameters:
* handle The handle returned from orb_advertise / orb_subscribe. * fd The fd returned from orb_advertise / orb_subscribe.
* state Pointer to an state of struct orb_state type. This is an * state Pointer to an state of struct orb_state type. This is an
* output parameter and will be set to the current state of topic. * output parameter and will be set to the current state of topic.
* *
@ -405,7 +443,7 @@ static inline int orb_copy(FAR const struct orb_metadata *meta,
* -1 on error. * -1 on error.
****************************************************************************/ ****************************************************************************/
int orb_get_state(int handle, FAR struct orb_state *state); int orb_get_state(int fd, FAR struct orb_state *state);
/**************************************************************************** /****************************************************************************
* Name: orb_check * Name: orb_check
@ -417,20 +455,20 @@ int orb_get_state(int handle, FAR struct orb_state *state);
* not using poll(), or to avoid the overhead of calling poll() when the * not using poll(), or to avoid the overhead of calling poll() when the
* topic is likely to have updated. * topic is likely to have updated.
* *
* Updates are tracked on a per-handle basis; this call will continue to * Updates are tracked on a per-fd basis; this call will continue to
* return true until orb_copy is called using the same handle. * return true until orb_copy is called using the same fd.
* *
* Input Parameters: * Input Parameters:
* handle A handle returned from orb_subscribe. * fd A fd returned from orb_subscribe.
* update Set to true if the topic has been updated since the * update Set to true if the topic has been updated since the
* last time it was copied using this handle. * last time it was copied using this fd.
* *
* Returned Value: * Returned Value:
* 0 if the check was successful, * 0 if the check was successful,
* -1 otherwise with errno set accordingly. * -1 otherwise with errno set accordingly.
****************************************************************************/ ****************************************************************************/
int orb_check(int handle, FAR bool *updated); int orb_check(int fd, FAR bool *updated);
/**************************************************************************** /****************************************************************************
* Name: orb_ioctl * Name: orb_ioctl
@ -439,7 +477,7 @@ int orb_check(int handle, FAR bool *updated);
* Ioctl control for the subscriber, the same as ioctl(). * Ioctl control for the subscriber, the same as ioctl().
* *
* Input Parameters: * Input Parameters:
* handle A handle returned from orb_advertise / orb_subscribe. * fd A fd returned from orb_advertise / orb_subscribe.
* cmd Ioctl command. * cmd Ioctl command.
* arg Ioctl argument. * arg Ioctl argument.
* *
@ -447,7 +485,7 @@ int orb_check(int handle, FAR bool *updated);
* 0 on success. * 0 on success.
****************************************************************************/ ****************************************************************************/
int orb_ioctl(int handle, int cmd, unsigned long arg); int orb_ioctl(int fd, int cmd, unsigned long arg);
/**************************************************************************** /****************************************************************************
* Name: orb_set_batch_interval * Name: orb_set_batch_interval
@ -462,14 +500,14 @@ int orb_ioctl(int handle, int cmd, unsigned long arg);
* hardware fifo, otherwise it's meaningless. * hardware fifo, otherwise it's meaningless.
* *
* Input Parameters: * Input Parameters:
* handle A handle returned from orb_subscribe. * fd A fd returned from orb_subscribe.
* batch_interval An batch interval in us. * batch_interval An batch interval in us.
* *
* Returned Value: * Returned Value:
* 0 on success, -1 otherwise with ERRNO set accordingly. * 0 on success, -1 otherwise with ERRNO set accordingly.
****************************************************************************/ ****************************************************************************/
int orb_set_batch_interval(int handle, unsigned batch_interval); int orb_set_batch_interval(int fd, unsigned batch_interval);
/**************************************************************************** /****************************************************************************
* Name: orb_get_batch_interval * Name: orb_get_batch_interval
@ -483,14 +521,14 @@ int orb_set_batch_interval(int handle, unsigned batch_interval);
* @see orb_set_batch_interval() * @see orb_set_batch_interval()
* *
* Input Parameters: * Input Parameters:
* handle A handle returned from orb_subscribe. * fd A fd returned from orb_subscribe.
* batch_interval The returned batch interval in us. * batch_interval The returned batch interval in us.
* *
* Returned Value: * Returned Value:
* 0 on success, -1 otherwise with ERRNO set accordingly. * 0 on success, -1 otherwise with ERRNO set accordingly.
****************************************************************************/ ****************************************************************************/
int orb_get_batch_interval(int handle, FAR unsigned *batch_interval); int orb_get_batch_interval(int fd, FAR unsigned *batch_interval);
/**************************************************************************** /****************************************************************************
* Name: * Name:
@ -499,14 +537,14 @@ int orb_get_batch_interval(int handle, FAR unsigned *batch_interval);
* Set the minimum interval between which updates seen for a subscription. * Set the minimum interval between which updates seen for a subscription.
* *
* Input Parameters: * Input Parameters:
* handle A handle returned from orb_subscribe. * fd A fd returned from orb_subscribe.
* interval An interval period in us. * interval An interval period in us.
* *
* Returned Value: * Returned Value:
* 0 on success, -1 otherwise with ERRNO set accordingly. * 0 on success, -1 otherwise with ERRNO set accordingly.
****************************************************************************/ ****************************************************************************/
int orb_set_interval(int handle, unsigned interval); int orb_set_interval(int fd, unsigned interval);
/**************************************************************************** /****************************************************************************
* Name: * Name:
@ -515,14 +553,14 @@ int orb_set_interval(int handle, unsigned interval);
* Get the minimum interval between which updates seen for a subscription. * Get the minimum interval between which updates seen for a subscription.
* *
* Input Parameters: * Input Parameters:
* handle A handle returned from orb_subscribe. * fd A fd returned from orb_subscribe.
* interval The returned interval period in us. * interval The returned interval period in us.
* *
* Returned Value: * Returned Value:
* 0 on success, -1 otherwise with ERRNO set accordingly. * 0 on success, -1 otherwise with ERRNO set accordingly.
****************************************************************************/ ****************************************************************************/
int orb_get_interval(int handle, FAR unsigned *interval); int orb_get_interval(int fd, FAR unsigned *interval);
/**************************************************************************** /****************************************************************************
* Name: * Name:
@ -532,16 +570,16 @@ int orb_get_interval(int handle, FAR unsigned *interval);
* Set the maximum frequency for a subscription. * Set the maximum frequency for a subscription.
* *
* Input Parameters: * Input Parameters:
* handle A handle returned from orb_subscribe. * fd A fd returned from orb_subscribe.
* frequency A frequency in hz. * frequency A frequency in hz.
* *
* Returned Value: * Returned Value:
* 0 on success, -1 otherwise with ERRNO set accordingly. * 0 on success, -1 otherwise with ERRNO set accordingly.
****************************************************************************/ ****************************************************************************/
static inline int orb_set_frequency(int handle, unsigned frequency) static inline int orb_set_frequency(int fd, unsigned frequency)
{ {
return orb_set_interval(handle, frequency ? 1000000 / frequency : 0); return orb_set_interval(fd, frequency ? 1000000 / frequency : 0);
} }
/**************************************************************************** /****************************************************************************
@ -552,19 +590,19 @@ static inline int orb_set_frequency(int handle, unsigned frequency)
* Get the maximum frequency for a subscription. * Get the maximum frequency for a subscription.
* *
* Input Parameters: * Input Parameters:
* handle A handle returned from orb_subscribe. * fd A fd returned from orb_subscribe.
* frequency The returned frequency in hz. * frequency The returned frequency in hz.
* *
* Returned Value: * Returned Value:
* 0 on success, -1 otherwise with ERRNO set accordingly. * 0 on success, -1 otherwise with ERRNO set accordingly.
****************************************************************************/ ****************************************************************************/
static inline int orb_get_frequency(int handle, FAR unsigned *frequency) static inline int orb_get_frequency(int fd, FAR unsigned *frequency)
{ {
unsigned interval; unsigned interval;
int ret; int ret;
ret = orb_get_interval(handle, &interval); ret = orb_get_interval(fd, &interval);
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;