static void btif_in_pan_generic_evt(UINT16 event, char *p_param) { BTIF_TRACE_EVENT("%s: event=%d", __FUNCTION__, event); switch (event) { case BTIF_PAN_CB_DISCONNECTING: { bt_bdaddr_t *bd_addr = (bt_bdaddr_t*)p_param; btpan_conn_t* conn = btpan_find_conn_addr(bd_addr->address); int btpan_conn_local_role; int btpan_remote_role; asrt(conn != NULL); if (conn) { btpan_conn_local_role = bta_role_to_btpan(conn->local_role); btpan_remote_role = bta_role_to_btpan(conn->remote_role); callback.connection_state_cb(BTPAN_STATE_DISCONNECTING, BT_STATUS_SUCCESS, (const bt_bdaddr_t*)conn->peer, btpan_conn_local_role, btpan_remote_role); } } break; default: { BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __FUNCTION__, event); } break; } }
/******************************************************************************* ** ** Function bta_fs_co_resume ** ** Description This function is executed by BTA when resuming a session. ** This is used to retrieve the session ID and related information ** ** Parameters evt - event that must be passed into the call-in function. ** app_id - application ID specified in the enable functions. ** It can be used to identify which profile is the caller ** of the call-out function. ** ** Returns void ** ** Note: Upon completion of the request, the related session information, ** if successful, and an error code (tBTA_FS_CO_STATUS) ** are returned in the call-in function, bta_fs_ci_resume(). ** *******************************************************************************/ void bta_fs_co_resume(UINT16 evt, UINT8 app_id) { UNUSED(evt); UNUSED(app_id); BTIF_TRACE_WARNING("[CO] bta_fs_co_resume - NOT implemented"); }
static int tap_if_up(const char *devname, const bt_bdaddr_t *addr) { struct ifreq ifr; int sk, err; sk = socket(AF_INET, SOCK_DGRAM, 0); if (sk < 0) return -1; //set mac addr memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, devname, IFNAMSIZ - 1); err = ioctl(sk, SIOCGIFHWADDR, &ifr); if (err < 0) { BTIF_TRACE_ERROR("Could not get network hardware for interface:%s, errno:%s", devname, strerror(errno)); close(sk); return -1; } strncpy(ifr.ifr_name, devname, IFNAMSIZ - 1); memcpy(ifr.ifr_hwaddr.sa_data, addr->address, 6); /* The IEEE has specified that the most significant bit of the most significant byte is used to * determine a multicast address. If its a 1, that means multicast, 0 means unicast. * Kernel returns an error if we try to set a multicast address for the tun-tap ethernet interface. * Mask this bit to avoid any issue with auto generated address. */ if (ifr.ifr_hwaddr.sa_data[0] & 0x01) { BTIF_TRACE_WARNING("Not a unicast MAC address, force multicast bit flipping"); ifr.ifr_hwaddr.sa_data[0] &= ~0x01; } err = ioctl(sk, SIOCSIFHWADDR, (caddr_t)&ifr); if (err < 0) { BTIF_TRACE_ERROR("Could not set bt address for interface:%s, errno:%s", devname, strerror(errno)); close(sk); return -1; } //bring it up memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, devname, IF_NAMESIZE - 1); ifr.ifr_flags |= IFF_UP; ifr.ifr_flags |= IFF_MULTICAST; err = ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr); if (err < 0) { BTIF_TRACE_ERROR("Could not bring up network interface:%s, errno:%d", devname, errno); close(sk); return -1; } close(sk); BTIF_TRACE_DEBUG("network interface: %s is up", devname); return 0; }
/******************************************************************************* ** ** Function bta_fs_co_sess_ssn ** ** Description This function is executed by BTA when resuming a session. ** This is used to inform call-out module if the ssn/file offset ** needs to be adjusted. ** ** Parameters ssn - the session sequence number of the first request ** after resume. ** app_id - application ID specified in the enable functions. ** It can be used to identify which profile is the caller ** of the call-out function. ** ** Returns void ** *******************************************************************************/ void bta_fs_co_sess_ssn(int fd, UINT8 ssn, UINT8 app_id) { UNUSED(fd); UNUSED(ssn); UNUSED(app_id); BTIF_TRACE_WARNING("[CO] bta_fs_co_suspend - NOT implemented"); }
/******************************************************************************* ** ** Function register_app ** ** Description Registers HID Device application ** ** Returns bt_status_t ** *******************************************************************************/ static bt_status_t register_app(bthd_app_param_t *p_app_param, bthd_qos_param_t *p_in_qos, bthd_qos_param_t *p_out_qos) { tBTA_HD_APP_INFO app_info; tBTA_HD_QOS_INFO in_qos; tBTA_HD_QOS_INFO out_qos; BTIF_TRACE_API("%s", __FUNCTION__); if (btif_hd_cb.app_registered) { BTIF_TRACE_WARNING("%s: application already registered", __FUNCTION__); return BT_STATUS_BUSY; } if (btif_hd_cb.status != BTIF_HD_ENABLED) { BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __FUNCTION__, btif_hd_cb.status); return BT_STATUS_NOT_READY; } app_info.p_name = p_app_param->name; app_info.p_description = p_app_param->description; app_info.p_provider = p_app_param->provider; app_info.subclass = p_app_param->subclass; app_info.descriptor.dl_len = p_app_param->desc_list_len; app_info.descriptor.dsc_list = p_app_param->desc_list; in_qos.service_type = p_in_qos->service_type; in_qos.token_rate = p_in_qos->token_rate; in_qos.token_bucket_size = p_in_qos->token_bucket_size; in_qos.peak_bandwidth = p_in_qos->peak_bandwidth; in_qos.access_latency = p_in_qos->access_latency; in_qos.delay_variation = p_in_qos->delay_variation; out_qos.service_type = p_out_qos->service_type; out_qos.token_rate = p_out_qos->token_rate; out_qos.token_bucket_size = p_out_qos->token_bucket_size; out_qos.peak_bandwidth = p_out_qos->peak_bandwidth; out_qos.access_latency = p_out_qos->access_latency; out_qos.delay_variation = p_out_qos->delay_variation; BTA_HdRegisterApp(&app_info, &in_qos, &out_qos); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function bta_fs_co_set_perms ** ** Description This function is called to set the permission a file/directory ** with name as p_src_path. ** ** Parameters p_src_path - (input) name of file/directory to set permission (fully qualified path). ** p_perms - the permission . ** app_id - (input) application ID specified in the enable functions. ** It can be used to identify which profile is the caller ** of the call-out function. ** ** Returns (tBTA_FS_CO_STATUS) status of the call. ** [BTA_FS_CO_OK if successful] ** [BTA_FS_CO_EACCES if p_dest_path already exists or could not be created (invalid path); ** or p_src_path is a directory and p_dest_path specifies a different path. ] ** [BTA_FS_CO_FAIL otherwise] ** *******************************************************************************/ void bta_fs_co_set_perms(const char *p_src_path, UINT8 *p_perms, UINT16 evt, UINT8 app_id) { UNUSED(p_src_path); UNUSED(p_perms); UNUSED(evt); UNUSED(app_id); BTIF_TRACE_WARNING("[CO] bta_fs_co_set_perms - NOT implemented"); }
/******************************************************************************* ** ** Function virtual_cable_unplug ** ** Description Sends Virtual Cable Unplug to host ** ** Returns bt_status_t ** *******************************************************************************/ static bt_status_t virtual_cable_unplug(void) { BTIF_TRACE_API("%s", __FUNCTION__); if (!btif_hd_cb.app_registered) { BTIF_TRACE_WARNING("%s: application not yet registered", __FUNCTION__); return BT_STATUS_NOT_READY; } if (btif_hd_cb.status != BTIF_HD_ENABLED) { BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __FUNCTION__, btif_hd_cb.status); return BT_STATUS_NOT_READY; } BTA_HdVirtualCableUnplug(); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function report_error ** ** Description Sends HANDSHAKE with error info for invalid SET_REPORT ** ** Returns bt_status_t ** *******************************************************************************/ static bt_status_t report_error(uint8_t error) { BTIF_TRACE_API("%s", __FUNCTION__); if (!btif_hd_cb.app_registered) { BTIF_TRACE_WARNING("%s: application not yet registered", __FUNCTION__); return BT_STATUS_NOT_READY; } if (btif_hd_cb.status != BTIF_HD_ENABLED) { BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __FUNCTION__, btif_hd_cb.status); return BT_STATUS_NOT_READY; } BTA_HdReportError(error); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function bta_fs_co_session_info ** ** Description This function is executed by BTA when a reliable session is ** established (p_sess_info != NULL) or ended (p_sess_info == NULL). ** ** Parameters bd_addr - the peer address ** p_sess_info - the session ID and related information. ** app_id - application ID specified in the enable functions. ** It can be used to identify which profile is the caller ** of the call-out function. ** ** Returns void ** *******************************************************************************/ void bta_fs_co_session_info(BD_ADDR bd_addr, UINT8 *p_sess_info, UINT8 ssn, tBTA_FS_CO_SESS_ST new_st, char *p_path, UINT8 *p_info, UINT8 app_id) { UNUSED(bd_addr); UNUSED(p_sess_info); UNUSED(ssn); UNUSED(new_st); UNUSED(p_path); UNUSED(p_info); UNUSED(app_id); BTIF_TRACE_WARNING("[CO] bta_fs_co_session_info - NOT implemented"); }
/******************************************************************************* ** ** Function bta_fs_co_suspend ** ** Description This function is executed by BTA when a reliable session is ** suspended. ** ** Parameters bd_addr - the peer address ** ssn - the session sequence number. ** info - the BTA specific information (like last active operation). ** p_offset- the location to receive object offset of the suspended session ** app_id - application ID specified in the enable functions. ** It can be used to identify which profile is the caller ** of the call-out function. ** ** Returns void ** *******************************************************************************/ void bta_fs_co_suspend(BD_ADDR bd_addr, UINT8 *p_sess_info, UINT8 ssn, UINT32 *p_timeout, UINT32 *p_offset, UINT8 info, UINT8 app_id) { UNUSED(bd_addr); UNUSED(p_sess_info); UNUSED(ssn); UNUSED(p_timeout); UNUSED(p_offset); UNUSED(info); UNUSED(app_id); BTIF_TRACE_WARNING("[CO] bta_fs_co_suspend - NOT implemented"); }
/******************************************************************************* ** ** Function btapp_fs_check_space ** ** Description determines access and if there is enough space for given files size on given path ** ** Parameters p_path - Fully qualified path and file name. ** WARNING: file name is stripped off! so it must be present! ** size - size of file to put (0 if unavailable or not applicable) ** app_id - in case application specific treatement is required (e.g opp versus ftp) ** Returns 0 if enough space, otherwise errno failure codes ** *******************************************************************************/ static int btapp_fs_check_space( const char *p_path, const UINT32 size, const UINT8 app_id ) { unsigned long long max_space; struct statfs fs_buffer; int err = 0; char *p_dir; char *p_end; UNUSED(app_id); if(size==BTA_FS_LEN_UNKNOWN) return 0; /* fail silently in case of no memory. write will catch if not enough space */ if (NULL != (p_dir = (char *) GKI_getbuf(strlen(p_path) + 1))) { strcpy(p_dir, p_path); if (NULL != (p_end = strrchr(p_dir, '/'))) { *p_end = '\0'; /* get fs info and calculate available space. if not enough, the fs error EFBIG is returned */ if (0 == statfs(p_dir, &fs_buffer)) { max_space = fs_buffer.f_bavail * fs_buffer.f_bsize; #if (BTA_FS_DEBUG==TRUE) BTIF_TRACE_DEBUG("btapp_fs_enough_space(file size: %d): (uint)max_size: %u", size, (UINT32)max_space); #endif if (max_space < size) err = EFBIG; } else { err = errno; BTIF_TRACE_WARNING("btapp_fs_enough_space(): statfs() failed with err: %d", err); } } else { err = ENOENT; } GKI_freebuf(p_dir); } else { err = ENOMEM; } return err; } /* btapp_fs_check_access_space() */
/******************************************************************************* ** ** Function bta_fs_co_mkdir ** ** Description This function is called to create a directory with ** the pathname given by path. The pathname is a null terminated ** string. All components of the path must already exist. ** ** Parameters p_path - (input) name of directory to create (fully qualified path). ** app_id - (input) application ID specified in the enable functions. ** It can be used to identify which profile is the caller ** of the call-out function. ** ** Returns (tBTA_FS_CO_STATUS) status of the call. ** [BTA_FS_CO_OK if successful] ** [BTA_FS_CO_FAIL if unsuccessful] ** *******************************************************************************/ tBTA_FS_CO_STATUS bta_fs_co_mkdir(const char *p_path, UINT8 app_id) { int err; tBTA_FS_CO_STATUS status = BTA_FS_CO_OK; if ((mkdir (p_path, 0666)) != 0) { err = errno; status = BTA_FS_CO_FAIL; BTIF_TRACE_WARNING("[CO] bta_fs_co_mkdir: error=%d, path [%s] app_id:%d", err, p_path, app_id); } return (status); }
/******************************************************************************* ** ** Function register_app ** ** Description Registers HID Device application ** ** Returns bt_status_t ** *******************************************************************************/ static bt_status_t send_report(bthd_report_type_t type, uint8_t id, uint16_t len, uint8_t *p_data) { tBTA_HD_REPORT report; APPL_TRACE_VERBOSE("%s: type=%d id=%d len=%d", __FUNCTION__, type, id, len); if (!btif_hd_cb.app_registered) { BTIF_TRACE_WARNING("%s: application not yet registered", __FUNCTION__); return BT_STATUS_NOT_READY; } if (btif_hd_cb.status != BTIF_HD_ENABLED) { BTIF_TRACE_WARNING("%s: BT-HD not enabled, status=%d", __FUNCTION__, btif_hd_cb.status); return BT_STATUS_NOT_READY; } if (type == BTHD_REPORT_TYPE_INTRDATA) { report.type = BTHD_REPORT_TYPE_INPUT; report.use_intr = TRUE; } else { report.type = (type & 0x03); report.use_intr = FALSE; } report.id = id; report.len = len; report.p_data = p_data; BTA_HdSendReport(&report); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function bta_fs_co_close ** ** Description This function is called by BTA when a connection to a ** client is closed. ** ** Parameters fd - file descriptor of file to close. ** app_id - application ID specified in the enable functions. ** It can be used to identify which profile is the caller ** of the call-out function. ** ** Returns (tBTA_FS_CO_STATUS) status of the call. ** [BTA_FS_CO_OK if successful], ** [BTA_FS_CO_FAIL if failed ] ** *******************************************************************************/ tBTA_FS_CO_STATUS bta_fs_co_close(int fd, UINT8 app_id) { tBTA_FS_CO_STATUS status = BTA_FS_CO_OK; int err; BTIF_TRACE_DEBUG("[CO] bta_fs_co_close: handle:%d, app id:%d", fd, app_id); if (close (fd) < 0) { err = errno; status = BTA_FS_CO_FAIL; BTIF_TRACE_WARNING("[CO] bta_fs_co_close: handle:%d error=%d app_id:%d", fd, err, app_id); } return (status); }
static void btpan_tap_fd_signaled(int fd, int type, int flags, uint32_t user_id) { assert(btpan_cb.tap_fd == INVALID_FD || btpan_cb.tap_fd == fd); if (btpan_cb.tap_fd != fd) { BTIF_TRACE_WARNING("%s Signaled on mismatched fds exp:%d act:%d\n", __func__, btpan_cb.tap_fd, fd); return; } if (flags & SOCK_THREAD_FD_EXCEPTION) { btpan_cb.tap_fd = INVALID_FD; btpan_tap_close(fd); btif_pan_close_all_conns(); } else if (flags & SOCK_THREAD_FD_RD) bta_dmexecutecallback(btu_exec_tap_fd_read, INT_TO_PTR(fd)); }
/******************************************************************************* ** ** Function btif_in_hf_client_generic_evt ** ** Description Processes generic events to be sent to JNI that are not triggered from the BTA. ** Always runs in BTIF context ** ** Returns void ** *******************************************************************************/ static void btif_in_hf_client_generic_evt(UINT16 event, char *p_param) { UNUSED(p_param); BTIF_TRACE_EVENT("%s: event=%d", __FUNCTION__, event); switch (event) { case BTIF_HF_CLIENT_CB_AUDIO_CONNECTING: { HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, (bthf_client_audio_state_t)BTHF_AUDIO_STATE_CONNECTING, &btif_hf_client_cb.connected_bda); } break; default: { BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __FUNCTION__, event); } break; } }
/******************************************************************************* ** ** Function bta_fs_co_read ** ** Description This function is called by BTA to read in data from the ** previously opened file on the phone. ** ** Parameters fd - file descriptor of file to read from. ** p_buf - buffer to read the data into. ** nbytes - number of bytes to read into the buffer. ** evt - event that must be passed into the call-in function. ** ssn - session sequence number. Ignored, if bta_fs_co_open ** was not called with BTA_FS_CO_RELIABLE. ** app_id - application ID specified in the enable functions. ** It can be used to identify which profile is the caller ** of the call-out function. ** ** Returns void ** ** Note: Upon completion of the request, bta_fs_ci_read() is ** called with the buffer of data, along with the number ** of bytes read into the buffer, and a status. The ** call-in function should only be called when ALL requested ** bytes have been read, the end of file has been detected, ** or an error has occurred. ** *******************************************************************************/ void bta_fs_co_read(int fd, UINT8 *p_buf, UINT16 nbytes, UINT16 evt, UINT8 ssn, UINT8 app_id) { tBTA_FS_CO_STATUS status = BTA_FS_CO_OK; INT32 num_read; int err; UNUSED(ssn); if ((num_read = read (fd, p_buf, nbytes)) < 0) { err = errno; status = BTA_FS_CO_FAIL; BTIF_TRACE_WARNING("[CO] bta_fs_co_read: handle:%d error=%d app_id:%d", fd, err, app_id); } else if (num_read < nbytes) status = BTA_FS_CO_EOF; bta_fs_ci_read(fd, (UINT16)num_read, status, evt); }
/******************************************************************************* ** ** Function btif_hd_upstreams_evt ** ** Description Executes events in btif context ** ** Returns void ** *******************************************************************************/ static void btif_hd_upstreams_evt(UINT16 event, char* p_param) { tBTA_HD *p_data = (tBTA_HD *)p_param; BTIF_TRACE_API("%s: event=%s", __FUNCTION__, dump_hd_event(event)); switch (event) { case BTA_HD_ENABLE_EVT: BTIF_TRACE_DEBUG("%s: status=%d", __FUNCTION__, p_data->status); if (p_data->status == BTA_HD_OK) { btif_storage_load_hidd(); btif_hd_cb.status = BTIF_HD_ENABLED; } else { btif_hd_cb.status = BTIF_HD_DISABLED; BTIF_TRACE_WARNING("Failed to enable BT-HD, status=%d", p_data->status); } break; case BTA_HD_DISABLE_EVT: BTIF_TRACE_DEBUG("%s: status=%d", __FUNCTION__, p_data->status); btif_hd_cb.status = BTIF_HD_DISABLED; if (p_data->status == BTA_HD_OK) memset(&btif_hd_cb, 0, sizeof(btif_hd_cb)); else BTIF_TRACE_WARNING("Failed to disable BT-HD, status=%d", p_data->status); break; case BTA_HD_REGISTER_APP_EVT: { bt_bdaddr_t *addr = (bt_bdaddr_t*) &p_data->reg_status.bda; if (!p_data->reg_status.in_use) { addr = NULL; } btif_hd_cb.app_registered = TRUE; HAL_CBACK(bt_hd_callbacks, application_state_cb, addr, BTHD_APP_STATE_REGISTERED); } break; case BTA_HD_UNREGISTER_APP_EVT: btif_hd_cb.app_registered = FALSE; HAL_CBACK(bt_hd_callbacks, application_state_cb, NULL, BTHD_APP_STATE_NOT_REGISTERED); break; case BTA_HD_OPEN_EVT: btif_storage_set_hidd((bt_bdaddr_t*) &p_data->conn.bda); HAL_CBACK(bt_hd_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda, BTHD_CONN_STATE_CONNECTED); break; case BTA_HD_CLOSE_EVT: HAL_CBACK(bt_hd_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda, BTHD_CONN_STATE_DISCONNECTED); break; case BTA_HD_GET_REPORT_EVT: HAL_CBACK(bt_hd_callbacks, get_report_cb, p_data->get_report.report_type, p_data->get_report.report_id, p_data->get_report.buffer_size); break; case BTA_HD_SET_REPORT_EVT: HAL_CBACK(bt_hd_callbacks, set_report_cb, p_data->set_report.report_type, p_data->set_report.report_id, p_data->set_report.len, p_data->set_report.p_data); break; case BTA_HD_SET_PROTOCOL_EVT: HAL_CBACK(bt_hd_callbacks, set_protocol_cb, p_data->set_protocol); break; case BTA_HD_INTR_DATA_EVT: HAL_CBACK(bt_hd_callbacks, intr_data_cb, p_data->intr_data.report_id, p_data->intr_data.len, p_data->intr_data.p_data); break; case BTA_HD_VC_UNPLUG_EVT: HAL_CBACK(bt_hd_callbacks, connection_state_cb, (bt_bdaddr_t*) &p_data->conn.bda, BTHD_CONN_STATE_DISCONNECTED); if (bta_dm_check_if_only_hd_connected(p_data->conn.bda)) { BTIF_TRACE_DEBUG("%s: Removing bonding as only HID profile connected", __FUNCTION__); BTA_DmRemoveDevice((UINT8 *) &p_data->conn.bda); } else { bt_bdaddr_t *bd_addr = (bt_bdaddr_t*)&p_data->conn.bda; BTIF_TRACE_DEBUG("%s: Only removing HID data as some other profiles " "connected", __FUNCTION__); btif_hd_remove_device(*bd_addr); } HAL_CBACK(bt_hd_callbacks, vc_unplug_cb); break; default: BTIF_TRACE_WARNING("%s: unknown event (%d)", __FUNCTION__, event); break; } }
static void bta_pan_callback_transfer(UINT16 event, char *p_param) { tBTA_PAN *p_data = (tBTA_PAN *)p_param; switch(event) { case BTA_PAN_ENABLE_EVT: BTIF_TRACE_DEBUG("BTA_PAN_ENABLE_EVT"); break; case BTA_PAN_SET_ROLE_EVT: { int btpan_role = bta_role_to_btpan(p_data->set_role.role); bt_status_t status = p_data->set_role.status == BTA_PAN_SUCCESS ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; btpan_control_state_t state = btpan_role == 0 ? BTPAN_STATE_DISABLED : BTPAN_STATE_ENABLED; callback.control_state_cb(state, btpan_role, status, TAP_IF_NAME); break; } case BTA_PAN_OPENING_EVT: { btpan_conn_t* conn; bdstr_t bds; bd2str((bt_bdaddr_t*)p_data->opening.bd_addr, &bds); BTIF_TRACE_DEBUG("BTA_PAN_OPENING_EVT handle %d, addr: %s", p_data->opening.handle, bds); conn = btpan_find_conn_addr(p_data->opening.bd_addr); asrt(conn != NULL); if (conn) { conn->handle = p_data->opening.handle; int btpan_conn_local_role = bta_role_to_btpan(conn->local_role); int btpan_remote_role = bta_role_to_btpan(conn->remote_role); callback.connection_state_cb(BTPAN_STATE_CONNECTING, BT_STATUS_SUCCESS, (const bt_bdaddr_t*)p_data->opening.bd_addr, btpan_conn_local_role, btpan_remote_role); } else BTIF_TRACE_ERROR("connection not found"); break; } case BTA_PAN_OPEN_EVT: { /* debug("BTA_PAN_OPEN_EVT, open status:%d, bd_addr = [%02X:%02X:%02X:%02X:%02X:%02X]", */ /* p_data->open.status, */ /* p_data->open.bd_addr[0], p_data->open.bd_addr[1], p_data->open.bd_addr[2], */ /* p_data->open.bd_addr[3], p_data->open.bd_addr[4], p_data->open.bd_addr[5]); */ btpan_connection_state_t state; bt_status_t status; btpan_conn_t *conn = btpan_find_conn_handle(p_data->open.handle); ALOGV("%s pan connection open status: %d", __func__, p_data->open.status); if(p_data->open.status == BTA_PAN_SUCCESS) { state = BTPAN_STATE_CONNECTED; status = BT_STATUS_SUCCESS; } else { state = BTPAN_STATE_DISCONNECTED; status = BT_STATUS_FAIL; btpan_cleanup_conn(conn); } /* debug("BTA_PAN_OPEN_EVT handle:%d, conn:%p", p_data->open.handle, conn); */ /* debug("conn bta local_role:%d, bta remote role:%d", conn->local_role, conn->remote_role); */ int btpan_conn_local_role = bta_role_to_btpan(p_data->open.local_role); /* debug("bta local_role:%d, bta remote role:%d", p_data->open.local_role, p_data->open.peer_role); */ int btpan_remote_role = bta_role_to_btpan(p_data->open.peer_role); callback.connection_state_cb(state, status, (const bt_bdaddr_t*)p_data->open.bd_addr, btpan_conn_local_role, btpan_remote_role); break; } case BTA_PAN_CLOSE_EVT: { btpan_conn_t* conn = btpan_find_conn_handle(p_data->close.handle); ALOGI("%s: event = BTA_PAN_CLOSE_EVT handle %d", __FUNCTION__, p_data->close.handle); if(conn && conn->handle >= 0) { /* debug("BTA_PAN_CLOSE_EVT, conn local_role:%d, remote_role:%d", conn->local_role, conn->remote_role); */ int btpan_conn_local_role = bta_role_to_btpan(conn->local_role); int btpan_remote_role = bta_role_to_btpan(conn->remote_role); callback.connection_state_cb(BTPAN_STATE_DISCONNECTED, 0, (const bt_bdaddr_t*)conn->peer, btpan_conn_local_role, btpan_remote_role); btpan_cleanup_conn(conn); } else BTIF_TRACE_ERROR("pan handle not found (%d)", p_data->close.handle); break; } default: BTIF_TRACE_WARNING("Unknown pan event %d", event); break; } }
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; } } }
/******************************************************************************* ** ** Function bta_fs_co_rmdir ** ** Description This function is called to remove a directory whose ** name is given by path. The directory must be empty. ** ** Parameters p_path - (input) name of directory to remove (fully qualified path). ** app_id - (input) application ID specified in the enable functions. ** It can be used to identify which profile is the caller ** of the call-out function. ** ** Returns (tBTA_FS_CO_STATUS) status of the call. ** [BTA_FS_CO_OK if successful] ** [BTA_FS_CO_EACCES if read-only] ** [BTA_FS_CO_ENOTEMPTY if directory is not empty] ** [BTA_FS_CO_FAIL otherwise] ** *******************************************************************************/ tBTA_FS_CO_STATUS bta_fs_co_rmdir(const char *p_path, UINT8 app_id) { int err, path_len; tBTA_FS_CO_STATUS status = BTA_FS_CO_OK; struct stat buffer; char *dirName, *tmp = NULL; path_len = strlen( p_path )+1; BTIF_TRACE_DEBUG( "bta_fs_co_rmdir( app_id: %d ): path_len: %d", app_id, path_len ); #if (TRUE==BTA_FS_DEBUG) BTIF_TRACE_DEBUG( "bta_fs_co_rmdir():path_len: %d, p_path", app_id ); BTIF_TRACE_DEBUG( p_path ); #endif /* allocate a temp buffer for path with 0 char. make sure not to crash if path is too big! */ dirName = (char*) calloc(1, path_len+1); if ( NULL != dirName ) { strcpy( dirName, p_path ); } else { BTIF_TRACE_WARNING( "bta_fs_co_rmdir( app_id: %d ) for path_len: %d::out of memory", app_id, path_len ); return BTA_FS_CO_FAIL; } if (NULL!= (tmp = strrchr(dirName, '/'))) { *tmp = '\0'; } if (stat(dirName, &buffer) == 0) { status = getAccess(6, &buffer, dirName); } else { free(dirName); #if (TRUE==BTA_FS_DEBUG) BTIF_TRACE_WARNING( "bta_fs_co_rmdir()::stat(dirName) failed" ); #endif return BTA_FS_CO_FAIL; } free(dirName); if (status != BTA_FS_CO_OK) { #if (TRUE==BTA_FS_DEBUG) BTIF_TRACE_WARNING( "bta_fs_co_rmdir()::getAccess(dirName) FAILED"); #endif return status; } if (stat(p_path, &buffer) == 0) { status = getAccess(6, &buffer, (char*)p_path); } else { #if (TRUE==BTA_FS_DEBUG) BTIF_TRACE_WARNING( "bta_fs_co_rmdir()::stat(p_path) FAILED"); #endif return BTA_FS_CO_FAIL; } if (status != BTA_FS_CO_OK) { #if (TRUE==BTA_FS_DEBUG) BTIF_TRACE_DEBUG( "bta_fs_co_rmdir()::getAccess(p_path) FAILED"); #endif return status; } //if ((rmdir (p_path)) != 0) if (del_path(p_path) != 0) { err = errno; BTIF_TRACE_WARNING( "bta_fs_co_rmdir():rmdir/del_path FAILED with err: %d", err ); if (err == EACCES) status = BTA_FS_CO_EACCES; else if (err == ENOTEMPTY) status = BTA_FS_CO_ENOTEMPTY; else status = BTA_FS_CO_FAIL; } return (status); }
/******************************************************************************* ** ** Function bta_fs_co_getdirentry ** ** Description This function is called to get a directory entry for the ** specified p_path. The first/next directory should be filled ** into the location specified by p_entry. ** ** Parameters p_path - directory to search (Fully qualified path) ** first_item - TRUE if first search, FALSE if next search ** (p_cur contains previous) ** p_entry (input/output) - Points to last entry data (valid when ** first_item is FALSE) ** evt - event that must be passed into the call-in function. ** app_id - application ID specified in the enable functions. ** It can be used to identify which profile is the caller ** of the call-out function. ** ** Returns void ** ** Note: Upon completion of the request, the status is passed ** in the bta_fs_ci_direntry() call-in function. ** BTA_FS_CO_OK is returned when p_entry is valid, ** BTA_FS_CO_EODIR is returned when no more entries [finished] ** BTA_FS_CO_FAIL is returned if an error occurred ** *******************************************************************************/ void bta_fs_co_getdirentry(const char *p_path, BOOLEAN first_item, tBTA_FS_DIRENTRY *p_entry, UINT16 evt, UINT8 app_id) { tBTA_FS_CO_STATUS co_status = BTA_FS_CO_FAIL; int status = -1; /* '0' - success, '-1' - fail */ struct tm *p_tm; DIR *dir; struct dirent *dirent; struct stat buf; char fullname[500]; UNUSED(app_id); BTIF_TRACE_DEBUG("Entered bta_fs_co_getdirentry"); /* First item is to be retrieved */ if (first_item) { BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: path = %s", p_path); dir = opendir(p_path); if(dir == NULL) { BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: dir is NULL so error out with errno=%d", errno); co_status = BTA_FS_CO_EODIR; bta_fs_ci_direntry(co_status, evt); return; } BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: dir = %p", dir); if((dirent = readdir(dir)) != NULL) { p_entry->refdata = (UINT32) dir; /* Save this for future searches */ status = 0; BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: dirent = %p", dirent); } else { BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: dirent = %p", dirent); /* Close the search if there are no more items */ closedir( (DIR*) p_entry->refdata); co_status = BTA_FS_CO_EODIR; } } else /* Get the next entry based on the p_ref data from previous search */ { if ((dirent = readdir((DIR*)p_entry->refdata)) == NULL) { /* Close the search if there are no more items */ closedir( (DIR*) p_entry->refdata); co_status = BTA_FS_CO_EODIR; BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: dirent = %p", dirent); } else { BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: dirent = %p", dirent); status = 0; } } if (status == 0) { BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: status = 0"); sprintf(fullname, "%s/%s", p_path, dirent->d_name); /* Load new values into the return structure (refdata is left untouched) */ if (stat(fullname, &buf) == 0) { p_entry->filesize = buf.st_size; p_entry->mode = 0; /* Default is normal read/write file access */ if (S_ISDIR(buf.st_mode)) p_entry->mode |= BTA_FS_A_DIR; else p_entry->mode |= BTA_FS_A_RDONLY; strcpy(p_entry->p_name, dirent->d_name); #if 0 fprintf(stderr, "bta_fs_co_getdirentry(): %s %9d %d\n", dirent->d_name, buf.st_size, p_entry->mode); #endif p_tm = localtime((const time_t*)&buf.st_mtime); if (p_tm != NULL) { sprintf(p_entry->crtime, "%04d%02d%02dT%02d%02d%02dZ", p_tm->tm_year + 1900, /* Base Year ISO 6201 */ p_tm->tm_mon + 1, /* month starts at 0 */ p_tm->tm_mday, p_tm->tm_hour, p_tm->tm_min, p_tm->tm_sec); } else p_entry->crtime[0] = '\0'; /* No valid time */ #if 0 fprintf(stderr, "bta_fs_co_getdirentry(): %s %9d %d %s\n", dirent->d_name, p_entry->filesize, p_entry->mode, p_entry->crtime); #endif co_status = BTA_FS_CO_OK; } else { BTIF_TRACE_WARNING("stat() failed! "); co_status = BTA_FS_CO_EACCES; } } BTIF_TRACE_DEBUG("bta_fs_co_getdirentry: calling bta_fs_ci_getdirentry"); bta_fs_ci_direntry(co_status, evt); }
/******************************************************************************* ** ** Function btif_hf_client_upstreams_evt ** ** Description Executes HF CLIENT UPSTREAMS events in btif context ** ** Returns void ** *******************************************************************************/ static void btif_hf_client_upstreams_evt(UINT16 event, char* p_param) { tBTA_HF_CLIENT *p_data = (tBTA_HF_CLIENT *)p_param; bdstr_t bdstr; BTIF_TRACE_DEBUG("%s: event=%s (%u)", __FUNCTION__, dump_hf_client_event(event), event); switch (event) { case BTA_HF_CLIENT_ENABLE_EVT: case BTA_HF_CLIENT_DISABLE_EVT: break; case BTA_HF_CLIENT_REGISTER_EVT: btif_hf_client_cb.handle = p_data->reg.handle; break; case BTA_HF_CLIENT_OPEN_EVT: if (p_data->open.status == BTA_HF_CLIENT_SUCCESS) { bdcpy(btif_hf_client_cb.connected_bda.address, p_data->open.bd_addr); btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_CONNECTED; btif_hf_client_cb.peer_feat = 0; btif_hf_client_cb.chld_feat = 0; //clear_phone_state(); } else if (btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_CONNECTING) { btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED; } else { BTIF_TRACE_WARNING("%s: HF CLient open failed, but another device connected. status=%d state=%d connected device=%s", __FUNCTION__, p_data->open.status, btif_hf_client_cb.state, bdaddr_to_string(&btif_hf_client_cb.connected_bda, bdstr, sizeof(bdstr))); break; } HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, btif_hf_client_cb.state, 0, 0, &btif_hf_client_cb.connected_bda); if (btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED) bdsetany(btif_hf_client_cb.connected_bda.address); if (p_data->open.status != BTA_HF_CLIENT_SUCCESS) btif_queue_advance(); break; case BTA_HF_CLIENT_CONN_EVT: btif_hf_client_cb.peer_feat = p_data->conn.peer_feat; btif_hf_client_cb.chld_feat = p_data->conn.chld_feat; btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED; HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, btif_hf_client_cb.state, btif_hf_client_cb.peer_feat, btif_hf_client_cb.chld_feat, &btif_hf_client_cb.connected_bda); /* Inform the application about in-band ringtone */ if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_INBAND) { HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED); } btif_queue_advance(); break; case BTA_HF_CLIENT_CLOSE_EVT: btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED; HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, btif_hf_client_cb.state, 0, 0, &btif_hf_client_cb.connected_bda); bdsetany(btif_hf_client_cb.connected_bda.address); btif_hf_client_cb.peer_feat = 0; btif_hf_client_cb.chld_feat = 0; btif_queue_advance(); break; case BTA_HF_CLIENT_IND_EVT: process_ind_evt(&p_data->ind); break; case BTA_HF_CLIENT_MIC_EVT: HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, BTHF_CLIENT_VOLUME_TYPE_MIC, p_data->val.value); break; case BTA_HF_CLIENT_SPK_EVT: HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, BTHF_CLIENT_VOLUME_TYPE_SPK, p_data->val.value); break; case BTA_HF_CLIENT_VOICE_REC_EVT: HAL_CBACK(bt_hf_client_callbacks, vr_cmd_cb, p_data->val.value); break; case BTA_HF_CLIENT_OPERATOR_NAME_EVT: HAL_CBACK(bt_hf_client_callbacks, current_operator_cb, p_data->operator.name); break; case BTA_HF_CLIENT_CLIP_EVT: HAL_CBACK(bt_hf_client_callbacks, clip_cb, p_data->number.number); break; case BTA_HF_CLIENT_BINP_EVT: HAL_CBACK(bt_hf_client_callbacks, last_voice_tag_number_callback, p_data->number.number); break; case BTA_HF_CLIENT_CCWA_EVT: HAL_CBACK(bt_hf_client_callbacks, call_waiting_cb, p_data->number.number); break; case BTA_HF_CLIENT_AT_RESULT_EVT: HAL_CBACK(bt_hf_client_callbacks, cmd_complete_cb, p_data->result.type, p_data->result.cme); break; case BTA_HF_CLIENT_CLCC_EVT: HAL_CBACK(bt_hf_client_callbacks, current_calls_cb, p_data->clcc.idx, p_data->clcc.inc ? BTHF_CLIENT_CALL_DIRECTION_INCOMING : BTHF_CLIENT_CALL_DIRECTION_OUTGOING, p_data->clcc.status, p_data->clcc.mpty ? BTHF_CLIENT_CALL_MPTY_TYPE_MULTI : BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE, p_data->clcc.number_present ? p_data->clcc.number : NULL); break; case BTA_HF_CLIENT_CNUM_EVT: if (p_data->cnum.service == 4) { HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, p_data->cnum.number, BTHF_CLIENT_SERVICE_VOICE); } else if (p_data->cnum.service == 5) { HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, p_data->cnum.number, BTHF_CLIENT_SERVICE_FAX); } else { HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, p_data->cnum.number, BTHF_CLIENT_SERVICE_UNKNOWN); } break; case BTA_HF_CLIENT_BTRH_EVT: if (p_data->val.value <= BTRH_CLIENT_RESP_AND_HOLD_REJECT) { HAL_CBACK(bt_hf_client_callbacks, resp_and_hold_cb, p_data->val.value); } break; case BTA_HF_CLIENT_BSIR_EVT: if (p_data->val.value != 0) { HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED); } else { HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, BTHF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED); } break; case BTA_HF_CLIENT_AUDIO_OPEN_EVT: HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_CLIENT_AUDIO_STATE_CONNECTED, &btif_hf_client_cb.connected_bda); break; case BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT: HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_CLIENT_AUDIO_STATE_CONNECTED_MSBC, &btif_hf_client_cb.connected_bda); break; case BTA_HF_CLIENT_AUDIO_CLOSE_EVT: HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_CLIENT_AUDIO_STATE_DISCONNECTED, &btif_hf_client_cb.connected_bda); break; case BTA_HF_CLIENT_RING_INDICATION: HAL_CBACK(bt_hf_client_callbacks, ring_indication_cb); break; default: BTIF_TRACE_WARNING("%s: Unhandled event: %d", __FUNCTION__, event); break; } }