示例#1
0
static void hsp_run(void){
    int err;
    if (hs_ring_received){
        hs_ring_received = 0;
        hs_send_button_press = 1;
    }

    if (hs_ok_received){
        hs_ok_received = 0;
    }
            
    if (hs_send_button_press){
        int err = 0;
        if (hsp_state == HSP_W4_USER_ACTION){
            err = send_str_over_rfcomm(rfcomm_cid, HSP_HS_AT_CKPD);
        } else {
            err = send_str_over_rfcomm(rfcomm_cid, HSP_HS_BUTTON_PRESS);
        }
        if (!err) hs_send_button_press = 0;
        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_W2_CONNECT_SCO:
            hsp_state = HSP_W4_SCO_CONNECTED;
            break;
        
        case HSP_W2_DISCONNECT_SCO:
            hsp_state = HSP_W4_SCO_DISCONNECTED;
            break;

        case HSP_ACTIVE:
            if (hs_ok_received) break;

             if (hs_microphone_gain >= 0){
                char buffer[20];
                sprintf(buffer, "%s=%d\r\n", HSP_HS_MICROPHONE_GAIN, hs_microphone_gain);
                err = send_str_over_rfcomm(rfcomm_cid, buffer);
                if (!err) 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);
                err = send_str_over_rfcomm(rfcomm_cid, buffer);
                if (!err) hs_speaker_gain = -1;
                break;
            }

            break;
        default:
            break;
    }
}
示例#2
0
文件: hfp.c 项目: badog1011/btstack
void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid){
    hfp_connection_t * context = provide_hfp_connection_context_for_bd_addr(bd_addr);
    log_info("hfp_connect %s, context %p", bd_addr_to_str(bd_addr), context);
    
    if (!context) {
        log_error("hfp_establish_service_level_connection for addr %s failed", bd_addr_to_str(bd_addr));
        return;
    }
    switch (context->state){
        case HFP_W2_DISCONNECT_RFCOMM:
            context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
            return;
        case HFP_W4_RFCOMM_DISCONNECTED:
            context->state = HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART;
            return;
        case HFP_IDLE:
            memcpy(context->remote_addr, bd_addr, 6);
            context->state = HFP_W4_SDP_QUERY_COMPLETE;
            connection_doing_sdp_query = context;
            context->service_uuid = service_uuid;
            sdp_query_rfcomm_channel_and_name_for_uuid(context->remote_addr, service_uuid);
            break;
        default:
            break;
    }
}
static void packet_handler(void* connection, uint8_t packet_type, uint16_t channel, uint8_t* packet, uint16_t size) {
    bd_addr_t event_addr;
    uint16_t mtu;

    int ret;

    switch (packet_type) {

    case RFCOMM_DATA_PACKET:
        printf("Received RFCOMM data on channel id %u, size %u\n", channel,
                size);
        hexdump(packet, size);
        rfcomm_send_internal(local_spp_channel, packet, size); // Simple ECHO
        break;

    case HCI_EVENT_PACKET:
        switch (packet[0]) {
        case BTSTACK_EVENT_STATE:
            // bt stack activated, get started
            if (packet[2] == HCI_STATE_WORKING){
                // Inquiry SDP at first
                sdp_query_rfcomm_channel_and_name_for_uuid(remote_addr, 0x1101/*0x1002*/); // 0x1101 is the UUID for SPP
            }
            break;

        case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
            // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
            if (packet[2]) {
                printf("RFCOMM channel open failed, status %u\n", packet[2]);
            } else {
                local_spp_channel = READ_BT_16(packet, 12);
                mtu = READ_BT_16(packet, 14);
                printf(
                        "RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u\n",
                        local_spp_channel, mtu);
            }
            break;

        case HCI_EVENT_DISCONNECTION_COMPLETE:
            printf("[bluetooth] Connection closed\n");
            break;

        default:
            break;
        }
        break;

    default:
        break;
    }
}
示例#4
0
static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
    if (packet_type != HCI_EVENT_PACKET) return;
    uint8_t event = packet[0];

    switch (event) {
        case BTSTACK_EVENT_STATE:
            // bt stack activated, get started
            if (packet[2] == HCI_STATE_WORKING){
//                sdp_query_rfcomm_channel_and_name_for_uuid(remote, 0x1101/*0x1002*/); // 0x1101 is the UUID for SPP
                sdp_query_rfcomm_channel_and_name_for_uuid(remote, 0x1002); // 0x1101 is the UUID for SPP
            }
            break;
        default:
            break;
    }
}
示例#5
0
static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
    printf("packet_handler type %u, packet[0] %x\n", packet_type, packet[0]);

    if (packet_type != HCI_EVENT_PACKET) return;
    uint8_t event = packet[0];

    switch (event) {
        case BTSTACK_EVENT_STATE:
            // bt stack activated, get started 
            if (packet[2] == HCI_STATE_WORKING){
                sdp_query_rfcomm_channel_and_name_for_uuid(remote, 0x1002);
            }
            break;
        default:
            break;
    }
}
示例#6
0
static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
    // printf("packet_handler type %u, packet[0] %x\n", packet_type, packet[0]);

    if (packet_type != HCI_EVENT_PACKET) return;
    uint8_t event = packet[0];

    switch (event) {
        case BTSTACK_EVENT_STATE:
            // bt stack activated, get started 
            if (packet[2] == HCI_STATE_WORKING){
                sdp_query_rfcomm_channel_and_name_for_uuid(remote, SDP_PublicBrowseGroup);
            }
            break;
        case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
            // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
            if (packet[2]) {
                printf("RFCOMM channel open failed, status %u\n", packet[2]);
            } else {
                // data: event(8), len(8), status (8), address (48), handle (16), server channel(8), rfcomm_cid(16), max frame size(16)
                rfcomm_cid = READ_BT_16(packet, 12);
                mtu = READ_BT_16(packet, 14);
                printf("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u\n", rfcomm_cid, mtu);
                if ((test_data_len > mtu)) {
                    test_data_len = mtu;
                }
                if (rfcomm_can_send_packet_now(rfcomm_cid)) send_packet();
                break;
            }
            break;
        case DAEMON_EVENT_HCI_PACKET_SENT:
        case RFCOMM_EVENT_CREDITS:
            if (rfcomm_can_send_packet_now(rfcomm_cid)) send_packet();
            break;
        default:
            break;
    }
}
示例#7
0
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;
    }
}
示例#8
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;
    }
}
示例#9
0
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;
}