static void cmd_le_set_adv_enable(struct bt_le *hci, const void *data, uint8_t size) { const struct bt_hci_cmd_le_set_adv_enable *cmd = data; uint8_t status; /* Valid range for advertising enable is 0x00 to 0x01 */ if (cmd->enable > 0x01) { cmd_status(hci, BT_HCI_ERR_INVALID_PARAMETERS, BT_HCI_CMD_LE_SET_ADV_ENABLE); return; } if (cmd->enable == hci->le_adv_enable) { cmd_status(hci, BT_HCI_ERR_COMMAND_DISALLOWED, BT_HCI_CMD_LE_SET_ADV_ENABLE); return; } hci->le_adv_enable = cmd->enable; status = BT_HCI_ERR_SUCCESS; cmd_complete(hci, BT_HCI_CMD_LE_SET_ADV_ENABLE, &status, sizeof(status)); }
static void cmd_le_create_conn_cancel(struct bt_le *hci, const void *data, uint8_t size) { struct bt_hci_evt_le_conn_complete evt; uint8_t status; if (hci->le_conn_enable == 0x00) { cmd_status(hci, BT_HCI_ERR_COMMAND_DISALLOWED, BT_HCI_CMD_LE_CREATE_CONN_CANCEL); return; } hci->le_conn_enable = 0x00; status = BT_HCI_ERR_SUCCESS; cmd_complete(hci, BT_HCI_CMD_LE_CREATE_CONN_CANCEL, &status, sizeof(status)); evt.status = BT_HCI_ERR_UNKNOWN_CONN_ID; evt.handle = cpu_to_le16(0x0000); evt.role = 0x00; evt.peer_addr_type = 0x00; memset(evt.peer_addr, 0, 6); evt.interval = cpu_to_le16(0x0000); evt.latency = cpu_to_le16(0x0000); evt.supv_timeout = cpu_to_le16(0x0000); evt.clock_accuracy = 0x00; if (hci->le_event_mask[0] & 0x01) le_meta_event(hci, BT_HCI_EVT_LE_CONN_COMPLETE, &evt, sizeof(evt)); }
static void cmd_read_local_amp_assoc(struct bt_amp *amp, const void *data, uint8_t size) { const struct bt_hci_cmd_read_local_amp_assoc *cmd = data; struct bt_hci_rsp_read_local_amp_assoc rsp; uint16_t len_so_far, remain_assoc_len, fragment_len; if (cmd->phy_handle != amp->phy_handle) { cmd_status(amp, BT_HCI_ERR_INVALID_PARAMETERS, BT_HCI_CMD_READ_LOCAL_AMP_ASSOC); return; } len_so_far = le16_to_cpu(cmd->len_so_far); remain_assoc_len = amp->local_assoc_len - len_so_far; fragment_len = remain_assoc_len > 248 ? 248 : remain_assoc_len; rsp.status = BT_HCI_ERR_SUCCESS; rsp.phy_handle = cmd->phy_handle; rsp.remain_assoc_len = cpu_to_le16(remain_assoc_len); memcpy(rsp.assoc_fragment, amp->local_assoc + len_so_far, fragment_len); cmd_complete(amp, BT_HCI_CMD_READ_LOCAL_AMP_ASSOC, &rsp, 4 + fragment_len); }
static void cmd_le_set_scan_enable(struct bt_le *hci, const void *data, uint8_t size) { const struct bt_hci_cmd_le_set_scan_enable *cmd = data; uint8_t status; /* Valid range for scan enable is 0x00 to 0x01 */ if (cmd->enable > 0x01) { cmd_status(hci, BT_HCI_ERR_INVALID_PARAMETERS, BT_HCI_CMD_LE_SET_SCAN_ENABLE); return; } /* Valid range for filter duplicates is 0x00 to 0x01 */ if (cmd->filter_dup > 0x01) { cmd_status(hci, BT_HCI_ERR_INVALID_PARAMETERS, BT_HCI_CMD_LE_SET_SCAN_ENABLE); return; } if (cmd->enable == hci->le_scan_enable) { cmd_status(hci, BT_HCI_ERR_COMMAND_DISALLOWED, BT_HCI_CMD_LE_SET_SCAN_ENABLE); return; } clear_scan_cache(hci); hci->le_scan_enable = cmd->enable; hci->le_scan_filter_dup = cmd->filter_dup; status = BT_HCI_ERR_SUCCESS; cmd_complete(hci, BT_HCI_CMD_LE_SET_SCAN_ENABLE, &status, sizeof(status)); }
static void cmd_logic_link_cancel(struct bt_amp *amp, const void *data, uint8_t size) { const struct bt_hci_cmd_logic_link_cancel *cmd = data; struct bt_hci_rsp_logic_link_cancel rsp; if (cmd->phy_handle == 0x00) { cmd_status(amp, BT_HCI_ERR_INVALID_PARAMETERS, BT_HCI_CMD_LOGIC_LINK_CANCEL); return; } if (amp->phy_mode != PHY_MODE_IDLE) { cmd_status(amp, BT_HCI_ERR_COMMAND_DISALLOWED, BT_HCI_CMD_LOGIC_LINK_CANCEL); return; } amp->logic_handle = 0x0000; rsp.status = BT_HCI_ERR_SUCCESS; rsp.phy_handle = amp->phy_handle; rsp.flow_spec = 0x00; cmd_complete(amp, BT_HCI_CMD_LOGIC_LINK_CANCEL, &rsp, sizeof(rsp)); }
static void cmd_read_bd_addr(struct bt_le *hci, const void *data, uint8_t size) { struct bt_hci_rsp_read_bd_addr rsp; rsp.status = BT_HCI_ERR_SUCCESS; memcpy(rsp.bdaddr, hci->bdaddr, 6); cmd_complete(hci, BT_HCI_CMD_READ_BD_ADDR, &rsp, sizeof(rsp)); }
static void cmd_reset(struct bt_le *hci, const void *data, uint8_t size) { uint8_t status; reset_defaults(hci); status = BT_HCI_ERR_SUCCESS; cmd_complete(hci, BT_HCI_CMD_RESET, &status, sizeof(status)); }
void CLIState::insert_completion() { const auto suggestion = cmd_complete(m_line.c_str()); if (!suggestion) return; m_line = suggestion; m_line += " "; m_line_position = m_line.size(); }
void serverlist_init() { master_t *master; for (master = masters; master->address; master++) { sock_init(&master->sock); sock_connect(&master->sock, master->address, PORT_MASTER); } cmd_add_global("list", serverlist_query); int c = cmd_add_global("c", serverlist_connect); cmd_complete(c, serverlist_connect_complete); }
static void cmd_read_local_commands(struct bt_le *hci, const void *data, uint8_t size) { struct bt_hci_rsp_read_local_commands rsp; rsp.status = BT_HCI_ERR_SUCCESS; memcpy(rsp.commands, hci->commands, 64); cmd_complete(hci, BT_HCI_CMD_READ_LOCAL_COMMANDS, &rsp, sizeof(rsp)); }
static void cmd_le_read_adv_tx_power(struct bt_le *hci, const void *data, uint8_t size) { struct bt_hci_rsp_le_read_adv_tx_power rsp; rsp.status = BT_HCI_ERR_SUCCESS; rsp.level = hci->le_adv_tx_power; cmd_complete(hci, BT_HCI_CMD_LE_READ_ADV_TX_POWER, &rsp, sizeof(rsp)); }
static void cmd_read_local_features(struct bt_le *hci, const void *data, uint8_t size) { struct bt_hci_rsp_read_local_features rsp; rsp.status = BT_HCI_ERR_SUCCESS; memcpy(rsp.features, hci->features, 8); cmd_complete(hci, BT_HCI_CMD_READ_LOCAL_FEATURES, &rsp, sizeof(rsp)); }
static void cmd_read_flow_control_mode(struct bt_amp *amp, const void *data, uint8_t size) { struct bt_hci_rsp_read_flow_control_mode rsp; rsp.status = BT_HCI_ERR_SUCCESS; rsp.mode = 0x01; cmd_complete(amp, BT_HCI_CMD_READ_FLOW_CONTROL_MODE, &rsp, sizeof(rsp)); }
static void cmd_le_read_supported_states(struct bt_le *hci, const void *data, uint8_t size) { struct bt_hci_rsp_le_read_supported_states rsp; rsp.status = BT_HCI_ERR_SUCCESS; memcpy(rsp.states, hci->le_states, 8); cmd_complete(hci, BT_HCI_CMD_LE_READ_SUPPORTED_STATES, &rsp, sizeof(rsp)); }
static void cmd_set_event_mask(struct bt_le *hci, const void *data, uint8_t size) { const struct bt_hci_cmd_set_event_mask *cmd = data; uint8_t status; memcpy(hci->event_mask, cmd->mask, 8); status = BT_HCI_ERR_SUCCESS; cmd_complete(hci, BT_HCI_CMD_SET_EVENT_MASK, &status, sizeof(status)); }
static void cmd_le_read_buffer_size(struct bt_le *hci, const void *data, uint8_t size) { struct bt_hci_rsp_le_read_buffer_size rsp; rsp.status = BT_HCI_ERR_SUCCESS; rsp.le_mtu = cpu_to_le16(hci->le_mtu); rsp.le_max_pkt = hci->le_max_pkt; cmd_complete(hci, BT_HCI_CMD_LE_READ_BUFFER_SIZE, &rsp, sizeof(rsp)); }
static void cmd_le_clear_resolv_list(struct bt_le *hci, const void *data, uint8_t size) { uint8_t status; clear_resolv_list(hci); status = BT_HCI_ERR_SUCCESS; cmd_complete(hci, BT_HCI_CMD_LE_CLEAR_RESOLV_LIST, &status, sizeof(status)); }
static void cmd_le_read_resolv_list_size(struct bt_le *hci, const void *data, uint8_t size) { struct bt_hci_rsp_le_read_resolv_list_size rsp; rsp.status = BT_HCI_ERR_SUCCESS; rsp.size = hci->le_resolv_list_size; cmd_complete(hci, BT_HCI_CMD_LE_READ_RESOLV_LIST_SIZE, &rsp, sizeof(rsp)); }
static void cmd_set_event_mask_page2(struct bt_amp *amp, const void *data, uint8_t size) { const struct bt_hci_cmd_set_event_mask_page2 *cmd = data; uint8_t status; memcpy(amp->event_mask + 8, cmd->mask, 8); status = BT_HCI_ERR_SUCCESS; cmd_complete(amp, BT_HCI_CMD_SET_EVENT_MASK_PAGE2, &status, sizeof(status)); }
static void cmd_read_data_block_size(struct bt_amp *amp, const void *data, uint8_t size) { struct bt_hci_rsp_read_data_block_size rsp; rsp.status = BT_HCI_ERR_SUCCESS; rsp.max_acl_len = cpu_to_le16(1492); rsp.block_len = cpu_to_le16(1492); rsp.num_blocks = cpu_to_le16(1); cmd_complete(amp, BT_HCI_CMD_READ_DATA_BLOCK_SIZE, &rsp, sizeof(rsp)); }
static void cmd_le_read_default_data_length(struct bt_le *hci, const void *data, uint8_t size) { struct bt_hci_rsp_le_read_default_data_length rsp; rsp.status = BT_HCI_ERR_SUCCESS; rsp.tx_len = cpu_to_le16(hci->le_default_tx_len); rsp.tx_time = cpu_to_le16(hci->le_default_tx_time); cmd_complete(hci, BT_HCI_CMD_LE_READ_DEFAULT_DATA_LENGTH, &rsp, sizeof(rsp)); }
static void cmd_le_set_random_address(struct bt_le *hci, const void *data, uint8_t size) { const struct bt_hci_cmd_le_set_random_address *cmd = data; uint8_t status; memcpy(hci->le_random_addr, cmd->addr, 6); status = BT_HCI_ERR_SUCCESS; cmd_complete(hci, BT_HCI_CMD_LE_SET_RANDOM_ADDRESS, &status, sizeof(status)); }
static void cmd_reset(struct bt_amp *amp, const void *data, uint8_t size) { uint8_t status; reset_defaults(amp); amp->local_assoc[0] = 0x00; amp->local_assoc_len = 1; status = BT_HCI_ERR_SUCCESS; cmd_complete(amp, BT_HCI_CMD_RESET, &status, sizeof(status)); }
static void cmd_read_buffer_size(struct bt_le *hci, const void *data, uint8_t size) { struct bt_hci_rsp_read_buffer_size rsp; rsp.status = BT_HCI_ERR_SUCCESS; rsp.acl_mtu = cpu_to_le16(0x0000); rsp.sco_mtu = 0x00; rsp.acl_max_pkt = cpu_to_le16(0x0000); rsp.sco_max_pkt = cpu_to_le16(0x0000); cmd_complete(hci, BT_HCI_CMD_READ_BUFFER_SIZE, &rsp, sizeof(rsp)); }
static void cmd_read_location_data(struct bt_amp *amp, const void *data, uint8_t size) { struct bt_hci_rsp_read_location_data rsp; rsp.status = BT_HCI_ERR_SUCCESS; rsp.domain_aware = 0x00; rsp.domain[0] = 0x58; rsp.domain[1] = 0x58; rsp.domain_options = 0x58; rsp.options = 0x00; cmd_complete(amp, BT_HCI_CMD_READ_LOCATION_DATA, &rsp, sizeof(rsp)); }
static void cmd_le_rand(struct bt_le *hci, const void *data, uint8_t size) { struct bt_hci_rsp_le_rand rsp; if (!bt_crypto_random_bytes(hci->crypto, rsp.number, 8)) { cmd_status(hci, BT_HCI_ERR_COMMAND_DISALLOWED, BT_HCI_CMD_LE_RAND); return; } rsp.status = BT_HCI_ERR_SUCCESS; cmd_complete(hci, BT_HCI_CMD_LE_RAND, &rsp, sizeof(rsp)); }
static void cmd_le_read_max_data_length(struct bt_le *hci, const void *data, uint8_t size) { struct bt_hci_rsp_le_read_max_data_length rsp; rsp.status = BT_HCI_ERR_SUCCESS; rsp.max_tx_len = cpu_to_le16(MAX_TX_LEN); rsp.max_tx_time = cpu_to_le16(MAX_TX_TIME); rsp.max_rx_len = cpu_to_le16(MAX_RX_LEN); rsp.max_rx_time = cpu_to_le16(MAX_RX_TIME); cmd_complete(hci, BT_HCI_CMD_LE_READ_MAX_DATA_LENGTH, &rsp, sizeof(rsp)); }
static void cmd_read_local_version(struct bt_le *hci, const void *data, uint8_t size) { struct bt_hci_rsp_read_local_version rsp; rsp.status = BT_HCI_ERR_SUCCESS; rsp.hci_ver = 0x08; rsp.hci_rev = cpu_to_le16(0x0000); rsp.lmp_ver = 0x08; rsp.manufacturer = cpu_to_le16(hci->manufacturer); rsp.lmp_subver = cpu_to_le16(0x0000); cmd_complete(hci, BT_HCI_CMD_READ_LOCAL_VERSION, &rsp, sizeof(rsp)); }
static void cmd_le_encrypt(struct bt_le *hci, const void *data, uint8_t size) { const struct bt_hci_cmd_le_encrypt *cmd = data; struct bt_hci_rsp_le_encrypt rsp; if (!bt_crypto_e(hci->crypto, cmd->key, cmd->plaintext, rsp.data)) { cmd_status(hci, BT_HCI_ERR_COMMAND_DISALLOWED, BT_HCI_CMD_LE_ENCRYPT); return; } rsp.status = BT_HCI_ERR_SUCCESS; cmd_complete(hci, BT_HCI_CMD_LE_ENCRYPT, &rsp, sizeof(rsp)); }
static void cmd_write_flow_control_mode(struct bt_amp *amp, const void *data, uint8_t size) { const struct bt_hci_cmd_write_flow_control_mode *cmd = data; uint8_t status; if (cmd->mode != 0x01) { cmd_status(amp, BT_HCI_ERR_INVALID_PARAMETERS, BT_HCI_CMD_WRITE_FLOW_CONTROL_MODE); return; } status = BT_HCI_ERR_SUCCESS; cmd_complete(amp, BT_HCI_CMD_WRITE_FLOW_CONTROL_MODE, &status, sizeof(status)); }