示例#1
0
/*************** PANU client routines *********************/
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
{
    uint8_t   event;
    bd_addr_t event_addr;
    bd_addr_t src_addr;
    bd_addr_t dst_addr;
    uint16_t  uuid_source;
    uint16_t  uuid_dest;
    uint16_t  mtu;    
    uint16_t  network_type;
    uint8_t   protocol_type;
    uint8_t   icmp_type;
    int       ihl;
    int       payload_offset;

    switch (packet_type) {
		case HCI_EVENT_PACKET:
            event = packet[0];
            switch (event) {            
                case BTSTACK_EVENT_STATE:
                    /* BT Stack activated, get started */ 
                    if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){
                        printf("BNEP Test ready\n");
                        show_usage();
                    }
                    break;

                case HCI_EVENT_COMMAND_COMPLETE:
					if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_bd_addr)){
                        reverse_bd_addr(&packet[6], local_addr);
                        printf("BD-ADDR: %s\n", bd_addr_to_str(local_addr));
                        break;
                    }
                    break;

                case HCI_EVENT_USER_CONFIRMATION_REQUEST:
                    // inform about user confirmation request
                    printf("SSP User Confirmation Request with numeric value '%06u'\n", little_endian_read_32(packet, 8));
                    printf("SSP User Confirmation Auto accept\n");
                    break;
				
				case BNEP_EVENT_CHANNEL_OPENED:
                    if (bnep_event_channel_opened_get_status(packet)) {
                        printf("BNEP channel open failed, status %02x\n", bnep_event_channel_opened_get_status(packet));
                    } else {
                        // data: event(8), len(8), status (8), bnep source uuid (16), bnep destination uuid (16), remote_address (48)
                        bnep_cid    = bnep_event_channel_opened_get_bnep_cid(packet);
                        uuid_source = bnep_event_channel_opened_get_source_uuid(packet);
                        uuid_dest   = bnep_event_channel_opened_get_destination_uuid(packet);
                        mtu         = bnep_event_channel_opened_get_mtu(packet);
                        //bt_flip_addr(event_addr, &packet[9]); 
                        memcpy(&event_addr, &packet[11], sizeof(bd_addr_t));
                        printf("BNEP connection open succeeded to %s source UUID 0x%04x dest UUID: 0x%04x, max frame size %u\n", bd_addr_to_str(event_addr), uuid_source, uuid_dest, mtu);
                    }
					break;
                    
                case BNEP_EVENT_CHANNEL_TIMEOUT:
                    printf("BNEP channel timeout! Channel will be closed\n");
                    break;
                    
                case BNEP_EVENT_CHANNEL_CLOSED:
                    printf("BNEP channel closed\n");
                    break;

                case BNEP_EVENT_CAN_SEND_NOW:
                    /* Check for parked network packets and send it out now */
                    if (network_buffer_len > 0) {
                        bnep_send(bnep_cid, network_buffer, network_buffer_len);
                        network_buffer_len = 0;
                    }
                    break;
                    
                default:
                    break;
            }
            break;
        case BNEP_DATA_PACKET:
            // show received packet on console

            // TODO: fix BNEP to return BD ADDR in little endian, to use these lines
            // bt_flip_addr(dst_addr, &packet[0]);
            // bt_flip_addr(src_addr, &packet[6]);
            // instead of these
            memcpy(dst_addr, &packet[0], 6);
            memcpy(src_addr, &packet[6], 6);
            // END TOOD

            network_type = big_endian_read_16(packet, 12);
            printf("BNEP packet received\n");
            printf("Dst Addr: %s\n", bd_addr_to_str(dst_addr));
            printf("Src Addr: %s\n", bd_addr_to_str(src_addr));
            printf("Net Type: %04x\n", network_type);
            // ignore the next 60 bytes
            // hexdumpf(&packet[74], size - 74);
            switch (network_type){
                case NETWORK_TYPE_IPv4:
                    ihl = packet[14] & 0x0f;
                    payload_offset = 14 + (ihl << 2);
                    // protocol
                    protocol_type = packet[14 + 9]; // offset 9 into IPv4
                    switch (protocol_type){
                        case 0x01:  // ICMP
                            icmp_type = packet[payload_offset];
                            hexdumpf(&packet[payload_offset], size - payload_offset);
                            printf("ICMP packet of type %x\n", icmp_type);
                            switch (icmp_type){
                                case ICMP_V4_TYPE_PING_REQUEST:
                                    printf("IPv4 Ping Request received, sending pong\n");
                                    send_ping_response_ipv4();
                                    break;
                                break;
                            }
                        case 0x11:  // UDP
                            printf("UDP IPv4 packet\n");                        
                            hexdumpf(&packet[payload_offset], size - payload_offset);
                            break;
                        default:
                            printf("Unknown IPv4 protocol type %x", protocol_type);
                            break;
                    }
                    break;
                case NETWORK_TYPE_IPv6:
                    protocol_type = packet[6];
                    switch(protocol_type){
                        case 0x11: // UDP
                            printf("UDP IPv6 packet\n");
                            payload_offset = 40;    // fixed
                            hexdumpf(&packet[payload_offset], size - payload_offset);

                            // send response

                            break;
                        default:
                            printf("IPv6 packet of protocol 0x%02x\n", protocol_type);
                            hexdumpf(&packet[14], size - 14);
                            break;
                    }
                    break;
                default:
                    printf("Unknown network type %x", network_type);
                    break;
            }

            break;            
            
        default:
            break;
    }
}
示例#2
0
// Bluetooth logic
static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
/* LISTING_PAUSE */
    bd_addr_t event_addr;
    uint8_t   rfcomm_channel_nr;
    uint16_t  mtu;
    int i;
    
    switch (packet_type) {
        case HCI_EVENT_PACKET:
            switch (hci_event_packet_get_type(packet)) {
                                    
                case HCI_EVENT_COMMAND_COMPLETE:
                    if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_bd_addr)){
                        reverse_bd_addr(&packet[6], event_addr);
                        printf("BD-ADDR: %s\n\r", bd_addr_to_str(event_addr));
                        break;
                    }
                    break;

                case HCI_EVENT_PIN_CODE_REQUEST:
                    // inform about pin code request
                    printf("Pin code request - using '0000'\n");
                    hci_event_pin_code_request_get_bd_addr(packet, event_addr);
                    gap_pin_code_response(event_addr, "0000");
                    break;
                
                case RFCOMM_EVENT_INCOMING_CONNECTION:
                    // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
                    rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr); 
                    rfcomm_channel_nr = rfcomm_event_incoming_connection_get_server_channel(packet);
                    rfcomm_channel_id = rfcomm_event_incoming_connection_get_rfcomm_cid(packet);
                    printf("RFCOMM channel %u requested for %s\n", rfcomm_channel_nr, bd_addr_to_str(event_addr));
                    rfcomm_accept_connection(rfcomm_channel_id);
                    break;
               
                case RFCOMM_EVENT_CHANNEL_OPENED:
                    // data: event(8), len(8), status (8), address (48), server channel(8), rfcomm_cid(16), max frame size(16)
                    if (rfcomm_event_channel_opened_get_status(packet)) {
                        printf("RFCOMM channel open failed, status %u\n", rfcomm_event_channel_opened_get_status(packet));
                    } else {
                        rfcomm_channel_id = rfcomm_event_channel_opened_get_rfcomm_cid(packet);
                        mtu = rfcomm_event_channel_opened_get_max_frame_size(packet);
                        printf("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u\n", rfcomm_channel_id, mtu);
                    }
                    break;
                    
                case RFCOMM_EVENT_CHANNEL_CLOSED:
                    rfcomm_channel_id = 0;
                    break;
                
                default:
                    break;
            }
            break;
