Lines Matching +full:sco +full:- +full:routing
5 /*-
6 * SPDX-License-Identifier: BSD-2-Clause
8 * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
327 * the routing table and must schedule cleaning for the routing table.
329 * so we have never added this hook to the routing table and it save
351 if (msg != NULL && msg->header.typecookie == NGM_L2CAP_COOKIE) {
420 if (msg->header.arglen != sizeof(*op))
423 op = (ng_l2cap_l2ca_con_op *)(msg->data);
428 pcb = ng_btsocket_l2cap_pcb_by_token(msg->header.token);
434 mtx_lock(&pcb->pcb_mtx);
439 "state=%d\n", __func__, msg->header.token,
440 pcb->src.b[5], pcb->src.b[4], pcb->src.b[3],
441 pcb->src.b[2], pcb->src.b[1], pcb->src.b[0],
442 pcb->dst.b[5], pcb->dst.b[4], pcb->dst.b[3],
443 pcb->dst.b[2], pcb->dst.b[1], pcb->dst.b[0],
444 pcb->psm, op->lcid, op->result, op->status,
445 pcb->state);
447 if (pcb->state != NG_BTSOCKET_L2CAP_CONNECTING) {
448 mtx_unlock(&pcb->pcb_mtx);
456 if (op->result == NG_L2CAP_PENDING) {
458 mtx_unlock(&pcb->pcb_mtx);
464 if (op->result == NG_L2CAP_SUCCESS){
465 if((pcb->idtype == NG_L2CAP_L2CA_IDTYPE_ATT)||
466 (pcb->idtype == NG_L2CAP_L2CA_IDTYPE_SMP)){
467 pcb->encryption = op->encryption; pcb->cid = op->lcid;
468 if(pcb->need_encrypt && !(pcb->encryption)){
470 pcb->state = NG_BTSOCKET_L2CAP_W4_ENC_CHANGE;
472 pcb->state = NG_BTSOCKET_L2CAP_OPEN;
473 soisconnected(pcb->so);
482 pcb->cid = op->lcid;
483 pcb->encryption = op->encryption;
490 pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
491 soisdisconnected(pcb->so);
493 pcb->cfg_state = NG_BTSOCKET_L2CAP_CFG_IN_SENT;
494 pcb->state = NG_BTSOCKET_L2CAP_CONFIGURING;
506 pcb->so->so_error = ng_btsocket_l2cap_result2errno(op->result);
507 pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
508 soisdisconnected(pcb->so);
510 mtx_unlock(&pcb->pcb_mtx);
527 if (msg->header.arglen != sizeof(*op))
530 op = (ng_l2cap_l2ca_con_rsp_op *)(msg->data);
535 pcb = ng_btsocket_l2cap_pcb_by_token(msg->header.token);
541 mtx_lock(&pcb->pcb_mtx);
546 __func__, msg->header.token,
547 pcb->src.b[5], pcb->src.b[4], pcb->src.b[3],
548 pcb->src.b[2], pcb->src.b[1], pcb->src.b[0],
549 pcb->dst.b[5], pcb->dst.b[4], pcb->dst.b[3],
550 pcb->dst.b[2], pcb->dst.b[1], pcb->dst.b[0],
551 pcb->psm, pcb->cid, op->result, pcb->state);
553 if (pcb->state != NG_BTSOCKET_L2CAP_CONNECTING) {
554 mtx_unlock(&pcb->pcb_mtx);
563 if (op->result != NG_L2CAP_SUCCESS) {
564 /* Close the socket - channel already closed */
565 pcb->so->so_error = ng_btsocket_l2cap_result2errno(op->result);
566 pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
567 soisdisconnected(pcb->so);
570 pcb->cfg_state = 0;
571 pcb->state = NG_BTSOCKET_L2CAP_CONFIGURING;
575 mtx_unlock(&pcb->pcb_mtx);
597 if (msg->header.arglen != sizeof(*ip))
600 ip = (ng_l2cap_l2ca_con_ind_ip *)(msg->data);
606 rt->src.b[5], rt->src.b[4], rt->src.b[3],
607 rt->src.b[2], rt->src.b[1], rt->src.b[0],
608 ip->bdaddr.b[5], ip->bdaddr.b[4], ip->bdaddr.b[3],
609 ip->bdaddr.b[2], ip->bdaddr.b[1], ip->bdaddr.b[0],
610 ip->psm, ip->lcid, ip->ident);
614 pcb = ng_btsocket_l2cap_pcb_by_addr(&rt->src, ip->psm);
618 mtx_lock(&pcb->pcb_mtx);
620 CURVNET_SET(pcb->so->so_vnet);
621 so1 = sonewconn(pcb->so, 0);
632 * address from hook's routing information.
639 mtx_lock(&pcb1->pcb_mtx);
641 if (bcmp(&pcb->src, NG_HCI_BDADDR_ANY, sizeof(pcb->src)) != 0)
642 bcopy(&pcb->src, &pcb1->src, sizeof(pcb1->src));
644 bcopy(&rt->src, &pcb1->src, sizeof(pcb1->src));
646 pcb1->flags &= ~NG_BTSOCKET_L2CAP_CLIENT;
648 bcopy(&ip->bdaddr, &pcb1->dst, sizeof(pcb1->dst));
649 pcb1->psm = ip->psm;
650 pcb1->cid = ip->lcid;
651 pcb1->rt = rt;
654 pcb1->imtu = pcb->imtu;
655 bcopy(&pcb->oflow, &pcb1->oflow, sizeof(pcb1->oflow));
656 pcb1->flush_timo = pcb->flush_timo;
658 token = pcb1->token;
665 &ip->bdaddr,
666 ip->ident, ip->lcid,
667 result,ip->linktype);
670 pcb1->so->so_error = error;
671 pcb1->state = NG_BTSOCKET_L2CAP_CLOSED;
672 soisdisconnected(pcb1->so);
674 pcb1->state = NG_BTSOCKET_L2CAP_CONNECTING;
675 soisconnecting(pcb1->so);
680 mtx_unlock(&pcb1->pcb_mtx);
684 mtx_unlock(&pcb->pcb_mtx);
696 if (msg->header.arglen != sizeof(*op))
699 op = (ng_l2cap_l2ca_enc_chg_op *)(msg->data);
703 pcb = ng_btsocket_l2cap_pcb_by_cid(&rt->src, op->lcid,
704 op->idtype);
710 mtx_lock(&pcb->pcb_mtx);
711 pcb->encryption = op->result;
713 if(pcb->need_encrypt){
715 if(pcb->state != NG_BTSOCKET_L2CAP_W4_ENC_CHANGE){
717 __func__, pcb->state);
718 }else if(pcb->encryption){
719 pcb->state = NG_BTSOCKET_L2CAP_OPEN;
720 soisconnected(pcb->so);
722 pcb->so->so_error = EPERM;
724 pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
725 soisdisconnected(pcb->so);
728 mtx_unlock(&pcb->pcb_mtx);
744 if (msg->header.arglen != sizeof(*op))
747 op = (ng_l2cap_l2ca_cfg_op *)(msg->data);
757 pcb = ng_btsocket_l2cap_pcb_by_token(msg->header.token);
769 mtx_lock(&pcb->pcb_mtx);
775 __func__, msg->header.token,
776 pcb->src.b[5], pcb->src.b[4], pcb->src.b[3],
777 pcb->src.b[2], pcb->src.b[1], pcb->src.b[0],
778 pcb->dst.b[5], pcb->dst.b[4], pcb->dst.b[3],
779 pcb->dst.b[2], pcb->dst.b[1], pcb->dst.b[0],
780 pcb->psm, pcb->cid, op->result, pcb->state, pcb->cfg_state);
782 if (pcb->state != NG_BTSOCKET_L2CAP_CONFIGURING) {
783 mtx_unlock(&pcb->pcb_mtx);
789 if (op->result == NG_L2CAP_SUCCESS) {
797 pcb->imtu = op->imtu;
798 bcopy(&op->oflow, &pcb->oflow, sizeof(pcb->oflow));
799 pcb->flush_timo = op->flush_timo;
807 pcb->cfg_state &= ~NG_BTSOCKET_L2CAP_CFG_IN_SENT;
808 pcb->cfg_state |= NG_BTSOCKET_L2CAP_CFG_IN;
810 if (pcb->cfg_state == NG_BTSOCKET_L2CAP_CFG_BOTH) {
811 /* Configuration complete - mark socket as open */
813 pcb->state = NG_BTSOCKET_L2CAP_OPEN;
814 soisconnected(pcb->so);
825 switch (op->result) {
828 pcb->so->so_error = EINVAL;
832 pcb->so->so_error = ECONNRESET;
840 pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
841 soisdisconnected(pcb->so);
844 mtx_unlock(&pcb->pcb_mtx);
862 if (msg->header.arglen != sizeof(*op))
865 op = (ng_l2cap_l2ca_cfg_rsp_op *)(msg->data);
870 pcb = ng_btsocket_l2cap_pcb_by_token(msg->header.token);
876 mtx_lock(&pcb->pcb_mtx);
882 __func__, msg->header.token,
883 pcb->src.b[5], pcb->src.b[4], pcb->src.b[3],
884 pcb->src.b[2], pcb->src.b[1], pcb->src.b[0],
885 pcb->dst.b[5], pcb->dst.b[4], pcb->dst.b[3],
886 pcb->dst.b[2], pcb->dst.b[1], pcb->dst.b[0],
887 pcb->psm, pcb->cid, op->result, pcb->state, pcb->cfg_state);
889 if (pcb->state != NG_BTSOCKET_L2CAP_CONFIGURING) {
890 mtx_unlock(&pcb->pcb_mtx);
897 if (op->result != NG_L2CAP_SUCCESS)
905 pcb->cfg_state &= ~NG_BTSOCKET_L2CAP_CFG_OUT_SENT;
906 pcb->cfg_state |= NG_BTSOCKET_L2CAP_CFG_OUT;
908 if (pcb->cfg_state == NG_BTSOCKET_L2CAP_CFG_BOTH) {
909 /* Configuration complete - mask socket as open */
911 pcb->state = NG_BTSOCKET_L2CAP_OPEN;
912 soisconnected(pcb->so);
914 if (!(pcb->cfg_state & NG_BTSOCKET_L2CAP_CFG_IN_SENT)) {
915 /* Send L2CA_Config request - incoming path */
920 pcb->cfg_state |= NG_BTSOCKET_L2CAP_CFG_IN_SENT;
924 mtx_unlock(&pcb->pcb_mtx);
936 pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
937 soisdisconnected(pcb->so);
939 mtx_unlock(&pcb->pcb_mtx);
957 if (msg->header.arglen != sizeof(*ip))
960 ip = (ng_l2cap_l2ca_cfg_ind_ip *)(msg->data);
965 pcb = ng_btsocket_l2cap_pcb_by_cid(&rt->src, ip->lcid,
972 mtx_lock(&pcb->pcb_mtx);
978 pcb->src.b[5], pcb->src.b[4], pcb->src.b[3],
979 pcb->src.b[2], pcb->src.b[1], pcb->src.b[0],
980 pcb->dst.b[5], pcb->dst.b[4], pcb->dst.b[3],
981 pcb->dst.b[2], pcb->dst.b[1], pcb->dst.b[0],
982 pcb->psm, pcb->cid, pcb->state, pcb->cfg_state);
984 /* XXX FIXME re-configuration on open socket */
985 if (pcb->state != NG_BTSOCKET_L2CAP_CONFIGURING) {
986 mtx_unlock(&pcb->pcb_mtx);
998 pcb->omtu = ip->omtu;
999 bcopy(&ip->iflow, &pcb->iflow, sizeof(pcb->iflow));
1000 pcb->flush_timo = ip->flush_timo;
1007 if (!(pcb->cfg_state & NG_BTSOCKET_L2CAP_CFG_OUT_SENT)) {
1012 pcb->so->so_error = error;
1018 pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
1019 soisdisconnected(pcb->so);
1021 pcb->cfg_state |= NG_BTSOCKET_L2CAP_CFG_OUT_SENT;
1024 mtx_unlock(&pcb->pcb_mtx);
1042 if (msg->header.arglen != sizeof(*op))
1045 op = (ng_l2cap_l2ca_discon_op *)(msg->data);
1055 pcb = ng_btsocket_l2cap_pcb_by_token(msg->header.token);
1061 mtx_lock(&pcb->pcb_mtx);
1063 /* XXX Close socket no matter what op->result says */
1064 if (pcb->state != NG_BTSOCKET_L2CAP_CLOSED) {
1068 __func__, msg->header.token,
1069 pcb->src.b[5], pcb->src.b[4], pcb->src.b[3],
1070 pcb->src.b[2], pcb->src.b[1], pcb->src.b[0],
1071 pcb->dst.b[5], pcb->dst.b[4], pcb->dst.b[3],
1072 pcb->dst.b[2], pcb->dst.b[1], pcb->dst.b[0],
1073 pcb->psm, pcb->cid, op->result, pcb->state);
1077 pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
1078 soisdisconnected(pcb->so);
1081 mtx_unlock(&pcb->pcb_mtx);
1099 if (msg->header.arglen != sizeof(*ip))
1102 ip = (ng_l2cap_l2ca_discon_ind_ip *)(msg->data);
1107 pcb = ng_btsocket_l2cap_pcb_by_cid(&rt->src, ip->lcid,
1108 ip->idtype);
1120 mtx_lock(&pcb->pcb_mtx);
1126 pcb->src.b[5], pcb->src.b[4], pcb->src.b[3],
1127 pcb->src.b[2], pcb->src.b[1], pcb->src.b[0],
1128 pcb->dst.b[5], pcb->dst.b[4], pcb->dst.b[3],
1129 pcb->dst.b[2], pcb->dst.b[1], pcb->dst.b[0],
1130 pcb->psm, pcb->cid, pcb->state);
1132 if (pcb->flags & NG_BTSOCKET_L2CAP_TIMO)
1135 pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
1136 soisdisconnected(pcb->so);
1138 mtx_unlock(&pcb->pcb_mtx);
1156 if (msg->header.arglen != sizeof(*op))
1159 op = (ng_l2cap_l2ca_write_op *)(msg->data);
1164 pcb = ng_btsocket_l2cap_pcb_by_token(msg->header.token);
1170 mtx_lock(&pcb->pcb_mtx);
1176 pcb->src.b[5], pcb->src.b[4], pcb->src.b[3],
1177 pcb->src.b[2], pcb->src.b[1], pcb->src.b[0],
1178 pcb->dst.b[5], pcb->dst.b[4], pcb->dst.b[3],
1179 pcb->dst.b[2], pcb->dst.b[1], pcb->dst.b[0],
1180 pcb->psm, pcb->cid, op->result, op->length,
1181 pcb->state);
1183 if (pcb->state != NG_BTSOCKET_L2CAP_OPEN) {
1184 mtx_unlock(&pcb->pcb_mtx);
1195 sbdroprecord(&pcb->so->so_snd);
1196 if (sbavail(&pcb->so->so_snd) > 0) {
1200 sbdroprecord(&pcb->so->so_snd); /* XXX */
1208 pcb->so->so_error = ng_btsocket_l2cap_result2errno(op->result);
1209 sowwakeup(pcb->so);
1211 mtx_unlock(&pcb->pcb_mtx);
1228 mtx_assert(&pcb->pcb_mtx, MA_OWNED);
1230 if (pcb->rt == NULL ||
1231 pcb->rt->hook == NULL || NG_HOOK_NOT_VALID(pcb->rt->hook))
1239 msg->header.token = pcb->token;
1241 ip = (ng_l2cap_l2ca_con_ip *)(msg->data);
1242 bcopy(&pcb->dst, &ip->bdaddr, sizeof(ip->bdaddr));
1243 ip->psm = pcb->psm;
1244 ip->linktype = ng_btsock_l2cap_addrtype_to_linktype(pcb->dsttype);
1245 ip->idtype = pcb->idtype;
1246 NG_SEND_MSG_HOOK(error, ng_btsocket_l2cap_node, msg,pcb->rt->hook, 0);
1264 if (rt == NULL || rt->hook == NULL || NG_HOOK_NOT_VALID(rt->hook))
1272 msg->header.token = token;
1274 ip = (ng_l2cap_l2ca_con_rsp_ip *)(msg->data);
1275 bcopy(dst, &ip->bdaddr, sizeof(ip->bdaddr));
1276 ip->ident = ident;
1277 ip->lcid = lcid;
1278 ip->linktype = linktype;
1279 ip->result = result;
1280 ip->status = 0;
1282 NG_SEND_MSG_HOOK(error, ng_btsocket_l2cap_node, msg, rt->hook, 0);
1298 mtx_assert(&pcb->pcb_mtx, MA_OWNED);
1300 if (pcb->rt == NULL ||
1301 pcb->rt->hook == NULL || NG_HOOK_NOT_VALID(pcb->rt->hook))
1309 msg->header.token = pcb->token;
1311 ip = (ng_l2cap_l2ca_cfg_ip *)(msg->data);
1312 ip->lcid = pcb->cid;
1313 ip->imtu = pcb->imtu;
1314 bcopy(&pcb->oflow, &ip->oflow, sizeof(ip->oflow));
1315 ip->flush_timo = pcb->flush_timo;
1316 ip->link_timo = pcb->link_timo;
1318 NG_SEND_MSG_HOOK(error, ng_btsocket_l2cap_node, msg,pcb->rt->hook, 0);
1334 mtx_assert(&pcb->pcb_mtx, MA_OWNED);
1336 if (pcb->rt == NULL ||
1337 pcb->rt->hook == NULL || NG_HOOK_NOT_VALID(pcb->rt->hook))
1345 msg->header.token = pcb->token;
1347 ip = (ng_l2cap_l2ca_cfg_rsp_ip *)(msg->data);
1348 ip->lcid = pcb->cid;
1349 ip->omtu = pcb->omtu;
1350 bcopy(&pcb->iflow, &ip->iflow, sizeof(ip->iflow));
1352 NG_SEND_MSG_HOOK(error, ng_btsocket_l2cap_node, msg, pcb->rt->hook, 0);
1369 mtx_assert(&pcb->pcb_mtx, MA_OWNED);
1371 if (pcb->rt == NULL ||
1372 pcb->rt->hook == NULL || NG_HOOK_NOT_VALID(pcb->rt->hook))
1380 msg->header.token = token;
1382 ip = (ng_l2cap_l2ca_discon_ip *)(msg->data);
1383 ip->lcid = pcb->cid;
1384 ip->idtype = pcb->idtype;
1386 NG_SEND_MSG_HOOK(error, ng_btsocket_l2cap_node, msg,pcb->rt->hook, 0);
1428 if (m->m_pkthdr.len < sizeof(*hdr)) {
1430 "%s: L2CAP data packet too small, len=%d\n", __func__, m->m_pkthdr.len);
1434 if (m->m_len < sizeof(*hdr)) {
1444 if (hdr->length != m->m_pkthdr.len) {
1447 __func__, m->m_pkthdr.len, hdr->length);
1466 rt->src.b[5], rt->src.b[4], rt->src.b[3],
1467 rt->src.b[2], rt->src.b[1], rt->src.b[0],
1468 hdr->dcid, hdr->length);
1470 if ((hdr->dcid >= NG_L2CAP_FIRST_CID) ||
1477 pcb = ng_btsocket_l2cap_pcb_by_cid(&rt->src, hdr->dcid,idtype);
1483 mtx_lock(&pcb->pcb_mtx);
1485 if (pcb->state != NG_BTSOCKET_L2CAP_OPEN) {
1489 rt->src.b[5], rt->src.b[4], rt->src.b[3],
1490 rt->src.b[2], rt->src.b[1], rt->src.b[0],
1491 hdr->dcid, pcb->state);
1493 mtx_unlock(&pcb->pcb_mtx);
1499 if (hdr->length > pcb->imtu) {
1504 rt->src.b[5], rt->src.b[4], rt->src.b[3],
1505 rt->src.b[2], rt->src.b[1], rt->src.b[0],
1506 hdr->dcid, hdr->length, pcb->imtu);
1508 mtx_unlock(&pcb->pcb_mtx);
1514 if (m->m_pkthdr.len > sbspace(&pcb->so->so_rcv)) {
1526 rt->src.b[5], rt->src.b[4], rt->src.b[3],
1527 rt->src.b[2], rt->src.b[1], rt->src.b[0],
1528 hdr->dcid, m->m_pkthdr.len,
1529 sbspace(&pcb->so->so_rcv));
1531 mtx_unlock(&pcb->pcb_mtx);
1537 sbappendrecord(&pcb->so->so_rcv, m);
1540 sorwakeup(pcb->so);
1542 mtx_unlock(&pcb->pcb_mtx);
1544 } else if (hdr->dcid == NG_L2CAP_CLT_CID) {
1548 if (hdr->length > NG_L2CAP_MTU_DEFAULT) {
1553 rt->src.b[5], rt->src.b[4], rt->src.b[3],
1554 rt->src.b[2], rt->src.b[1], rt->src.b[0],
1555 hdr->length);
1560 if (m->m_pkthdr.len < sizeof(*clt_hdr)) {
1565 rt->src.b[5], rt->src.b[4], rt->src.b[3],
1566 rt->src.b[2], rt->src.b[1], rt->src.b[0],
1567 hdr->length);
1571 if (m->m_len < sizeof(*clt_hdr)) {
1585 rt->src.b[5], rt->src.b[4], rt->src.b[3],
1586 rt->src.b[2], rt->src.b[1], rt->src.b[0],
1587 clt_hdr->psm, hdr->length);
1594 mtx_lock(&pcb->pcb_mtx);
1596 if (bcmp(&rt->src, &pcb->src, sizeof(pcb->src)) != 0 ||
1597 pcb->psm != clt_hdr->psm ||
1598 pcb->state != NG_BTSOCKET_L2CAP_OPEN ||
1599 (pcb->so->so_options & SO_BROADCAST) == 0 ||
1600 m->m_pkthdr.len > sbspace(&pcb->so->so_rcv))
1605 * socket's queue. If m_dup() failed - no big deal
1611 sbappendrecord(&pcb->so->so_rcv, copy);
1612 sorwakeup(pcb->so);
1615 mtx_unlock(&pcb->pcb_mtx);
1631 switch (msg->header.cmd) {
1635 (ng_l2cap_node_hook_info_ep *)msg->data;
1636 if (hook == NULL || msg->header.arglen != sizeof(*ep))
1639 if (bcmp(&ep->addr, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0)
1658 bcopy(&ep->addr, &rt->src, sizeof(rt->src));
1659 rt->hook = hook;
1666 rt->src.b[5], rt->src.b[4], rt->src.b[3],
1667 rt->src.b[2], rt->src.b[1], rt->src.b[0]);
1672 "%s: Unknown message, cmd=%d\n", __func__, msg->header.cmd);
1701 switch (msg->header.cmd) {
1745 "%s: Unknown L2CA message, cmd=%d\n", __func__, msg->header.cmd);
1774 switch(item->el_flags & NGQF_TYPE) {
1787 switch (msg->header.cmd) {
1810 ("%s: invalid item type=%ld\n", __func__, (item->el_flags & NGQF_TYPE)));
1840 mtx_lock(&pcb->pcb_mtx);
1843 if (pcb->rt != NULL &&
1844 pcb->rt->hook != NULL && NG_HOOK_NOT_VALID(pcb->rt->hook)) {
1845 if (pcb->flags & NG_BTSOCKET_L2CAP_TIMO)
1848 pcb->so->so_error = ENETDOWN;
1849 pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
1850 soisdisconnected(pcb->so);
1852 pcb->token = 0;
1853 pcb->cid = 0;
1854 pcb->rt = NULL;
1857 mtx_unlock(&pcb->pcb_mtx);
1862 * Now cleanup routing table
1868 if (rt->hook != NULL && NG_HOOK_NOT_VALID(rt->hook)) {
1871 NG_HOOK_SET_PRIVATE(rt->hook, NULL);
1872 NG_HOOK_UNREF(rt->hook); /* Remove extra reference */
1941 /* Routing table */
1958 so->so_error = ECONNABORTED;
1984 if (so->so_type != SOCK_SEQPACKET)
1997 if ((so->so_snd.sb_hiwat == 0) || (so->so_rcv.sb_hiwat == 0)) {
2011 so->so_pcb = (caddr_t) pcb;
2012 pcb->so = so;
2013 pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
2016 pcb->imtu = pcb->omtu = NG_L2CAP_MTU_DEFAULT;
2019 pcb->iflow.flags = 0x0;
2020 pcb->iflow.service_type = NG_HCI_SERVICE_TYPE_BEST_EFFORT;
2021 pcb->iflow.token_rate = 0xffffffff; /* maximum */
2022 pcb->iflow.token_bucket_size = 0xffffffff; /* maximum */
2023 pcb->iflow.peak_bandwidth = 0x00000000; /* maximum */
2024 pcb->iflow.latency = 0xffffffff; /* don't care */
2025 pcb->iflow.delay_variation = 0xffffffff; /* don't care */
2027 bcopy(&pcb->iflow, &pcb->oflow, sizeof(pcb->oflow));
2029 pcb->flush_timo = NG_L2CAP_FLUSH_TIMO_DEFAULT;
2030 pcb->link_timo = NG_L2CAP_LINK_TIMO_DEFAULT;
2039 mtx_init(&pcb->pcb_mtx, "btsocks_l2cap_pcb_mtx", NULL,
2041 callout_init_mtx(&pcb->timo, &pcb->pcb_mtx, 0);
2071 pcb->token = token;
2099 if (sa->l2cap_family != AF_BLUETOOTH)
2102 if ((sa->l2cap_len != sizeof(*sa))&&
2103 (sa->l2cap_len != sizeof(struct sockaddr_l2cap_compat)))
2106 psm = le16toh(sa->l2cap_psm);
2119 if (psm != 0 && psm == pcb->psm &&
2120 bcmp(&pcb->src, &sa->l2cap_bdaddr, sizeof(bdaddr_t)) == 0)
2127 bcopy(&sa->l2cap_bdaddr, &pcb->src, sizeof(pcb->src));
2128 pcb->psm = psm;
2159 if (pcb->state == NG_BTSOCKET_L2CAP_CONNECTING)
2165 if (sa->l2cap_family != AF_BLUETOOTH)
2167 if (sa->l2cap_len == sizeof(*sal)){
2170 sa->l2cap_len = sizeof(*sa);
2171 sa->l2cap_bdaddr_type = BDADDR_BREDR;
2173 if (sa->l2cap_len != sizeof(*sa))
2175 if ((sa->l2cap_psm && sa->l2cap_cid))
2177 if (bcmp(&sa->l2cap_bdaddr, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0)
2179 if((sa->l2cap_bdaddr_type == BDADDR_BREDR)&&
2180 (sa->l2cap_psm == 0))
2182 if(sa->l2cap_bdaddr_type != BDADDR_BREDR){
2183 if(sa->l2cap_cid == NG_L2CAP_ATT_CID){
2185 }else if (sa->l2cap_cid == NG_L2CAP_SMP_CID){
2193 if (pcb->psm != 0 && pcb->psm != le16toh(sa->l2cap_psm))
2196 * Routing. Socket should be bound to some source address. The source
2204 mtx_lock(&pcb->pcb_mtx);
2207 bcopy(&sa->l2cap_bdaddr, &pcb->dst, sizeof(pcb->dst));
2208 pcb->psm = le16toh(sa->l2cap_psm);
2209 pcb->dsttype = sa->l2cap_bdaddr_type;
2210 pcb->cid = 0;
2211 pcb->idtype = idtype;
2212 pcb->rt = NULL;
2213 have_src = bcmp(&pcb->src, NG_HCI_BDADDR_ANY, sizeof(pcb->src));
2216 if (rt->hook == NULL || NG_HOOK_NOT_VALID(rt->hook))
2221 if (bcmp(&pcb->src, &rt->src, sizeof(rt->src)) == 0)
2224 if (bcmp(&pcb->dst, &rt->src, sizeof(rt->src)) != 0)
2230 pcb->rt = rt;
2233 bcopy(&rt->src, &pcb->src, sizeof(pcb->src));
2234 pcb->srctype =
2235 (sa->l2cap_bdaddr_type == BDADDR_BREDR)?
2248 pcb->flags |= NG_BTSOCKET_L2CAP_CLIENT;
2249 pcb->state = NG_BTSOCKET_L2CAP_CONNECTING;
2250 soisconnecting(pcb->so);
2256 mtx_unlock(&pcb->pcb_mtx);
2290 if (sopt->sopt_level != SOL_L2CAP)
2293 mtx_lock(&pcb->pcb_mtx);
2295 switch (sopt->sopt_dir) {
2297 switch (sopt->sopt_name) {
2299 error = sooptcopyout(sopt, &pcb->imtu,
2300 sizeof(pcb->imtu));
2304 error = sooptcopyout(sopt, &pcb->omtu,
2305 sizeof(pcb->omtu));
2309 error = sooptcopyout(sopt, &pcb->iflow,
2310 sizeof(pcb->iflow));
2314 error = sooptcopyout(sopt, &pcb->oflow,
2315 sizeof(pcb->oflow));
2319 error = sooptcopyout(sopt, &pcb->flush_timo,
2320 sizeof(pcb->flush_timo));
2323 error = sooptcopyout(sopt, &pcb->need_encrypt,
2324 sizeof(pcb->need_encrypt));
2338 * May be this should indicate re-configuration of the open
2342 if (pcb->state != NG_BTSOCKET_L2CAP_CLOSED) {
2347 switch (sopt->sopt_name) {
2351 pcb->imtu = v.mtu;
2357 bcopy(&v.flow, &pcb->oflow, sizeof(pcb->oflow));
2364 pcb->flush_timo = v.flush_timo;
2367 if((pcb->state != NG_BTSOCKET_L2CAP_OPEN) &&
2368 (pcb->state != NG_BTSOCKET_L2CAP_W4_ENC_CHANGE)){
2372 pcb->need_encrypt = (v.encryption)?1:0;
2388 mtx_unlock(&pcb->pcb_mtx);
2408 mtx_lock(&pcb->pcb_mtx);
2411 if (pcb->flags & NG_BTSOCKET_L2CAP_TIMO)
2414 if (pcb->state != NG_BTSOCKET_L2CAP_CLOSED &&
2415 pcb->state != NG_BTSOCKET_L2CAP_DISCONNECTING)
2419 pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
2423 mtx_unlock(&pcb->pcb_mtx);
2426 mtx_destroy(&pcb->pcb_mtx);
2431 so->so_pcb = NULL;
2449 mtx_lock(&pcb->pcb_mtx);
2451 if (pcb->state == NG_BTSOCKET_L2CAP_DISCONNECTING) {
2452 mtx_unlock(&pcb->pcb_mtx);
2456 if (pcb->state != NG_BTSOCKET_L2CAP_CLOSED) {
2458 if (pcb->flags & NG_BTSOCKET_L2CAP_TIMO)
2461 error = ng_btsocket_l2cap_send_l2ca_discon_req(pcb->token, pcb);
2463 pcb->state = NG_BTSOCKET_L2CAP_DISCONNECTING;
2472 mtx_unlock(&pcb->pcb_mtx);
2501 if (pcb->psm == 0) {
2530 .l2cap_psm = htole16(pcb->psm),
2532 bcopy(&pcb->dst, &l2cap->l2cap_bdaddr, sizeof(l2cap->l2cap_bdaddr));
2533 switch(pcb->idtype){
2535 l2cap->l2cap_cid = NG_L2CAP_ATT_CID;
2538 l2cap->l2cap_cid = NG_L2CAP_SMP_CID;
2541 l2cap->l2cap_cid = 0;
2544 l2cap->l2cap_bdaddr_type = pcb->dsttype;
2571 mtx_lock(&pcb->pcb_mtx);
2574 if (pcb->state != NG_BTSOCKET_L2CAP_OPEN) {
2575 mtx_unlock(&pcb->pcb_mtx);
2581 if (pcb->rt == NULL ||
2582 pcb->rt->hook == NULL || NG_HOOK_NOT_VALID(pcb->rt->hook)) {
2583 mtx_unlock(&pcb->pcb_mtx);
2589 if (m->m_pkthdr.len > pcb->omtu) {
2591 "%s: Packet too big, len=%d, omtu=%d\n", __func__, m->m_pkthdr.len, pcb->omtu);
2593 mtx_unlock(&pcb->pcb_mtx);
2605 sbappendrecord(&pcb->so->so_snd, m);
2608 if (!(pcb->flags & NG_BTSOCKET_L2CAP_TIMO)) {
2613 sbdroprecord(&pcb->so->so_snd); /* XXX */
2616 mtx_unlock(&pcb->pcb_mtx);
2635 mtx_assert(&pcb->pcb_mtx, MA_OWNED);
2637 if (sbavail(&pcb->so->so_snd) == 0)
2640 m = m_dup(pcb->so->so_snd.sb_mb, M_NOWAIT);
2647 if (m->m_len < sizeof(*hdr))
2658 hdr->token = pcb->token;
2659 hdr->length = m->m_pkthdr.len - sizeof(*hdr);
2660 hdr->lcid = pcb->cid;
2661 hdr->idtype = pcb->idtype;
2664 __func__, m->m_pkthdr.len, hdr->length, hdr->lcid,
2665 hdr->token, pcb->state);
2672 NG_SEND_DATA_ONLY(error, pcb->rt->hook, m);
2694 .l2cap_psm = htole16(pcb->psm),
2695 .l2cap_bdaddr_type = pcb->srctype,
2697 bcopy(&pcb->src, &l2cap->l2cap_bdaddr, sizeof(l2cap->l2cap_bdaddr));
2721 if (p->so == NULL || !SOLISTENING(p->so) || p->psm != psm)
2724 if (bcmp(&p->src, bdaddr, sizeof(p->src)) == 0)
2727 if (bcmp(&p->src, NG_HCI_BDADDR_ANY, sizeof(p->src)) == 0)
2750 if (p->token == token)
2769 if (p->cid == cid &&
2770 bcmp(src, &p->src, sizeof(p->src)) == 0&&
2771 p->idtype == idtype)
2784 mtx_assert(&pcb->pcb_mtx, MA_OWNED);
2786 if (!(pcb->flags & NG_BTSOCKET_L2CAP_TIMO)) {
2787 pcb->flags |= NG_BTSOCKET_L2CAP_TIMO;
2788 callout_reset(&pcb->timo, bluetooth_l2cap_ertx_timeout(),
2802 mtx_assert(&pcb->pcb_mtx, MA_OWNED);
2804 if (pcb->flags & NG_BTSOCKET_L2CAP_TIMO) {
2805 callout_stop(&pcb->timo);
2806 pcb->flags &= ~NG_BTSOCKET_L2CAP_TIMO;
2821 mtx_assert(&pcb->pcb_mtx, MA_OWNED);
2823 pcb->flags &= ~NG_BTSOCKET_L2CAP_TIMO;
2824 pcb->so->so_error = ETIMEDOUT;
2826 switch (pcb->state) {
2831 if (pcb->cid != 0)
2835 pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
2836 soisdisconnected(pcb->so);
2840 /* Send timeout - drop packet and wakeup sender */
2841 sbdroprecord(&pcb->so->so_snd);
2842 sowwakeup(pcb->so);
2846 /* Disconnect timeout - disconnect the socket anyway */
2847 pcb->state = NG_BTSOCKET_L2CAP_CLOSED;
2848 soisdisconnected(pcb->so);
2853 "%s: Invalid socket state=%d\n", __func__, pcb->state);
2903 case 0x0a: /* Max number of SCO connections to a unit */
2915 case 0x1b: /* SCO offset rejected */
2916 case 0x1c: /* SCO interval rejected */
2917 case 0x1d: /* SCO air mode rejected */