📄 tcs.c
字号:
s32tcs_add_sco_link(u8 err_code, u32 hci_hdl){ D_MISC("tcs_add_sco_link: Added SCO handle %d\n",hci_hdl); if (err_code) { D_ERR("Failure establishing SCO link: %s\n", get_err_msg(err_code)); return -1; } else /* If we initiate the setup of the SCO link we sould send connect here */ tcs[0].sco_hdl = hci_hdl; return 0;}void tcs_receive_data(l2cap_con *l2cap, u8* data, u32 len){#define FNC "tcs_receive_data: " tcs_message *tcs_msg; tcs_msg = (tcs_message*) data; PRINTPKT(FNC, data, len); switch (tcs_msg->prot_disc) { case CALL_CONTROL: D_REC(FNC"Received CALL_CONTROL message\n"); process_cc_msg(l2cap, data, len); break; case GROUP_MANAGEMENT: D_REC(FNC"Received GROUP_MANAGEMENT message\n"); process_gw_msg(l2cap, data, len); break; case CONNECTIONLESS: D_REC(FNC"Received CONNECTIONLESS message\n"); process_cl_msg(l2cap, data, len); break; default: D_ERR(FNC"Unknown protocol discriminator (0x%x)\n", tcs_msg->prot_disc); }#undef FNC }voidprocess_cc_msg(l2cap_con *l2cap, u8* data, u32 len){#define FNC "process_cc_msg: " tcs_message *tcs_msg; tcs_msg = (tcs_message*) data; switch (tcs_msg->type) { case ALERTING: D_REC(FNC"Received ALERTING message\n"); tcs[0].tcs_cur_state = CALL_DELIVERED; break; case CALL_PROCEEDING: D_REC(FNC"Received CALL_PROCEEDING message\n"); break; case CONNECT: D_REC(FNC"Received CONNECT message\n"); tcs[0].tcs_cur_state = ACTIVE; send_single_octet_msg(l2cap, CONNECT_ACKNOWLEDGE, CALL_CONTROL); break; case CONNECT_ACKNOWLEDGE: D_REC(FNC"Received CONNECT_ACKNOWLEDGE message\n"); tcs[0].tcs_cur_state = ACTIVE; break; case PROGRESS: D_REC(FNC"Received PROGRESS message\n"); break; case SETUP: if (tcs[0].tcs_cur_state != STATE_NULL) { DSYS(FNC"Received SETUP in wrong state (%d)\n", tcs[0].tcs_cur_state); } else { u8 alert_nfo[4]; D_REC(FNC"Received SETUP\n"); tcs[0].tcs_cur_state = CALL_PRESENT; alert_nfo[0] = BEARER_CAPABILITY; alert_nfo[1] = 2; alert_nfo[2] = SCO_LINK; alert_nfo[3] = (CVSD << 5) | (HV3_PACKET & 0x1f); send_tcs_msg(l2cap, ALERTING, CALL_CONTROL, alert_nfo, 4); tcs[0].tcs_cur_state = CALL_RECEIVED; } break; case SETUP_ACKNOWLEDGE: D_REC(FNC"Received SETUP_ACKNOWLEDGE message\n"); break; case DISCONNECT: D_REC(FNC"Received DISCONNECT message\n"); tcs[0].tcs_cur_state = DISCONNECT_INDICATION; send_single_octet_msg(l2cap, RELEASE, CALL_CONTROL); tcs[0].tcs_cur_state = RELEASE_REQUEST; break; case RELEASE: D_REC(FNC"Received RELEASE message\n"); if (lp_disconnect(tcs[0].sco_hdl)) { D_ERR("lp_disconnect failed\n"); } else { send_single_octet_msg(l2cap, RELEASE_COMPLETE, CALL_CONTROL); } break; case RELEASE_COMPLETE: D_REC(FNC"Received RELEASE_COMPLETE message\n"); tcs[0].tcs_cur_state = STATE_NULL; break; case INFORMATION: D_REC(FNC"Received INFORMATION message %c\n",tcs_msg->info[1]); break; case START_DTMF: D_REC(FNC"Received START_DTMF message\n"); break; case START_DTMF_ACKNOWLEDGE: D_REC(FNC"Received START_DTMF_ACKNOWLEDGE message\n"); break; case START_DTMF_REJECT: D_REC(FNC"Received START_DTMF_REJECT message\n"); break; case STOP_DTMF: D_REC(FNC"Received STOP_DTMF message\n"); break; case STOP_DTMF_ACKNOWLEDGE: D_REC(FNC"Received STOP_DTMF_ACKNOWLEDGE message\n"); break; default: D_ERR(FNC"Unknown message type (0x%x)\n", tcs_msg->type); break; }#undef FNC}voidprocess_gw_msg(l2cap_con *l2cap, u8* data, u32 len){#define FNC "process_gw_msg: " tcs_message *tcs_msg; tcs_msg = (tcs_message*) data; switch (tcs_msg->type) { case INFO_SUGGEST: D_REC(FNC"Received INFO_SUGGEST message\n"); break; case INFO_ACCEPT: D_REC(FNC"Received INFO_ACCEPT message\n"); break; case LISTEN_REQUEST: D_REC(FNC"Received LISTEN_REQUEST message\n"); break; case LISTEN_ACCEPT: D_REC(FNC"Received LISTEN_ACCEPT message\n"); break; case LISTEN_SUGGEST: D_REC(FNC"Received LISTEN_SUGGEST message\n"); break; case LISTEN_REJECT: D_REC(FNC"Received LISTEN_REJECT message\n"); break; case ACCESS_RIGHTS_REQUEST: D_REC(FNC"Received ACCESS_RIGHTS_REQUEST message\n"); break; case ACCESS_RIGHTS_ACCEPT: D_REC(FNC"Received ACCESS_RIGHTS_ACCEPT message\n"); break; case ACCESS_RIGHTS_REJECT: D_REC(FNC"Received ACCESS_RIGHTS_REJECT message\n"); break; default: D_ERR(FNC"Unknown message type (0x%x)\n", tcs_msg->type); break; }#undef FNC}voidprocess_cl_msg(l2cap_con *l2cap, u8* data, u32 len){#define FNC "process_cl_msg: " tcs_message *tcs_msg; tcs_msg = (tcs_message*) data; switch (tcs_msg->type) { case CL_INFO: D_REC(FNC"Received CL_INFO message\n"); break; default: D_ERR(FNC"Unknown message type (0x%x)\n", tcs_msg->type); break; }#undef FNC}s32send_single_octet_msg(l2cap_con *l2cap, u8 type, u8 prot_disc){ bt_tx_buf *tx_buf; tcs_message *msg; u32 tcs_frame_size; tcs_frame_size = 1; tx_buf = subscribe_bt_buf(sizeof(tcs_tx_buf) + tcs_frame_size); if (!tx_buf) { D_ERR("send_single_octet_msg: didn't get a valid tx_buf\n"); return -1; } tx_buf->cur_len = tcs_frame_size; msg = (tcs_message*) (tx_buf->data + sizeof(tcs_tx_buf)); msg->type = type & 0x1f; msg->prot_disc = prot_disc & 0x7; printk("send_single_octet_msg : prot_disc 0x%x, type : 0x%x \n", prot_disc, type); return l2cap_send_data(tx_buf, l2cap);}s32tcs_connect(l2cap_con *l2cap){ hci_add_sco_connection(tcs[0].acl_hdl); return send_single_octet_msg(l2cap, CONNECT, CALL_CONTROL);}s32tcs_disconnect(l2cap_con *l2cap){ u8 disconnect_nfo[2]; disconnect_nfo[0] = CAUSE; disconnect_nfo[1] = NORMAL_CALL_CLEARING; return send_tcs_msg(l2cap, DISCONNECT, CALL_CONTROL, disconnect_nfo,2);}s32tcs_setup(l2cap_con *l2cap, u8 *nbr, u8 nbr_len){ u8 setup_nfo[11 + nbr_len]; tcs[0].tcs_cur_state = CALL_INITIATED; setup_nfo[0] = CALL_CLASS; setup_nfo[1] = INTERCOM_CALL; setup_nfo[2] = BEARER_CAPABILITY; setup_nfo[3] = 2; setup_nfo[4] = SCO_LINK; setup_nfo[5] = (CVSD << 5) | (HV3_PACKET & 0x1f); setup_nfo[6] = SIGNAL; setup_nfo[7] = INTERNAL_CALL_SIGNAL; setup_nfo[8] = CALLED_PARTY_NUMBER; setup_nfo[9] = nbr_len; setup_nfo[10] = 0x10; memcpy(&setup_nfo[11], nbr, nbr_len); if (nbr_len) { return send_tcs_msg(l2cap, SETUP, CALL_CONTROL, setup_nfo, 11 + nbr_len); } else { return send_tcs_msg(l2cap, SETUP, CALL_CONTROL, setup_nfo, 8); } /* If using telephone number change length to nbr_len+11 */}s32tcs_send_information(l2cap_con *l2cap, u8 ch){ u8 nfo[2]; if (tcs[0].tcs_cur_state != ACTIVE) { D_ERR("tcs_send_information: Not in state ACTIVE!\n"); } nfo[0] = KEYPAD_FACILITY; nfo[1] = ch; return send_tcs_msg(l2cap, INFORMATION, CALL_CONTROL, nfo, 2);}s32send_tcs_msg(l2cap_con *l2cap, u8 type, u8 prot_disc, u8 *nfo, u32 nfo_len){#define FNC "send_tcs_msg: "bt_tx_buf *tx_buf; tcs_message *msg; u32 tcs_frame_size; tcs_frame_size = 1 + nfo_len; tx_buf = subscribe_bt_buf(sizeof(tcs_tx_buf) + tcs_frame_size); if (!tx_buf) { D_ERR(FNC"didn't get a valid tx_buf\n"); return -1; } tx_buf->cur_len = tcs_frame_size; msg = (tcs_message*) (tx_buf->data + sizeof(tcs_tx_buf)); msg->type = type; msg->prot_disc = prot_disc; if (nfo_len) { memcpy(msg->info, nfo, nfo_len); } PRINTPKT(FNC,(u8*)msg, tcs_frame_size); return l2cap_send_data(tx_buf, l2cap);#undef FNC}/****************** END OF FILE tcs.c ***************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -