int uORB::Manager::node_open ( Flavor f, const struct orb_metadata *meta, const void *data, bool advertiser, int *instance, int priority ) { char path[orb_maxpath]; int fd, ret; /* * If meta is null, the object was not defined, i.e. it is not * known to the system. We can't advertise/subscribe such a thing. */ if (nullptr == meta) { errno = ENOENT; return ERROR; } /* * Advertiser must publish an initial value. */ if (advertiser && (data == nullptr)) { errno = EINVAL; return ERROR; } /* * Generate the path to the node and try to open it. */ ret = uORB::Utils::node_mkpath(path, f, meta, instance); if (ret != OK) { errno = -ret; return ERROR; } /* open the path as either the advertiser or the subscriber */ fd = open(path, (advertiser) ? O_WRONLY : O_RDONLY); /* if we want to advertise and the node existed, we have to re-try again */ if ((fd >= 0) && (instance != nullptr) && (advertiser)) { /* close the fd, we want a new one */ close(fd); /* the node_advertise call will automatically go for the next free entry */ fd = -1; } /* we may need to advertise the node... */ if (fd < 0) { /* try to create the node */ ret = node_advertise(meta, instance, priority); if (ret == OK) { /* update the path, as it might have been updated during the node_advertise call */ ret = uORB::Utils::node_mkpath(path, f, meta, instance); if (ret != OK) { errno = -ret; return ERROR; } } /* on success, try the open again */ if (ret == OK) { fd = open(path, (advertiser) ? O_WRONLY : O_RDONLY); } } if (fd < 0) { errno = EIO; return ERROR; } /* everything has been OK, we can return the handle now */ return fd; }
int uORB::Manager::node_open(const struct orb_metadata *meta, const void *data, bool advertiser, int *instance, int priority) { char path[orb_maxpath]; int fd = -1, ret; /* * If meta is null, the object was not defined, i.e. it is not * known to the system. We can't advertise/subscribe such a thing. */ if (nullptr == meta) { errno = ENOENT; return PX4_ERROR; } /* * Advertiser must publish an initial value. */ if (advertiser && (data == nullptr)) { errno = EINVAL; return PX4_ERROR; } /* if we have an instance and are an advertiser, we will generate a new node and set the instance, * so we do not need to open here */ if (!instance || !advertiser) { /* * Generate the path to the node and try to open it. */ ret = uORB::Utils::node_mkpath(path, meta, instance); if (ret != OK) { errno = -ret; return PX4_ERROR; } /* open the path as either the advertiser or the subscriber */ fd = px4_open(path, advertiser ? PX4_F_WRONLY : PX4_F_RDONLY); } else { *instance = 0; } /* we may need to advertise the node... */ if (fd < 0) { /* try to create the node */ ret = node_advertise(meta, instance, priority); if (ret == PX4_OK) { /* update the path, as it might have been updated during the node_advertise call */ ret = uORB::Utils::node_mkpath(path, meta, instance); if (ret != PX4_OK) { errno = -ret; return PX4_ERROR; } } /* on success, try the open again */ if (ret == PX4_OK) { fd = px4_open(path, (advertiser) ? PX4_F_WRONLY : PX4_F_RDONLY); } } /* else if (advertiser) { * We have a valid fd and are an advertiser. * This can happen if the topic is already subscribed/published, and orb_advertise() is called, * where instance==nullptr. * We would need to set the priority here (via px4_ioctl(fd, ...) and a new IOCTL), but orb_advertise() * uses ORB_PRIO_DEFAULT, and a subscriber also creates the node with ORB_PRIO_DEFAULT. So we don't need * to do anything here. } */ if (fd < 0) { errno = EIO; return PX4_ERROR; } /* everything has been OK, we can return the handle now */ return fd; }