Exemplo n.º 1
0
static void hsp_run(void){

    if (wait_ok) return;

    if (hs_accept_sco_connection && hci_can_send_command_packet_now()){
        hs_accept_sco_connection = 0;
        
        log_info("HSP: sending hci_accept_connection_request.");
        // remote supported feature eSCO is set if link type is eSCO
        // eSCO: S4 - max latency == transmission interval = 0x000c == 12 ms, 
        uint16_t max_latency;
        uint8_t  retransmission_effort;
        uint16_t packet_types;
        
        if (hci_remote_esco_supported(rfcomm_handle)){
            max_latency = 0x000c;
            retransmission_effort = 0x02;
            packet_types = 0x388;
        } else {
            max_latency = 0xffff;
            retransmission_effort = 0xff;
            packet_types = 0x003f;
        }
        
        uint16_t sco_voice_setting = hci_get_sco_voice_setting();
        
        log_info("HFP: sending hci_accept_connection_request, sco_voice_setting %02x", sco_voice_setting);
        hci_send_cmd(&hci_accept_synchronous_connection, remote, 8000, 8000, max_latency, 
                        sco_voice_setting, retransmission_effort, packet_types);
        return;
    }

    if (hsp_release_audio_connection){
        if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
            rfcomm_request_can_send_now_event(rfcomm_cid);
            return;
        }
        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(rfcomm_cid);
        return;
    }

    if (hsp_establish_audio_connection){
        if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
            rfcomm_request_can_send_now_event(rfcomm_cid);
            return;
        }
        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){
        if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
            rfcomm_request_can_send_now_event(rfcomm_cid);
            return;
        }
        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_client_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, remote, BLUETOOTH_SERVICE_CLASS_HEADSET_AUDIO_GATEWAY_AG);
            break;
        
        case HSP_AUDIO_CONNECTION_ESTABLISHED:
        case HSP_RFCOMM_CONNECTION_ESTABLISHED:

            if (hs_microphone_gain >= 0){
                if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
                    rfcomm_request_can_send_now_event(rfcomm_cid);
                    return;
                }
                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){
                if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
                    rfcomm_request_can_send_now_event(rfcomm_cid);
                    return;
                }
                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(rfcomm_cid);
            break;
        default:
            break;
    }
}
Exemplo n.º 2
0
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;
    }
}
Exemplo n.º 3
0
static int hfp_ag_run_for_audio_connection(hfp_connection_t * context){
    if (context->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED ||
        context->state > HFP_W2_DISCONNECT_SCO) return 0;


    if (context->state == HFP_AUDIO_CONNECTION_ESTABLISHED && context->release_audio_connection){
        context->state = HFP_W4_SCO_DISCONNECTED;
        context->release_audio_connection = 0;
        gap_disconnect(context->sco_handle);
        return 1;
    }

    if (context->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return 0;
    
    // run codecs exchange
    int done = codecs_exchange_state_machine(context);
    if (done) return done;
    // printf(" -> State machine: Audio Connection\n");

    if (context->codecs_state != HFP_CODECS_EXCHANGED) return done;
    if (context->establish_audio_connection){
        context->state = HFP_W4_SCO_CONNECTED;
        context->establish_audio_connection = 0;
        hci_send_cmd(&hci_setup_synchronous_connection, context->con_handle, 8000, 8000, 0xFFFF, hci_get_sco_voice_setting(), 0xFF, 0x003F);
        return 1;
    
    }
    return 0;
}