Ejemplo n.º 1
0
int
ng_l2cap_lp_qos_req(ng_l2cap_p l2cap, u_int16_t con_handle,
		ng_l2cap_flow_p flow)
{
	struct ng_mesg		*msg = NULL;
	ng_hci_lp_qos_req_ep	*ep = NULL;
	ng_l2cap_con_p		 con = NULL;
	int			 error = 0;

	/* Verify that we have this connection */
	con = ng_l2cap_con_by_handle(l2cap, con_handle);
	if (con == NULL) {
		NG_L2CAP_ERR(
"%s: %s - unexpected LP_QoSSetupReq event. " \
"Connection does not exist, con_handle=%d\n",
			__func__, NG_NODE_NAME(l2cap->node), con_handle);

		return (ENOENT);
	}

	/* Verify connection state */
	if (con->state != NG_L2CAP_CON_OPEN) {
		NG_L2CAP_ERR(
"%s: %s - unexpected LP_QoSSetupReq event. " \
"Invalid connection state, state=%d, con_handle=%d\n",
			__func__, NG_NODE_NAME(l2cap->node), con->state,
			con->con_handle);

		return (EINVAL);
	}

	/* Check if lower layer protocol is still connected */
	if (l2cap->hci == NULL || NG_HOOK_NOT_VALID(l2cap->hci)) {
		NG_L2CAP_ERR(
"%s: %s - hook \"%s\" is not connected or valid",
			__func__, NG_NODE_NAME(l2cap->node), NG_L2CAP_HOOK_HCI);

		return (ENOTCONN);
	}

	/* Create and send LP_QoSSetupReq event */
	NG_MKMESSAGE(msg, NGM_HCI_COOKIE, NGM_HCI_LP_QOS_REQ,
		sizeof(*ep), M_NOWAIT);
	if (msg == NULL)
		return (ENOMEM);

	ep = (ng_hci_lp_qos_req_ep *) (msg->data);
	ep->con_handle = con_handle;
	ep->flags = flow->flags;
	ep->service_type = flow->service_type;
	ep->token_rate = flow->token_rate;
	ep->peak_bandwidth = flow->peak_bandwidth;
	ep->latency = flow->latency;
	ep->delay_variation = flow->delay_variation;

	NG_SEND_MSG_HOOK(error, l2cap->node, msg, l2cap->hci, 0);
	
	return (error);
} /* ng_l2cap_lp_con_req */
Ejemplo n.º 2
0
int
ng_l2cap_lp_discon_ind(ng_l2cap_p l2cap, struct ng_mesg *msg)
{
	ng_hci_lp_discon_ind_ep	*ep = NULL;
	ng_l2cap_con_p		 con = NULL;
	int			 error = 0;

	/* Check message */
	if (msg->header.arglen != sizeof(*ep)) {
		NG_L2CAP_ALERT(
"%s: %s - invalid LP_DisconnectInd message size\n",
			__func__, NG_NODE_NAME(l2cap->node));
		error = EMSGSIZE;
		goto out;
	}

	ep = (ng_hci_lp_discon_ind_ep *) (msg->data);

	/* Check if we have this connection */
	con = ng_l2cap_con_by_handle(l2cap, ep->con_handle);
	if (con == NULL) {
		NG_L2CAP_ERR(
"%s: %s - unexpected LP_DisconnectInd event. " \
"Connection does not exist, con_handle=%d\n",
			__func__, NG_NODE_NAME(l2cap->node), ep->con_handle);
		error = ENOENT;
		goto out;
	}

	/* XXX Verify connection state -- do we need to check this? */
	if (con->state != NG_L2CAP_CON_OPEN) {
		NG_L2CAP_ERR(
"%s: %s - unexpected LP_DisconnectInd event. " \
"Invalid connection state, state=%d, con_handle=%d\n",
			__func__, NG_NODE_NAME(l2cap->node), con->state, 
			con->con_handle);
		error = EINVAL;
		goto out;
	}

	/*
	 * Notify upper layer and remove connection
	 * Note: The connection could have auto disconnect timeout set. Try
	 * to remove it. If auto disconnect timeout happened then ignore
	 * disconnect indication and let timeout handle that.
	 */

	if (con->flags & NG_L2CAP_CON_AUTO_DISCON_TIMO)
		if ((error = ng_l2cap_discon_untimeout(con)) != 0)
			return (error);

	ng_l2cap_con_fail(con, ep->reason);
out:
	return (error);
} /* ng_l2cap_lp_discon_ind */
Ejemplo n.º 3
0
int
ng_l2cap_lp_discon_ind(ng_l2cap_p l2cap, struct ng_mesg *msg)
{
	ng_hci_lp_discon_ind_ep	*ep = NULL;
	ng_l2cap_con_p		 con = NULL;
	int			 error = 0;

	/* Check message */
	if (msg->header.arglen != sizeof(*ep)) {
		NG_L2CAP_ALERT(
"%s: %s - invalid LP_DisconnectInd message size\n",
			__func__, NG_NODE_NAME(l2cap->node));
		error = EMSGSIZE;
		goto out;
	}

	ep = (ng_hci_lp_discon_ind_ep *) (msg->data);

	/* Check if we have this connection */
	con = ng_l2cap_con_by_handle(l2cap, ep->con_handle);
	if (con == NULL) {
		NG_L2CAP_ERR(
"%s: %s - unexpected LP_DisconnectInd event. " \
"Connection does not exist, con_handle=%d\n",
			__func__, NG_NODE_NAME(l2cap->node), ep->con_handle);
		error = ENOENT;
		goto out;
	}

	/* XXX Verify connection state -- do we need to check this? */
	if (con->state != NG_L2CAP_CON_OPEN) {
		NG_L2CAP_ERR(
"%s: %s - unexpected LP_DisconnectInd event. " \
"Invalid connection state, state=%d, con_handle=%d\n",
			__func__, NG_NODE_NAME(l2cap->node), con->state, 
			con->con_handle);
		error = EINVAL;
		goto out;
	}

	/* Notify upper layer and remove connection */
	con->state = NG_L2CAP_CON_CLOSED;
	ng_l2cap_con_fail(con, ep->reason);
out:
	return (error);
} /* ng_l2cap_lp_discon_ind */
Ejemplo n.º 4
0
int
ng_l2cap_lp_qos_ind(ng_l2cap_p l2cap, struct ng_mesg *msg)
{
	ng_hci_lp_qos_ind_ep	*ep = NULL;
	ng_l2cap_con_p		 con = NULL;
	int			 error = 0;

	/* Check message */
	if (msg->header.arglen != sizeof(*ep)) {
		NG_L2CAP_ALERT(
"%s: %s - invalid LP_QoSViolation message size\n",
			__func__, NG_NODE_NAME(l2cap->node));
		error = EMSGSIZE;
		goto out;
	}

	ep = (ng_hci_lp_qos_ind_ep *) (msg->data);

	/* Check if we have this connection */
	con = ng_l2cap_con_by_handle(l2cap, ep->con_handle);
	if (con == NULL) {
		NG_L2CAP_ERR(
"%s: %s - unexpected LP_QoSViolationInd event. " \
"Connection does not exist, con_handle=%d\n",
			__func__, NG_NODE_NAME(l2cap->node), ep->con_handle);
		error = ENOENT;
		goto out;
	}

	/* Verify connection state */
	if (con->state != NG_L2CAP_CON_OPEN) {
		NG_L2CAP_ERR(
"%s: %s - unexpected LP_QoSViolationInd event. " \
"Invalid connection state, state=%d, con_handle=%d\n",
			__func__, NG_NODE_NAME(l2cap->node), con->state, 
			con->con_handle);
		error = EINVAL;
		goto out;
	}

	/* XXX FIXME Notify upper layer and terminate channels if required */
out:
	return (error);
} /* ng_l2cap_qos_ind */
Ejemplo n.º 5
0
int
ng_l2cap_lp_receive(ng_l2cap_p l2cap, struct mbuf *m)
{
	ng_hci_acldata_pkt_t	*acl_hdr = NULL;
	ng_l2cap_hdr_t		*l2cap_hdr = NULL;
	ng_l2cap_con_p		 con = NULL;
	u_int16_t		 con_handle, length, pb;
	int			 error = 0;

	/* Check ACL data packet */
	if (m->m_pkthdr.len < sizeof(*acl_hdr)) {
		NG_L2CAP_ERR(
"%s: %s - invalid ACL data packet. Packet too small, length=%d\n",
			__func__, NG_NODE_NAME(l2cap->node), m->m_pkthdr.len);
		error = EMSGSIZE;
		goto drop;
	}

	/* Strip ACL data packet header */
	NG_L2CAP_M_PULLUP(m, sizeof(*acl_hdr));
	if (m == NULL)
		return (ENOBUFS);

	acl_hdr = mtod(m, ng_hci_acldata_pkt_t *);
	m_adj(m, sizeof(*acl_hdr));

	/* Get ACL connection handle, PB flag and payload length */
	acl_hdr->con_handle = le16toh(acl_hdr->con_handle);
	con_handle = NG_HCI_CON_HANDLE(acl_hdr->con_handle);
	pb = NG_HCI_PB_FLAG(acl_hdr->con_handle);
	length = le16toh(acl_hdr->length);

	NG_L2CAP_INFO(
"%s: %s - got ACL data packet, con_handle=%d, PB=%#x, length=%d\n",
		__func__, NG_NODE_NAME(l2cap->node), con_handle, pb, length);

	/* Get connection descriptor */
	con = ng_l2cap_con_by_handle(l2cap, con_handle);
	if (con == NULL) {
		NG_L2CAP_ERR(
"%s: %s - unexpected ACL data packet. " \
"Connection does not exist, con_handle=%d\n",
			__func__, NG_NODE_NAME(l2cap->node), con_handle);
		error = ENOENT;
		goto drop;
	}

	/* Verify connection state */
	if (con->state != NG_L2CAP_CON_OPEN) {
		NG_L2CAP_ERR(
"%s: %s - unexpected ACL data packet. Invalid connection state=%d\n",
			__func__, NG_NODE_NAME(l2cap->node), con->state);
		error = EHOSTDOWN;
		goto drop;
	}

	/* Process packet */
	if (pb == NG_HCI_PACKET_START) {
		if (con->rx_pkt != NULL) {
			NG_L2CAP_ERR(
"%s: %s - dropping incomplete L2CAP packet, got %d bytes, want %d bytes\n",
				__func__, NG_NODE_NAME(l2cap->node),
				con->rx_pkt->m_pkthdr.len, con->rx_pkt_len);
			NG_FREE_M(con->rx_pkt);
			con->rx_pkt_len = 0;
		}

		/* Get L2CAP header */
		if (m->m_pkthdr.len < sizeof(*l2cap_hdr)) {
			NG_L2CAP_ERR(
"%s: %s - invalid L2CAP packet start fragment. Packet too small, length=%d\n",
				__func__, NG_NODE_NAME(l2cap->node),
				m->m_pkthdr.len);
			error = EMSGSIZE;
			goto drop;
		}

		NG_L2CAP_M_PULLUP(m, sizeof(*l2cap_hdr));
		if (m == NULL)
			return (ENOBUFS);

		l2cap_hdr = mtod(m, ng_l2cap_hdr_t *);

		NG_L2CAP_INFO(
"%s: %s - staring new L2CAP packet, con_handle=%d, length=%d\n",
			__func__, NG_NODE_NAME(l2cap->node), con_handle,
			le16toh(l2cap_hdr->length));

		/* Start new L2CAP packet */
		con->rx_pkt = m;
		con->rx_pkt_len = le16toh(l2cap_hdr->length)+sizeof(*l2cap_hdr);
	} else if (pb == NG_HCI_PACKET_FRAGMENT) {