/******************************************************************************* ** ** Function BTM_SetLocalDeviceName ** ** Description This function is called to set the local device name. ** ** Returns status of the operation ** *******************************************************************************/ tBTM_STATUS BTM_SetLocalDeviceName (char *p_name) { UINT8 *p; if (!p_name || !p_name[0] || (strlen ((char *)p_name) > BD_NAME_LEN)) return (BTM_ILLEGAL_VALUE); if (!controller_get_interface()->get_is_ready()) return (BTM_DEV_RESET); #if BTM_MAX_LOC_BD_NAME_LEN > 0 /* Save the device name if local storage is enabled */ p = (UINT8 *)btm_cb.cfg.bd_name; if (p != (UINT8 *)p_name) { BCM_STRNCPY_S(btm_cb.cfg.bd_name, sizeof(btm_cb.cfg.bd_name), p_name, BTM_MAX_LOC_BD_NAME_LEN); btm_cb.cfg.bd_name[BTM_MAX_LOC_BD_NAME_LEN] = '\0'; } #else p = (UINT8 *)p_name; #endif if (btsnd_hcic_change_name(p)) return (BTM_CMD_STARTED); else return (BTM_NO_RESOURCES); }
/******************************************************************************* ** ** Function l2cble_set_fixed_channel_tx_data_length ** ** Description This function update max fixed channel tx data length if applicable ** ** Returns void ** *******************************************************************************/ void l2cble_set_fixed_channel_tx_data_length(BD_ADDR remote_bda, UINT16 fix_cid, UINT16 tx_mtu) { tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(remote_bda, BT_TRANSPORT_LE); UINT16 cid = fix_cid - L2CAP_FIRST_FIXED_CHNL; L2CAP_TRACE_DEBUG("%s TX MTU = %d", __FUNCTION__, tx_mtu); if (!controller_get_interface()->supports_ble_packet_extension()) { L2CAP_TRACE_WARNING("%s, request not supported", __FUNCTION__); return; } /* See if we have a link control block for the connection */ if (p_lcb == NULL) return; if (p_lcb->p_fixed_ccbs[cid] != NULL) { if (tx_mtu > BTM_BLE_DATA_SIZE_MAX) tx_mtu = BTM_BLE_DATA_SIZE_MAX; p_lcb->p_fixed_ccbs[cid]->tx_data_len = tx_mtu; } l2cble_update_data_length(p_lcb); }
static void reset_complete(void *result) { assert(result == FUTURE_SUCCESS); const controller_t *controller = controller_get_interface(); /* Tell L2CAP that all connections are gone */ l2cu_device_reset (); /* Clear current security state */ for (int devinx = 0; devinx < BTM_SEC_MAX_DEVICE_RECORDS; devinx++) { btm_cb.sec_dev_rec[devinx].sec_state = BTM_SEC_STATE_IDLE; } /* After the reset controller should restore all parameters to defaults. */ btm_cb.btm_inq_vars.inq_counter = 1; btm_cb.btm_inq_vars.inq_scan_window = HCI_DEF_INQUIRYSCAN_WINDOW; btm_cb.btm_inq_vars.inq_scan_period = HCI_DEF_INQUIRYSCAN_INTERVAL; btm_cb.btm_inq_vars.inq_scan_type = HCI_DEF_SCAN_TYPE; btm_cb.btm_inq_vars.page_scan_window = HCI_DEF_PAGESCAN_WINDOW; btm_cb.btm_inq_vars.page_scan_period = HCI_DEF_PAGESCAN_INTERVAL; btm_cb.btm_inq_vars.page_scan_type = HCI_DEF_SCAN_TYPE; #if (BLE_INCLUDED == TRUE) btm_cb.ble_ctr_cb.conn_state = BLE_CONN_IDLE; btm_cb.ble_ctr_cb.bg_conn_type = BTM_BLE_CONN_NONE; btm_cb.ble_ctr_cb.p_select_cback = NULL; gatt_reset_bgdev_list(); btm_ble_multi_adv_init(); #endif btm_pm_reset(); l2c_link_processs_num_bufs(controller->get_acl_buffer_count_classic()); #if (BLE_INCLUDED == TRUE) #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) /* Set up the BLE privacy settings */ if (controller->supports_ble() && controller->supports_ble_privacy() && controller->get_ble_resolving_list_max_size() > 0) { btm_ble_resolving_list_init(controller->get_ble_resolving_list_max_size()); /* set the default random private address timeout */ btsnd_hcic_ble_set_rand_priv_addr_timeout(BTM_BLE_PRIVATE_ADDR_INT); } #endif if (controller->supports_ble()) { btm_ble_white_list_init(controller->get_ble_white_list_size()); l2c_link_processs_ble_num_bufs(controller->get_acl_buffer_count_ble()); } #endif BTM_SetPinType (btm_cb.cfg.pin_type, btm_cb.cfg.pin_code, btm_cb.cfg.pin_code_len); for (int i = 0; i <= controller->get_last_features_classic_index(); i++) { btm_decode_ext_features_page(i, controller->get_features_classic(i)->as_array); } btm_report_device_status(BTM_DEV_STATUS_UP); }
/***************************************************************************** ** ** Function BTU_BleAclPktSize ** ** Description export the BLE ACL packet size. ** ** Returns UINT16 ** ******************************************************************************/ UINT16 BTU_BleAclPktSize(void) { #if BLE_INCLUDED == TRUE return controller_get_interface()->get_acl_packet_size_ble(); #else return 0; #endif }
/******************************************************************************* ** ** Function l2c_bcst_msg ** ** Description ** ** Returns void ** *******************************************************************************/ void l2c_bcst_msg( BT_HDR *p_buf, UINT16 psm ) { UINT8 *p; /* Ensure we have enough space in the buffer for the L2CAP and HCI headers */ if (p_buf->offset < L2CAP_BCST_MIN_OFFSET) { L2CAP_TRACE_ERROR ("L2CAP - cannot send buffer, offset: %d", p_buf->offset); GKI_freebuf (p_buf); return; } /* Step back some bytes to add the headers */ p_buf->offset -= (HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_BCST_OVERHEAD); p_buf->len += L2CAP_PKT_OVERHEAD + L2CAP_BCST_OVERHEAD; /* Set the pointer to the beginning of the data */ p = (UINT8 *)(p_buf + 1) + p_buf->offset; /* First, the HCI transport header */ UINT16_TO_STREAM (p, 0x0050 | (L2CAP_PKT_START << 12) | (2 << 14)); uint16_t acl_data_size = controller_get_interface()->get_acl_data_size_classic(); /* The HCI transport will segment the buffers. */ if (p_buf->len > acl_data_size) { UINT16_TO_STREAM (p, acl_data_size); } else { UINT16_TO_STREAM (p, p_buf->len); } /* Now the L2CAP header */ UINT16_TO_STREAM (p, p_buf->len - L2CAP_PKT_OVERHEAD); UINT16_TO_STREAM (p, L2CAP_CONNECTIONLESS_CID); UINT16_TO_STREAM (p, psm); p_buf->len += HCI_DATA_PREAMBLE_SIZE; if (p_buf->len <= controller_get_interface()->get_acl_packet_size_classic()) { //counter_add("l2cap.ch2.tx.bytes", p_buf->len); //counter_add("l2cap.ch2.tx.pkts", 1); bte_main_hci_send(p_buf, BT_EVT_TO_LM_HCI_ACL); } }
/******************************************************************************* ** ** Function btm_ble_clear_white_list_complete ** ** Description Indicates white list cleared. ** *******************************************************************************/ void btm_ble_clear_white_list_complete(UINT8 *p_data, UINT16 evt_len) { tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; UINT8 status; UNUSED(evt_len); BTM_TRACE_EVENT ("btm_ble_clear_white_list_complete"); STREAM_TO_UINT8 (status, p_data); if (status == HCI_SUCCESS) p_cb->white_list_avail_size = controller_get_interface()->get_ble_white_list_size(); }
/******************************************************************************* ** ** Function BTM_SetDeviceClass ** ** Description This function is called to set the local device class ** ** Returns status of the operation ** *******************************************************************************/ tBTM_STATUS BTM_SetDeviceClass (DEV_CLASS dev_class) { if(!memcmp (btm_cb.devcb.dev_class, dev_class, DEV_CLASS_LEN)) return(BTM_SUCCESS); memcpy (btm_cb.devcb.dev_class, dev_class, DEV_CLASS_LEN); if (!controller_get_interface()->get_is_ready()) return (BTM_DEV_RESET); if (!btsnd_hcic_write_dev_class (dev_class)) return (BTM_NO_RESOURCES); return (BTM_SUCCESS); }
/******************************************************************************* ** ** Function btm_random_pseudo_to_identity_addr ** ** Description This function map a random pseudo address to a public address ** random_pseudo is input and output parameter ** *******************************************************************************/ BOOLEAN btm_random_pseudo_to_identity_addr(BD_ADDR random_pseudo, UINT8 *p_static_addr_type) { #if BLE_PRIVACY_SPT == TRUE tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (random_pseudo); if (p_dev_rec != NULL) { if (p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) { * p_static_addr_type = p_dev_rec->ble.static_addr_type; memcpy(random_pseudo, p_dev_rec->ble.static_addr, BD_ADDR_LEN); if (controller_get_interface()->supports_ble_privacy()) { *p_static_addr_type |= BLE_ADDR_TYPE_ID_BIT; } return TRUE; } } #endif return FALSE; }
/******************************************************************************* ** ** Function btm_ble_refresh_local_resolvable_private_addr ** ** Description This function refresh the currently used resolvable private address for the ** active link to the remote device ** *******************************************************************************/ void btm_ble_refresh_local_resolvable_private_addr(BD_ADDR pseudo_addr, BD_ADDR local_rpa) { #if BLE_PRIVACY_SPT == TRUE tACL_CONN *p = btm_bda_to_acl(pseudo_addr, BT_TRANSPORT_LE); BD_ADDR dummy_bda = {0}; if (p != NULL) { if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) { p->conn_addr_type = BLE_ADDR_RANDOM; if (memcmp(local_rpa, dummy_bda, BD_ADDR_LEN)) { memcpy(p->conn_addr, local_rpa, BD_ADDR_LEN); } else { memcpy(p->conn_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, BD_ADDR_LEN); } } else { p->conn_addr_type = BLE_ADDR_PUBLIC; memcpy(p->conn_addr, &controller_get_interface()->get_address()->address, BD_ADDR_LEN); } } #endif }
/******************************************************************************* ** ** Function btm_identity_addr_to_random_pseudo ** ** Description This function map a static BD address to a pseudo random address ** in security database. ** *******************************************************************************/ BOOLEAN btm_identity_addr_to_random_pseudo(BD_ADDR bd_addr, UINT8 *p_addr_type, BOOLEAN refresh) { #if BLE_PRIVACY_SPT == TRUE tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_identity_addr(bd_addr, *p_addr_type); BTM_TRACE_EVENT ("%s", __func__); /* evt reported on static address, map static address to random pseudo */ if (p_dev_rec != NULL) { /* if RPA offloading is supported, or 4.2 controller, do RPA refresh */ if (refresh && controller_get_interface()->get_ble_resolving_list_max_size() != 0) { btm_ble_read_resolving_list_entry(p_dev_rec); } /* assign the original address to be the current report address */ if (!btm_ble_init_pseudo_addr (p_dev_rec, bd_addr)) { memcpy(bd_addr, p_dev_rec->ble.pseudo_addr, BD_ADDR_LEN); } *p_addr_type = p_dev_rec->ble.ble_addr_type; return TRUE; } #endif return FALSE; }
int btpan_tap_open() { struct ifreq ifr; int fd, err; const char *clonedev = "/dev/tun"; /* open the clone device */ if ((fd = open(clonedev, O_RDWR)) < 0) { BTIF_TRACE_DEBUG("could not open %s, err:%d", clonedev, errno); return fd; } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; strncpy(ifr.ifr_name, TAP_IF_NAME, IFNAMSIZ); /* try to create the device */ if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0) { BTIF_TRACE_DEBUG("ioctl error:%d, errno:%s", err, strerror(errno)); close(fd); return err; } if (tap_if_up(TAP_IF_NAME, controller_get_interface()->get_address()) == 0) { int flags = fcntl(fd, F_GETFL, 0); fcntl(fd, F_SETFL, flags | O_NONBLOCK); return fd; } BTIF_TRACE_ERROR("can not bring up tap interface:%s", TAP_IF_NAME); close(fd); return INVALID_FD; }
/******************************************************************************* ** ** Function l2cble_start_conn_update ** ** Description start BLE connection parameter update process based on status ** ** Parameters: lcb : l2cap link control block ** ** Return value: none ** *******************************************************************************/ static void l2cble_start_conn_update (tL2C_LCB *p_lcb) { UINT16 min_conn_int, max_conn_int, slave_latency, supervision_tout; tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev(p_lcb->remote_bd_addr); tACL_CONN *p_acl_cb = btm_bda_to_acl(p_lcb->remote_bd_addr, BT_TRANSPORT_LE); if (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) return; if (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) { /* application requests to disable parameters update. If parameters are already updated, lets set them up to what has been requested during connection establishement */ if (p_lcb->conn_update_mask & L2C_BLE_NOT_DEFAULT_PARAM && /* current connection interval is greater than default min */ p_lcb->min_interval > BTM_BLE_CONN_INT_MIN) { /* use 7.5 ms as fast connection parameter, 0 slave latency */ min_conn_int = max_conn_int = BTM_BLE_CONN_INT_MIN; slave_latency = BTM_BLE_CONN_SLAVE_LATENCY_DEF; supervision_tout = BTM_BLE_CONN_TIMEOUT_DEF; /* if both side 4.1, or we are master device, send HCI command */ if (p_lcb->link_role == HCI_ROLE_MASTER #if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) || (HCI_LE_CONN_PARAM_REQ_SUPPORTED(controller_get_interface()->get_features_ble()->as_array) && HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features)) #endif ) { btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, min_conn_int, max_conn_int, slave_latency, supervision_tout, 0, 0); p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING; } else { l2cu_send_peer_ble_par_req (p_lcb, min_conn_int, max_conn_int, slave_latency, supervision_tout); } p_lcb->conn_update_mask &= ~L2C_BLE_NOT_DEFAULT_PARAM; p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; } } else { /* application allows to do update, if we were delaying one do it now */ if (p_lcb->conn_update_mask & L2C_BLE_NEW_CONN_PARAM) { /* if both side 4.1, or we are master device, send HCI command */ if (p_lcb->link_role == HCI_ROLE_MASTER #if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE) || (HCI_LE_CONN_PARAM_REQ_SUPPORTED(controller_get_interface()->get_features_ble()->as_array) && HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features)) #endif ) { btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, p_lcb->min_interval, p_lcb->max_interval, p_lcb->latency, p_lcb->timeout, 0, 0); p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING; } else { l2cu_send_peer_ble_par_req (p_lcb, p_lcb->min_interval, p_lcb->max_interval, p_lcb->latency, p_lcb->timeout); } p_lcb->conn_update_mask &= ~L2C_BLE_NEW_CONN_PARAM; p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM; } } }
/******************************************************************************* ** ** Function l2cble_advertiser_conn_comp ** ** Description This function is called when an HCI Connection Complete ** event is received while we are an advertiser (so we are slave). ** ** Returns void ** *******************************************************************************/ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type, UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout) { int i; tL2C_LCB *p_lcb; tBTM_SEC_DEV_REC *p_dev_rec; UNUSED(type); UNUSED(conn_interval); UNUSED(conn_latency); UNUSED(conn_timeout); /* See if we have a link control block for the remote device */ p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE); /* If we don't have one, create one and accept the connection. */ if (!p_lcb) { p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE); if (!p_lcb) { btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION); L2CAP_TRACE_ERROR ("l2cble_advertiser_conn_comp - failed to allocate LCB"); return; } else { if (!l2cu_initialize_fixed_ccb (p_lcb, L2CAP_ATT_CID, &l2cb.fixed_reg[L2CAP_ATT_CID - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts)) { btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION); L2CAP_TRACE_WARNING ("l2cble_scanner_conn_comp - LCB but no CCB"); return ; } } } /* Save the handle */ p_lcb->handle = handle; /* Connected OK. Change state to connected, we were advertising, so we are slave */ p_lcb->link_role = HCI_ROLE_SLAVE; p_lcb->transport = BT_TRANSPORT_LE; /* update link parameter, set slave link as non-spec default upon link up */ p_lcb->min_interval = p_lcb->max_interval = conn_interval; p_lcb->timeout = conn_timeout; p_lcb->latency = conn_latency; p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM; /* Tell BTM Acl management about the link */ p_dev_rec = btm_find_or_alloc_dev (bda); btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE); #if BLE_PRIVACY_SPT == TRUE btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, TRUE); #endif p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT; if (!HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(controller_get_interface()->get_features_ble()->as_array)) { p_lcb->link_state = LST_CONNECTED; l2cu_process_fixed_chnl_resp (p_lcb); } /* when adv and initiating are both active, cancel the direct connection */ if (l2cb.is_ble_connecting && memcmp(bda, l2cb.ble_connecting_bda, BD_ADDR_LEN) == 0) { L2CA_CancelBleConnectReq(bda); } }
// TODO(zachoverflow): get rid of this function UINT8 *BTM_ReadLocalFeatures (void) { // Discarding const modifier for now, until this function dies return (UINT8 *)controller_get_interface()->get_features_classic(0)->as_array; }
/******************************************************************************* ** ** Function BTM_IsDeviceUp ** ** Description This function is called to check if the device is up. ** ** Returns TRUE if device is up, else FALSE ** *******************************************************************************/ BOOLEAN BTM_IsDeviceUp (void) { return controller_get_interface()->get_is_ready(); }
const packet_fragmenter_t *packet_fragmenter_get_interface() { controller = controller_get_interface(); buffer_allocator = buffer_allocator_get_interface(); return &interface; }