static int
ng_btsocket_hci_raw_node_rcvdata(hook_p hook, item_p item)
{
	struct mbuf	*nam = NULL;
	int		 error;

	/*
	 * Check for empty sockets list creates LOR when both sender and
	 * receiver device are connected to the same host, so remove it
	 * for now
	 */

	MGET(nam, M_NOWAIT, MT_SONAME);
	if (nam != NULL) {
		struct sockaddr_hci	*sa = mtod(nam, struct sockaddr_hci *);

		nam->m_len = sizeof(struct sockaddr_hci);

		sa->hci_len = sizeof(*sa);
		sa->hci_family = AF_BLUETOOTH;
		strlcpy(sa->hci_node, NG_PEER_NODE_NAME(hook),
			sizeof(sa->hci_node));

		NGI_GET_M(item, nam->m_next);
		NGI_M(item) = nam;

		lockmgr(&ng_btsocket_hci_raw_queue_lock, LK_EXCLUSIVE);
		if (NG_BT_ITEMQ_FULL(&ng_btsocket_hci_raw_queue)) {
			NG_BTSOCKET_HCI_RAW_ERR(
"%s: Input queue is full\n", __func__);

			NG_BT_ITEMQ_DROP(&ng_btsocket_hci_raw_queue);
			NG_FREE_ITEM(item);
			error = ENOBUFS;
		} else {
			ng_ref_item(item);
			NG_BT_ITEMQ_ENQUEUE(&ng_btsocket_hci_raw_queue, item);
			error = ng_btsocket_hci_raw_wakeup_input_task();
		}
		lockmgr(&ng_btsocket_hci_raw_queue_lock, LK_RELEASE);
	} else {
Example #2
0
/*
 * Receive data on a hook
 *
 * If data comes in the right link send a copy out right2left, and then
 * send the original onwards out through the left link.
 * Do the opposite for data coming in from the left link.
 * Data coming in right2left or left2right is forwarded
 * on through the appropriate destination hook as if it had come
 * from the other side.
 */
static int
ngt_rcvdata(hook_p hook, item_p item)
{
	const sc_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
	struct hookinfo *const hinfo = NG_HOOK_PRIVATE(hook);
	struct hookinfo *dest;
	struct hookinfo *dup;
	int error = 0;
	struct mbuf *m;
	meta_p meta;

	m = NGI_M(item);
	meta = NGI_META(item); /* leave these owned by the item */
	/* Which hook? */
	if (hinfo == &sc->left) {
		dup = &sc->left2right;
		dest = &sc->right;
	} else if (hinfo == &sc->right) {
		dup = &sc->right2left;
		dest = &sc->left;
	} else if (hinfo == &sc->right2left) {
		dup = NULL;
		dest = &sc->right;
	} else if (hinfo == &sc->left2right) {
		dup = NULL;
		dest = &sc->left;
	} else {
		panic("%s: no hook!", __func__);
#ifdef	RESTARTABLE_PANICS
		return(EINVAL);
#endif
	}

	/* Update stats on incoming hook */
	hinfo->stats.inOctets += m->m_pkthdr.len;
	hinfo->stats.inFrames++;

	/*
	 * Don't make a copy if only the dup hook exists.
	 */
	if ((dup && dup->hook) && (dest->hook == NULL)) {
		dest = dup;
		dup = NULL;
	}

	/* Duplicate packet and meta info if requried */
	if (dup != NULL) {
		struct mbuf *m2;
		meta_p meta2;

		/* Copy packet (failure will not stop the original)*/
		m2 = m_dup(m, M_NOWAIT);
		if (m2) {

			/* Copy meta info */
			/* If we can't get a copy, tough.. */
			if (meta != NULL) {
				meta2 = ng_copy_meta(meta);
			} else
				meta2 = NULL;

			/* Deliver duplicate */
			dup->stats.outOctets += m->m_pkthdr.len;
			dup->stats.outFrames++;
			NG_SEND_DATA(error, dup->hook, m2, meta2);
		}
	}
	/* Deliver frame out destination hook */
	dest->stats.outOctets += m->m_pkthdr.len;
	dest->stats.outFrames++;
	if (dest->hook)
		NG_FWD_ITEM_HOOK(error, item, dest->hook);
	else
		NG_FREE_ITEM(item);
	return (0);
}