Пример #1
0
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;
}
Пример #2
0
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;
}