FreeBSD/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c
/*
 * SCO sockets default message input routine
 */
SCO sockets default message input routine
SCO sockets default message input routine
static void
ng_btsocket_sco_default_msg_input(struct ng_mesg *msg, hook_p hook)
{
	ng_btsocket_sco_rtentry_t	*rt = NULL;
	if (hook == NULL || NG_HOOK_NOT_VALID(hook))
		return;
	rt = (ng_btsocket_sco_rtentry_t *) NG_HOOK_PRIVATE(hook);
	switch (msg->header.cmd) {
	case NGM_HCI_NODE_UP: {
		ng_hci_node_up_ep	*ep = NULL;
		if (msg->header.arglen != sizeof(*ep))
			break;
		ep = (ng_hci_node_up_ep *)(msg->data);
		if (bcmp(&ep->bdaddr, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0)
			break;
		if (rt == NULL) {
			rt = malloc(sizeof(*rt),
				M_NETGRAPH_BTSOCKET_SCO, M_NOWAIT|M_ZERO);
			if (rt == NULL)
				break;
			NG_HOOK_SET_PRIVATE(hook, rt);
			mtx_lock(&ng_btsocket_sco_rt_mtx);
			LIST_INSERT_HEAD(&ng_btsocket_sco_rt, rt, next);
		} else
			mtx_lock(&ng_btsocket_sco_rt_mtx);
		bcopy(&ep->bdaddr, &rt->src, sizeof(rt->src));
		rt->pkt_size = (ep->pkt_size == 0)? 60 : ep->pkt_size;
		rt->num_pkts = ep->num_pkts;
		rt->hook = hook;
		mtx_unlock(&ng_btsocket_sco_rt_mtx);
		NG_BTSOCKET_SCO_INFO(
"%s: Updating hook \"%s\", src bdaddr=%x:%x:%x:%x:%x:%x, pkt_size=%d, " \
"num_pkts=%d\n",	__func__, NG_HOOK_NAME(hook), 
			rt->src.b[5], rt->src.b[4], rt->src.b[3], 
			rt->src.b[2], rt->src.b[1], rt->src.b[0],
			rt->pkt_size, rt->num_pkts);
		} break;
	case NGM_HCI_SYNC_CON_QUEUE: {
		ng_hci_sync_con_queue_ep	*ep = NULL;
		ng_btsocket_sco_pcb_t		*pcb = NULL;
		if (rt == NULL || msg->header.arglen != sizeof(*ep))
			break;
		ep = (ng_hci_sync_con_queue_ep *)(msg->data);
		rt->pending -= ep->completed;
		if (rt->pending < 0) {
			NG_BTSOCKET_SCO_WARN(
"%s: Pending packet counter is out of sync! bdaddr=%x:%x:%x:%x:%x:%x, " \
"handle=%d, pending=%d, completed=%d\n",
				__func__,
				rt->src.b[5], rt->src.b[4], rt->src.b[3],
				rt->src.b[2], rt->src.b[1], rt->src.b[0],
				ep->con_handle, rt->pending,
				ep->completed);
			rt->pending = 0;
		}
		mtx_lock(&ng_btsocket_sco_sockets_mtx);
		pcb = ng_btsocket_sco_pcb_by_handle(&rt->src, ep->con_handle);
		if (pcb == NULL) {
			mtx_unlock(&ng_btsocket_sco_sockets_mtx);
			break;
		}
		if (pcb->state == NG_BTSOCKET_SCO_OPEN) {
			ng_btsocket_sco_untimeout(pcb);
			for (; ep->completed > 0; ep->completed --)
				sbdroprecord(&pcb->so->so_snd);
			if (sbavail(&pcb->so->so_snd) > 0)
				if (ng_btsocket_sco_send2(pcb) == 0)
					ng_btsocket_sco_timeout(pcb);
			sowwakeup(pcb->so);
		}
		mtx_unlock(&pcb->pcb_mtx);
		mtx_unlock(&ng_btsocket_sco_sockets_mtx);
	} break;
	default:
		NG_BTSOCKET_SCO_WARN(
"%s: Unknown message, cmd=%d\n", __func__, msg->header.cmd);
		break;
	}
	NG_FREE_MSG(msg); 
}
static void ng_btsocket_sco_default_msg_input ( struct ng_mesg * msg , hook_p hook ) { ng_btsocket_sco_rtentry_t * rt = NULL ; if ( hook == NULL || NG_HOOK_NOT_VALID ( hook ) ) return ; rt = ( ng_btsocket_sco_rtentry_t * ) NG_HOOK_PRIVATE ( hook ) ; switch ( msg -> header . cmd ) { case NGM_HCI_NODE_UP : { ng_hci_node_up_ep * ep = NULL ; if ( msg -> header . arglen != sizeof ( * ep ) ) break ; ep = ( ng_hci_node_up_ep * ) ( msg -> data ) ; if ( bcmp ( & ep -> bdaddr , NG_HCI_BDADDR_ANY , sizeof ( bdaddr_t ) ) == 0 ) break ; if ( rt == NULL ) { rt = malloc ( sizeof ( * rt ) , M_NETGRAPH_BTSOCKET_SCO , M_NOWAIT | M_ZERO ) ; if ( rt == NULL ) break ; NG_HOOK_SET_PRIVATE ( hook , rt ) ; mtx_lock ( & ng_btsocket_sco_rt_mtx ) ; LIST_INSERT_HEAD ( & ng_btsocket_sco_rt , rt , next ) ; } else mtx_lock ( & ng_btsocket_sco_rt_mtx ) ; bcopy ( & ep -> bdaddr , & rt -> src , sizeof ( rt -> src ) ) ; rt -> pkt_size = ( ep -> pkt_size == 0 ) ? 60 : ep -> pkt_size ; rt -> num_pkts = ep -> num_pkts ; rt -> hook = hook ; mtx_unlock ( & ng_btsocket_sco_rt_mtx ) ; NG_BTSOCKET_SCO_INFO ( " \" \" " " \n " , __func__ , NG_HOOK_NAME ( hook ) , rt -> src . b [ 5 ] , rt -> src . b [ 4 ] , rt -> src . b [ 3 ] , rt -> src . b [ 2 ] , rt -> src . b [ 1 ] , rt -> src . b [ 0 ] , rt -> pkt_size , rt -> num_pkts ) ; } break ; case NGM_HCI_SYNC_CON_QUEUE : { ng_hci_sync_con_queue_ep * ep = NULL ; ng_btsocket_sco_pcb_t * pcb = NULL ; if ( rt == NULL || msg -> header . arglen != sizeof ( * ep ) ) break ; ep = ( ng_hci_sync_con_queue_ep * ) ( msg -> data ) ; rt -> pending -= ep -> completed ; if ( rt -> pending < 0 ) { NG_BTSOCKET_SCO_WARN ( " " " \n " , __func__ , rt -> src . b [ 5 ] , rt -> src . b [ 4 ] , rt -> src . b [ 3 ] , rt -> src . b [ 2 ] , rt -> src . b [ 1 ] , rt -> src . b [ 0 ] , ep -> con_handle , rt -> pending , ep -> completed ) ; rt -> pending = 0 ; } mtx_lock ( & ng_btsocket_sco_sockets_mtx ) ; pcb = ng_btsocket_sco_pcb_by_handle ( & rt -> src , ep -> con_handle ) ; if ( pcb == NULL ) { mtx_unlock ( & ng_btsocket_sco_sockets_mtx ) ; break ; } if ( pcb -> state == NG_BTSOCKET_SCO_OPEN ) { ng_btsocket_sco_untimeout ( pcb ) ; for ( ; ep -> completed > 0 ; ep -> completed -- ) sbdroprecord ( & pcb -> so -> so_snd ) ; if ( sbavail ( & pcb -> so -> so_snd ) > 0 ) if ( ng_btsocket_sco_send2 ( pcb ) == 0 ) ng_btsocket_sco_timeout ( pcb ) ; sowwakeup ( pcb -> so ) ; } mtx_unlock ( & pcb -> pcb_mtx ) ; mtx_unlock ( & ng_btsocket_sco_sockets_mtx ) ; } break ; default : NG_BTSOCKET_SCO_WARN ( " \n " , __func__ , msg -> header . cmd ) ; break ; } NG_FREE_MSG ( msg ) ; }
SCO sockets default message input routine
SCO sockets default message input routine
/* Find socket */ /* pcb is locked */ /* Check state */ /* Remove timeout */ /* Drop completed packets from the send queue */ /* Send more if we have any */ /* Wake up writers */ /* Checks for msg != NULL */