34 #include <sys/types.h> 39 #include <px4_platform_common/px4_config.h> 40 #include <px4_platform_common/posix.h> 41 #include <px4_platform_common/tasks.h> 71 #ifdef ORB_USE_PUBLISHER_RULES 72 const char *file_name = PX4_STORAGEDIR
"/orb_publisher.rules";
73 int ret = readPublisherRulesFromFile(file_name, _publisher_rule);
76 _has_publisher_rules =
true;
77 PX4_INFO(
"Using orb rules from %s", file_name);
80 PX4_ERR(
"Failed to read publisher rules file %s (%s)", file_name, strerror(-ret));
98 PX4_ERR(
"Failed to allocate DeviceMaster");
118 if (node !=
nullptr) {
125 #ifdef ORB_COMMUNICATOR 142 if (ret == -1 && meta !=
nullptr && !_remote_topics.empty()) {
143 ret = (_remote_topics.find(meta->
o_name) != _remote_topics.end()) ?
OK : PX4_ERROR;
153 unsigned long is_advertised;
156 if (!is_advertised) {
171 int priority,
unsigned int queue_size)
173 #ifdef ORB_USE_PUBLISHER_RULES 176 if (_has_publisher_rules) {
177 const char *prog_name = px4_get_taskname();
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);
188 if (findTopic(_publisher_rule, meta->
o_name)) {
189 PX4_DEBUG(
"not allowing %s to publish topic %s", prog_name, meta->
o_name);
198 int fd =
node_open(meta,
true, instance, priority);
200 if (fd == PX4_ERROR) {
201 PX4_ERR(
"%s advertise failed (%i)", meta->
o_name, errno);
210 if (result < 0 && queue_size > 1) {
211 PX4_WARN(
"orb_advertise_multi: failed to set queue size");
220 if (result == PX4_ERROR) {
221 PX4_WARN(
"px4_ioctl ORBIOCGADVERTISER failed. fd = %d", fd);
225 #ifdef ORB_COMMUNICATOR 227 uORB::DeviceNode::topic_advertised(meta, priority);
233 if (result == PX4_ERROR) {
234 PX4_WARN(
"orb_publish failed");
243 #ifdef ORB_USE_PUBLISHER_RULES 272 #ifdef ORB_USE_PUBLISHER_RULES 293 if (ret != (
int)meta->
o_size) {
339 if ((PX4_OK != ret) && (EEXIST == errno)) {
356 if (
nullptr == meta) {
363 if (!instance || !advertiser) {
375 fd =
px4_open(path, advertiser ? PX4_F_WRONLY : PX4_F_RDONLY);
399 fd =
px4_open(path, (advertiser) ? PX4_F_WRONLY : PX4_F_RDONLY);
423 #ifdef ORB_COMMUNICATOR 426 _comm_channel = channel;
428 if (_comm_channel !=
nullptr) {
435 return _comm_channel;
438 int16_t uORB::Manager::process_remote_topic(
const char *topic_name,
bool isAdvertisement)
442 if (isAdvertisement) {
443 _remote_topics.insert(topic_name);
446 _remote_topics.erase(topic_name);
452 int16_t uORB::Manager::process_add_subscription(
const char *messageName, int32_t msgRateInHz)
454 PX4_DEBUG(
"entering Manager_process_add_subscription: name: %s", messageName);
457 _remote_subscriber_topics.insert(messageName);
462 if (ret ==
OK && device_master) {
465 if (node ==
nullptr) {
466 PX4_DEBUG(
"DeviceNode(%s) not created yet", messageName);
470 node->process_add_subscription(msgRateInHz);
480 int16_t uORB::Manager::process_remove_subscription(
const char *messageName)
483 _remote_subscriber_topics.erase(messageName);
488 if (ret ==
OK && device_master) {
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);
498 node->process_remove_subscription();
506 int16_t uORB::Manager::process_received_message(
const char *messageName, int32_t length, uint8_t *
data)
513 if (ret ==
OK && device_master) {
517 if (node ==
nullptr) {
518 PX4_DEBUG(
"No existing subscriber found for message: [%s] nodepath:[%s]", messageName, nodepath);
522 node->process_received_message(length, data);
530 bool uORB::Manager::is_remote_subscriber_present(
const char *messageName)
533 return _remote_subscriber_topics.find(messageName);
535 return (_remote_subscriber_topics.find(messageName) != _remote_subscriber_topics.end());
540 #ifdef ORB_USE_PUBLISHER_RULES 542 bool uORB::Manager::startsWith(
const char *pre,
const char *str)
544 size_t lenpre = strlen(pre),
545 lenstr = strlen(str);
546 return lenstr < lenpre ? false : strncmp(pre, str, lenpre) == 0;
549 bool uORB::Manager::findTopic(
const PublisherRule &rule,
const char *topic_name)
551 const char **topics_ptr = rule.topics;
553 while (*topics_ptr) {
554 if (strcmp(*topics_ptr, topic_name) == 0) {
564 void uORB::Manager::strTrim(
const char **str)
566 while (**str ==
' ' || **str ==
'\t') { ++(*str); }
569 int uORB::Manager::readPublisherRulesFromFile(
const char *file_name, PublisherRule &rule)
572 static const int line_len = 1024;
574 char *line =
new char[line_len];
580 fp = fopen(file_name,
"r");
587 const char *restrict_topics_str =
"restrict_topics:";
588 const char *module_str =
"module:";
589 const char *ignore_others =
"ignore_others:";
591 rule.ignore_other_topics =
false;
592 rule.module_name =
nullptr;
593 rule.topics =
nullptr;
595 while (fgets(line, line_len, fp) && ret == PX4_OK) {
597 if (strlen(line) < 2 || line[0] ==
'#') {
601 if (startsWith(restrict_topics_str, line)) {
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;
608 for (
int i = 0; topics[i]; ++i) {
609 if (topics[i] ==
',' || topics[i] ==
'\n') {
622 if (num_topics > 0) {
623 rule.topics =
new const char *[num_topics + 1];
625 strTrim((
const char **)&topics);
626 rule.topics[topic++] = topics;
628 while (topic < num_topics) {
631 strTrim((
const char **)&topics);
632 rule.topics[topic++] = topics;
639 rule.topics[num_topics] =
nullptr;
642 }
else if (startsWith(module_str, line)) {
644 char *
start = line + strlen(module_str);
645 strTrim((
const char **)&start);
646 int len = strlen(start);
648 if (len > 0 && start[len - 1] ==
'\n') {
652 rule.module_name = strdup(start);
654 }
else if (startsWith(ignore_others, line)) {
655 const char *
start = line + strlen(ignore_others);
658 if (startsWith(
"true", start)) {
659 rule.ignore_other_topics =
true;
663 PX4_ERR(
"orb rules file: wrong format: %s", line);
668 if (ret == PX4_OK && (!rule.module_name || !rule.topics)) {
669 PX4_ERR(
"Wrong format in orb publisher rules file");
int node_advertise(const struct orb_metadata *meta, bool is_advertiser, int *instance=nullptr, int priority=ORB_PRIO_DEFAULT)
Advertise a node; don'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
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.
static bool initialize()
Initialize the singleton.
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.
#define ORBIOCGPRIORITY
Get the priority for the topic.
#define ORBIOCSETINTERVAL
Set the minimum interval at which the topic can be seen to be updated for this subscription.
static bool terminate()
Terminate the singleton.
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.
int orb_unadvertise(orb_advert_t handle)
Unadvertise a topic.
Per-object device instance.
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.
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.
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.
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
#define ORBIOCUPDATED
Check whether the topic has been updated since it was last read, sets *(bool *)arg.
#define ORBIOCLASTUPDATE
Fetch the time at which the topic was last updated into *(uint64_t *)arg.
#define ORB_MULTI_MAX_INSTANCES
Maximum number of multi topic instances.
Interface to enable remote subscriptions.
int orb_get_interval(int handle, unsigned *interval)
Get the minimum interval between which updates are seen for a subscription.
#define ORBIOCSETQUEUESIZE
Set the queue size of the topic.
static int unadvertise(orb_advert_t handle)
#define ORBIOCGADVERTISER
Get the global advertiser handle for the topic.
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 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)
int advertise(const struct orb_metadata *meta, bool is_advertiser, int *instance, int priority)
This is implemented as a singleton.