| 1658 | */ |
| 1659 | |
| 1660 | int |
| 1661 | ng_btsocket_sco_send(struct socket *so, int flags, struct mbuf *m, |
| 1662 | struct sockaddr *nam, struct mbuf *control, struct thread *td) |
| 1663 | { |
| 1664 | ng_btsocket_sco_pcb_t *pcb = so2sco_pcb(so); |
| 1665 | int error = 0; |
| 1666 | |
| 1667 | if (ng_btsocket_sco_node == NULL) { |
| 1668 | error = ENETDOWN; |
| 1669 | goto drop; |
| 1670 | } |
| 1671 | |
| 1672 | /* Check socket and input */ |
| 1673 | if (pcb == NULL || m == NULL || control != NULL) { |
| 1674 | error = EINVAL; |
| 1675 | goto drop; |
| 1676 | } |
| 1677 | |
| 1678 | mtx_lock(&pcb->pcb_mtx); |
| 1679 | |
| 1680 | /* Make sure socket is connected */ |
| 1681 | if (pcb->state != NG_BTSOCKET_SCO_OPEN) { |
| 1682 | mtx_unlock(&pcb->pcb_mtx); |
| 1683 | error = ENOTCONN; |
| 1684 | goto drop; |
| 1685 | } |
| 1686 | |
| 1687 | /* Check route */ |
| 1688 | if (pcb->rt == NULL || |
| 1689 | pcb->rt->hook == NULL || NG_HOOK_NOT_VALID(pcb->rt->hook)) { |
| 1690 | mtx_unlock(&pcb->pcb_mtx); |
| 1691 | error = ENETDOWN; |
| 1692 | goto drop; |
| 1693 | } |
| 1694 | |
| 1695 | /* Check packet size */ |
| 1696 | if (m->m_pkthdr.len > pcb->rt->pkt_size) { |
| 1697 | NG_BTSOCKET_SCO_ERR( |
| 1698 | "%s: Packet too big, len=%d, pkt_size=%d\n", |
| 1699 | __func__, m->m_pkthdr.len, pcb->rt->pkt_size); |
| 1700 | |
| 1701 | mtx_unlock(&pcb->pcb_mtx); |
| 1702 | error = EMSGSIZE; |
| 1703 | goto drop; |
| 1704 | } |
| 1705 | |
| 1706 | /* |
| 1707 | * First put packet on socket send queue. Then check if we have |
| 1708 | * pending timeout. If we do not have timeout then we must send |
| 1709 | * packet and schedule timeout. Otherwise do nothing and wait for |
| 1710 | * NGM_HCI_SYNC_CON_QUEUE message. |
| 1711 | */ |
| 1712 | |
| 1713 | sbappendrecord(&pcb->so->so_snd, m); |
| 1714 | m = NULL; |
| 1715 | |
| 1716 | if (!(pcb->flags & NG_BTSOCKET_SCO_TIMO)) { |
| 1717 | error = ng_btsocket_sco_send2(pcb); |
nothing calls this directly
no test coverage detected