コード例 #1
0
ファイル: hfp_ag.c プロジェクト: yourskp/btstack
static void hfp_run_for_context(hfp_connection_t *context){
    if (!context) return;
    if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return;
    
    if (context->command == HFP_CMD_UNKNOWN){
        context->ok_pending = 0;
        context->send_error = 0;
        context->command = HFP_CMD_NONE;
        hfp_ag_error(context->rfcomm_cid);
        return;
    }

    if (context->ok_pending){
        context->ok_pending = 0;
        context->command = HFP_CMD_NONE;
        hfp_ag_ok(context->rfcomm_cid);
        return;
    }

    if (context->send_error){
        context->send_error = 0;
        context->command = HFP_CMD_NONE;
        hfp_ag_error(context->rfcomm_cid); 
        return;
    }
    
    int done = hfp_ag_run_for_context_service_level_connection(context);
    if (!done){
        done = hfp_ag_run_for_context_service_level_connection_queries(context);
    } 

    if (!done){
        done = incoming_call_state_machine(context);
    }

    if (!done){  
        done = hfp_ag_run_for_audio_connection(context);
    }
    

    if (context->command == HFP_CMD_NONE && !done){
        log_info("context->command == HFP_CMD_NONE");
        switch(context->state){
            case HFP_W2_DISCONNECT_RFCOMM:
                context->state = HFP_W4_RFCOMM_DISCONNECTED;
                rfcomm_disconnect_internal(context->rfcomm_cid);
                break;
            default:
                break;
        }
    }
    if (done){
        context->command = HFP_CMD_NONE;
    }
}
コード例 #2
0
ファイル: spp_streamer.c プロジェクト: BertoDiaz/btstack
static void send_packet(){
    int err = rfcomm_send_internal(rfcomm_cid, (uint8_t*) test_data, test_data_len);
    if (err){
        printf("rfcomm_send_internal -> error 0X%02x", err);
        return;
    }
    
    if (data_to_send < test_data_len){
        rfcomm_disconnect_internal(rfcomm_cid);
        rfcomm_cid = 0;
        state = DONE;
        printf("SPP Streamer: enough data send, closing DLC\n");
        return;
    }
    data_to_send -= test_data_len;
}
コード例 #3
0
ファイル: hfp_ag.c プロジェクト: shangdawei/btstack-1
void hfp_run_for_context(hfp_connection_t *context){
    if (!context) return;

    if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return;

    // printf("AG hfp_run_for_context 1 state %d, command %d\n", context->state, context->command);
    if (context->send_ok){
        hfp_ag_ok(context->rfcomm_cid);
        context->send_ok = 0;
        return;
    }

    if (context->send_error){
        hfp_ag_error(context->rfcomm_cid); 
        context->send_error = 0;
        return;
    }
    int done;
    if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return;
    hfp_ag_run_for_context_service_level_connection(context);

    if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return;
    done = hfp_ag_run_for_context_service_level_connection_queries(context);
    if (!rfcomm_can_send_packet_now(context->rfcomm_cid) || done) return;
    done = hfp_ag_run_for_context_codecs_connection(context);

    if (context->command == HFP_CMD_NONE){
        switch(context->state){
            case HFP_W2_DISCONNECT_RFCOMM:
                // printf("rfcomm_disconnect_internal cid 0x%02x\n", context->rfcomm_cid);
                context->state = HFP_W4_RFCOMM_DISCONNECTED;
                rfcomm_disconnect_internal(context->rfcomm_cid);
                break;
            default:
                break;
        }
    }
    context->command = HFP_CMD_NONE;

}
コード例 #4
0
ファイル: daemon.c プロジェクト: sristi194/uubt
static int btstack_command_handler(connection_t *connection, uint8_t *packet, uint16_t size){
    
    bd_addr_t addr;
    uint16_t cid;
    uint16_t psm;
    uint16_t service_channel;
    uint16_t mtu;
    uint8_t  reason;
    uint8_t  rfcomm_channel;
    uint8_t  rfcomm_credits;
    uint32_t service_record_handle;
    client_state_t *client;
    
    uint16_t serviceSearchPatternLen;
    uint16_t attributeIDListLen;

    // BTstack internal commands - 16 Bit OpCode, 8 Bit ParamLen, Params...
    switch (READ_CMD_OCF(packet)){
        case BTSTACK_GET_STATE:
            log_info("BTSTACK_GET_STATE");
            hci_emit_state();
            break;
        case BTSTACK_SET_POWER_MODE:
            log_info("BTSTACK_SET_POWER_MODE %u", packet[3]);
            // track client power requests
            client = client_for_connection(connection);
            if (!client) break;
            client->power_mode = packet[3];
            // handle merged state
            if (!clients_require_power_on()){
                start_power_off_timer();
            } else if (!power_management_sleep) {
                stop_power_off_timer();
                hci_power_control(HCI_POWER_ON);
            }
            break;
        case BTSTACK_GET_VERSION:
            log_info("BTSTACK_GET_VERSION");
            hci_emit_btstack_version();
            break;   
#ifdef USE_BLUETOOL
        case BTSTACK_SET_SYSTEM_BLUETOOTH_ENABLED:
            log_info("BTSTACK_SET_SYSTEM_BLUETOOTH_ENABLED %u", packet[3]);
            iphone_system_bt_set_enabled(packet[3]);
            hci_emit_system_bluetooth_enabled(iphone_system_bt_enabled());
            break;
            
        case BTSTACK_GET_SYSTEM_BLUETOOTH_ENABLED:
            log_info("BTSTACK_GET_SYSTEM_BLUETOOTH_ENABLED");
            hci_emit_system_bluetooth_enabled(iphone_system_bt_enabled());
            break;
#else
        case BTSTACK_SET_SYSTEM_BLUETOOTH_ENABLED:
        case BTSTACK_GET_SYSTEM_BLUETOOTH_ENABLED:
            hci_emit_system_bluetooth_enabled(0);
            break;
#endif
        case BTSTACK_SET_DISCOVERABLE:
            log_info("BTSTACK_SET_DISCOVERABLE discoverable %u)", packet[3]);
            // track client discoverable requests
            client = client_for_connection(connection);
            if (!client) break;
            client->discoverable = packet[3];
            // merge state
            hci_discoverable_control(clients_require_discoverable());
            break;
        case BTSTACK_SET_BLUETOOTH_ENABLED:
            log_info("BTSTACK_SET_BLUETOOTH_ENABLED: %u\n", packet[3]);
            if (packet[3]) {
                // global enable
                global_enable = 1;
                hci_power_control(HCI_POWER_ON);
            } else {
                global_enable = 0;
                clients_clear_power_request();
                hci_power_control(HCI_POWER_OFF);
            }
            break;
        case L2CAP_CREATE_CHANNEL_MTU:
            bt_flip_addr(addr, &packet[3]);
            psm = READ_BT_16(packet, 9);
            mtu = READ_BT_16(packet, 11);
            l2cap_create_channel_internal( connection, NULL, addr, psm, mtu);
            break;
        case L2CAP_CREATE_CHANNEL:
            bt_flip_addr(addr, &packet[3]);
            psm = READ_BT_16(packet, 9);
            l2cap_create_channel_internal( connection, NULL, addr, psm, 150);   // until r865
            break;
        case L2CAP_DISCONNECT:
            cid = READ_BT_16(packet, 3);
            reason = packet[5];
            l2cap_disconnect_internal(cid, reason);
            break;
        case L2CAP_REGISTER_SERVICE:
            psm = READ_BT_16(packet, 3);
            mtu = READ_BT_16(packet, 5);
            l2cap_register_service_internal(connection, NULL, psm, mtu);
            break;
        case L2CAP_UNREGISTER_SERVICE:
            psm = READ_BT_16(packet, 3);
            l2cap_unregister_service_internal(connection, psm);
            break;
        case L2CAP_ACCEPT_CONNECTION:
            cid    = READ_BT_16(packet, 3);
            l2cap_accept_connection_internal(cid);
            break;
        case L2CAP_DECLINE_CONNECTION:
            cid    = READ_BT_16(packet, 3);
            reason = packet[7];
            l2cap_decline_connection_internal(cid, reason);
            break;
        case RFCOMM_CREATE_CHANNEL:
            bt_flip_addr(addr, &packet[3]);
            rfcomm_channel = packet[9];
            rfcomm_create_channel_internal( connection, &addr, rfcomm_channel );
            break;
        case RFCOMM_CREATE_CHANNEL_WITH_CREDITS:
            bt_flip_addr(addr, &packet[3]);
            rfcomm_channel = packet[9];
            rfcomm_credits = packet[10];
            rfcomm_create_channel_with_initial_credits_internal( connection, &addr, rfcomm_channel, rfcomm_credits );
            break;
        case RFCOMM_DISCONNECT:
            cid = READ_BT_16(packet, 3);
            reason = packet[5];
            rfcomm_disconnect_internal(cid);
            break;
        case RFCOMM_REGISTER_SERVICE:
            rfcomm_channel = packet[3];
            mtu = READ_BT_16(packet, 4);
            rfcomm_register_service_internal(connection, rfcomm_channel, mtu);
            break;
        case RFCOMM_REGISTER_SERVICE_WITH_CREDITS:
            rfcomm_channel = packet[3];
            mtu = READ_BT_16(packet, 4);
            rfcomm_credits = packet[6];
            rfcomm_register_service_with_initial_credits_internal(connection, rfcomm_channel, mtu, rfcomm_credits);
            break;
        case RFCOMM_UNREGISTER_SERVICE:
            service_channel = READ_BT_16(packet, 3);
            rfcomm_unregister_service_internal(service_channel);
            break;
        case RFCOMM_ACCEPT_CONNECTION:
            cid    = READ_BT_16(packet, 3);
            rfcomm_accept_connection_internal(cid);
            break;
        case RFCOMM_DECLINE_CONNECTION:
            cid    = READ_BT_16(packet, 3);
            reason = packet[7];
            rfcomm_decline_connection_internal(cid);
            break;            
        case RFCOMM_GRANT_CREDITS:
            cid    = READ_BT_16(packet, 3);
            rfcomm_credits = packet[5];
            rfcomm_grant_credits(cid, rfcomm_credits);
            break;
        case RFCOMM_PERSISTENT_CHANNEL: {
            if (remote_device_db) {
                // enforce \0
                packet[3+248] = 0;
                rfcomm_channel = remote_device_db->persistent_rfcomm_channel((char*)&packet[3]);
            } else {
                // NOTE: hack for non-iOS platforms
                rfcomm_channel = rfcomm_channel_generator++;
            }
            log_info("RFCOMM_EVENT_PERSISTENT_CHANNEL %u", rfcomm_channel);
            uint8_t event[4];
            event[0] = RFCOMM_EVENT_PERSISTENT_CHANNEL;
            event[1] = sizeof(event) - 2;
            event[2] = 0;
            event[3] = rfcomm_channel;
            hci_dump_packet(HCI_EVENT_PACKET, 0, event, sizeof(event));
            socket_connection_send_packet(connection, HCI_EVENT_PACKET, 0, (uint8_t *) event, sizeof(event));
            break;
        }
            
        case SDP_REGISTER_SERVICE_RECORD:
            log_info("SDP_REGISTER_SERVICE_RECORD size %u\n", size);
            sdp_register_service_internal(connection, &packet[3]);
            break;
        case SDP_UNREGISTER_SERVICE_RECORD:
            service_record_handle = READ_BT_32(packet, 3);
            log_info("SDP_UNREGISTER_SERVICE_RECORD handle 0x%x ", service_record_handle);
            sdp_unregister_service_internal(connection, service_record_handle);
            break;
        case SDP_CLIENT_QUERY_RFCOMM_SERVICES: 
            bt_flip_addr(addr, &packet[3]);

            serviceSearchPatternLen = de_get_len(&packet[9]);
            memcpy(serviceSearchPattern, &packet[9], serviceSearchPatternLen);

            sdp_query_rfcomm_register_callback(handle_sdp_rfcomm_service_result, connection);
            sdp_query_rfcomm_channel_and_name_for_search_pattern(addr, serviceSearchPattern);

            break;
        case SDP_CLIENT_QUERY_SERVICES:
            bt_flip_addr(addr, &packet[3]);
            sdp_parser_init();
            sdp_parser_register_callback(handle_sdp_client_query_result);

            serviceSearchPatternLen = de_get_len(&packet[9]);
            memcpy(serviceSearchPattern, &packet[9], serviceSearchPatternLen);
            
            attributeIDListLen = de_get_len(&packet[9+serviceSearchPatternLen]); 
            memcpy(attributeIDList, &packet[9+serviceSearchPatternLen], attributeIDListLen);
            
            sdp_client_query(addr, (uint8_t*)&serviceSearchPattern[0], (uint8_t*)&attributeIDList[0]);

            // sdp_general_query_for_uuid(addr, 0x1002);
            break;
        default:
            log_error("Error: command %u not implemented\n:", READ_CMD_OCF(packet));
            break;
    }
    
    // verbose log info on command before dumped command unknown to PacketLogger or Wireshark
    hci_dump_packet( HCI_COMMAND_DATA_PACKET, 1, packet, size);

    return 0;
}
コード例 #5
0
ファイル: hsp_hs.c プロジェクト: brianjang/btstack
static void hsp_run(void){
    if (!rfcomm_can_send_packet_now(rfcomm_cid)) return;
    if (wait_ok) return;

    if (hsp_release_audio_connection){
        hsp_release_audio_connection = 0;
        wait_ok = 1;
        hsp_hs_send_str_over_rfcomm(rfcomm_cid, HSP_HS_AT_CKPD);
        return;
    }

    if (hsp_disconnect_rfcomm){
        hsp_disconnect_rfcomm = 0;
        hsp_establish_audio_connection = 0;
        rfcomm_disconnect_internal(rfcomm_cid);
        return;
    }

    if (hsp_establish_audio_connection){
        hsp_establish_audio_connection = 0;
        wait_ok = 1;
        hsp_hs_send_str_over_rfcomm(rfcomm_cid, HSP_HS_AT_CKPD);
        return;
    }
    
    if (hs_send_button_press){
        hs_send_button_press = 0;
        wait_ok = 1;
        hsp_hs_send_str_over_rfcomm(rfcomm_cid, HSP_HS_AT_CKPD);
        return;
    }

    switch (hsp_state){
        case HSP_SDP_QUERY_RFCOMM_CHANNEL:
            hsp_state = HSP_W4_SDP_QUERY_COMPLETE;
            sdp_query_rfcomm_channel_and_name_for_uuid(remote, SDP_Headset_AG);
            break;
        
        case HSP_AUDIO_CONNECTION_ESTABLISHED:
        case HSP_RFCOMM_CONNECTION_ESTABLISHED:

            if (hs_microphone_gain >= 0){
                char buffer[20];
                sprintf(buffer, "%s=%d\r\n", HSP_HS_MICROPHONE_GAIN, hs_microphone_gain);
                hsp_hs_send_str_over_rfcomm(rfcomm_cid, buffer);
                hs_microphone_gain = -1;
                break;
            }

            if (hs_speaker_gain >= 0){
                char buffer[20];
                sprintf(buffer, "%s=%d\r\n", HSP_HS_SPEAKER_GAIN, hs_speaker_gain);
                hsp_hs_send_str_over_rfcomm(rfcomm_cid, buffer);
                hs_speaker_gain = -1;
                break;
            }
            break;
        case HSP_W4_RFCOMM_DISCONNECTED:
            rfcomm_disconnect_internal(rfcomm_cid);
            break;
        default:
            break;
    }
}
コード例 #6
0
ファイル: hsp_ag.c プロジェクト: Mechelix/btstack
static void hsp_run(void){
    int err;

    if (ag_send_ok){
        ag_send_ok = 0;  
        err = hsp_ag_send_str_over_rfcomm(rfcomm_cid, HSP_AG_OK);
        if (err){
            ag_send_ok = 1;  
        } 
        return;
    }

    if (ag_send_error){
        ag_send_error = 0;
        err = hsp_ag_send_str_over_rfcomm(rfcomm_cid, HSP_AG_ERROR);
        if (err) {
            ag_send_error = 1;
        }
        return;
    }
    
    switch (hsp_state){
        case HSP_SDP_QUERY_RFCOMM_CHANNEL:
            hsp_state = HSP_W4_SDP_QUERY_COMPLETE;
            log_info("Start SDP query %s, 0x%02x", bd_addr_to_str(remote), SDP_HSP);
            sdp_query_rfcomm_channel_and_name_for_uuid(remote, SDP_HSP);
            break;

        case HSP_W4_RING_ANSWER:
            if (ag_ring){
                ag_ring = 0;
                err = hsp_ag_send_str_over_rfcomm(rfcomm_cid, HSP_AG_RING);
                if (err) {
                    ag_ring = 1;
                }
                break;
            }

            if (!ag_num_button_press_received) break;    
            ag_send_ok = 0;

            ag_num_button_press_received = 0;
            hsp_state = HSP_W2_CONNECT_SCO;

            err = hsp_ag_send_str_over_rfcomm(rfcomm_cid, HSP_AG_OK);
            if (err) {
                hsp_state = HSP_W4_RING_ANSWER;
                ag_num_button_press_received = 1;
            }
            break;
        case HSP_W2_CONNECT_SCO:
            if (!hci_can_send_command_packet_now()) break;
            hsp_state = HSP_W4_SCO_CONNECTED;
            hci_send_cmd(&hci_setup_synchronous_connection, rfcomm_handle, 8000, 8000, 0xFFFF, hci_get_sco_voice_setting(), 0xFF, 0x003F);
            break;
        
        case HSP_W2_DISCONNECT_SCO:
            ag_num_button_press_received = 0;
        
            hsp_state = HSP_W4_SCO_DISCONNECTED;
            gap_disconnect(sco_handle);
            break;
        
        case HSP_W2_DISCONNECT_RFCOMM:
            hsp_state = HSP_W4_RFCOMM_DISCONNECTED;
            rfcomm_disconnect_internal(rfcomm_cid);
            break;
        case HSP_ACTIVE:
            
            if (ag_microphone_gain >= 0){
                int gain = ag_microphone_gain;
                ag_microphone_gain = -1;
                char buffer[10];
                sprintf(buffer, "%s=%d\r\n", HSP_MICROPHONE_GAIN, gain);
                err = hsp_ag_send_str_over_rfcomm(rfcomm_cid, buffer);
                if (err) {
                    ag_microphone_gain = gain;
                }
                break;
            }

            if (ag_speaker_gain >= 0){
                int gain = ag_speaker_gain;
                ag_speaker_gain = -1;
                char buffer[10];
                sprintf(buffer, "%s=%d\r\n", HSP_SPEAKER_GAIN, gain);
                err = hsp_ag_send_str_over_rfcomm(rfcomm_cid, buffer);
                if (err) {
                    ag_speaker_gain = gain;
                }
                break;
            }
            break;
        default:
            break;
    }
}
コード例 #7
0
ファイル: hfp_ag.c プロジェクト: badog1011/btstack
void hfp_run_for_context(hfp_connection_t *context) {
    // printf(" hfp_run_for_context \n");
    if (!context) return;
    if (!rfcomm_can_send_packet_now(context->rfcomm_cid)) return;
    //printf(" hfp_run_for_context 1 state %d, command %d\n", context->state, context->command);

    if (context->state == HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) {
        if (context->send_ok) {
            hfp_ag_ok(context->rfcomm_cid);
            context->send_ok = 0;
            return;
        }

        if (context->send_error) {
            hfp_ag_error(context->rfcomm_cid);
            context->send_error = 0;
            return;
        }

        if (context->enable_status_update_for_ag_indicators) {
            int i;
            for (i = 0; i < context->ag_indicators_nr; i++) {
                if (context->ag_indicators[i].enabled == 0) continue;
                if (context->ag_indicators[i].status_changed == 0) continue;
                hfp_ag_transfer_ag_indicators_status_cmd(context->rfcomm_cid, context->ag_indicators[i]);
                context->ag_indicators[i].status_changed = 0;
                return;
            }
        }

        if (context->enable_extended_audio_gateway_error_report) {
            if (context->extended_audio_gateway_error) {
                hfp_ag_report_extended_audio_gateway_error(context->rfcomm_cid, context->extended_audio_gateway_error);
                context->extended_audio_gateway_error = 0;
                return;
            }
        }
    }


    if (context->state == HFP_AUDIO_CONNECTION_ESTABLISHED) {
        // TODO
    }

    switch(context->command) {
    // START codec setup
    case HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP:
        if (!hfp_ag_choose_codec(context)) {
            hfp_ag_error(context->rfcomm_cid);
            break;
        }
        switch (context->state) {
        case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
            // hfp_ag_ok(context->rfcomm_cid);
            context->negotiated_codec = hfp_ag_choose_codec(context);
            hfp_ag_cmd_confirm_codec(context->rfcomm_cid, context->negotiated_codec);
            context->state = HFP_SLE_W4_EXCHANGE_COMMON_CODEC;
            break;
        default:
            hfp_ag_error(context->rfcomm_cid);
            break;
        }
        break;

    case HFP_CMD_CONFIRM_COMMON_CODEC:
        hfp_ag_ok(context->rfcomm_cid);
        context->state = HFP_CODECS_CONNECTION_ESTABLISHED;
        break;
    // END codec setup

    case HFP_CMD_SUPPORTED_FEATURES:
        switch(context->state) {
        case HFP_W4_EXCHANGE_SUPPORTED_FEATURES:
            hfp_ag_exchange_supported_features_cmd(context->rfcomm_cid);
            if (has_codec_negotiation_feature(context)) {
                context->state = HFP_W4_NOTIFY_ON_CODECS;
                break;
            }
            context->state = HFP_W4_RETRIEVE_INDICATORS;
            break;
        default:
            break;
        }
        break;
    case HFP_CMD_AVAILABLE_CODECS:
        switch(context->state) {
        case HFP_W4_NOTIFY_ON_CODECS:
            hfp_ag_retrieve_codec_cmd(context->rfcomm_cid);
            context->state = HFP_W4_RETRIEVE_INDICATORS;
            break;
        default:
            break;
        }
        break;
    case HFP_CMD_INDICATOR:
        switch(context->state) {
        case HFP_W4_RETRIEVE_INDICATORS:
            if (context->retrieve_ag_indicators == 0) break;
            hfp_ag_retrieve_indicators_cmd(context->rfcomm_cid, context);
            context->state = HFP_W4_RETRIEVE_INDICATORS_STATUS;
            break;
        case HFP_W4_RETRIEVE_INDICATORS_STATUS:
            if (context->retrieve_ag_indicators_status == 0) break;
            hfp_ag_retrieve_indicators_status_cmd(context->rfcomm_cid);
            context->state = HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE;
            break;
        default:
            break;
        }
        break;
    case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE:
        switch(context->state) {
        case HFP_W4_ENABLE_INDICATORS_STATUS_UPDATE:
            hfp_ag_toggle_indicator_status_update_cmd(context->rfcomm_cid, 1);
            if (has_call_waiting_and_3way_calling_feature(context)) {
                context->state = HFP_W4_RETRIEVE_CAN_HOLD_CALL;
                break;
            }
            if (has_hf_indicators_feature(context)) {
                context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS;
                break;
            }
            context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
            hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0);
            break;
        case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
            // TODO
            break;
        default:
            break;
        }
        break;
    case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES:
        switch(context->state) {
        case HFP_W4_RETRIEVE_CAN_HOLD_CALL:
            hfp_ag_retrieve_can_hold_call_cmd(context->rfcomm_cid);
            if (has_hf_indicators_feature(context)) {
                context->state = HFP_W4_LIST_GENERIC_STATUS_INDICATORS;
                break;
            }
            context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
            hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0);
            break;
        default:
            break;
        }
        break;
    case HFP_CMD_GENERIC_STATUS_INDICATOR:
        switch(context->state) {
        case HFP_W4_LIST_GENERIC_STATUS_INDICATORS:
            if (context->list_generic_status_indicators == 0) break;
            hfp_ag_list_supported_generic_status_indicators_cmd(context->rfcomm_cid);
            context->state = HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS;
            context->list_generic_status_indicators = 0;
            break;
        case HFP_W4_RETRIEVE_GENERIC_STATUS_INDICATORS:
            if (context->retrieve_generic_status_indicators == 0) break;
            hfp_ag_retrieve_supported_generic_status_indicators_cmd(context->rfcomm_cid);
            context->state = HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS;
            context->retrieve_generic_status_indicators = 0;
            break;
        case HFP_W4_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
            if (context->retrieve_generic_status_indicators_state == 0) break;
            hfp_ag_retrieve_initital_supported_generic_status_indicators_cmd(context->rfcomm_cid);
            context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
            context->retrieve_generic_status_indicators_state = 0;
            hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, 0);
            break;
        default:
            break;
        }
        break;
    case HFP_CMD_QUERY_OPERATOR_SELECTION:
        if (context->state != HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) break;
        if (context->operator_name_format == 1) {
            if (context->network_operator.format != 0) {
                hfp_ag_error(context->rfcomm_cid);
                break;
            }
            hfp_ag_ok(context->rfcomm_cid);
            context->operator_name_format = 0;
            break;
        }
        if (context->operator_name == 1) {
            hfp_ag_report_network_operator_name_cmd(context->rfcomm_cid, context->network_operator);
            context->operator_name = 0;
            break;
        }
        break;
    case HFP_CMD_NONE:
        switch(context->state) {
        case HFP_W2_DISCONNECT_RFCOMM:
            // printf("rfcomm_disconnect_internal cid 0x%02x\n", context->rfcomm_cid);
            context->state = HFP_W4_RFCOMM_DISCONNECTED;
            rfcomm_disconnect_internal(context->rfcomm_cid);
            break;
        default:
            break;
        }
        break;
    default:
        break;
    }
    // done
    context->command = HFP_CMD_NONE;
}
コード例 #8
0
ファイル: classic_test.c プロジェクト: dwtguh/btstack
int  stdin_process(struct data_source *ds){
    char buffer;
    read(ds->fd, &buffer, 1);

    // passkey input
    if (ui_digits_for_passkey){
        if (buffer < '0' || buffer > '9') return 0;
        printf("%c", buffer);
        fflush(stdout);
        ui_passkey = ui_passkey * 10 + buffer - '0';
        ui_digits_for_passkey--;
        if (ui_digits_for_passkey == 0){
            printf("\nSending Passkey '%06u'\n", ui_passkey);
            hci_send_cmd(&hci_user_passkey_request_reply, remote, ui_passkey);
        }
        return 0;
    }
    if (ui_chars_for_pin){
        printf("%c", buffer);
        fflush(stdout);
        if (buffer == '\n'){
            printf("\nSending Pin '%s'\n", ui_pin);
            hci_send_cmd(&hci_pin_code_request_reply, remote, ui_pin_offset, ui_pin);
        } else {
            ui_pin[ui_pin_offset++] = buffer;
        }
        return 0;
    }

    switch (buffer){
        case 'c':
            gap_connectable = 0;
            hci_connectable_control(0);
            show_usage();
            break;
        case 'C':
            gap_connectable = 1;
            hci_connectable_control(1);
            show_usage();
            break;
        case 'd':
            gap_discoverable = 0;
            hci_discoverable_control(0);
            show_usage();
            break;
        case 'D':
            gap_discoverable = 1;
            hci_discoverable_control(1);
            show_usage();
            break;
        case 'b':
            gap_bondable = 0;
            // gap_set_bondable_mode(0);
            update_auth_req();
            show_usage();
            break;
        case 'B':
            gap_bondable = 1;
            // gap_set_bondable_mode(1);
            update_auth_req();
            show_usage();
            break;
        case 'm':
            gap_mitm_protection = 0;
            update_auth_req();
            show_usage();
            break;
        case 'M':
            gap_mitm_protection = 1;
            update_auth_req();
            show_usage();
            break;

        case '<':
            gap_dedicated_bonding_mode = 0;
            update_auth_req();
            show_usage();
            break;
        case '>':
            gap_dedicated_bonding_mode = 1;
            update_auth_req();
            show_usage();
            break;

        case 'e':
            gap_io_capabilities = "IO_CAPABILITY_DISPLAY_ONLY";
            hci_ssp_set_io_capability(IO_CAPABILITY_DISPLAY_ONLY);
            show_usage();
            break;
        case 'f':
            gap_io_capabilities = "IO_CAPABILITY_DISPLAY_YES_NO";
            hci_ssp_set_io_capability(IO_CAPABILITY_DISPLAY_YES_NO);
            show_usage();
            break;
        case 'g':
            gap_io_capabilities = "IO_CAPABILITY_NO_INPUT_NO_OUTPUT";
            hci_ssp_set_io_capability(IO_CAPABILITY_NO_INPUT_NO_OUTPUT);
            show_usage();
            break;
        case 'h':
            gap_io_capabilities = "IO_CAPABILITY_KEYBOARD_ONLY";
            hci_ssp_set_io_capability(IO_CAPABILITY_KEYBOARD_ONLY);
            show_usage();
            break;

        case 'i':
            start_scan();
            break;

        case 'j':
            printf("Start dedicated bonding to %s using MITM %u\n", bd_addr_to_str(remote), gap_mitm_protection);
            gap_dedicated_bonding(remote, gap_mitm_protection);
            break;

        case 'z':
            printf("Start dedicated bonding to %s using legacy pairing\n", bd_addr_to_str(remote));
            gap_dedicated_bonding(remote, gap_mitm_protection);
            break;

        case 'y':
            printf("Disabling SSP for this session\n");
            hci_send_cmd(&hci_write_simple_pairing_mode, 0);
            break;

        case 'k':
            printf("Start SDP query for SPP service\n");
            sdp_query_rfcomm_channel_and_name_for_uuid(remote_rfcomm, 0x1101);
            break;

        case 't':
            printf("Terminate connection with handle 0x%04x\n", handle);
            hci_send_cmd(&hci_disconnect, handle, 0x13);  // remote closed connection
            break;

        case 'p':
            printf("Creating HCI Connection to %s\n", bd_addr_to_str(remote));
            hci_send_cmd(&hci_create_connection, remote, hci_usable_acl_packet_types(), 0, 0, 0, 1);
            break;
            // printf("Creating L2CAP Connection to %s, PSM SDP\n", bd_addr_to_str(remote));
            // l2cap_create_channel_internal(NULL, packet_handler, remote, PSM_SDP, 100);
            // break;
        // case 'u':
        //     printf("Creating L2CAP Connection to %s, PSM 3\n", bd_addr_to_str(remote));
        //     l2cap_create_channel_internal(NULL, packet_handler, remote, 3, 100);
        //     break;
        case 'q':
            printf("Send L2CAP Data\n");
            l2cap_send_internal(local_cid, (uint8_t *) "0123456789", 10);
       break;
        case 'r':
            printf("Send L2CAP ECHO Request\n");
            l2cap_send_echo_request(handle, (uint8_t *)  "Hello World!", 13);
            break;
        case 's':
            printf("L2CAP Channel Closed\n");
            l2cap_disconnect_internal(local_cid, 0);
            break;
        case 'x':
            printf("Outgoing L2CAP Channels to SDP will also require SSP\n");
            l2cap_require_security_level_2_for_outgoing_sdp();
            break;

        case 'l':
            printf("Creating RFCOMM Channel to %s #%u\n", bd_addr_to_str(remote_rfcomm), rfcomm_channel_nr);
             rfcomm_create_channel_internal(NULL, remote_rfcomm, rfcomm_channel_nr);
            break;
        case 'n':
            printf("Send RFCOMM Data\n");   // mtu < 60 
            rfcomm_send_internal(rfcomm_channel_id, (uint8_t *) "012345678901234567890123456789012345678901234567890123456789", mtu);
            break;
        case 'u':
            printf("Sending RLS indicating framing error\n");   // mtu < 60 
            rfcomm_send_local_line_status(rfcomm_channel_id, 9);
            break;
        case 'v':
            printf("Sending RPN CMD to select 115200 baud\n");   // mtu < 60 
            rfcomm_send_port_configuration(rfcomm_channel_id, RPN_BAUD_115200, RPN_DATA_BITS_8, RPN_STOP_BITS_1_0, RPN_PARITY_NONE, 0);
            break;
        case 'w':
            printf("Sending RPN REQ to query remote port settings\n");   // mtu < 60 
            rfcomm_query_port_configuration(rfcomm_channel_id);
            break;
        case 'o':
            printf("RFCOMM Channel Closed\n");
            rfcomm_disconnect_internal(rfcomm_channel_id);
            rfcomm_channel_id = 0;
            break;

        case '+':
            printf("Initiate SSP on current connection\n");
            gap_request_security_level(handle, LEVEL_2);
            break;

        case '*':
            printf("Sending SSP User Confirmation for %s\n", bd_addr_to_str(remote));
            hci_send_cmd(&hci_user_confirmation_request_reply, remote);
            break;

        case '=':
            printf("Deleting Link Key for %s\n", bd_addr_to_str(remote));
            hci_drop_link_key_for_bd_addr(remote);
            break;

        case 'U':
            printf("Sending UCD data on handle 0x%04x\n", handle);
            send_ucd_packet();
            break;

        case 'Q':
            printf("Closing HCI Connection to handle 0x%04x\n", handle);
            gap_disconnect(handle);
            break;

        default:
            show_usage();
            break;

    }
    return 0;
}