📄 hci.c
字号:
s32 create_connection(u8 bd_addr[], u32 pkt_type, u8 psrm, u8 psm, u32 c_off, u32 rol_sw){ D_CMD(__FUNCTION__ "\n"); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(CREATE_CONNECTION, HCI_LC); memcpy(c_pkt.data, bd_addr, 6); c_pkt.data[6] = (pkt_type & 0xff); c_pkt.data[7] = (pkt_type >> 8); c_pkt.data[8] = psrm; c_pkt.data[9] = psm; c_pkt.data[10] = (c_off & 0xff); c_pkt.data[11] = (c_off >> 8); c_pkt.data[12] = rol_sw; c_pkt.len = 13; return send_cmd((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN); }s32hci_add_sco_connection(u32 hci_hdl){ D_CMD(__FUNCTION__ "\n"); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(ADD_SCO_CONNECTION, HCI_LC); c_pkt.data[0] = hci_hdl & 0xff; c_pkt.data[1] = hci_hdl >> 8; c_pkt.data[2] = 0xe0; c_pkt.data[3] = 0x00; c_pkt.len = 4; return send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT);}/* The Hci_Disconnect function is used to terminate an existing connection. The Connection_Handle function parameter indicates which connection is to be disconnected. The Reason function parameter indicates the reason for ending the connection, see page 552 specification core 1.0B */s32 disconnect(u32 hdl, u8 reason){ D_CMD(__FUNCTION__ "\n"); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(DISCONNECT, HCI_LC); c_pkt.data[0] = hdl & 0xff; c_pkt.data[1] = hdl >> 8; c_pkt.data[2] = reason; c_pkt.len = 3; return send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT);}/* A positive response to a previous connection request, role = 0 sets master, role = 1 sets slave */s32 accept_connection_request(u8 bd[], u8 role){ D_CMD(__FUNCTION__ ": bd_addr %x %x %x %x %x %x\n",bd[0], bd[1], bd[2], bd[3], bd[4], bd[5]); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(ACCEPT_CONNECTION_REQUEST, HCI_LC); memcpy(c_pkt.data, bd, 6); c_pkt.data[6] = role; c_pkt.len = 7; return send_cmd((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN);}/* The Reject_Connection_Request function is used to decline a new incoming connection request. The Reject_Connection_Request function shall only be called after a Connection Request event has occurred. */s32 reject_connection_request(u8 bd[], u32 reason){ u32 c = 0; D_CMD(__FUNCTION__ ": Rejecting bd_addr %x %x %x %x %x %x\n", bd[0],bd[1],bd[2],bd[3],bd[4],bd[5]); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(REJECT_CONNECTION_REQUEST, HCI_LC); memcpy(c_pkt.data, bd, 6); c += 6; c_pkt.data[c++] = reason; c_pkt.len = c; return send_cmd((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN);}s32hci_link_key_request_reply(u8 *bd, u8* link_key){ u32 c = 0; s32 tmp; print_data(__FUNCTION__ ": BD_addr", bd, 6); print_data(__FUNCTION__ ": Link Key", link_key, 16); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(LINK_KEY_REQUEST_REPLY, HCI_LC); memcpy(c_pkt.data, bd, 6); c += 6; memcpy(c_pkt.data + c, link_key, 16); c += 16; c_pkt.len = c; tmp = send_cmd_block((u8*) &c_pkt , c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT); if (tmp < 0) { return tmp; } else { return result_param; }}s32hci_link_key_request_negative_reply(u8 *bd){ s32 tmp; print_data(__FUNCTION__ ": BD_addr", bd, 6); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(LINK_KEY_REQUEST_NEGATIVE_REPLY, HCI_LC); memcpy(c_pkt.data, bd, 6); c_pkt.len = 6; tmp = send_cmd_block((u8*) &c_pkt , c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT); printk(__FUNCTION__ ": Returned from send_secblock\n"); if (tmp < 0) { return tmp; } else { return result_param; }}/* fixme -- does this really need to be non blocking ? */s32hci_pin_code_request_reply(u8 *bd, u8 *pin, u8 pin_len){ u32 c = 0; s32 tmp; print_data(__FUNCTION__ ": New pin is\n", pin, pin_len); print_data(__FUNCTION__ ": BD_addr", bd, 6); print_data(__FUNCTION__ ": pin", pin, pin_len); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(PIN_CODE_REQUEST_REPLY, HCI_LC); memcpy(c_pkt.data, bd, 6); c += 6; c_pkt.data[c++] = pin_len; memcpy(c_pkt.data + c, pin, 16); c += 16; c_pkt.len = c; tmp = send_cmd_block((u8*) &c_pkt , c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT); if (tmp < 0) { return tmp; } else { return result_param; }}s32hci_pin_code_request_negative_reply(u8 *bd){ s32 tmp; print_data(__FUNCTION__ ": BD_addr", bd, 6); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(PIN_CODE_REQUEST_NEGATIVE_REPLY, HCI_LC); memcpy(c_pkt.data, bd, 6); c_pkt.len = 6; tmp = send_cmd_block((u8*) &c_pkt , c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT); if (tmp < 0) { return tmp; } else { return result_param; }}/* The Change_Connection_Packet_Type function is used to change which packet types can be used for a connection that is currently established. See page 564 in the BT specification core v1.0B for more info about the packet types.*/s32change_connection_packet_type(u32 hci_hdl, u32 pkt_type){ D_CMD(__FUNCTION__ ": for connnection handle 0x%x\n", hci_hdl); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(CHANGE_CONNECTION_PACKET_TYPE, HCI_LC); c_pkt.data[0] = hci_hdl & 0xff; c_pkt.data[1] = (hci_hdl >> 8) & 0xff; c_pkt.data[2] = pkt_type & 0xff; c_pkt.data[3] = (pkt_type >> 8) & 0xff; c_pkt.len = 4; return send_cmd((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN);}/* * The Authentication_Requested command is used to try to authenticate the * remote device associated with the specified Connection Handle. The Host * must not issue the Authentication_Requested command with a * Connection_Handle corresponding to an encrypted link. On an authentication * failure, the Host Controller or Link Manager shall not automatically detach * the link. The Host is responsible for issuing a Disconnect command to * terminate the link if the action is appropriate. *//* * The response to AUTHENTICATION_REQUESTED can be: * 1) Authentication Complete or * 2) Link Key Request */s32hci_authentication_requested_bd(BD_ADDR bd){ s32 tmp; tmp = get_con_hdl(bd); if (tmp < 0) { D_ERR(__FUNCTION__ ": No connection handle found for bd 0x%02x:%02x:%02x:%02x:%02x:%02x:\n", bd[5], bd[4], bd[3], bd[2], bd[1], bd[0]); return -1; } else { return hci_authentication_requested((u16)tmp); }}s32hci_authentication_requested(u16 con_hdl){ D_CMD(__FUNCTION__ ": At connection handle %d\n", con_hdl); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(AUTHENTICATION_REQUESTED, HCI_LC); c_pkt.data[0] = con_hdl & 0xff; c_pkt.data[1] = (con_hdl >> 8) & 0xff; c_pkt.len = 2; return send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT);}/* * The Set_Connection_Encryption command is used to enable and disable the * link level encryption. Note: the Connection_Handle command parameter is * used to identify the other Bluetooth device which forms the connection. The * Connection Handle should be a Connection Handle for an ACL connection. * While the encryption is being changed, all ACL traffic must be turned off * for all Connection Handles associated with the remote device. */s32hci_set_connection_encryption_bd(BD_ADDR bd, u8 enable){ s32 tmp; tmp = get_con_hdl(bd); if (tmp < 0) { D_ERR(__FUNCTION__ ": No connection handle found for bd 0x%02x:%02x:%02x:%02x:%02x:%02x:\n", bd[5], bd[4], bd[3], bd[2], bd[1], bd[0]); return -1; } else { return hci_set_connection_encryption((u16)tmp, enable); } }s32hci_set_connection_encryption(u16 con_hdl, u8 enable){ D_CMD(__FUNCTION__ ": enable:%d at connection handle %d\n", enable, con_hdl); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(SET_CONNECTION_ENCRYPTION, HCI_LC); c_pkt.data[0] = con_hdl & 0xff; c_pkt.data[1] = (con_hdl >> 8) & 0xff; c_pkt.data[2] = enable; c_pkt.len = 3; return send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT);}/* fixme -- fix return code so we know whether role change was succesful or not */s32hci_switch_role(u8 *bd, u8 role){ DSYS(__FUNCTION__ ": role %d\n", role); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(SWITCH_ROLE, HCI_LP); memcpy(c_pkt.data, bd, 6); c_pkt.data[6] = role; c_pkt.len = 7; return send_cmd((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN);}s32role_discovery(u16 con_hdl){ D_CMD(__FUNCTION__ "\n"); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(ROLE_DISCOVERY, HCI_LP); c_pkt.data[0] = con_hdl & 0xff; c_pkt.data[1] = (con_hdl >> 8) & 0xff; c_pkt.len = 2; return send_cmd((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN);}s32write_link_policy_settings(u16 con_hdl, u16 settings){ D_CMD(__FUNCTION__ "\n"); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(WRITE_LINK_POLICY_SETTINGS, HCI_LP); c_pkt.data[0] = con_hdl & 0xff; c_pkt.data[1] = (con_hdl >> 8) & 0xff; c_pkt.data[2] = settings & 0xff; c_pkt.data[3] = (settings >> 8) & 0xff; c_pkt.len = 4; return send_cmd((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN); }s32remote_name_request(u8 *bd){ s32 c = 0; s32 zero = 0; D_CMD(__FUNCTION__ ": for bd address 0x%02x:%02x:%02x:%02x:%02x:%02x\n" , bd[5], bd[4], bd[3], bd[2], bd[1], bd[0]); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(REMOTE_NAME_REQUEST, HCI_LC); memcpy(c_pkt.data, bd, 6); c += 6; memcpy(c_pkt.data + c, &zero, 4); c += 4; c_pkt.len = c; return send_cmd((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN);}/* Definitions of the Link Policy Commands functions *//* Definitions of the Host Controller & Basband Command functions */voidhci_flush_all(){ s32 i; for (i = 0; i < MAX_NBR_OF_CONNECTIONS; i++) { if (hci_ctrl.con[i].state != NOT_CONNECTED) { printk(__FUNCTION__ ": Flushing handle:%d\n",hci_ctrl.con[i].con_hdl); hci_flush(hci_ctrl.con[i].con_hdl); } } }s32 hci_flush(u32 hdl){ D_CMD(__FUNCTION__ "\n"); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(FLUSH, HCI_HC); c_pkt.data[0] = (hdl & 0xff); c_pkt.data[1] = ((hdl >> 8) & 0xff); c_pkt.len = 2; return send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT);}s32hci_create_new_unit_link_key(void){ s32 tmp; D_CMD(__FUNCTION__ "\n"); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(CREATE_NEW_UNIT_KEY, HCI_HC); c_pkt.len = 0; tmp = send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT); if (tmp < 0) { return tmp; } else { return result_param; } }s32hci_read_stored_link_key(u8 *bd, u8 flag){ s32 tmp; D_CMD(__FUNCTION__ "\n"); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(READ_STORED_LINK_KEY, HCI_HC); memcpy(c_pkt.data, bd , 6); c_pkt.data[6] = flag; c_pkt.len = 7; tmp = send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT); if (tmp < 0) { return tmp; } else { return result_param; } }s32hci_write_stored_link_key(u8 *bd, u8* link_key){ s32 tmp; D_CMD(__FUNCTION__ "\n"); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(WRITE_STORED_LINK_KEY, HCI_HC); /* For now we only stor one key att time with this command */ c_pkt.data[0] = 1; memcpy(c_pkt.data + 1, bd , 6); memcpy(c_pkt.data + 7, link_key, 16); c_pkt.len = 23; tmp = send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT); if (tmp < 0) { return tmp; } else { return result_param; }}s32hci_delete_stored_link_key(u8 *bd, u8 flag){ s32 tmp; D_CMD(__FUNCTION__ "\n"); c_pkt.type = CMD_PKT; c_pkt.opcode = hci_put_opcode(DELETE_STORED_LINK_KEY, HCI_HC); memcpy(c_pkt.data, bd , 6); c_pkt.data[6] = flag; c_pkt.len = 7; tmp = send_cmd_block((u8*) &c_pkt, c_pkt.len + CMD_HDR_LEN + HCI_HDR_LEN, DEFAULT_TIMEOUT); if (tmp <
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -