/******************************************************************************* ** ** Function bta_hl_co_get_echo_config ** ** Description This function is called to get the echo test ** maximum APDU size configurations ** ** Parameters app_id - HDP application ID ** p_echo_cfg (output) - pointer to the Echo test maximum APDU size ** configuration ** ** Returns Bloolean - TRUE success *******************************************************************************/ BOOLEAN bta_hl_co_get_echo_config(UINT8 app_id, tBTA_HL_ECHO_CFG *p_echo_cfg) { UINT8 app_idx; BOOLEAN success = FALSE; btif_hl_app_cb_t *p_acb; tBTA_HL_SUP_FEATURE *p_sup; BTIF_TRACE_DEBUG2("%s app_id=%d",__FUNCTION__, app_id ); if (btif_hl_find_app_idx(app_id, &app_idx)) { p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx); p_sup = &p_acb->sup_feature; p_echo_cfg->max_rx_apdu_size = p_sup->echo_cfg.max_rx_apdu_size; p_echo_cfg->max_tx_apdu_size = p_sup->echo_cfg.max_tx_apdu_size; success = TRUE; } BTIF_TRACE_DEBUG4("%s success=%d max tx_size=%d rx_size=%d", __FUNCTION__, success, p_echo_cfg->max_tx_apdu_size, p_echo_cfg->max_rx_apdu_size ); return success; }
/* clear the queued PLAY command. if bSend is TRUE, forward to app */ void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp) { BTIF_TRACE_DEBUG2("%s: bSendToApp=%d", __FUNCTION__, bSendToApp); if (btif_rc_cb.rc_pending_play) { if (bSendToApp) { tBTA_AV_REMOTE_CMD remote_cmd; APPL_TRACE_DEBUG1("%s: Sending queued PLAYED event to app", __FUNCTION__); memset (&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD)); remote_cmd.rc_handle = btif_rc_cb.rc_handle; remote_cmd.rc_id = AVRC_ID_PLAY; remote_cmd.hdr.ctype = AVRC_CMD_CTRL; remote_cmd.hdr.opcode = AVRC_OP_PASS_THRU; /* delay sending to app, else there is a timing issue in the framework, ** which causes the audio to be on th device's speaker. Delay between ** OPEN & RC_PLAYs */ GKI_delay (200); /* send to app - both PRESSED & RELEASED */ remote_cmd.key_state = AVRC_STATE_PRESS; handle_rc_passthrough_cmd( &remote_cmd ); GKI_delay (100); remote_cmd.key_state = AVRC_STATE_RELEASE; handle_rc_passthrough_cmd( &remote_cmd ); } btif_rc_cb.rc_pending_play = FALSE; } }
/*************************************************************************** * Function handle_rc_connect * * - Argument: tBTA_AV_RC_OPEN RC open data structure * * - Description: RC connection event handler * ***************************************************************************/ void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open) { BTIF_TRACE_DEBUG2("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle); bt_status_t result = BT_STATUS_SUCCESS; int i; char bd_str[18]; if(p_rc_open->status == BTA_AV_SUCCESS) { memcpy(btif_rc_cb.rc_addr, p_rc_open->peer_addr, sizeof(BD_ADDR)); btif_rc_cb.rc_features = p_rc_open->peer_features; btif_rc_cb.rc_connected = TRUE; btif_rc_cb.rc_handle = p_rc_open->rc_handle; result = uinput_driver_check(); if(result == BT_STATUS_SUCCESS) { init_uinput(); } } else { BTIF_TRACE_ERROR2("%s Connect failed with error code: %d", __FUNCTION__, p_rc_open->status); btif_rc_cb.rc_connected = FALSE; } }
static bt_status_t btpan_connect(const bt_bdaddr_t *bd_addr, int local_role, int remote_role) { BTIF_TRACE_DEBUG2("local_role:%d, remote_role:%d", local_role, remote_role); int bta_local_role = btpan_role_to_bta(local_role); int bta_remote_role = btpan_role_to_bta(remote_role); btpan_new_conn(-1, bd_addr->address, bta_local_role, bta_remote_role); BTA_PanOpen((UINT8*)bd_addr->address, bta_local_role, bta_remote_role); return BT_STATUS_SUCCESS; }
static bt_status_t btpan_jni_init(const btpan_callbacks_t* callbacks) { BTIF_TRACE_DEBUG2("stack_initialized = %d, btpan_cb.enabled:%d", stack_initialized, btpan_cb.enabled); jni_initialized = TRUE; if(stack_initialized && !btpan_cb.enabled) btif_pan_init(); callback = *callbacks; return BT_STATUS_SUCCESS; }
/*************************************************************************** ** ** Function btif_rc_handler ** ** Description RC event handler ** ***************************************************************************/ void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data) { BTIF_TRACE_DEBUG2 ("%s event:%s", __FUNCTION__, dump_rc_event(event)); switch (event) { case BTA_AV_RC_OPEN_EVT: { BTIF_TRACE_DEBUG1("Peer_features:%x", p_data->rc_open.peer_features); handle_rc_connect( &(p_data->rc_open) ); }break; case BTA_AV_RC_CLOSE_EVT: { handle_rc_disconnect( &(p_data->rc_close) ); }break; case BTA_AV_REMOTE_CMD_EVT: { BTIF_TRACE_DEBUG2("rc_id:0x%x key_state:%d", p_data->remote_cmd.rc_id, p_data->remote_cmd.key_state); handle_rc_passthrough_cmd( (&p_data->remote_cmd) ); } break; case BTA_AV_RC_FEAT_EVT: { BTIF_TRACE_DEBUG1("Peer_features:%x", p_data->rc_feat.peer_features); btif_rc_cb.rc_features = p_data->rc_feat.peer_features; /* TODO Handle RC_FEAT_EVT*/ } break; case BTA_AV_META_MSG_EVT: { BTIF_TRACE_DEBUG2("BTA_AV_META_MSG_EVT code:%d label:%d", p_data->meta_msg.code, p_data->meta_msg.label); BTIF_TRACE_DEBUG3(" company_id:0x%x len:%d handle:%d", p_data->meta_msg.company_id, p_data->meta_msg.len, p_data->meta_msg.rc_handle); /* handle the metamsg command */ handle_rc_metamsg_cmd(&(p_data->meta_msg)); } break; default: BTIF_TRACE_DEBUG1("Unhandled RC event : 0x%x", event); } }
/*************************************************************************** * Function handle_rc_disconnect * * - Argument: tBTA_AV_RC_CLOSE RC close data structure * * - Description: RC disconnection event handler * ***************************************************************************/ void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close) { BTIF_TRACE_DEBUG2("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle); btif_rc_cb.rc_handle = 0; btif_rc_cb.rc_connected = FALSE; memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR)); btif_rc_cb.rc_features = 0; close_uinput(); }
static bt_status_t btif_mp_notify_evt(void* msg) { BT_HDR *p_msg = (BT_HDR *)msg; char *p = (char *)(p_msg + 1); UINT8 mp_op_code; UINT8 mp_op_paraLen; STREAM_TO_UINT8 (mp_op_code, p); STREAM_TO_UINT8 (mp_op_paraLen, p); BTIF_TRACE_DEBUG2("%s: notify1 :%s", __FUNCTION__, p); p[mp_op_paraLen] = NULL; BTIF_TRACE_DEBUG2("%s: notify2 :%s", __FUNCTION__, p); HAL_CBACK(bt_hal_cbacks, dut_mode_recv_cb, mp_op_code, p); return BT_STATUS_SUCCESS; }
/******************************************************************************* ** ** Function bta_hl_co_advrtise_source_sdp ** ** Description This function is called to find out whether the SOURCE MDEP ** configuration information should be advertize in the SDP or nopt ** ** Parameters app_id - application ID ** ** Returns Bloolean - TRUE advertise the SOURCE MDEP configuration ** information ** *******************************************************************************/ BOOLEAN bta_hl_co_advrtise_source_sdp(UINT8 app_id) { BOOLEAN advertize_source_sdp=FALSE; UINT8 app_idx; if (btif_hl_find_app_idx(app_id, &app_idx)) { advertize_source_sdp = p_btif_hl_cb->acb[app_idx].sup_feature.advertize_source_sdp; } BTIF_TRACE_DEBUG2("%s advertize_flag=%d", __FUNCTION__, advertize_source_sdp ); return advertize_source_sdp; }
int btpan_tap_open() { struct ifreq ifr; int fd, err; const char *clonedev = "/dev/tun"; /* open the clone device */ //system("insmod /system/lib/modules/tun.ko"); if( (fd = open(clonedev, O_RDWR)) < 0 ) { BTIF_TRACE_DEBUG2("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 )//|| tap_setup_ip(TAP_IF_NAME) == FALSE) { BTIF_TRACE_DEBUG2("ioctl error:%d, errno:%s", err, strerror(errno)); close(fd); return err; } BTM_GetLocalDeviceAddr (local_addr); if(tap_if_up(TAP_IF_NAME, local_addr) == 0) { return fd; } BTIF_TRACE_ERROR1("can not bring up tap interface:%s", TAP_IF_NAME); close(fd); return -1; }
void btif_pan_init() { BTIF_TRACE_DEBUG2("jni_initialized = %d, btpan_cb.enabled:%d", jni_initialized, btpan_cb.enabled); stack_initialized = TRUE; if (jni_initialized && !btpan_cb.enabled) { BTIF_TRACE_DEBUG0("Enabling PAN...."); memset(&btpan_cb, 0, sizeof(btpan_cb)); btpan_cb.tap_fd = -1; int i; for(i = 0; i < MAX_PAN_CONNS; i++) btpan_cleanup_conn(&btpan_cb.conns[i]); BTA_PanEnable(bta_pan_callback); btpan_cb.enabled = 1; btpan_enable(BTPAN_LOCAL_ROLE); } }
btpan_conn_t* btpan_new_conn(int handle, const BD_ADDR addr, int local_role, int remote_role ) { int i; for(i = 0; i < MAX_PAN_CONNS; i++) { BTIF_TRACE_DEBUG2("conns[%d]:%d", i, btpan_cb.conns[i].handle); if(btpan_cb.conns[i].handle == -1) { BTIF_TRACE_DEBUG3("handle:%d, local_role:%d, remote_role:%d", handle, local_role, remote_role); btpan_cb.conns[i].handle = handle; bdcpy(btpan_cb.conns[i].peer, addr); btpan_cb.conns[i].local_role = local_role; btpan_cb.conns[i].remote_role = remote_role; return &btpan_cb.conns[i]; } } BTIF_TRACE_DEBUG1("MAX_PAN_CONNS:%d exceeded, return NULL as failed", MAX_PAN_CONNS); return NULL; }
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_DEBUG0("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_DEBUG2("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_ERROR0("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); ALOGI("%s: event = BTA_PAN_OPEN_EVT p_data->open.status %d", __FUNCTION__, 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); btpan_close_conn(conn); 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_ERROR1("pan handle not found (%d)", p_data->close.handle); break; } default: BTIF_TRACE_WARNING1("Unknown pan event %d", event); break; } }
/*************************************************************************** * Function handle_rc_passthrough_cmd * * - Argument: tBTA_AV_RC rc_id remote control command ID * tBTA_AV_STATE key_state status of key press * * - Description: Remote control command handler * ***************************************************************************/ void handle_rc_passthrough_cmd ( tBTA_AV_REMOTE_CMD *p_remote_cmd) { const char *status; int pressed, i; /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up this PLAY */ if (p_remote_cmd) { /* queue AVRC PLAY if GAVDTP Open notification to app is pending (2 second timer) */ if ((p_remote_cmd->rc_id == BTA_AV_RC_PLAY) && (!btif_av_is_connected())) { if (p_remote_cmd->key_state == AVRC_STATE_PRESS) { APPL_TRACE_WARNING1("%s: AVDT not open, queuing the PLAY command", __FUNCTION__); btif_rc_cb.rc_pending_play = TRUE; } return; } if ((p_remote_cmd->rc_id == BTA_AV_RC_PAUSE) && (btif_rc_cb.rc_pending_play)) { APPL_TRACE_WARNING1("%s: Clear the pending PLAY on PAUSE received", __FUNCTION__); btif_rc_cb.rc_pending_play = FALSE; return; } } if (p_remote_cmd->key_state == AVRC_STATE_RELEASE) { status = "released"; pressed = 0; } else { status = "pressed"; pressed = 1; } /* If this is Play/Pause command (press or release) before processing, check the following * a voice call has ended recently * the remote device is not of type headset * If the above conditions meet, drop the Play/Pause command * This fix is to interop with certain carkits which sends an automatic PLAY or PAUSE * commands right after call ends */ if((p_remote_cmd->rc_id == BTA_AV_RC_PLAY || p_remote_cmd->rc_id == BTA_AV_RC_PAUSE)&& (btif_hf_call_terminated_recently() == TRUE) && (check_cod( (const bt_bdaddr_t*)&(btif_rc_cb.rc_addr), COD_AV_HEADSETS) != TRUE)) { BTIF_TRACE_DEBUG2("%s:Dropping the play/Pause command received right after call end cmd:%d", __FUNCTION__,p_remote_cmd->rc_id); return; } for (i = 0; key_map[i].name != NULL; i++) { if (p_remote_cmd->rc_id == key_map[i].avrcp) { BTIF_TRACE_DEBUG3("%s: %s %s", __FUNCTION__, key_map[i].name, status); /* MusicPlayer uses a long_press_timeout of 1 second for PLAYPAUSE button * and maps that to autoshuffle. So if for some reason release for PLAY/PAUSE * comes 1 second after the press, the MediaPlayer UI goes into a bad state. * The reason for the delay could be sniff mode exit or some AVDTP procedure etc. * The fix is to generate a release right after the press and drown the 'actual' * release. */ if ((key_map[i].release_quirk == 1) && (pressed == 0)) { BTIF_TRACE_DEBUG2("%s: AVRC %s Release Faked earlier, drowned now", __FUNCTION__, key_map[i].name); return; } send_key(uinput_fd, key_map[i].mapped_id, pressed); if ((key_map[i].release_quirk == 1) && (pressed == 1)) { GKI_delay(30); // 30ms BTIF_TRACE_DEBUG2("%s: AVRC %s Release quirk enabled, send release now", __FUNCTION__, key_map[i].name); send_key(uinput_fd, key_map[i].mapped_id, 0); } break; } } if (key_map[i].name == NULL) BTIF_TRACE_ERROR3("%s AVRCP: unknown button 0x%02X %s", __FUNCTION__, p_remote_cmd->rc_id, status); }
/*************************************************************************** * Function handle_rc_passthrough_cmd * * - Argument: tBTA_AV_RC rc_id remote control command ID * tBTA_AV_STATE key_state status of key press * * - Description: Remote control command handler * ***************************************************************************/ void handle_rc_passthrough_cmd ( tBTA_AV_REMOTE_CMD *p_remote_cmd) { const char *status; int pressed, i; /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up this PLAY */ if (p_remote_cmd) { /* queue AVRC PLAY if GAVDTP Open notification to app is pending (2 second timer) */ if ((p_remote_cmd->rc_id == BTA_AV_RC_PLAY) && (!btif_av_is_connected())) { if (p_remote_cmd->key_state == AVRC_STATE_PRESS) { APPL_TRACE_WARNING1("%s: AVDT not open, queuing the PLAY command", __FUNCTION__); btif_rc_cb.rc_pending_play = TRUE; } return; } if ((p_remote_cmd->rc_id == BTA_AV_RC_PAUSE) && (btif_rc_cb.rc_pending_play)) { APPL_TRACE_WARNING1("%s: Clear the pending PLAY on PAUSE received", __FUNCTION__); btif_rc_cb.rc_pending_play = FALSE; return; } } if (p_remote_cmd->key_state == AVRC_STATE_RELEASE) { status = "released"; pressed = 0; } else { status = "pressed"; pressed = 1; } for (i = 0; key_map[i].name != NULL; i++) { if (p_remote_cmd->rc_id == key_map[i].avrcp) { BTIF_TRACE_DEBUG3("%s: %s %s", __FUNCTION__, key_map[i].name, status); /* MusicPlayer uses a long_press_timeout of 1 second for PLAYPAUSE button * and maps that to autoshuffle. So if for some reason release for PLAY/PAUSE * comes 1 second after the press, the MediaPlayer UI goes into a bad state. * The reason for the delay could be sniff mode exit or some AVDTP procedure etc. * The fix is to generate a release right after the press and drown the 'actual' * release. */ if ((key_map[i].release_quirk == 1) && (pressed == 0)) { BTIF_TRACE_DEBUG2("%s: AVRC %s Release Faked earlier, drowned now", __FUNCTION__, key_map[i].name); return; } send_key(uinput_fd, key_map[i].mapped_id, pressed); if ((key_map[i].release_quirk == 1) && (pressed == 1)) { GKI_delay(30); // 30ms BTIF_TRACE_DEBUG2("%s: AVRC %s Release quirk enabled, send release now", __FUNCTION__, key_map[i].name); send_key(uinput_fd, key_map[i].mapped_id, 0); } break; } } if (key_map[i].name == NULL) BTIF_TRACE_ERROR3("%s AVRCP: unknown button 0x%02X %s", __FUNCTION__, p_remote_cmd->rc_id, status); }
/******************************************************************************* ** ** Function btif_hf_upstreams_evt ** ** Description Executes HF UPSTREAMS events in btif context ** ** Returns void ** *******************************************************************************/ static void btif_hf_upstreams_evt(UINT16 event, char* p_param) { tBTA_AG *p_data = (tBTA_AG *)p_param; bdstr_t bdstr; BTIF_TRACE_DEBUG2("%s: event=%s", __FUNCTION__, dump_hf_event(event)); switch (event) { case BTA_AG_ENABLE_EVT: case BTA_AG_DISABLE_EVT: break; case BTA_AG_REGISTER_EVT: btif_hf_cb.handle = p_data->reg.hdr.handle; break; case BTA_AG_OPEN_EVT: if (p_data->open.status == BTA_AG_SUCCESS) { bdcpy(btif_hf_cb.connected_bda.address, p_data->open.bd_addr); btif_hf_cb.state = BTHF_CONNECTION_STATE_CONNECTED; btif_hf_cb.peer_feat = 0; clear_phone_state(); } else if (btif_hf_cb.state == BTHF_CONNECTION_STATE_CONNECTING) { btif_hf_cb.state = BTHF_CONNECTION_STATE_DISCONNECTED; } else { BTIF_TRACE_WARNING4("%s: AG open failed, but another device connected. status=%d state=%d connected device=%s", __FUNCTION__, p_data->open.status, btif_hf_cb.state, bd2str(&btif_hf_cb.connected_bda, &bdstr)); break; } HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb.state, &btif_hf_cb.connected_bda); if (btif_hf_cb.state == BTHF_CONNECTION_STATE_DISCONNECTED) bdsetany(btif_hf_cb.connected_bda.address); if (p_data->open.status != BTA_AG_SUCCESS) btif_queue_advance(); break; case BTA_AG_CLOSE_EVT: btif_hf_cb.state = BTHF_CONNECTION_STATE_DISCONNECTED; HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb.state, &btif_hf_cb.connected_bda); bdsetany(btif_hf_cb.connected_bda.address); btif_hf_cb.peer_feat = 0; clear_phone_state(); /* If AG_OPEN was received but SLC was not setup in a specified time (10 seconds), ** then AG_CLOSE may be received. We need to advance the queue here */ btif_queue_advance(); break; case BTA_AG_CONN_EVT: btif_hf_cb.peer_feat = p_data->conn.peer_feat; btif_hf_cb.state = BTHF_CONNECTION_STATE_SLC_CONNECTED; HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb.state, &btif_hf_cb.connected_bda); btif_queue_advance(); break; case BTA_AG_AUDIO_OPEN_EVT: HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTED, &btif_hf_cb.connected_bda); break; case BTA_AG_AUDIO_CLOSE_EVT: HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_DISCONNECTED, &btif_hf_cb.connected_bda); break; /* BTA auto-responds, silently discard */ case BTA_AG_SPK_EVT: case BTA_AG_MIC_EVT: HAL_CBACK(bt_hf_callbacks, volume_cmd_cb, (event == BTA_AG_SPK_EVT) ? BTHF_VOLUME_TYPE_SPK : BTHF_VOLUME_TYPE_MIC, p_data->val.num); break; case BTA_AG_AT_A_EVT: HAL_CBACK(bt_hf_callbacks, answer_call_cmd_cb); break; /* Java needs to send OK/ERROR for these commands */ case BTA_AG_AT_BLDN_EVT: case BTA_AG_AT_D_EVT: HAL_CBACK(bt_hf_callbacks, dial_call_cmd_cb, (event == BTA_AG_AT_D_EVT) ? p_data->val.str : NULL); break; case BTA_AG_AT_CHUP_EVT: HAL_CBACK(bt_hf_callbacks, hangup_call_cmd_cb); break; case BTA_AG_AT_CIND_EVT: HAL_CBACK(bt_hf_callbacks, cind_cmd_cb); break; case BTA_AG_AT_VTS_EVT: HAL_CBACK(bt_hf_callbacks, dtmf_cmd_cb, p_data->val.str[0]); break; case BTA_AG_AT_BVRA_EVT: HAL_CBACK(bt_hf_callbacks, vr_cmd_cb, (p_data->val.num == 1) ? BTHF_VR_STATE_STARTED : BTHF_VR_STATE_STOPPED); break; case BTA_AG_AT_NREC_EVT: HAL_CBACK(bt_hf_callbacks, nrec_cmd_cb, (p_data->val.num == 1) ? BTHF_NREC_START : BTHF_NREC_STOP); break; /* TODO: Add a callback for CBC */ case BTA_AG_AT_CBC_EVT: break; case BTA_AG_AT_CKPD_EVT: HAL_CBACK(bt_hf_callbacks, key_pressed_cmd_cb); break; /* Java needs to send OK/ERROR for these commands */ case BTA_AG_AT_CHLD_EVT: HAL_CBACK(bt_hf_callbacks, chld_cmd_cb, atoi(p_data->val.str)); break; case BTA_AG_AT_CLCC_EVT: HAL_CBACK(bt_hf_callbacks, clcc_cmd_cb, p_data->val.num); break; case BTA_AG_AT_COPS_EVT: HAL_CBACK(bt_hf_callbacks, cops_cmd_cb); break; case BTA_AG_AT_UNAT_EVT: HAL_CBACK(bt_hf_callbacks, unknown_at_cmd_cb, p_data->val.str); break; case BTA_AG_AT_CNUM_EVT: HAL_CBACK(bt_hf_callbacks, cnum_cmd_cb); break; /* TODO: Some of these commands may need to be sent to app. For now respond with error */ case BTA_AG_AT_BINP_EVT: case BTA_AG_AT_BTRH_EVT: send_at_result(BTA_AG_OK_ERROR, BTA_AG_ERR_OP_NOT_SUPPORTED); break; default: BTIF_TRACE_WARNING2("%s: Unhandled event: %d", __FUNCTION__, event); break; } }