Exemple #1
0
static void daemon_packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
    switch (packet_type) {
        case HCI_EVENT_PACKET:
            deamon_status_event_handler(packet, size);
            switch (packet[0]){
                case HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS:
                    // ACL buffer freed...
                    daemon_retry_parked();
                    // no need to tell clients
                    return;
                case RFCOMM_EVENT_CREDITS:
                    // RFCOMM CREDITS received...
                    daemon_retry_parked();
                    break;
                default:
                    break;
            }
        case DAEMON_EVENT_PACKET:
            switch (packet[0]){
                case DAEMON_EVENT_NEW_RFCOMM_CREDITS:
                    daemon_retry_parked();
                    break;
                default:
                    break;
            }
        default:
            break;
    }
    if (connection) {
        socket_connection_send_packet(connection, packet_type, channel, packet, size);
    } else {
        socket_connection_send_packet_all(packet_type, channel, packet, size);
    }
}
/**
 * send HCI packet to all connections 
 */
void socket_connection_send_packet_all(uint16_t type, uint16_t channel, uint8_t *packet, uint16_t size){
    linked_item_t *next;
    linked_item_t *it;
    for (it = (linked_item_t *) connections; it ; it = next){
        next = it->next; // cache pointer to next connection_t to allow for removal
        socket_connection_send_packet( (connection_t *) linked_item_get_user(it), type, channel, packet, size);
    }
}
Exemple #3
0
// send hci cmd packet
int bt_send_cmd(const hci_cmd_t *cmd, ...){
    va_list argptr;
    va_start(argptr, cmd);
    uint16_t len = hci_create_cmd_internal(hci_cmd_buffer, cmd, argptr);
    va_end(argptr);
    socket_connection_send_packet(btstack_connection, HCI_COMMAND_DATA_PACKET, 0, hci_cmd_buffer, len);
    return 0;
}
Exemple #4
0
// define new packet type SDP_CLIENT_PACKET
static void handle_sdp_client_query_result(sdp_query_event_t * event){
    sdp_query_attribute_value_event_t * ve;
    sdp_query_complete_event_t * complete_event;

    switch (event->type){
        case SDP_QUERY_ATTRIBUTE_VALUE:
            ve = (sdp_query_attribute_value_event_t*) event;
            
            sdp_client_assert_buffer(ve->attribute_length);

            attribute_value[ve->data_offset] = ve->data;

            if ((uint16_t)(ve->data_offset+1) == ve->attribute_length){
                hexdump(attribute_value, ve->attribute_length);

                int event_len = 1 + 3 * 2 + ve->attribute_length; 
                uint8_t event[event_len];
                event[0] = SDP_QUERY_ATTRIBUTE_VALUE;
                event[1] = ve->record_id;
                event[3] = ve->attribute_id;
                event[5] = ve->attribute_length;

                memcpy(&event[7], attribute_value, ve->attribute_length);
                hci_dump_packet(SDP_CLIENT_PACKET, 0, event, event_len);
                socket_connection_send_packet(NULL, SDP_CLIENT_PACKET, 0, event, event_len);
            }

            break;
        case SDP_QUERY_COMPLETE:
            complete_event = (sdp_query_complete_event_t*) event;
            uint8_t event[] = { SDP_QUERY_COMPLETE, 1, complete_event->status};
            hci_dump_packet(HCI_EVENT_PACKET, 0, event, sizeof(event));
            socket_connection_send_packet(NULL, HCI_EVENT_PACKET, 0, event, sizeof(event));
            break;
    }
}
Exemple #5
0
static void handle_sdp_rfcomm_service_result(sdp_query_event_t * rfcomm_event, void * context){
    switch (rfcomm_event->type){
        case SDP_QUERY_RFCOMM_SERVICE: {
            sdp_query_rfcomm_service_event_t * service_event = (sdp_query_rfcomm_service_event_t*) rfcomm_event;
            int name_len = strlen((const char*)service_event);
            int event_len = 3 + name_len; 
            uint8_t event[event_len];
            event[0] = rfcomm_event->type;
            event[1] = 1 + name_len;
            event[2] = service_event->channel_nr;
            memcpy(&event[3], service_event->service_name, name_len);
            hci_dump_packet(HCI_EVENT_PACKET, 0, event, event_len);
            socket_connection_send_packet(context, HCI_EVENT_PACKET, 0, event, event_len);
            break;
        }
        case SDP_QUERY_COMPLETE: {
            sdp_query_complete_event_t * complete_event = (sdp_query_complete_event_t*) rfcomm_event;
            uint8_t event[] = { rfcomm_event->type, 1, complete_event->status};
            hci_dump_packet(HCI_EVENT_PACKET, 0, event, sizeof(event));
            socket_connection_send_packet(context, HCI_EVENT_PACKET, 0, event, sizeof(event));
            break;
        }
    }
}
Exemple #6
0
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;
}
Exemple #7
0
void bt_send_acl(uint8_t * data, uint16_t len){
    // send
    socket_connection_send_packet(btstack_connection, HCI_ACL_DATA_PACKET, 0, data, len);
}
Exemple #8
0
void bt_send_rfcomm(uint16_t rfcomm_cid, uint8_t *data, uint16_t len){
    // send
    socket_connection_send_packet(btstack_connection, RFCOMM_DATA_PACKET, rfcomm_cid, data, len);
}
Exemple #9
0
void bt_send_l2cap(uint16_t source_cid, uint8_t *data, uint16_t len){
    // send
    socket_connection_send_packet(btstack_connection, L2CAP_DATA_PACKET, source_cid, data, len);
}