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 {
/* * 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); }