Lines Matching defs:dlc
51 * RFCOMM DLC - Upper Protocol API
61 * attach a new RFCOMM DLC to handle, populate with reasonable defaults
67 struct rfcomm_dlc *dlc;
73 dlc = kmem_intr_zalloc(sizeof(struct rfcomm_dlc), KM_NOSLEEP);
74 if (dlc == NULL)
77 dlc->rd_state = RFCOMM_DLC_CLOSED;
78 dlc->rd_mtu = rfcomm_mtu_default;
80 dlc->rd_proto = proto;
81 dlc->rd_upper = upper;
83 dlc->rd_laddr.bt_len = sizeof(struct sockaddr_bt);
84 dlc->rd_laddr.bt_family = AF_BLUETOOTH;
85 dlc->rd_laddr.bt_psm = L2CAP_PSM_RFCOMM;
87 dlc->rd_raddr.bt_len = sizeof(struct sockaddr_bt);
88 dlc->rd_raddr.bt_family = AF_BLUETOOTH;
89 dlc->rd_raddr.bt_psm = L2CAP_PSM_RFCOMM;
91 dlc->rd_lmodem = RFCOMM_MSC_RTC | RFCOMM_MSC_RTR | RFCOMM_MSC_DV;
93 callout_init(&dlc->rd_timeout, 0);
94 callout_setfunc(&dlc->rd_timeout, rfcomm_dlc_timeout, dlc);
96 *handle = dlc;
101 * rfcomm_bind_pcb(dlc, sockaddr)
103 * bind DLC to local address
106 rfcomm_bind_pcb(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr)
109 if (dlc->rd_state != RFCOMM_DLC_CLOSED)
112 memcpy(&dlc->rd_laddr, addr, sizeof(struct sockaddr_bt));
117 * rfcomm_sockaddr_pcb(dlc, sockaddr)
122 rfcomm_sockaddr_pcb(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr)
125 memcpy(addr, &dlc->rd_laddr, sizeof(struct sockaddr_bt));
130 * rfcomm_connect_pcb(dlc, sockaddr)
132 * Initiate connection of RFCOMM DLC to remote address.
135 rfcomm_connect_pcb(struct rfcomm_dlc *dlc, struct sockaddr_bt *dest)
140 if (dlc->rd_state != RFCOMM_DLC_CLOSED)
143 memcpy(&dlc->rd_raddr, dest, sizeof(struct sockaddr_bt));
145 if (dlc->rd_raddr.bt_channel < RFCOMM_CHANNEL_MIN
146 || dlc->rd_raddr.bt_channel > RFCOMM_CHANNEL_MAX
147 || bdaddr_any(&dlc->rd_raddr.bt_bdaddr))
150 if (dlc->rd_raddr.bt_psm == L2CAP_PSM_ANY)
151 dlc->rd_raddr.bt_psm = L2CAP_PSM_RFCOMM;
152 else if (dlc->rd_raddr.bt_psm != L2CAP_PSM_RFCOMM
153 && (dlc->rd_raddr.bt_psm < 0x1001
154 || L2CAP_PSM_INVALID(dlc->rd_raddr.bt_psm)))
162 rs = rfcomm_session_lookup(&dlc->rd_laddr, &dlc->rd_raddr);
165 &dlc->rd_laddr);
172 err = l2cap_connect_pcb(rs->rs_l2cap, &dlc->rd_raddr);
184 /* construct DLC */
185 dlc->rd_dlci = RFCOMM_MKDLCI(IS_INITIATOR(rs) ? 0:1, dest->bt_channel);
186 if (rfcomm_dlc_lookup(rs, dlc->rd_dlci))
189 l2cap_sockaddr_pcb(rs->rs_l2cap, &dlc->rd_laddr);
192 * attach the DLC to the session and start it off
194 dlc->rd_session = rs;
195 dlc->rd_state = RFCOMM_DLC_WAIT_SESSION;
196 LIST_INSERT_HEAD(&rs->rs_dlcs, dlc, rd_next);
199 err = rfcomm_dlc_connect(dlc);
205 * rfcomm_peeraddr_pcb(dlc, sockaddr)
210 rfcomm_peeraddr_pcb(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr)
213 memcpy(addr, &dlc->rd_raddr, sizeof(struct sockaddr_bt));
218 * rfcomm_disconnect_pcb(dlc, linger)
220 * disconnect RFCOMM DLC
223 rfcomm_disconnect_pcb(struct rfcomm_dlc *dlc, int linger)
225 struct rfcomm_session *rs = dlc->rd_session;
228 KASSERT(dlc != NULL);
230 switch (dlc->rd_state) {
237 RFCOMM_FRAME_DM, dlc->rd_dlci);
243 rfcomm_dlc_close(dlc, 0);
247 if (dlc->rd_txbuf != NULL && linger != 0) {
248 dlc->rd_flags |= RFCOMM_DLC_SHUTDOWN;
254 dlc->rd_state = RFCOMM_DLC_WAIT_DISCONNECT;
256 dlc->rd_dlci);
257 callout_schedule(&dlc->rd_timeout, rfcomm_ack_timeout * hz);
265 UNKNOWN(dlc->rd_state);
275 * detach RFCOMM DLC from handle
280 struct rfcomm_dlc *dlc = *handle;
282 if (dlc->rd_state != RFCOMM_DLC_CLOSED)
283 rfcomm_dlc_close(dlc, 0);
285 m_freem(dlc->rd_txbuf);
286 dlc->rd_txbuf = NULL;
288 dlc->rd_upper = NULL;
292 * If callout is invoking we can't free the DLC so
295 if (callout_invoking(&dlc->rd_timeout))
296 dlc->rd_flags |= RFCOMM_DLC_DETACH;
298 callout_destroy(&dlc->rd_timeout);
299 kmem_intr_free(dlc, sizeof(*dlc));
304 * rfcomm_listen_pcb(dlc)
306 * This DLC is a listener. We look for an existing listening session
312 rfcomm_listen_pcb(struct rfcomm_dlc *dlc)
319 if (dlc->rd_state != RFCOMM_DLC_CLOSED)
322 if (dlc->rd_laddr.bt_channel != RFCOMM_CHANNEL_ANY
323 && (dlc->rd_laddr.bt_channel < RFCOMM_CHANNEL_MIN
324 || dlc->rd_laddr.bt_channel > RFCOMM_CHANNEL_MAX))
327 if (dlc->rd_laddr.bt_psm == L2CAP_PSM_ANY)
328 dlc->rd_laddr.bt_psm = L2CAP_PSM_RFCOMM;
329 else if (dlc->rd_laddr.bt_psm != L2CAP_PSM_RFCOMM
330 && (dlc->rd_laddr.bt_psm < 0x1001
331 || L2CAP_PSM_INVALID(dlc->rd_laddr.bt_psm)))
337 if (addr.bt_psm != dlc->rd_laddr.bt_psm)
340 if (bdaddr_same(&dlc->rd_laddr.bt_bdaddr, &addr.bt_bdaddr))
346 &dlc->rd_laddr);
359 if (dlc->rd_laddr.bt_channel == RFCOMM_CHANNEL_ANY) {
374 dlc->rd_laddr.bt_channel = channel;
377 dlc->rd_session = rs;
378 dlc->rd_state = RFCOMM_DLC_LISTEN;
379 LIST_INSERT_HEAD(&rs->rs_dlcs, dlc, rd_next);
385 * rfcomm_send_pcb(dlc, mbuf)
387 * Output data on DLC. This is streamed data, so we add it
388 * to our buffer and start the DLC, which will assemble
392 rfcomm_send_pcb(struct rfcomm_dlc *dlc, struct mbuf *m)
395 if (dlc->rd_txbuf != NULL) {
396 dlc->rd_txbuf->m_pkthdr.len += m->m_pkthdr.len;
397 m_cat(dlc->rd_txbuf, m);
399 dlc->rd_txbuf = m;
402 if (dlc->rd_state == RFCOMM_DLC_OPEN)
403 rfcomm_dlc_start(dlc);
409 * rfcomm_rcvd_pcb(dlc, space)
414 * size when the DLC is attached and anytime data is cleared from the
418 rfcomm_rcvd_pcb(struct rfcomm_dlc *dlc, size_t space)
421 KASSERT(dlc != NULL);
423 dlc->rd_rxsize = space;
429 if (dlc->rd_state == RFCOMM_DLC_OPEN
430 && (dlc->rd_session->rs_flags & RFCOMM_SESSION_CFC))
431 rfcomm_dlc_start(dlc);
437 * rfcomm_setopt(dlc, sopt)
439 * set DLC options
442 rfcomm_setopt(struct rfcomm_dlc *dlc, const struct sockopt *sopt)
455 else if (dlc->rd_state == RFCOMM_DLC_CLOSED)
456 dlc->rd_mtu = mtu;
475 dlc->rd_mode = mode;
477 if (dlc->rd_state == RFCOMM_DLC_OPEN)
478 err = rfcomm_dlc_setmode(dlc);
490 * rfcomm_getopt(dlc, sopt)
492 * get DLC options
495 rfcomm_getopt(struct rfcomm_dlc *dlc, struct sockopt *sopt)
501 return sockopt_set(sopt, &dlc->rd_mtu, sizeof(uint16_t));
505 fc.lmodem = dlc->rd_lmodem;
506 fc.rmodem = dlc->rd_rmodem;
507 fc.tx_cred = uimax(dlc->rd_txcred, 0xff);
508 fc.rx_cred = uimax(dlc->rd_rxcred, 0xff);
509 if (dlc->rd_session
510 && (dlc->rd_session->rs_flags & RFCOMM_SESSION_CFC))
516 return sockopt_setint(sopt, dlc->rd_mode);