?? rfcomm.c
字號:
u32 rfcomm_frame_size; if (len > SHORT_PAYLOAD_SIZE) { long_frame *uih_pkt; mcc_long_frame *mcc_pkt; /* Create long uih packet and long mcc packet */ rfcomm_frame_size = (sizeof(long_frame) + sizeof(mcc_long_frame) + len +FCS_SIZE); tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size); if (!tx_buf) { D_ERR("rfcomm_test_msg : didn't get a valid tx_buf\n"); return -ENOMEM; } tx_buf->cur_len = rfcomm_frame_size; uih_pkt = (long_frame*) (tx_buf->data + sizeof(rfcomm_tx_buf)); set_uih_hdr((short_frame*) uih_pkt, CTRL_CHAN, len + sizeof(mcc_long_frame), rfcomm->initiator); uih_pkt->data[uih_pkt->h.length.bits.len] = crc_calc((u8*) uih_pkt, SHORT_CRC_CHECK); mcc_pkt = (mcc_long_frame*) uih_pkt->data; /* Always one in the TEST messages */ mcc_pkt->h.type.ea = EA; /* cr tells whether it is a commmand (1) or a response (0) */ mcc_pkt->h.type.cr = cr; mcc_pkt->h.type.type = TEST; mcc_pkt->h.length.bits.ea = EA; mcc_pkt->h.length.bits.len = len; swap_long_frame(uih_pkt); swap_mcc_long_frame(mcc_pkt); memcpy(mcc_pkt->value,test_pattern,len); } else if (len > (SHORT_PAYLOAD_SIZE-sizeof(mcc_short_frame))) { long_frame *uih_pkt; mcc_short_frame *mcc_pkt; /* Create long uih packet and short mcc packet */ rfcomm_frame_size = (sizeof(long_frame) + sizeof(mcc_short_frame) + len+FCS_SIZE); tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size); if (!tx_buf) { D_ERR("rfcomm_test_msg : didn't get a valid tx_buf\n"); return -ENOMEM; } tx_buf->cur_len = rfcomm_frame_size; uih_pkt = (long_frame*) (tx_buf->data + sizeof(rfcomm_tx_buf)); set_uih_hdr((short_frame*) uih_pkt, CTRL_CHAN, len + sizeof(mcc_short_frame), rfcomm->initiator); uih_pkt->data[uih_pkt->h.length.bits.len] = crc_calc((u8*) uih_pkt, SHORT_CRC_CHECK); mcc_pkt = (mcc_short_frame*) uih_pkt->data; /* Always one in the TEST messages */ mcc_pkt->h.type.ea = EA; /* cr tells whether it is a commmand (1) or a response (0) */ mcc_pkt->h.type.cr = cr; mcc_pkt->h.type.type = TEST; mcc_pkt->h.length.ea = EA; mcc_pkt->h. length.len = len; swap_long_frame(uih_pkt); memcpy(mcc_pkt->value,test_pattern,len); } else { short_frame *uih_pkt; mcc_short_frame *mcc_pkt; /* Creat short uih packet and short mcc packet */ rfcomm_frame_size = (sizeof(short_frame) + sizeof(mcc_short_frame) + len+FCS_SIZE); tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size); if (!tx_buf) { D_ERR("rfcomm_test_msg : didn't get a valid tx_buf\n"); return -ENOMEM; } tx_buf->cur_len = rfcomm_frame_size; uih_pkt = (short_frame*) (tx_buf->data +sizeof(rfcomm_tx_buf)); set_uih_hdr((void*) uih_pkt, CTRL_CHAN, len + sizeof(mcc_short_frame), rfcomm->initiator); uih_pkt->data[uih_pkt->h.length.len] = crc_calc((u8*) uih_pkt, SHORT_CRC_CHECK); mcc_pkt = (mcc_short_frame*) uih_pkt->data; /* Always one in the TEST messages */ mcc_pkt->h.type.ea = EA; /* cr tells whether it is a commmand (1) or a response (0) */ mcc_pkt->h.type.cr = cr; mcc_pkt->h.type.type = TEST; mcc_pkt->h.length.ea = EA; mcc_pkt->h. length.len = len; memcpy(mcc_pkt->value,test_pattern,len); } return l2cap_send_data(tx_buf, rfcomm->l2cap);}/* Turns on the RFCOMM flow control */s32 rfcomm_fcon_msg(rfcomm_con *rfcomm, u8 cr){ bt_tx_buf *tx_buf; short_frame *uih_pkt; mcc_short_frame *mcc_pkt; u32 rfcomm_frame_size; rfcomm_frame_size = (sizeof(short_frame) + sizeof(mcc_short_frame) + FCS_SIZE); tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size); if (!tx_buf) { D_ERR("rfcomm_fcon_msg : didn't get a valid tx_buf\n"); return -ENOMEM; } tx_buf->cur_len = rfcomm_frame_size; uih_pkt = (short_frame*) (tx_buf->data + sizeof(rfcomm_tx_buf)); set_uih_hdr(uih_pkt, CTRL_CHAN, sizeof(mcc_short_frame), rfcomm->initiator); uih_pkt->data[sizeof(mcc_short_frame)] = crc_calc((u8*) uih_pkt, SHORT_CRC_CHECK); mcc_pkt = (mcc_short_frame*) (uih_pkt->data); mcc_pkt->h.type.ea = EA; mcc_pkt->h.type.cr = cr; mcc_pkt->h.type.type = FCON; mcc_pkt->h.length.ea = EA; mcc_pkt->h.length.len = 0; return l2cap_send_data(tx_buf, rfcomm->l2cap);}/* Turns off the RFCOMM flow control */s32 rfcomm_fcoff_msg(rfcomm_con *rfcomm, u8 cr){ bt_tx_buf *tx_buf; short_frame *uih_pkt; mcc_short_frame *mcc_pkt; u32 rfcomm_frame_size; rfcomm_frame_size = (sizeof(short_frame) + sizeof(mcc_short_frame) + FCS_SIZE); tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size); if (!tx_buf) { D_ERR("rfcomm_fcoff_msg : didn't get a valid tx_buf\n"); return -ENOMEM; } tx_buf->cur_len = rfcomm_frame_size; uih_pkt = (short_frame*) (tx_buf->data + sizeof(rfcomm_tx_buf)); set_uih_hdr(uih_pkt, CTRL_CHAN, sizeof(mcc_short_frame), rfcomm->initiator); uih_pkt->data[sizeof(mcc_short_frame)] = crc_calc((u8*) uih_pkt, SHORT_CRC_CHECK); mcc_pkt = (mcc_short_frame*) (uih_pkt->data); mcc_pkt->h.type.ea = 1; mcc_pkt->h.type.cr = cr; mcc_pkt->h.type.type = FCOFF; mcc_pkt->h.length.ea = 1; mcc_pkt->h.length.len = 0; return l2cap_send_data(tx_buf, rfcomm->l2cap);}s32 rfcomm_rpn_msg(rfcomm_con *rfcomm, u8 cr, u8 dlci, u8 req){ bt_tx_buf *tx_buf; rpn_msg* rpn_pkt; u32 rfcomm_frame_size; u32 rfcomm_payload_size; rfcomm_frame_size = sizeof(rpn_msg); if (req) { rfcomm_frame_size -= sizeof(rpn_values); } rfcomm_payload_size = (rfcomm_frame_size - sizeof(short_frame) - FCS_SIZE); tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size); if (!tx_buf) { D_ERR("rfcomm_rpn_msg : didn't get a valid tx_buf\n"); return -ENOMEM; } tx_buf->cur_len = rfcomm_frame_size; rpn_pkt = (rpn_msg*) (tx_buf->data + sizeof(rfcomm_tx_buf)); set_uih_hdr((short_frame*) rpn_pkt, CTRL_CHAN, rfcomm_payload_size, rfcomm->initiator); rpn_pkt->fcs = crc_calc((u8*) rpn_pkt, SHORT_CRC_CHECK); rpn_pkt->mcc_s_head.type.ea = EA; rpn_pkt->mcc_s_head.type.cr = cr; rpn_pkt->mcc_s_head.type.type = RPN; rpn_pkt->mcc_s_head.length.ea = EA; rpn_pkt->dlci.ea = EA; rpn_pkt->dlci.cr = 1; /* Fixed value */ rpn_pkt->dlci.d = dlci & 1; rpn_pkt->dlci.server_chn = (dlci >> 1); if (req) { rpn_pkt->mcc_s_head.length.len = 1; /* Fix, since the packet is ends here when it is a request */ rpn_pkt->rpn_val.bit_rate = rpn_pkt->fcs; return l2cap_send_data(tx_buf, rfcomm->l2cap); } else { rpn_pkt->mcc_s_head.length.len = 8; memcpy(&(rpn_pkt->rpn_val), &rpn_val, sizeof(rpn_values)); //print_data("",(u8*) rpn_pkt, rfcomm_frame_size); return l2cap_send_data(tx_buf, rfcomm->l2cap); }}s32 rfcomm_rls_msg(rfcomm_con *rfcomm, u8 cr, u8 dlci, u8 err_code){ bt_tx_buf *tx_buf; rls_msg* rls_pkt; u32 rfcomm_frame_size; u32 rfcomm_payload_size; rfcomm_frame_size = sizeof(rls_msg); rfcomm_payload_size = rfcomm_frame_size - sizeof(short_frame)-FCS_SIZE; tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size); if (!tx_buf) { D_ERR("rfcomm_rls_msg : didn't get a valid tx_buf\n"); return -ENOMEM; } tx_buf->cur_len = rfcomm_frame_size; rls_pkt = (rls_msg*) (tx_buf->data + sizeof(rfcomm_tx_buf)); set_uih_hdr((short_frame*) rls_pkt, CTRL_CHAN, rfcomm_payload_size, rfcomm->initiator); rls_pkt->fcs = crc_calc((u8*) rls_pkt, SHORT_CRC_CHECK); rls_pkt->mcc_s_head.type.ea = EA; rls_pkt->mcc_s_head.type.cr = cr; rls_pkt->mcc_s_head.type.type = RLS; rls_pkt->mcc_s_head.length.ea = EA; rls_pkt->mcc_s_head.length.len = 2; rls_pkt->dlci.ea = EA; rls_pkt->dlci.cr = 1; /* Fixed value */ rls_pkt->dlci.d = dlci & 1; rls_pkt->dlci.server_chn = dlci >> 1; rls_pkt->error = err_code; rls_pkt->res = 0; return l2cap_send_data(tx_buf, rfcomm->l2cap);}/* Sends an PN-messages and sets the not negotiable parameters to their default values in RFCOMM */s32 send_pn_msg(rfcomm_con *rfcomm, u8 prior, u32 frame_size, u8 credit_flow, u8 credits, u8 dlci, u8 cr){ bt_tx_buf *tx_buf; pn_msg *pn_pkt; u32 rfcomm_frame_size; D_CTRL("send_pn_msg: DLCI 0x%02x, prior:0x%02x, frame_size:%d, credit_flow:%x, credits:%d, cr:%x\n", dlci, prior, frame_size, credit_flow, credits, cr); rfcomm_frame_size = sizeof *pn_pkt; tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size); if (!tx_buf) { D_ERR("send_pn_msg : didn't get a valid tx_buf\n"); return -ENOMEM; } tx_buf->cur_len = rfcomm_frame_size; pn_pkt = (pn_msg*) (tx_buf->data + sizeof(rfcomm_tx_buf)); /* Set the UIH headers */ set_uih_hdr((void*) pn_pkt, CTRL_CHAN, rfcomm_frame_size - (sizeof(short_frame) + FCS_SIZE), rfcomm->initiator); pn_pkt->fcs = crc_calc((u8*) pn_pkt, SHORT_CRC_CHECK); /* set the MCC-packet header */ pn_pkt->mcc_s_head.type.ea = 1; pn_pkt->mcc_s_head.type.cr = cr; pn_pkt->mcc_s_head.type.type = PN; pn_pkt->mcc_s_head.length.ea = 1; /* The PN packet has a fix length of 8 bytes */ pn_pkt->mcc_s_head.length.len = 8; /* Set the parameters in the PN-packet */ pn_pkt->res1 = 0; pn_pkt->res2 = 0; pn_pkt->dlci = dlci; pn_pkt->frame_type = 0; pn_pkt->credit_flow = credit_flow; pn_pkt->prior = prior; pn_pkt->ack_timer = 0; put_unaligned(cpu_to_le16(frame_size), &pn_pkt->frame_size); pn_pkt->credits = credits; pn_pkt->max_nbrof_retrans = 0; return l2cap_send_data(tx_buf, rfcomm->l2cap);}/* Sendares a Not supported command - command, which needs 3 bytes */s32 send_nsc_msg(rfcomm_con *rfcomm, mcc_type cmd, u8 cr) { bt_tx_buf *tx_buf; nsc_msg *nsc_pkt; u32 rfcomm_frame_size; rfcomm_frame_size = sizeof(nsc_msg); tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size); if (!tx_buf) { D_ERR("send_nsc_msg : didn't get a valid tx_buf\n"); return -ENOMEM; } tx_buf->cur_len = rfcomm_frame_size; nsc_pkt = (nsc_msg*) (tx_buf->data + sizeof(rfcomm_tx_buf)); set_uih_hdr((void*) nsc_pkt, CTRL_CHAN, sizeof(nsc_msg) - sizeof(short_frame) - FCS_SIZE, rfcomm->initiator); nsc_pkt->fcs = crc_calc((u8*) nsc_pkt, SHORT_CRC_CHECK); nsc_pkt->mcc_s_head.type.ea = 1; nsc_pkt->mcc_s_head.type.cr = cr; nsc_pkt->mcc_s_head.type.type = NSC; nsc_pkt->mcc_s_head.length.ea = 1; nsc_pkt->mcc_s_head.length.len = 1; nsc_pkt->command_type.ea = 1; nsc_pkt->command_type.cr = cmd.cr; nsc_pkt->command_type.type = cmd.type; return l2cap_send_data(tx_buf, rfcomm->l2cap);}s32 rfcomm_msc_msg(rfcomm_con *rfcomm, u8 value, u8 cr, u8 dlci){ bt_tx_buf *tx_buf; msc_msg *msc_pkt; u32 rfcomm_frame_size; D_CTRL(FNC"val:%d, cr:%d, dlci:%d\n", value, cr, dlci); rfcomm_frame_size = sizeof(msc_msg); tx_buf = subscribe_bt_buf(sizeof(rfcomm_tx_buf) + rfcomm_frame_size); if (!tx_buf) { D_ERR(FNC"didn't get a valid tx_buf\n"); return -ENOMEM; } tx_buf->cur_len = rfcomm_frame_size; msc_pkt = (msc_msg*) (tx_buf->data + sizeof(rfcomm_tx_buf)); set_uih_hdr((void*) msc_pkt, CTRL_CHAN, sizeof(msc_msg) - sizeof(short_frame) - FCS_SIZE, rfcomm->initiator); msc_pkt->fcs = crc_calc((u8*) msc_pkt, SHORT_CRC_CHECK); msc_pkt->mcc_s_head.type.ea = 1; msc_pkt->mcc_s_head.type.cr = cr; msc_pkt->mcc_s_head.type.type = MSC; msc_pkt->mcc_s_head.length.ea = 1; msc_pkt->mcc_s_head.length.len = 2; msc_pkt->dlci.ea = 1; msc_pkt->dlci.cr = 1; msc_pkt->dlci.d = dlci & 1; msc_pkt->dlci.server_chn = (dlci >> 1) & 0x1f; msc_pkt->v24_sigs = value;return l2cap_send_data(tx_buf, rfcomm->l2cap);}voidset_uih_hdr(short_frame *uih_pkt, u8 dlci, u32 len, u8 cr){ uih_pkt->h.addr.ea = 1; uih_pkt->h.addr.cr = cr; uih_pkt->h.addr.d = dlci & 0x1; uih_pkt->h.addr.server_chn = dlci >> 1; uih_pkt->h.control = CLR_PF(UIH); if (len > SHORT_PAYLOAD_SIZE) { ((long_frame*) uih_pkt)->h.length.bits.ea = 0; ((long_frame*) uih_pkt)->h.length.bits.len = len; } else { uih_pkt->h.length.ea = 1; uih_pkt->h.length.len = len; }}rfcomm_con* get_new_rfcomm_con(void){ s32 i = 0; D_CTRL(FNC"rfcomm_con -> ttyBT%d\n",i); for (i = 0 ; i < BT_NBR_DATAPORTS ; i ++) { if (rfcomm_con_list[i].dlci[0].state == DISCONNECTED) { rfcomm_con_list[i].l2cap = NULL; return &rfcomm_con_list[i]; } } return NULL;}rfcomm_con* get_rfcomm_con(u8 line){ if(line >= BT_NBR_DATAPORTS) { return NULL; } return &rfcomm_con_list[line];}s32valid_dlci(u8 dlci){ if ((dlci < 62) && (dlci > 1)) { return TRUE; } else { return FALSE; }}/* fetches the 'last' non DISCONNECTED dlci number in this session, returns -1 if no connected dlci was found */s32 get_connected_dlci(rfcomm_con *rfcomm){ s32 tmp; tmp = 61; while ((tmp >= 0) && (rfcomm != NULL) && (rfcomm->dlci[tmp].state == DISCONNECTED)) { tmp--; } return tmp;}/* Functions for the crc-check and calculation */#define CRC_VALID 0xcf/* This functions check whether the checksum is correct or not. Length is the number of bytes in the message, data points to the beginning of the message */u32 crc_check(u8 *data, u32 length, u8 check_sum){ u8 fcs = 0xff; RF_DATA(FNC, data, length); while (length--) { fcs = crctab
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -