Lines Matching refs:link
70 struct hci_link *link;
78 link = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL);
79 if (link == NULL) {
80 link = hci_link_alloc(unit, bdaddr, HCI_LINK_ACL);
81 if (link == NULL)
85 switch(link->hl_state) {
106 hci_link_free(link, err);
110 link->hl_flags |= HCI_LINK_CREATE_CON;
111 link->hl_state = HCI_LINK_WAIT_CONNECT;
128 * will keep the link alive.
130 callout_stop(&link->hl_expire);
134 UNKNOWN(link->hl_state);
139 link->hl_refcnt++;
141 return link;
145 * Close ACL connection. When there are no more references to this link,
149 hci_acl_close(struct hci_link *link, int err)
152 KASSERT(link != NULL);
154 if (--link->hl_refcnt == 0) {
155 if (link->hl_state == HCI_LINK_CLOSED)
156 hci_link_free(link, err);
158 callout_schedule(&link->hl_expire, hci_acl_expiry * hz);
168 * There should not be a link to the same bdaddr already, we check
174 struct hci_link *link;
190 link = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL);
191 if (link != NULL) {
192 DPRINTF("%s: rejecting connection (link exists)\n",
198 link = hci_link_alloc(unit, bdaddr, HCI_LINK_ACL);
199 if (link != NULL) {
200 link->hl_state = HCI_LINK_WAIT_CONNECT;
203 callout_schedule(&link->hl_expire, hci_acl_expiry * hz);
206 return link;
212 struct hci_link *link = arg;
217 callout_ack(&link->hl_expire);
219 if (link->hl_refcnt > 0)
222 DPRINTF("link #%d expired\n", link->hl_handle);
224 switch (link->hl_state) {
227 hci_link_free(link, ECONNRESET);
234 cp.con_handle = htole16(link->hl_handle);
237 err = hci_send_cmd(link->hl_unit, HCI_CMD_DISCONNECT,
248 UNKNOWN(link->hl_state);
257 * Initiate any Link Mode change requests.
260 hci_acl_setmode(struct hci_link *link)
264 KASSERT(link != NULL);
265 KASSERT(link->hl_unit != NULL);
267 if (link->hl_state != HCI_LINK_OPEN)
270 if ((link->hl_flags & HCI_LINK_AUTH_REQ)
271 && !(link->hl_flags & HCI_LINK_AUTH)) {
275 link->hl_handle);
277 link->hl_state = HCI_LINK_WAIT_AUTH;
278 cp.con_handle = htole16(link->hl_handle);
279 err = hci_send_cmd(link->hl_unit, HCI_CMD_AUTH_REQ,
285 if ((link->hl_flags & HCI_LINK_ENCRYPT_REQ)
286 && !(link->hl_flags & HCI_LINK_ENCRYPT)) {
292 link->hl_handle);
294 link->hl_state = HCI_LINK_WAIT_ENCRYPT;
295 cp.con_handle = htole16(link->hl_handle);
298 err = hci_send_cmd(link->hl_unit, HCI_CMD_SET_CON_ENCRYPTION,
304 if ((link->hl_flags & HCI_LINK_SECURE_REQ)) {
307 /* always change link key for SECURE requests */
308 link->hl_flags &= ~HCI_LINK_SECURE;
310 DPRINTF("changing link key for handle #%d\n",
311 link->hl_handle);
313 link->hl_state = HCI_LINK_WAIT_SECURE;
314 cp.con_handle = htole16(link->hl_handle);
316 err = hci_send_cmd(link->hl_unit, HCI_CMD_CHANGE_CON_LINK_KEY,
326 * Link Mode changed.
329 * is complete. We notify upstream and restart the link.
332 hci_acl_linkmode(struct hci_link *link)
338 link->hl_handle,
339 (link->hl_flags & HCI_LINK_AUTH ? "on" : "off"),
340 (link->hl_flags & HCI_LINK_ENCRYPT ? "on" : "off"),
341 (link->hl_flags & HCI_LINK_SECURE ? "on" : "off"));
343 if (link->hl_flags & HCI_LINK_AUTH)
346 if (link->hl_flags & HCI_LINK_ENCRYPT)
349 if (link->hl_flags & HCI_LINK_SECURE)
353 * The link state will only be OPEN here if the mode change
362 if (chan->lc_link != link)
382 l2cap_send_connect_rsp(link, chan->lc_ident,
390 l2cap_send_connect_rsp(link, chan->lc_ident,
414 link->hl_state = HCI_LINK_OPEN;
415 hci_acl_start(link);
427 struct hci_link *link;
451 link = hci_link_lookup_handle(unit, handle);
452 if (link == NULL) {
481 if (link->hl_rxp != NULL) {
485 m_freem(link->hl_rxp);
488 link->hl_rxp = m;
493 if (link->hl_rxp == NULL) {
500 got = m->m_pkthdr.len + link->hl_rxp->m_pkthdr.len;
501 m_cat(link->hl_rxp, m);
502 m = link->hl_rxp;
520 link->hl_rxp = NULL;
529 l2cap_recv_frame(m, link);
537 * Send ACL data on link
541 * attached to the link, so that completed fragments can be marked off and
545 hci_acl_send(struct mbuf *m, struct hci_link *link,
552 KASSERT(link != NULL);
557 if (link->hl_state == HCI_LINK_CLOSED) {
571 mlen = link->hl_unit->hci_max_acl_size;
574 device_xname(link->hl_unit->hci_dev), link->hl_handle, plen, mlen);
594 TAILQ_INSERT_TAIL(&link->hl_txq, pdu, lp_next);
595 link->hl_txqlen += num;
597 hci_acl_start(link);
612 * Start sending ACL data on link.
615 * is queued, after link mode changes have completed, or when device
623 hci_acl_start(struct hci_link *link)
631 KASSERT(link != NULL);
633 unit = link->hl_unit;
637 if (link->hl_state != HCI_LINK_OPEN)
640 if (link->hl_txqlen == 0 || unit->hci_num_acl_pkts == 0)
644 pdu = TAILQ_FIRST(&link->hl_txq);
660 handle = HCI_MK_CON_HANDLE(link->hl_handle,
663 handle = HCI_MK_CON_HANDLE(link->hl_handle,
675 link->hl_txqlen--;
690 link->hl_state = HCI_LINK_BLOCK;
692 link->hl_state = HCI_LINK_OPEN;
705 if (TAILQ_NEXT(link, hl_next)) {
706 TAILQ_REMOVE(&unit->hci_links, link, hl_next);
707 TAILQ_INSERT_TAIL(&unit->hci_links, link, hl_next);
717 hci_acl_complete(struct hci_link *link, int num)
722 DPRINTFN(5, "handle #%d (%d)\n", link->hl_handle, num);
725 pdu = TAILQ_FIRST(&link->hl_txq);
727 aprint_error_dev(link->hl_unit->hci_dev,
729 num, link->hl_handle);
739 TAILQ_REMOVE(&link->hl_txq, pdu, lp_next);
786 * There should already be an ACL link up and running before
803 * Ok, got new pcb so we can start a new link and fill
835 struct hci_link *link;
856 link = hci_link_lookup_handle(unit, handle);
857 if (link == NULL || link->hl_type == HCI_LINK_ACL) {
864 (*link->hl_sco->sp_proto->input)(link->hl_sco->sp_upper, m);
872 hci_sco_start(struct hci_link *link)
881 hci_sco_complete(struct hci_link *link, int num)
884 DPRINTFN(5, "handle #%d (num=%d)\n", link->hl_handle, num);
885 link->hl_sco->sp_pending--;
886 (*link->hl_sco->sp_proto->complete)(link->hl_sco->sp_upper, num);
897 struct hci_link *link;
901 link = malloc(sizeof(struct hci_link), M_BLUETOOTH, M_NOWAIT | M_ZERO);
902 if (link == NULL)
905 link->hl_unit = unit;
906 link->hl_type = type;
907 link->hl_state = HCI_LINK_CLOSED;
908 bdaddr_copy(&link->hl_bdaddr, bdaddr);
911 callout_init(&link->hl_expire, 0);
912 callout_setfunc(&link->hl_expire, hci_acl_timeout, link);
914 TAILQ_INIT(&link->hl_txq); /* outgoing packets */
915 TAILQ_INIT(&link->hl_reqs); /* request queue */
917 link->hl_mtu = L2CAP_MTU_DEFAULT; /* L2CAP signal mtu */
918 link->hl_flush = L2CAP_FLUSH_TIMO_DEFAULT; /* flush timeout */
921 MBUFQ_INIT(&link->hl_data);
924 TAILQ_INSERT_TAIL(&unit->hci_links, link, hl_next);
925 return link;
929 hci_link_free(struct hci_link *link, int err)
935 KASSERT(link != NULL);
938 link->hl_handle, link->hl_type,
939 link->hl_state, link->hl_refcnt);
942 if (link->hl_refcnt > 0) {
946 if (chan->lc_link == link)
950 KASSERT(link->hl_refcnt == 0);
953 while ((req = TAILQ_FIRST(&link->hl_reqs)) != NULL)
956 KASSERT(TAILQ_EMPTY(&link->hl_reqs));
959 while ((pdu = TAILQ_FIRST(&link->hl_txq)) != NULL) {
960 TAILQ_REMOVE(&link->hl_txq, pdu, lp_next);
963 link->hl_unit->hci_num_acl_pkts += pdu->lp_pending;
968 KASSERT(TAILQ_EMPTY(&link->hl_txq));
971 m_freem(link->hl_rxp);
972 link->hl_rxp = NULL;
974 /* SCO master ACL link */
975 if (link->hl_link != NULL) {
976 hci_acl_close(link->hl_link, err);
977 link->hl_link = NULL;
981 if (link->hl_sco != NULL) {
984 pcb = link->hl_sco;
986 link->hl_sco = NULL;
991 MBUFQ_DRAIN(&link->hl_data);
995 * link structure but the timeout function will call us back in
998 link->hl_state = HCI_LINK_CLOSED;
999 callout_stop(&link->hl_expire);
1000 if (callout_invoking(&link->hl_expire))
1003 callout_destroy(&link->hl_expire);
1009 if (link->hl_clock != 0) {
1012 memo = hci_memo_new(link->hl_unit, &link->hl_bdaddr);
1014 memo->clock_offset = link->hl_clock;
1017 TAILQ_REMOVE(&link->hl_unit->hci_links, link, hl_next);
1018 free(link, M_BLUETOOTH);
1022 * Lookup HCI link by address and type. Note that for SCO links there may
1023 * be more than one link per address, so we only return links with no
1029 struct hci_link *link;
1034 TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
1035 if (link->hl_type != type)
1038 if (type == HCI_LINK_SCO && link->hl_handle != 0)
1041 if (bdaddr_same(&link->hl_bdaddr, bdaddr))
1045 return link;
1051 struct hci_link *link;
1055 TAILQ_FOREACH(link, &unit->hci_links, hl_next) {
1056 if (handle == link->hl_handle)
1060 return link;