PX4 Firmware
PX4 Autopilot Software http://px4.io
uORBManager.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2012-2015 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <stdarg.h>
37 #include <fcntl.h>
38 
39 #include <px4_platform_common/px4_config.h>
40 #include <px4_platform_common/posix.h>
41 #include <px4_platform_common/tasks.h>
42 
43 #include "uORBDeviceNode.hpp"
44 #include "uORBUtils.hpp"
45 #include "uORBManager.hpp"
46 
48 
50 {
51  if (_Instance == nullptr) {
52  _Instance = new uORB::Manager();
53  }
54 
55  return _Instance != nullptr;
56 }
57 
59 {
60  if (_Instance != nullptr) {
61  delete _Instance;
62  _Instance = nullptr;
63  return true;
64  }
65 
66  return false;
67 }
68 
70 {
71 #ifdef ORB_USE_PUBLISHER_RULES
72  const char *file_name = PX4_STORAGEDIR"/orb_publisher.rules";
73  int ret = readPublisherRulesFromFile(file_name, _publisher_rule);
74 
75  if (ret == PX4_OK) {
76  _has_publisher_rules = true;
77  PX4_INFO("Using orb rules from %s", file_name);
78 
79  } else {
80  PX4_ERR("Failed to read publisher rules file %s (%s)", file_name, strerror(-ret));
81  }
82 
83 #endif /* ORB_USE_PUBLISHER_RULES */
84 
85 }
86 
88 {
89  delete _device_master;
90 }
91 
93 {
94  if (!_device_master) {
96 
97  if (_device_master == nullptr) {
98  PX4_ERR("Failed to allocate DeviceMaster");
99  errno = ENOMEM;
100  }
101  }
102 
103  return _device_master;
104 }
105 
106 int uORB::Manager::orb_exists(const struct orb_metadata *meta, int instance)
107 {
108  int ret = PX4_ERROR;
109 
110  // instance valid range: [0, ORB_MULTI_MAX_INSTANCES)
111  if ((instance < 0) || (instance > (ORB_MULTI_MAX_INSTANCES - 1))) {
112  return ret;
113  }
114 
115  if (get_device_master()) {
116  uORB::DeviceNode *node = _device_master->getDeviceNode(meta, instance);
117 
118  if (node != nullptr) {
119  if (node->is_advertised()) {
120  return PX4_OK;
121  }
122  }
123  }
124 
125 #ifdef ORB_COMMUNICATOR
126 
127  /*
128  * Generate the path to the node and try to open it.
129  */
130  char path[orb_maxpath];
131  int inst = instance;
132 
133  ret = uORB::Utils::node_mkpath(path, meta, &inst);
134 
135  if (ret != OK) {
136  errno = -ret;
137  return PX4_ERROR;
138  }
139 
140  ret = px4_access(path, F_OK);
141 
142  if (ret == -1 && meta != nullptr && !_remote_topics.empty()) {
143  ret = (_remote_topics.find(meta->o_name) != _remote_topics.end()) ? OK : PX4_ERROR;
144  }
145 
146  if (ret == 0) {
147  // we know the topic exists, but it's not necessarily advertised/published yet (for example
148  // if there is only a subscriber)
149  // The open() will not lead to memory allocations.
150  int fd = px4_open(path, 0);
151 
152  if (fd >= 0) {
153  unsigned long is_advertised;
154 
155  if (px4_ioctl(fd, ORBIOCISADVERTISED, (unsigned long)&is_advertised) == 0) {
156  if (!is_advertised) {
157  ret = PX4_ERROR;
158  }
159  }
160 
161  px4_close(fd);
162  }
163  }
164 
165 #endif /* ORB_COMMUNICATOR */
166 
167  return ret;
168 }
169 
171  int priority, unsigned int queue_size)
172 {
173 #ifdef ORB_USE_PUBLISHER_RULES
174 
175  // check publisher rule
176  if (_has_publisher_rules) {
177  const char *prog_name = px4_get_taskname();
178 
179  if (strcmp(_publisher_rule.module_name, prog_name) == 0) {
180  if (_publisher_rule.ignore_other_topics) {
181  if (!findTopic(_publisher_rule, meta->o_name)) {
182  PX4_DEBUG("not allowing %s to publish topic %s", prog_name, meta->o_name);
183  return (orb_advert_t)_Instance;
184  }
185  }
186 
187  } else {
188  if (findTopic(_publisher_rule, meta->o_name)) {
189  PX4_DEBUG("not allowing %s to publish topic %s", prog_name, meta->o_name);
190  return (orb_advert_t)_Instance;
191  }
192  }
193  }
194 
195 #endif /* ORB_USE_PUBLISHER_RULES */
196 
197  /* open the node as an advertiser */
198  int fd = node_open(meta, true, instance, priority);
199 
200  if (fd == PX4_ERROR) {
201  PX4_ERR("%s advertise failed (%i)", meta->o_name, errno);
202  return nullptr;
203  }
204 
205  /* Set the queue size. This must be done before the first publication; thus it fails if
206  * this is not the first advertiser.
207  */
208  int result = px4_ioctl(fd, ORBIOCSETQUEUESIZE, (unsigned long)queue_size);
209 
210  if (result < 0 && queue_size > 1) {
211  PX4_WARN("orb_advertise_multi: failed to set queue size");
212  }
213 
214  /* get the advertiser handle and close the node */
215  orb_advert_t advertiser;
216 
217  result = px4_ioctl(fd, ORBIOCGADVERTISER, (unsigned long)&advertiser);
218  px4_close(fd);
219 
220  if (result == PX4_ERROR) {
221  PX4_WARN("px4_ioctl ORBIOCGADVERTISER failed. fd = %d", fd);
222  return nullptr;
223  }
224 
225 #ifdef ORB_COMMUNICATOR
226  // For remote systems call over and inform them
227  uORB::DeviceNode::topic_advertised(meta, priority);
228 #endif /* ORB_COMMUNICATOR */
229 
230  /* the advertiser must perform an initial publish to initialise the object */
231  result = orb_publish(meta, advertiser, data);
232 
233  if (result == PX4_ERROR) {
234  PX4_WARN("orb_publish failed");
235  return nullptr;
236  }
237 
238  return advertiser;
239 }
240 
242 {
243 #ifdef ORB_USE_PUBLISHER_RULES
244 
245  if (handle == _Instance) {
246  return PX4_OK; //pretend success
247  }
248 
249 #endif /* ORB_USE_PUBLISHER_RULES */
250 
251  return uORB::DeviceNode::unadvertise(handle);
252 }
253 
255 {
256  return node_open(meta, false);
257 }
258 
260 {
261  int inst = instance;
262  return node_open(meta, false, &inst);
263 }
264 
266 {
267  return px4_close(fd);
268 }
269 
270 int uORB::Manager::orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data)
271 {
272 #ifdef ORB_USE_PUBLISHER_RULES
273 
274  if (handle == _Instance) {
275  return PX4_OK; //pretend success
276  }
277 
278 #endif /* ORB_USE_PUBLISHER_RULES */
279 
280  return uORB::DeviceNode::publish(meta, handle, data);
281 }
282 
283 int uORB::Manager::orb_copy(const struct orb_metadata *meta, int handle, void *buffer)
284 {
285  int ret;
286 
287  ret = px4_read(handle, buffer, meta->o_size);
288 
289  if (ret < 0) {
290  return PX4_ERROR;
291  }
292 
293  if (ret != (int)meta->o_size) {
294  errno = EIO;
295  return PX4_ERROR;
296  }
297 
298  return PX4_OK;
299 }
300 
301 int uORB::Manager::orb_check(int handle, bool *updated)
302 {
303  /* Set to false here so that if `px4_ioctl` fails to false. */
304  *updated = false;
305  return px4_ioctl(handle, ORBIOCUPDATED, (unsigned long)(uintptr_t)updated);
306 }
307 
308 int uORB::Manager::orb_stat(int handle, uint64_t *time)
309 {
310  return px4_ioctl(handle, ORBIOCLASTUPDATE, (unsigned long)(uintptr_t)time);
311 }
312 
313 int uORB::Manager::orb_priority(int handle, int32_t *priority)
314 {
315  return px4_ioctl(handle, ORBIOCGPRIORITY, (unsigned long)(uintptr_t)priority);
316 }
317 
318 int uORB::Manager::orb_set_interval(int handle, unsigned interval)
319 {
320  return px4_ioctl(handle, ORBIOCSETINTERVAL, interval * 1000);
321 }
322 
323 int uORB::Manager::orb_get_interval(int handle, unsigned *interval)
324 {
325  int ret = px4_ioctl(handle, ORBIOCGETINTERVAL, (unsigned long)interval);
326  *interval /= 1000;
327  return ret;
328 }
329 
330 int uORB::Manager::node_advertise(const struct orb_metadata *meta, bool is_advertiser, int *instance, int priority)
331 {
332  int ret = PX4_ERROR;
333 
334  if (get_device_master()) {
335  ret = _device_master->advertise(meta, is_advertiser, instance, priority);
336  }
337 
338  /* it's PX4_OK if it already exists */
339  if ((PX4_OK != ret) && (EEXIST == errno)) {
340  ret = PX4_OK;
341  }
342 
343  return ret;
344 }
345 
346 int uORB::Manager::node_open(const struct orb_metadata *meta, bool advertiser, int *instance, int priority)
347 {
348  char path[orb_maxpath];
349  int fd = -1;
350  int ret = PX4_ERROR;
351 
352  /*
353  * If meta is null, the object was not defined, i.e. it is not
354  * known to the system. We can't advertise/subscribe such a thing.
355  */
356  if (nullptr == meta) {
357  errno = ENOENT;
358  return PX4_ERROR;
359  }
360 
361  /* if we have an instance and are an advertiser, we will generate a new node and set the instance,
362  * so we do not need to open here */
363  if (!instance || !advertiser) {
364  /*
365  * Generate the path to the node and try to open it.
366  */
367  ret = uORB::Utils::node_mkpath(path, meta, instance);
368 
369  if (ret != OK) {
370  errno = -ret;
371  return PX4_ERROR;
372  }
373 
374  /* open the path as either the advertiser or the subscriber */
375  fd = px4_open(path, advertiser ? PX4_F_WRONLY : PX4_F_RDONLY);
376 
377  } else {
378  *instance = 0;
379  }
380 
381  /* we may need to advertise the node... */
382  if (fd < 0) {
383 
384  /* try to create the node */
385  ret = node_advertise(meta, advertiser, instance, priority);
386 
387  if (ret == PX4_OK) {
388  /* update the path, as it might have been updated during the node_advertise call */
389  ret = uORB::Utils::node_mkpath(path, meta, instance);
390 
391  if (ret != PX4_OK) {
392  errno = -ret;
393  return PX4_ERROR;
394  }
395  }
396 
397  /* on success, try to open again */
398  if (ret == PX4_OK) {
399  fd = px4_open(path, (advertiser) ? PX4_F_WRONLY : PX4_F_RDONLY);
400  }
401  }
402 
403  /*
404  else if (advertiser) {
405  * We have a valid fd and are an advertiser.
406  * This can happen if the topic is already subscribed/published, and orb_advertise() is called,
407  * where instance==nullptr.
408  * We would need to set the priority here (via px4_ioctl(fd, ...) and a new IOCTL), but orb_advertise()
409  * uses ORB_PRIO_DEFAULT, and a subscriber also creates the node with ORB_PRIO_DEFAULT. So we don't need
410  * to do anything here.
411  }
412  */
413 
414  if (fd < 0) {
415  errno = EIO;
416  return PX4_ERROR;
417  }
418 
419  /* everything has been OK, we can return the handle now */
420  return fd;
421 }
422 
423 #ifdef ORB_COMMUNICATOR
424 void uORB::Manager::set_uorb_communicator(uORBCommunicator::IChannel *channel)
425 {
426  _comm_channel = channel;
427 
428  if (_comm_channel != nullptr) {
429  _comm_channel->register_handler(this);
430  }
431 }
432 
433 uORBCommunicator::IChannel *uORB::Manager::get_uorb_communicator()
434 {
435  return _comm_channel;
436 }
437 
438 int16_t uORB::Manager::process_remote_topic(const char *topic_name, bool isAdvertisement)
439 {
440  int16_t rc = 0;
441 
442  if (isAdvertisement) {
443  _remote_topics.insert(topic_name);
444 
445  } else {
446  _remote_topics.erase(topic_name);
447  }
448 
449  return rc;
450 }
451 
452 int16_t uORB::Manager::process_add_subscription(const char *messageName, int32_t msgRateInHz)
453 {
454  PX4_DEBUG("entering Manager_process_add_subscription: name: %s", messageName);
455 
456  int16_t rc = 0;
457  _remote_subscriber_topics.insert(messageName);
458  char nodepath[orb_maxpath];
459  int ret = uORB::Utils::node_mkpath(nodepath, messageName);
460  DeviceMaster *device_master = get_device_master();
461 
462  if (ret == OK && device_master) {
463  uORB::DeviceNode *node = device_master->getDeviceNode(nodepath);
464 
465  if (node == nullptr) {
466  PX4_DEBUG("DeviceNode(%s) not created yet", messageName);
467 
468  } else {
469  // node is present.
470  node->process_add_subscription(msgRateInHz);
471  }
472 
473  } else {
474  rc = -1;
475  }
476 
477  return rc;
478 }
479 
480 int16_t uORB::Manager::process_remove_subscription(const char *messageName)
481 {
482  int16_t rc = -1;
483  _remote_subscriber_topics.erase(messageName);
484  char nodepath[orb_maxpath];
485  int ret = uORB::Utils::node_mkpath(nodepath, messageName);
486  DeviceMaster *device_master = get_device_master();
487 
488  if (ret == OK && device_master) {
489  uORB::DeviceNode *node = device_master->getDeviceNode(nodepath);
490 
491  // get the node name.
492  if (node == nullptr) {
493  PX4_DEBUG("[posix-uORB::Manager::process_remove_subscription(%d)]Error No existing subscriber found for message: [%s]",
494  __LINE__, messageName);
495 
496  } else {
497  // node is present.
498  node->process_remove_subscription();
499  rc = 0;
500  }
501  }
502 
503  return rc;
504 }
505 
506 int16_t uORB::Manager::process_received_message(const char *messageName, int32_t length, uint8_t *data)
507 {
508  int16_t rc = -1;
509  char nodepath[orb_maxpath];
510  int ret = uORB::Utils::node_mkpath(nodepath, messageName);
511  DeviceMaster *device_master = get_device_master();
512 
513  if (ret == OK && device_master) {
514  uORB::DeviceNode *node = device_master->getDeviceNode(nodepath);
515 
516  // get the node name.
517  if (node == nullptr) {
518  PX4_DEBUG("No existing subscriber found for message: [%s] nodepath:[%s]", messageName, nodepath);
519 
520  } else {
521  // node is present.
522  node->process_received_message(length, data);
523  rc = 0;
524  }
525  }
526 
527  return rc;
528 }
529 
530 bool uORB::Manager::is_remote_subscriber_present(const char *messageName)
531 {
532 #ifdef __PX4_NUTTX
533  return _remote_subscriber_topics.find(messageName);
534 #else
535  return (_remote_subscriber_topics.find(messageName) != _remote_subscriber_topics.end());
536 #endif
537 }
538 #endif /* ORB_COMMUNICATOR */
539 
540 #ifdef ORB_USE_PUBLISHER_RULES
541 
542 bool uORB::Manager::startsWith(const char *pre, const char *str)
543 {
544  size_t lenpre = strlen(pre),
545  lenstr = strlen(str);
546  return lenstr < lenpre ? false : strncmp(pre, str, lenpre) == 0;
547 }
548 
549 bool uORB::Manager::findTopic(const PublisherRule &rule, const char *topic_name)
550 {
551  const char **topics_ptr = rule.topics;
552 
553  while (*topics_ptr) {
554  if (strcmp(*topics_ptr, topic_name) == 0) {
555  return true;
556  }
557 
558  ++topics_ptr;
559  }
560 
561  return false;
562 }
563 
564 void uORB::Manager::strTrim(const char **str)
565 {
566  while (**str == ' ' || **str == '\t') { ++(*str); }
567 }
568 
569 int uORB::Manager::readPublisherRulesFromFile(const char *file_name, PublisherRule &rule)
570 {
571  FILE *fp;
572  static const int line_len = 1024;
573  int ret = PX4_OK;
574  char *line = new char[line_len];
575 
576  if (!line) {
577  return -ENOMEM;
578  }
579 
580  fp = fopen(file_name, "r");
581 
582  if (fp == NULL) {
583  delete[](line);
584  return -errno;
585  }
586 
587  const char *restrict_topics_str = "restrict_topics:";
588  const char *module_str = "module:";
589  const char *ignore_others = "ignore_others:";
590 
591  rule.ignore_other_topics = false;
592  rule.module_name = nullptr;
593  rule.topics = nullptr;
594 
595  while (fgets(line, line_len, fp) && ret == PX4_OK) {
596 
597  if (strlen(line) < 2 || line[0] == '#') {
598  continue;
599  }
600 
601  if (startsWith(restrict_topics_str, line)) {
602  //read topics list
603  char *start = line + strlen(restrict_topics_str);
604  strTrim((const char **)&start);
605  char *topics = strdup(start);
606  int topic_len = 0, num_topics = 0;
607 
608  for (int i = 0; topics[i]; ++i) {
609  if (topics[i] == ',' || topics[i] == '\n') {
610  if (topic_len > 0) {
611  topics[i] = 0;
612  ++num_topics;
613  }
614 
615  topic_len = 0;
616 
617  } else {
618  ++topic_len;
619  }
620  }
621 
622  if (num_topics > 0) {
623  rule.topics = new const char *[num_topics + 1];
624  int topic = 0;
625  strTrim((const char **)&topics);
626  rule.topics[topic++] = topics;
627 
628  while (topic < num_topics) {
629  if (*topics == 0) {
630  ++topics;
631  strTrim((const char **)&topics);
632  rule.topics[topic++] = topics;
633 
634  } else {
635  ++topics;
636  }
637  }
638 
639  rule.topics[num_topics] = nullptr;
640  }
641 
642  } else if (startsWith(module_str, line)) {
643  //read module name
644  char *start = line + strlen(module_str);
645  strTrim((const char **)&start);
646  int len = strlen(start);
647 
648  if (len > 0 && start[len - 1] == '\n') {
649  start[len - 1] = 0;
650  }
651 
652  rule.module_name = strdup(start);
653 
654  } else if (startsWith(ignore_others, line)) {
655  const char *start = line + strlen(ignore_others);
656  strTrim(&start);
657 
658  if (startsWith("true", start)) {
659  rule.ignore_other_topics = true;
660  }
661 
662  } else {
663  PX4_ERR("orb rules file: wrong format: %s", line);
664  ret = -EINVAL;
665  }
666  }
667 
668  if (ret == PX4_OK && (!rule.module_name || !rule.topics)) {
669  PX4_ERR("Wrong format in orb publisher rules file");
670  ret = -EINVAL;
671  }
672 
673  delete[](line);
674  fclose(fp);
675  return ret;
676 }
677 #endif /* ORB_USE_PUBLISHER_RULES */
int node_advertise(const struct orb_metadata *meta, bool is_advertiser, int *instance=nullptr, int priority=ORB_PRIO_DEFAULT)
Advertise a node; don&#39;t consider it an error if the node has already been advertised.
static ssize_t publish(const orb_metadata *meta, orb_advert_t handle, const void *data)
Method to publish a data to this node.
DeviceMaster * _device_master
virtual ~Manager()
Definition: uORBManager.cpp:87
int orb_set_interval(int handle, unsigned interval)
Set the minimum interval between which updates are seen for a subscription.
uORB::DeviceMaster * get_device_master()
Get the DeviceMaster.
Definition: uORBManager.cpp:92
static bool initialize()
Initialize the singleton.
Definition: uORBManager.cpp:49
int orb_unsubscribe(int handle)
Unsubscribe from a topic.
#define ORBIOCGETINTERVAL
Get the minimum interval at which the topic can be seen to be updated for this subscription.
Definition: drv_orb_dev.h:74
LidarLite * instance
Definition: ll40ls.cpp:65
#define ORBIOCGPRIORITY
Get the priority for the topic.
Definition: drv_orb_dev.h:68
const char * o_name
unique object name
Definition: uORB.h:51
#define ORBIOCSETINTERVAL
Set the minimum interval at which the topic can be seen to be updated for this subscription.
Definition: drv_orb_dev.h:62
static bool terminate()
Terminate the singleton.
Definition: uORBManager.cpp:58
int orb_subscribe(const struct orb_metadata *meta)
Subscribe to a topic.
int node_open(const struct orb_metadata *meta, bool advertiser, int *instance=nullptr, int priority=ORB_PRIO_DEFAULT)
Common implementation for orb_advertise and orb_subscribe.
orb_advert_t orb_advertise_multi(const struct orb_metadata *meta, const void *data, int *instance, int priority, unsigned int queue_size=1)
Advertise as the publisher of a topic.
ssize_t px4_read(int fd, void *buffer, size_t buflen)
int orb_unadvertise(orb_advert_t handle)
Unadvertise a topic.
Per-object device instance.
uint8_t * data
Definition: dataman.cpp:149
int orb_priority(int handle, int32_t *priority)
Return the priority of the topic.
__BEGIN_DECLS typedef void * orb_advert_t
ORB topic advertiser handle.
Definition: uORB.h:134
bool is_advertised() const
Return true if this topic has been advertised.
#define ORBIOCISADVERTISED
Check whether the topic is advertised, sets *(unsigned long *)arg to 1 if advertised, 0 otherwise.
Definition: drv_orb_dev.h:77
int fd
Definition: dataman.cpp:146
int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data)
Publish new data to a topic.
virtual int16_t register_handler(uORBCommunicator::IChannelRxHandler *handler)=0
Register Message Handler.
int orb_subscribe_multi(const struct orb_metadata *meta, unsigned instance)
Subscribe to a multi-instance of a topic.
static int start()
Definition: dataman.cpp:1452
int orb_copy(const struct orb_metadata *meta, int handle, void *buffer)
Fetch data from a topic.
static Manager * _Instance
int orb_exists(const struct orb_metadata *meta, int instance)
Check if a topic has already been created and published (advertised)
static constexpr unsigned orb_maxpath
Definition: uORBCommon.hpp:45
Object metadata.
Definition: uORB.h:50
int px4_open(const char *path, int flags,...)
#define ORBIOCUPDATED
Check whether the topic has been updated since it was last read, sets *(bool *)arg.
Definition: drv_orb_dev.h:59
#define ORBIOCLASTUPDATE
Fetch the time at which the topic was last updated into *(uint64_t *)arg.
Definition: drv_orb_dev.h:56
#define ORB_MULTI_MAX_INSTANCES
Maximum number of multi topic instances.
Definition: uORB.h:62
Interface to enable remote subscriptions.
const uint16_t o_size
object size
Definition: uORB.h:52
int orb_get_interval(int handle, unsigned *interval)
Get the minimum interval between which updates are seen for a subscription.
#define OK
Definition: uavcan_main.cpp:71
#define ORBIOCSETQUEUESIZE
Set the queue size of the topic.
Definition: drv_orb_dev.h:71
static int unadvertise(orb_advert_t handle)
#define ORBIOCGADVERTISER
Get the global advertiser handle for the topic.
Definition: drv_orb_dev.h:65
Master control device for ObjDev.
int orb_check(int handle, bool *updated)
Check whether a topic has been published to since the last orb_copy.
int px4_access(const char *pathname, int mode)
int orb_stat(int handle, uint64_t *time)
Return the last time that the topic was updated.
uORB::DeviceNode * getDeviceNode(const char *node_name)
Public interface for getDeviceNodeLocked().
static int node_mkpath(char *buf, const struct orb_metadata *meta, int *instance=nullptr)
Definition: uORBUtils.cpp:38
int advertise(const struct orb_metadata *meta, bool is_advertiser, int *instance, int priority)
int px4_close(int fd)
This is implemented as a singleton.
Definition: uORBManager.hpp:64
int px4_ioctl(int fd, int cmd, unsigned long arg)