Esempio n. 1
0
static void gap_run(){

    if (!hci_can_send_command_packet_now()) return;

    if (todos & SET_ADVERTISEMENT_DATA){
        printf("GAP_RUN: set advertisement data\n");
        todos &= ~SET_ADVERTISEMENT_DATA;
        hci_send_cmd(&hci_le_set_advertising_data, adv_data_len, adv_data);
        return;
    }    

    if (todos & SET_ADVERTISEMENT_PARAMS){
        todos &= ~SET_ADVERTISEMENT_PARAMS;
        uint8_t adv_type = 0;   // default
        bd_addr_t null_addr;
        memset(null_addr, 0, 6);
        uint16_t adv_int_min = 0x0030;
        uint16_t adv_int_max = 0x0030;
        hci_send_cmd(&hci_le_set_advertising_parameters, adv_int_min, adv_int_max, adv_type, 0, 0, &null_addr, 0x07, 0x00);
        return;
    }    

    if (todos & ENABLE_ADVERTISEMENTS){
        printf("GAP_RUN: enable advertisements\n");
        todos &= ~ENABLE_ADVERTISEMENTS;
        hci_send_cmd(&hci_le_set_advertise_enable, 1);
        return;
    }
}
Esempio n. 2
0
static void gap_run(){
    if (!hci_can_send_command_packet_now()) return;

    if (todos & DISABLE_ADVERTISEMENTS){
        todos &= ~DISABLE_ADVERTISEMENTS;
        printf("GAP_RUN: disable advertisements\n");
        advertisements_enabled = 0;
        hci_send_cmd(&hci_le_set_advertise_enable, 0);
        return;
    }    

    if (todos & SET_ADVERTISEMENT_DATA){
        printf("GAP_RUN: set advertisement data\n");
        todos &= ~SET_ADVERTISEMENT_DATA;
        hci_send_cmd(&hci_le_set_advertising_data, adv_data_len, adv_data);
        return;
    }    

    if (todos & SET_ADVERTISEMENT_PARAMS){
        todos &= ~SET_ADVERTISEMENT_PARAMS;
        uint8_t adv_type = gap_adv_type();
        bd_addr_t null_addr;
        memset(null_addr, 0, 6);
        uint16_t adv_int_min = 0x800;
        uint16_t adv_int_max = 0x800;
        switch (adv_type){
            case 0:
            case 2:
            case 3:
                hci_send_cmd(&hci_le_set_advertising_parameters, adv_int_min, adv_int_max, adv_type, gap_random, 0, &null_addr, 0x07, 0x00);
                break;
            case 1:
            case 4:
                hci_send_cmd(&hci_le_set_advertising_parameters, adv_int_min, adv_int_max, adv_type, gap_random, tester_address_type, &tester_address, 0x07, 0x00);
                break;
        }
        return;
    }    

    if (todos & SET_SCAN_RESPONSE_DATA){
        printf("GAP_RUN: set scan response data\n");
        todos &= ~SET_SCAN_RESPONSE_DATA;
        hci_send_cmd(&hci_le_set_scan_response_data, adv_data_len, adv_data);
        // hack for menu
        if ((todos & ENABLE_ADVERTISEMENTS) == 0) show_usage();
        return;
    }    

    if (todos & ENABLE_ADVERTISEMENTS){
        printf("GAP_RUN: enable advertisements\n");
        todos &= ~ENABLE_ADVERTISEMENTS;
        advertisements_enabled = 1;
        hci_send_cmd(&hci_le_set_advertise_enable, 1);
        show_usage();
        return;
    }
}
Esempio n. 3
0
    void btstack_libusb_device_base::btstack_packet_handler( std::uint8_t packet_type, std::uint8_t *packet, std::uint16_t size)
    {
        bool no_log = false;

        switch (packet_type) {
            case HCI_EVENT_PACKET:
                log_info( "*HCI_EVENT_PACKET: %i; size: %lu", packet_type, size );

                if ( size >= 2 )
                {
                    const std::uint8_t event_code       = packet[ 0 ];
                    const std::uint8_t parameter_length = packet[ 1 ];
                    packet += 2;

                    if ( parameter_length  + 2 == size )
                    {
                        handle_event( event_code, parameter_length, packet );
                    }
                    else
                    {
                        log_error( "!!unresonable HCI_EVENT_parameter_length: %i; size: %lu plength: %lu", packet_type, size, parameter_length );
                    }
                }
                else
                {
                    log_error( "!!unresonable HCI_EVENT_SIZE: %i; size: %lu", packet_type, size);
                }

                break;
            case HCI_ACL_DATA_PACKET:
                log_info( "*HCI_ACL_DATA_PACKET: %i; size: %lu", packet_type, size );

                if ( size > 8 )
                {
                    hexdump( packet, size );
                    const std::uint16_t hci_length       = read_u16( packet + 2 );
                    const std::uint16_t l2cap_length     = read_u16( packet + 4 );
                    const std::uint16_t l2cap_channel_id = read_u16( packet + 6 );

                    if ( l2cap_channel_id == 0x0004 && l2cap_length == size - 8 && hci_length == size - 4 )
                    {
                        size    -= hci_header_size;
                        packet  += hci_header_size;
                        log_info( "*ATT-Command: %i", size );
                        hexdump( packet, size ), no_log = true;

                        hci_reserve_packet_buffer();
                        uint8_t     *acl_buffer      = hci_get_outgoing_packet_buffer();
                        std::size_t out_buffer_size  = mtu_size_;

                        l2cap_input_( packet, size, acl_buffer + hci_header_size, out_buffer_size );

                        send_acl_package( acl_buffer, out_buffer_size + hci_header_size );
                    }
                }
                break;
            default:
                break;
        }

        if ( !no_log )
            hexdump( packet, size );

        static int init_phase = 0;

        if ( hci_can_send_command_packet_now() && init_phase < 100 )
        {
            if ( init_phase == 0 )
            {
                std::uint8_t      adv_data[ 31 ] = { 0 };
                const std::size_t size           = advertising_data_( adv_data, sizeof( adv_data ) );

                hci_send_cmd( &hci_le_set_advertising_data, size, adv_data );
            }
            else if ( init_phase == 1 )
            {
                hci_send_cmd( &hci_le_set_advertise_enable, 1 );
            }

            ++init_phase;
        }
    }
Esempio n. 4
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;
    }
}
Esempio n. 5
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;
    }
}