/******************************************************************************* ** ** Function btif_dm_start_discovery ** ** Description Start device discovery/inquiry ** ** Returns bt_status_t ** *******************************************************************************/ bt_status_t btif_dm_start_discovery(void) { btbm_discovery_type type; unsigned int ret = 0; BT_CUST_ID id = 0; unsigned int value = 0; /* #ifdef __BT_4_0_BLE__ type = BTBM_DISCOVERY_DUAL; #else type = BTBM_DISCOVERY_BR_EDR_ONLY; #endif */ id = getCustID("LESupport"); ret = getCustValue(id, &value); type = value ? BTBM_DISCOVERY_DUAL : BTBM_DISCOVERY_BR_EDR_ONLY; ALOGI("+++[btif_dm_start_discovery] type:[%d]+++!\n", type); if (!btif_is_enabled()) return BT_STATUS_NOT_READY; if(!btmtk_gap_start_discovery(type)) { ALOGE("[btmtk_gap_start_discovery] failed!\n"); return BT_STATUS_FAIL; } ALOGI("---[btif_dm_start_discovery]---!\n"); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function btif_shutdown_bluetooth ** ** Description destroy BTIF task and prepares BT scheduler for startup ** ** Returns bt_status_t ** *******************************************************************************/ bt_status_t btif_shutdown_bluetooth(void) { ALOGI("+++[btif_shutdown_bluetooth]+++!\n"); if (btif_is_enabled()) { ALOGI("[btif_shutdown_bluetooth]:disable bt before shutdown!\n"); /* shutdown called prior to disabling, initiate disable */ btif_disable_bluetooth(); //bt_hal_cbacks = NULL; btif_shutdown_pending = 1; btmtk_gap_cleanup(0); goto exit; } ALOGI("[btif_shutdown_bluetooth]:btmtk_gap_cleanup entry!\n"); if(btif_shutdown_pending == 0) { btmtk_gap_cleanup(1); } else { btif_shutdown_pending = 0; btmtk_gap_exit(); } exit: btif_dut_mode = 0; ALOGI("---[GAP] btif_shutdown_bluetooth---!\n"); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function btif_disable_bluetooth ** ** Description Inititates shutdown of Bluetooth system. ** Any active links will be dropped and device entering ** non connectable/discoverable mode ** ** Returns void ** *******************************************************************************/ bt_status_t btif_disable_bluetooth(void) { tBTA_STATUS status; if (!btif_is_enabled()) { BTIF_TRACE_ERROR0("btif_disable_bluetooth : not yet enabled"); return BT_STATUS_NOT_READY; } bte_main_disable(); GKI_destroy_task(BTIF_TASK); bte_main_shutdown(); BTIF_TRACE_DEBUG0("BTIF DISABLE BLUETOOTH"); btif_core_state = BTIF_CORE_STATE_DISABLED; HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF); return BT_STATUS_SUCCESS; }
bt_status_t btif_shutdown_bluetooth(void) { BTIF_TRACE_DEBUG1("%s", __FUNCTION__); if (btif_is_enabled()) { BTIF_TRACE_WARNING0("shutdown while still enabled, initiate disable"); /* shutdown called prior to disabling, initiate disable */ btif_disable_bluetooth(); btif_shutdown_pending = 1; return BT_STATUS_NOT_READY; } btif_shutdown_pending = 0; GKI_destroy_task(BTIF_TASK); bte_main_shutdown(); btif_dut_mode = 0; BTIF_TRACE_DEBUG1("%s done", __FUNCTION__); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function btif_get_remote_service_record ** ** Description Looks up the service matching uuid on the remote device ** and fetches the SCN and service_name if the UUID is found ** ** Returns bt_status_t ** *******************************************************************************/ bt_status_t btif_get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid) { char *addr = (char *)remote_addr->address; bt_addr_struct bdaddr; ALOGI("+++[btif_get_remote_service_record] addr:[%02x:%02x:%02x:%02x:%02x:%02x], UUID:[%p]+++!\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], uuid->uu); if (!btif_is_enabled()) return BT_STATUS_NOT_READY; ALOGI("---[btif_get_remote_service_record]---!\n"); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function btif_get_adapter_properties ** ** Description Fetch all available properties (local & remote) ** ** Returns bt_status_t ** *******************************************************************************/ bt_status_t btif_get_adapter_properties(void) { ALOGI("+++[btif_get_adapter_properties]+++!\n"); if (!btif_is_enabled()) return BT_STATUS_NOT_READY; if (!btmtk_gap_get_adapter_properties()) { ALOGE("[btmtk_gap_get_adapter_properties] failed!\n"); return BT_STATUS_FAIL; } ALOGI("---[btif_get_adapter_properties]---!\n"); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function btif_disable_service ** ** Description Disables the service 'service_ID' to the service_mask. ** Upon BT disable, BTIF core shall invoke the BTA APIs to ** disable the profiles ** ** Returns bt_status_t ** *******************************************************************************/ bt_status_t btif_disable_service(uint8_t service_id) { ALOGI("+++[btif_disable_service]+++!\n"); /* If BT is enabled, we need to switch to BTIF context and trigger the * disable for that profile so that the appropriate uuid_property_changed will * be triggerred. Otherwise, we just need to clear the service_id in the mask */ btif_enabled_services &= (uint32_t)(~(1<<service_id)); if (btif_is_enabled()) { btmtk_disable_service(service_id); } ALOGI("---[btif_disable_service]---!\n"); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function btif_set_adapter_property ** ** Description Updates core stack with property value and stores it in ** local cache ** ** Returns bt_status_t ** *******************************************************************************/ bt_status_t btif_set_adapter_property(const bt_property_t *property) { ALOGI("+++[btif_set_adapter_property] type:[%d], len:[%d], val:[%p]+++!\n", property->type, property->len, property->val); if (!btif_is_enabled()) return BT_STATUS_NOT_READY; if(!btmtk_gap_set_adapter_property(property)) { ALOGE("[btmtk_gap_set_adapter_property] failed!\n"); return BT_STATUS_FAIL; } ALOGI("---[btif_set_adapter_property]---!\n"); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function btif_dm_cancel_discovery ** ** Description Cancels search ** ** Returns bt_status_t ** *******************************************************************************/ bt_status_t btif_dm_cancel_discovery(void) { btbm_discovery_type type; ALOGI("+++[btif_dm_cancel_discovery]+++!\n"); if (!btif_is_enabled()) return BT_STATUS_NOT_READY; if(!btmtk_gap_cancel_discovery()) { ALOGE("[btmtk_gap_cancel_discovery] failed!\n"); return BT_STATUS_FAIL; } ALOGI("---[btif_dm_cancel_discovery]---!\n"); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function btif_get_adapter_property ** ** Description Fetches property value from local cache ** ** Returns bt_status_t ** *******************************************************************************/ bt_status_t btif_get_adapter_property(bt_property_type_t type) { ALOGI("+++[btif_get_adapter_property] type:[%d]+++!\n", type); /* Allow get_adapter_property only for BDADDR and BDNAME if BT is disabled */ if (!btif_is_enabled() && (type != BT_PROPERTY_BDADDR) && (type != BT_PROPERTY_BDNAME)) return BT_STATUS_NOT_READY; if (!btmtk_gap_get_adapter_property(type)) { ALOGE("[btmtk_gap_get_adapter_property] failed!\n"); return BT_STATUS_FAIL; } ALOGI("---[btif_get_adapter_property]---!\n"); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function btif_enable_service ** ** Description Enables the service 'service_ID' to the service_mask. ** Upon BT enable, BTIF core shall invoke the BTA APIs to ** enable the profiles ** ** Returns bt_status_t ** *******************************************************************************/ bt_status_t btif_enable_service(uint8_t service_id) { ALOGI("+++[btif_enable_service]+++!\n"); /* If BT is enabled, we need to switch to BTIF context and trigger the * enable for that profile * * Otherwise, we just set the flag. On BT_Enable, the DM will trigger * enable for the profiles that have been enabled */ btif_enabled_services |= (1 << service_id); if (btif_is_enabled()) { btmtk_enable_service(service_id); } ALOGI("---[btif_enable_service]---!\n"); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function btif_dm_remove_bond ** ** Description Removes bonding with the specified device ** ** Returns bt_status_t ** *******************************************************************************/ bt_status_t btif_dm_remove_bond(const bt_bdaddr_t *remote_addr) { char *addr = (char *)remote_addr->address; bt_addr_struct bdaddr; ALOGI("+++[btif_dm_remove_bond] addr:[%02x:%02x:%02x:%02x:%02x:%02x]+++!\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); if (!btif_is_enabled()) return BT_STATUS_NOT_READY; btmtk_util_convert_array2bdaddr(&bdaddr, (bt_bdaddr_t *)remote_addr); if(!btmtk_gap_remove_bond(&bdaddr)) { ALOGE("[btmtk_gap_cancel_bond] failed!\n"); return BT_STATUS_FAIL; } ALOGI("---[btif_dm_remove_bond]---!\n"); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function btif_get_remote_device_property ** ** Description Fetches the remote device property from the NVRAM ** ** Returns bt_status_t ** *******************************************************************************/ bt_status_t btif_get_remote_device_property(bt_bdaddr_t *remote_addr, bt_property_type_t type) { char *addr = (char *)remote_addr->address; bt_addr_struct bdaddr; ALOGI("+++[btif_get_remote_device_property] addr:[%02x:%02x:%02x:%02x:%02x:%02x]+++!\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); if (!btif_is_enabled()) return BT_STATUS_NOT_READY; btmtk_util_convert_array2bdaddr(&bdaddr, remote_addr); if(!btmtk_gap_get_remote_device_property(&bdaddr, type)) { ALOGE("[btmtk_gap_get_remote_device_property] failed!\n"); return BT_STATUS_FAIL; } ALOGI("---[btif_get_remote_device_property]---!\n"); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function btif_dm_pin_reply ** ** Description BT legacy pairing - PIN code reply ** ** Returns bt_status_t ** *******************************************************************************/ bt_status_t btif_dm_pin_reply( const bt_bdaddr_t *remote_addr, uint8_t accept, uint8_t pin_len, bt_pin_code_t *pin_code) { char *addr = (char *)remote_addr->address; bt_addr_struct bdaddr; ALOGI("+++[btif_dm_pin_reply] addr:[%02x:%02x:%02x:%02x:%02x:%02x]+++!\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); if (!btif_is_enabled()) return BT_STATUS_NOT_READY; btmtk_util_convert_array2bdaddr(&bdaddr, (bt_bdaddr_t *)remote_addr); if(!btmtk_gap_pin_reply(&bdaddr, accept, pin_len, pin_code->pin)) { ALOGE("[btmtk_gap_pin_reply] failed!\n"); return BT_STATUS_FAIL; } ALOGI("---[btif_dm_pin_reply]---!\n"); return BT_STATUS_SUCCESS; }
BOOLEAN btif_av_stream_ready(void) { btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle); BTIF_TRACE_DEBUG3("btif_av_stream_ready : sm hdl %d, state %d, flags %x", btif_av_cb.sm_handle, state, btif_av_cb.flags); /* also make sure main adapter is enabled */ if (btif_is_enabled() == 0) { BTIF_TRACE_EVENT0("main adapter not enabled"); return FALSE; } /* check if we are remotely suspended */ if (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) return FALSE; return (state == BTIF_AV_STATE_OPENED); }
/******************************************************************************* ** ** Function btif_disable_bluetooth ** ** Description Inititates shutdown of Bluetooth system. ** Any active links will be dropped and device entering ** non connectable/discoverable mode ** ** Returns void ** *******************************************************************************/ bt_status_t btif_disable_bluetooth(void) { ALOGI("+++[btif_disable_bluetooth]+++!\n"); if (!btif_is_enabled()) { ALOGE("btif_disable_bluetooth : not yet enabled"); return BT_STATUS_NOT_READY; } btif_core_state = BTIF_CORE_STATE_DISABLING; /* cleanup rfcomm & l2cap api */ btif_sock_cleanup(); if (!btmtk_gap_disable()) { ALOGE("[btmtk_gap_power_off] failed!\n"); btif_core_state = BTIF_CORE_STATE_ENABLED; return BT_STATUS_FAIL; } ALOGI("---[btif_disable_bluetooth]---!\n"); return BT_STATUS_SUCCESS; }
static void btu_exec_tap_fd_read(void *p_param) { struct pollfd ufd; int fd = (int)p_param; if (fd == -1 || fd != btpan_cb.tap_fd) return; // Don't occupy BTU context too long, avoid GKI buffer overruns and // give other profiles a chance to run by limiting the amount of memory // PAN can use from the shared pool buffer. for(int i = 0; i < PAN_POOL_MAX && btif_is_enabled() && btpan_cb.flow; i++) { BT_HDR *buffer = (BT_HDR *)GKI_getpoolbuf(PAN_POOL_ID); if (!buffer) { BTIF_TRACE_WARNING("%s unable to allocate buffer for packet.", __func__); break; } buffer->offset = PAN_MINIMUM_OFFSET; buffer->len = GKI_get_buf_size(buffer) - sizeof(BT_HDR) - buffer->offset; UINT8 *packet = (UINT8 *)buffer + sizeof(BT_HDR) + buffer->offset; // If we don't have an undelivered packet left over, pull one from the TAP driver. // We save it in the congest_packet right away in case we can't deliver it in this // attempt. if (!btpan_cb.congest_packet_size) { ssize_t ret = read(fd, btpan_cb.congest_packet, sizeof(btpan_cb.congest_packet)); switch (ret) { case -1: BTIF_TRACE_ERROR("%s unable to read from driver: %s", __func__, strerror(errno)); GKI_freebuf(buffer); return; case 0: BTIF_TRACE_WARNING("%s end of file reached.", __func__); GKI_freebuf(buffer); return; default: btpan_cb.congest_packet_size = ret; break; } } memcpy(packet, btpan_cb.congest_packet, MIN(btpan_cb.congest_packet_size, buffer->len)); buffer->len = MIN(btpan_cb.congest_packet_size, buffer->len); if (buffer->len > sizeof(tETH_HDR) && should_forward((tETH_HDR *)packet)) { // Extract the ethernet header from the buffer since the PAN_WriteBuf inside // forward_bnep can't handle two pointers that point inside the same GKI buffer. tETH_HDR hdr; memcpy(&hdr, packet, sizeof(tETH_HDR)); // Skip the ethernet header. buffer->len -= sizeof(tETH_HDR); buffer->offset += sizeof(tETH_HDR); if (forward_bnep(&hdr, buffer) != FORWARD_CONGEST) btpan_cb.congest_packet_size = 0; } else { BTIF_TRACE_WARNING("%s dropping packet of length %d", __func__, buffer->len); btpan_cb.congest_packet_size = 0; GKI_freebuf(buffer); } // Bail out of the loop if reading from the TAP fd would block. ufd.fd = fd; ufd.events = POLLIN; ufd.revents = 0; if(poll(&ufd, 1, 0) <= 0 || IS_EXCEPTION(ufd.revents)) { btsock_thread_add_fd(pan_pth, fd, 0, SOCK_THREAD_FD_RD, 0); return; } } }