/* LISTING_RESUME */
        case RFCOMM_DATA_PACKET:
            for (i=0;i<size;i++){
                putchar(packet[i]);
            };
            putchar('\n');
            rfcomm_send_credit = 1;
            break;
/* LISTING_PAUSE */
        default:
            break;
    }
/* LISTING_RESUME */ 
}
示例#3
0
static void packet_handler (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 == RFCOMM_DATA_PACKET){
        // skip over leading newline
        while (size > 0 && (packet[0] == '\n' || packet[0] == '\r')){
            size--;
            packet++;
        }
        if (strncmp((char *)packet, HSP_AG_RING, strlen(HSP_AG_RING)) == 0){
            emit_ring_event();
        } else if (strncmp((char *)packet, HSP_AG_OK, strlen(HSP_AG_OK)) == 0){
           wait_ok = 0;
        } else if (strncmp((char *)packet, HSP_MICROPHONE_GAIN, strlen(HSP_MICROPHONE_GAIN)) == 0){
            uint8_t gain = (uint8_t)atoi((char*)&packet[strlen(HSP_MICROPHONE_GAIN)]);
            emit_event(HSP_SUBEVENT_MICROPHONE_GAIN_CHANGED, gain);
        
        } else if (strncmp((char *)packet, HSP_SPEAKER_GAIN, strlen(HSP_SPEAKER_GAIN)) == 0){
            uint8_t gain = (uint8_t)atoi((char*)&packet[strlen(HSP_SPEAKER_GAIN)]);
            emit_event(HSP_SUBEVENT_SPEAKER_GAIN_CHANGED, gain);
        } else {
            if (!hsp_hs_callback) return;
            // strip trailing newline
            while (size > 0 && (packet[size-1] == '\n' || packet[size-1] == '\r')){
                size--;
            }
            // add trailing \0
            packet[size] = 0;
            // re-use incoming buffer to avoid reserving large buffers - ugly but efficient
            uint8_t * event = packet - 4;
            event[0] = HCI_EVENT_HSP_META;
            event[1] = size + 2;
            event[2] = HSP_SUBEVENT_AG_INDICATION;
            event[3] = size;
            (*hsp_hs_callback)(event, size+4);
        }
        hsp_run();
        return;
    }

    if (packet_type != HCI_EVENT_PACKET) return;
    uint8_t event = hci_event_packet_get_type(packet);
    bd_addr_t event_addr;
    uint16_t handle;

    switch (event) {
        case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{
            if (hsp_state < HSP_RFCOMM_CONNECTION_ESTABLISHED) return;
            int index = 2;
            uint8_t status = packet[index++];
            sco_handle = little_endian_read_16(packet, index);
            index+=2;
            bd_addr_t address; 
            memcpy(address, &packet[index], 6);
            index+=6;
            uint8_t link_type = packet[index++];
            uint8_t transmission_interval = packet[index++];  // measured in slots
            uint8_t retransmission_interval = packet[index++];// measured in slots
            uint16_t rx_packet_length = little_endian_read_16(packet, index); // measured in bytes
            index+=2;
            uint16_t tx_packet_length = little_endian_read_16(packet, index); // measured in bytes
            index+=2;
            uint8_t air_mode = packet[index];

            if (status != 0){
                log_error("(e)SCO Connection failed, status %u", status);
                emit_event_audio_connected(status, sco_handle);
                hsp_state = HSP_RFCOMM_CONNECTION_ESTABLISHED ;
                break;
            }

            switch (link_type){
                case 0x00:
                    log_info("SCO Connection established.");
                    if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval);
                    if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval);
                    if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length);
                    if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length);
                    break;
                case 0x02:
                    log_info("eSCO Connection established.");
                    break;
                default:
                    log_error("(e)SCO reserved link_type 0x%2x", link_type);
                    break;
            }
            log_info("sco_handle 0x%2x, address %s, transmission_interval %u slots, retransmission_interval %u slots, " 
                 " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)", sco_handle,
                 bd_addr_to_str(address), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode);

            hsp_state = HSP_AUDIO_CONNECTION_ESTABLISHED;
            emit_event_audio_connected(status, sco_handle);
            break;                
        }

        case RFCOMM_EVENT_INCOMING_CONNECTION:
            // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
            if (hsp_state != HSP_IDLE) return;

            reverse_bd_addr(&packet[2], event_addr); 
            rfcomm_cid = little_endian_read_16(packet, 9);
            log_info("RFCOMM channel %u requested for %s", packet[8], bd_addr_to_str(event_addr));
            hsp_state = HSP_W4_RFCOMM_CONNECTED;
            rfcomm_accept_connection(rfcomm_cid);
            break;

        case RFCOMM_EVENT_CHANNEL_OPENED:
            // printf("RFCOMM_EVENT_CHANNEL_OPENED packet_handler type %u, packet[0] %x\n", packet_type, packet[0]);
            // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
            if (hsp_state != HSP_W4_RFCOMM_CONNECTED) return;
            if (packet[2]) {
                log_info("RFCOMM channel open failed, status %u", packet[2]);
                hsp_state = HSP_IDLE;
                hsp_hs_reset_state();
            } else {
                // data: event(8) , len(8), status (8), address (48), handle (16), server channel(8), rfcomm_cid(16), max frame size(16)
                rfcomm_handle = little_endian_read_16(packet, 9);
                rfcomm_cid = little_endian_read_16(packet, 12);
                mtu = little_endian_read_16(packet, 14);
                log_info("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u, handle %02x", rfcomm_cid, mtu, rfcomm_handle);
                hsp_state = HSP_RFCOMM_CONNECTION_ESTABLISHED;
            }
            emit_event(HSP_SUBEVENT_RFCOMM_CONNECTION_COMPLETE, packet[2]);
            break;

        case RFCOMM_EVENT_CAN_SEND_NOW:
            hsp_run();
            break;
        
        case HCI_EVENT_DISCONNECTION_COMPLETE:
            handle = little_endian_read_16(packet,3);
            if (handle == sco_handle){
                sco_handle = 0;
                hsp_state = HSP_RFCOMM_CONNECTION_ESTABLISHED;
                emit_event(HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE,0);
                break;
            } 
            if (handle == rfcomm_handle) {
                rfcomm_handle = 0;
                hsp_state = HSP_IDLE;
                emit_event(HSP_SUBEVENT_RFCOMM_DISCONNECTION_COMPLETE,0);
                hsp_hs_reset_state();
            }
            break;

        case RFCOMM_EVENT_CHANNEL_CLOSED:
            hsp_hs_reset_state();
            hsp_hs_callback(packet, size);
            break;

        default:
            break;
    }

    hsp_run();
}
示例#4
0
// Bluetooth logic
static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
    bd_addr_t event_addr;
    uint8_t   rfcomm_channel_nr;
    uint16_t  mtu;
    
    uint8_t event_code;
	// uint8_t channel;
	uint8_t message_id;

	switch (packet_type) {
		case HCI_EVENT_PACKET:
			switch (hci_event_packet_get_type(packet)) {
					
				case BTSTACK_EVENT_STATE:
					if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){
                        printf("BTstack is up and running\n");
                        // start ANT init
                        ant_send_cmd(&ant_reset); 
                    }
					break;
				
				case HCI_EVENT_COMMAND_COMPLETE:
					if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_bd_addr)){
                        reverse_bd_addr(&packet[6], event_addr);
                        printf("BD-ADDR: %s\n\r", bd_addr_to_str(event_addr));
                        break;
                    }
					break;

				case HCI_EVENT_LINK_KEY_REQUEST:
					// deny link key request
                    printf("Link key request\n\r");
                    hci_event_link_key_request_get_bd_addr(packet, event_addr);
					hci_send_cmd(&hci_link_key_request_negative_reply, &event_addr);
					break;
					
				case HCI_EVENT_PIN_CODE_REQUEST:
					// inform about pin code request
                    printf("Pin code request - using '0000'\n\r");
                    hci_event_pin_code_request_get_bd_addr(packet, event_addr);
					hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000");
					break;
                
                case RFCOMM_EVENT_INCOMING_CONNECTION:
                    // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
                    rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr); 
                    rfcomm_channel_nr = rfcomm_event_incoming_connection_get_server_channel(packet);
                    rfcomm_channel_id = rfcomm_event_incoming_connection_get_rfcomm_cid(packet);
                    printf("RFCOMM channel %u requested for %s\n", rfcomm_channel_nr, bd_addr_to_str(event_addr));
                    rfcomm_accept_connection(rfcomm_channel_id);
                    break;
               
                case RFCOMM_EVENT_CHANNEL_OPENED:
                    // data: event(8), len(8), status (8), address (48), server channel(8), rfcomm_cid(16), max frame size(16)
                    if (rfcomm_event_channel_opened_get_status(packet)) {
                        printf("RFCOMM channel open failed, status %u\n", rfcomm_event_channel_opened_get_status(packet));
                    } else {
                        rfcomm_channel_id = rfcomm_event_channel_opened_get_rfcomm_cid(packet);
                        mtu = rfcomm_event_channel_opened_get_max_frame_size(packet);
                        printf("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u\n", rfcomm_channel_id, mtu);
                    }
                    break;
                    
                case RFCOMM_EVENT_CHANNEL_CLOSED:
                    rfcomm_channel_id = 0;
                    break;
                

                case 0xff:	// vendor specific -> ANT
                	
                	// vendor specific ant message
                	if (packet[2] != 0x00) break;
                	if (packet[3] != 0x05) break;

					event_code = packet[7];

                	printf("ANT Event: ");
                	printf_hexdump(packet, size);

					switch(event_code){
						
						case MESG_STARTUP_MESG_ID:
							// 2. assign channel
							ant_send_cmd(&ant_assign_channel, 0, 0x00, 0);
							break;

						case MESG_RESPONSE_EVENT_ID:
							// channel    = packet[8];
							message_id = packet[9];
							switch (message_id){
								case MESG_ASSIGN_CHANNEL_ID:
									// 3. set channel ID
									ant_send_cmd(&ant_channel_id, 0, 33, 1, 1);
									break; 
								case MESG_CHANNEL_ID_ID:
									// 4. open channel
									ant_send_cmd(&ant_open_channel, 0);
							}
							break;

						default:
							break;
					}
                	break;

				default:
					break;
			} 
            break;
                        
        default:
            break;
	}
}
示例#5
0
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
    UNUSED(channel);
    UNUSED(size);

    bd_addr_t addr;
    int i;
    int index;
    
    if (packet_type != HCI_EVENT_PACKET) return;

    uint8_t event = hci_event_packet_get_type(packet);

    switch(state){ 
        /* @text In INIT, an inquiry  scan is started, and the application transits to 
         * ACTIVE state.
         */
        case INIT:
            switch(event){
                case BTSTACK_EVENT_STATE:
                    if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){
                        start_scan();
                        state = ACTIVE;
                    }
                    break;
                default:
                    break;
            }
            break;

        /* @text In ACTIVE, the following events are processed:
         *  - GAP Inquiry result event: BTstack provides a unified inquiry result that contain
         *    Class of Device (CoD), page scan mode, clock offset. RSSI and name (from EIR) are optional.
         *  - Inquiry complete event: the remote name is requested for devices without a fetched 
         *    name. The state of a remote name can be one of the following: 
         *    REMOTE_NAME_REQUEST, REMOTE_NAME_INQUIRED, or REMOTE_NAME_FETCHED.
         *  - Remote name request complete event: the remote name is stored in the table and the 
         *    state is updated to REMOTE_NAME_FETCHED. The query of remote names is continued.
         */
        case ACTIVE:
            switch(event){

                case GAP_EVENT_INQUIRY_RESULT:
                    if (deviceCount >= MAX_DEVICES) break;  // already full
                    gap_event_inquiry_result_get_bd_addr(packet, addr);
                    index = getDeviceIndexForAddress(addr);
                    if (index >= 0) break;   // already in our list

                    memcpy(devices[deviceCount].address, addr, 6);
                    devices[deviceCount].pageScanRepetitionMode = gap_event_inquiry_result_get_page_scan_repetition_mode(packet);
                    devices[deviceCount].clockOffset = gap_event_inquiry_result_get_clock_offset(packet);
                    // print info
                    printf("Device found: %s ",  bd_addr_to_str(addr));
                    printf("with COD: 0x%06x, ", (unsigned int) gap_event_inquiry_result_get_class_of_device(packet));
                    printf("pageScan %d, ",      devices[deviceCount].pageScanRepetitionMode);
                    printf("clock offset 0x%04x",devices[deviceCount].clockOffset);
                    if (gap_event_inquiry_result_get_rssi_available(packet)){
                        printf(", rssi %d dBm", (int8_t) gap_event_inquiry_result_get_rssi(packet));
                    }
                    if (gap_event_inquiry_result_get_name_available(packet)){
                        char name_buffer[240];
                        int name_len = gap_event_inquiry_result_get_name_len(packet);
                        memcpy(name_buffer, gap_event_inquiry_result_get_name(packet), name_len);
                        name_buffer[name_len] = 0;
                        printf(", name '%s'", name_buffer);
                        devices[deviceCount].state = REMOTE_NAME_FETCHED;;
                    } else {
                        devices[deviceCount].state = REMOTE_NAME_REQUEST;
                    }
                    printf("\n");
                    deviceCount++;
                    break;

                case GAP_EVENT_INQUIRY_COMPLETE:
                    for (i=0;i<deviceCount;i++) {
                        // retry remote name request
                        if (devices[i].state == REMOTE_NAME_INQUIRED)
                            devices[i].state = REMOTE_NAME_REQUEST;
                    }
                    continue_remote_names();
                    break;

                case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
                    reverse_bd_addr(&packet[3], addr);
                    index = getDeviceIndexForAddress(addr);
                    if (index >= 0) {
                        if (packet[2] == 0) {
                            printf("Name: '%s'\n", &packet[9]);
                            devices[index].state = REMOTE_NAME_FETCHED;
                        } else {
                            printf("Failed to get name: page timeout\n");
                        }
                    }
                    continue_remote_names();
                    break;

                default:
                    break;
            }
            break;
            
        default:
            break;
    }
}
示例#6
0
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
//static void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){
	bd_addr_t addr;
	int i;
	int index;
	int numResponses;
	
	// printf("packet_handler: pt: 0x%02x, packet[0]: 0x%02x\n", packet_type, packet[0]);
	if (packet_type != HCI_EVENT_PACKET) return;

	uint8_t event = hci_event_packet_get_type(packet);

	switch(state){

		case INIT: 
			if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){
				bt_send_cmd(&hci_write_inquiry_mode, 0x01); // with RSSI
				state = W4_INQUIRY_MODE_COMPLETE;
			}
			break;

		case W4_INQUIRY_MODE_COMPLETE:
			switch(event){
				case HCI_EVENT_COMMAND_COMPLETE:
					if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_write_inquiry_mode)) {
						start_scan();
						state = ACTIVE;
					}
					break;
				case HCI_EVENT_COMMAND_STATUS:
					if (HCI_EVENT_IS_COMMAND_STATUS(packet, hci_write_inquiry_mode)) {
						printf("Ignoring error (0x%x) from hci_write_inquiry_mode.\n", packet[2]);
						start_scan();
						state = ACTIVE;
					}
					break;
				default:
					break;
			}

			break;
			
		case ACTIVE:
			switch(event){
				case HCI_EVENT_INQUIRY_RESULT:
				case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:{
                    numResponses = hci_event_inquiry_result_get_num_responses(packet);
                    int offset = 3;
                    for (i=0; i<numResponses && deviceCount < MAX_DEVICES;i++){
                        reverse_bd_addr(&packet[offset], addr);
                        offset += 6;
                        index = getDeviceIndexForAddress(addr);
                        if (index >= 0) continue;   // already in our list
                        memcpy(devices[deviceCount].address, addr, 6);

                        devices[deviceCount].pageScanRepetitionMode = packet[offset];
                        offset += 1;

                        if (event == HCI_EVENT_INQUIRY_RESULT){
                            offset += 2; // Reserved + Reserved
                            devices[deviceCount].classOfDevice = little_endian_read_24(packet, offset);
                            offset += 3;
                            devices[deviceCount].clockOffset =   little_endian_read_16(packet, offset) & 0x7fff;
                            offset += 2;
                            devices[deviceCount].rssi  = 0;
                        } else {
                            offset += 1; // Reserved
                            devices[deviceCount].classOfDevice = little_endian_read_24(packet, offset);
                            offset += 3;
                            devices[deviceCount].clockOffset =   little_endian_read_16(packet, offset) & 0x7fff;
                            offset += 2;
                            devices[deviceCount].rssi  = packet[offset];
                            offset += 1;
                        }
                        devices[deviceCount].state = REMOTE_NAME_REQUEST;
                        printf("Device found: %s with COD: 0x%06x, pageScan %d, clock offset 0x%04x, rssi 0x%02x\n", bd_addr_to_str(addr),
                                devices[deviceCount].classOfDevice, devices[deviceCount].pageScanRepetitionMode,
                                devices[deviceCount].clockOffset, devices[deviceCount].rssi);
                        deviceCount++;
                    }

                    break;
                }
					
				case HCI_EVENT_INQUIRY_COMPLETE:
					for (i=0;i<deviceCount;i++) {
						// retry remote name request
						if (devices[i].state == REMOTE_NAME_INQUIRED)
							devices[i].state = REMOTE_NAME_REQUEST;
					}
					if (has_more_remote_name_requests()){
						do_next_remote_name_request();
						break;
					} 
					start_scan();
					break;

				case DAEMON_EVENT_REMOTE_NAME_CACHED:
					reverse_bd_addr(&packet[3], addr);
					printf("Cached remote name for %s: '%s'\n", bd_addr_to_str(addr), &packet[9]);
					break;

				case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE:
					reverse_bd_addr(&packet[3], addr);
					index = getDeviceIndexForAddress(addr);
					if (index >= 0) {
						if (packet[2] == 0) {
							printf("Name: '%s'\n", &packet[9]);
							devices[index].state = REMOTE_NAME_FETCHED;
						} else {
							printf("Failed to get name: page timeout\n");
						}
					}
					if (has_more_remote_name_requests()){
						do_next_remote_name_request();
						break;
					} 
					start_scan();
					break;

				default:
					break;
			}
			break;
			
		default:
			break;
	}
}
示例#7
0
static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){

    UNUSED(channel);
    UNUSED(size);

    bd_addr_t event_addr;
    uint16_t psm;

    switch (packet_type){
        case HCI_EVENT_PACKET:
            switch (packet[0]) {
                case BTSTACK_EVENT_STATE:
                    // bt stack activated, get started 
                    if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){
                        printf("BTstack L2CAP Test Ready\n");
                        show_usage();
                    }
                    break;
                case HCI_EVENT_CONNECTION_COMPLETE:
                    handle = hci_event_connection_complete_get_connection_handle(packet);
                    break;

                case L2CAP_EVENT_CHANNEL_OPENED:
                    // inform about new l2cap connection
                    reverse_bd_addr(&packet[3], event_addr);
                    psm = little_endian_read_16(packet, 11); 
                    local_cid = little_endian_read_16(packet, 13); 
                    handle = little_endian_read_16(packet, 9);
                    if (packet[2] == 0) {
                        printf("Channel successfully opened: %s, handle 0x%02x, psm 0x%02x, local cid 0x%02x, remote cid 0x%02x\n",
                               bd_addr_to_str(event_addr), handle, psm, local_cid,  little_endian_read_16(packet, 15));
                    } else {
                        printf("L2CAP connection to device %s failed. status code %u\n", bd_addr_to_str(event_addr), packet[2]);
                    }
                    break;

                case L2CAP_EVENT_INCOMING_CONNECTION: {
                    uint16_t l2cap_cid  = little_endian_read_16(packet, 12);
                    if (l2cap_ertm){
                        printf("L2CAP Accepting incoming connection request in ERTM\n"); 
                        l2cap_accept_ertm_connection(l2cap_cid, &ertm_config, ertm_buffer, sizeof(ertm_buffer));
                    } else {
                        printf("L2CAP Accepting incoming connection request in Basic Mode\n"); 
                        l2cap_accept_connection(l2cap_cid);
                    }
                    break;
                }
                default:
                    break;
            }
            break;

        case L2CAP_DATA_PACKET:
            printf_hexdump(packet, size);
            break;

    }
    if (packet_type != HCI_EVENT_PACKET) return;


}