static void rfcomm_ua_recv(struct bthost *bthost, struct btconn *conn, struct l2conn *l2conn, const void *data, uint16_t len) { const struct rfcomm_cmd *ua_hdr = data; uint8_t channel = RFCOMM_GET_CHANNEL(ua_hdr->address); struct rfcomm_connection_data *conn_data = bthost->rfcomm_conn_data; uint8_t type = RFCOMM_GET_TYPE(ua_hdr->control); uint8_t buf[14]; struct rfcomm_hdr *hdr; struct rfcomm_mcc *mcc; struct rfcomm_pn *pn_cmd; if (channel && conn_data && conn_data->channel == channel) { if (conn_data->cb) conn_data->cb(conn->handle, l2conn->scid, conn_data->user_data, true); free(bthost->rfcomm_conn_data); bthost->rfcomm_conn_data = NULL; return; } if (!conn_data || !RFCOMM_TEST_CR(type)) return; memset(buf, 0, sizeof(buf)); hdr = (struct rfcomm_hdr *) buf; mcc = (struct rfcomm_mcc *) (buf + sizeof(*hdr)); pn_cmd = (struct rfcomm_pn *) (buf + sizeof(*hdr) + sizeof(*mcc)); hdr->address = RFCOMM_ADDR(1, 0); hdr->control = RFCOMM_CTRL(RFCOMM_UIH, 0); hdr->length = RFCOMM_LEN8(sizeof(*mcc) + sizeof(*pn_cmd)); mcc->type = RFCOMM_MCC_TYPE(1, RFCOMM_PN); mcc->length = RFCOMM_LEN8(sizeof(*pn_cmd)); pn_cmd->dlci = conn_data->channel * 2; pn_cmd->priority = 7; pn_cmd->ack_timer = 0; pn_cmd->max_retrans = 0; pn_cmd->mtu = 667; pn_cmd->credits = 7; buf[sizeof(*hdr) + sizeof(*mcc) + sizeof(*pn_cmd)] = rfcomm_fcs(buf); send_acl(bthost, conn->handle, l2conn->dcid, buf, sizeof(buf)); }
static void rfcomm_dm_recv(struct bthost *bthost, struct btconn *conn, struct l2conn *l2conn, const void *data, uint16_t len) { const struct rfcomm_cmd *hdr = data; uint8_t channel = RFCOMM_GET_CHANNEL(hdr->address); struct rfcomm_connection_data *conn_data = bthost->rfcomm_conn_data; if (conn_data && conn_data->channel == channel) { if (conn_data->cb) conn_data->cb(conn->handle, l2conn->scid, conn_data->user_data, false); free(bthost->rfcomm_conn_data); bthost->rfcomm_conn_data = NULL; } }
static void rfcomm_sabm_recv(struct bthost *bthost, struct btconn *conn, struct l2conn *l2conn, const void *data, uint16_t len) { const struct rfcomm_cmd *hdr = data; uint8_t dlci = RFCOMM_GET_DLCI(hdr->address); struct rfcomm_conn_cb_data *cb; uint8_t chan = RFCOMM_GET_CHANNEL(hdr->address); cb = bthost_find_rfcomm_cb_by_channel(bthost, chan); if (!dlci || cb) { rfcomm_ua_send(bthost, conn, l2conn, 1, dlci); if (cb && cb->func) cb->func(conn->handle, l2conn->scid, cb->user_data, true); } else { rfcomm_dm_send(bthost, conn, l2conn, 1, dlci); } }
static bool uih_frame(struct rfcomm_frame *rfcomm_frame, uint8_t indent) { uint8_t credits; struct l2cap_frame *frame = &rfcomm_frame->l2cap_frame; struct rfcomm_lhdr *hdr = &rfcomm_frame->hdr; if (!RFCOMM_GET_CHANNEL(hdr->address)) return mcc_frame(rfcomm_frame, indent); /* fetching credits from UIH frame */ if (GET_PF(hdr->control)) { if (!l2cap_frame_get_u8(frame, &credits)) return false; hdr->credits = credits; print_field("%*cCredits: %d", indent, ' ', hdr->credits); } packet_hexdump(frame->data, frame->size); return true; }