예제 #1
0
int	hci_connected(uint8_t *packet, uint16_t size)
{
  bd_addr_t event_addr;
	
  // inform about new l2cap connection
  bt_flip_addr(event_addr, &packet[3]);
  uint16_t psm = READ_BT_16(packet, 11); 
  bt_accessor(0)->connflags.source_cid = READ_BT_16(packet, 13); 
  bt_accessor(0)->connflags.con_handle = READ_BT_16(packet, 9);
  if (packet[2] == 0) {
    printf("Channel successfully opened: ");
    print_bd_addr(event_addr);
    printf(", handle 0x%02x, psm 0x%02x, source cid 0x%02x, dest cid 0x%02x\n",
	   bt_accessor(0)->connflags.con_handle, psm, bt_accessor(0)->connflags.source_cid,  READ_BT_16(packet, 15));
    
    // send SABM command on dlci 0
    printf("Sending SABM #0\n");
    _bt_rfcomm_send_sabm(bt_accessor(0)->connflags.source_cid, 1, 0);
  } else {
    printf("L2CAP connection to device ");
    print_bd_addr(event_addr);
    printf(" failed. status code %u\n", packet[2]);
    return (1);
  }
  return (0);
}
예제 #2
0
int	hci_inquiry_result(uint8_t *packet, uint16_t size)
{
  int numResponses;
  bd_addr_t addr;
  t_device	res;
  int				i;
  
  numResponses = packet[2];
  for (i=0; i< numResponses && btscan_count_node(bt_accessor(0)->root) < MAX_DEVICES;i++)
    {
      bt_flip_addr(addr, &packet[3+i*6]);
      if (btscan_find_node(bt_accessor(0)->root, addr))
	continue;
      memset(&res, 0, sizeof(res));
      memcpy(res.address, addr, 6);
      res.pageScanRepetitionMode =    packet [3 + numResponses*(6)         + i*1];
      res.classOfDevice = READ_BT_24(packet, 3 + numResponses*(packet[0] == HCI_EVENT_INQUIRY_RESULT_WITH_RSSI ?
							       (6+1+1) :
							       (6+1+1+1))+ i*3);
      res.clockOffset = READ_BT_16(packet, 3 + numResponses*(packet[0] == HCI_EVENT_INQUIRY_RESULT_WITH_RSSI ?
							     (6+1+1+3) :
							     (6+1+1+1+3)) + i*2) & 0x7fff;
      res.rssi  = (packet[0] == HCI_EVENT_INQUIRY_RESULT_WITH_RSSI ? packet [3 + numResponses*(6+1+1+3+2) + i*1] : 0);
      res.state = 1;
      printf("Device found: "); 
      print_bd_addr(addr);
      printf(" with COD: 0x%06x, pageScan %u, clock offset 0x%04x\n", res.classOfDevice, res.pageScanRepetitionMode, res.clockOffset);
      bt_accessor(0)->root = btscan_add_node(bt_accessor(0)->root, &res);
    }
  return (0);
}
예제 #3
0
파일: mitm.c 프로젝트: darkfall/ArduinoBot
int main (int argc, const char * argv[]){
	// parse addr of Bob
	uint8_t ok = 0;
	if (argc >= 2) {
		ok = sscan_bd_addr((uint8_t *) argv[1], bob_addr);
	} 
	if (!ok) {
		printf("Usage: mitm 12:34:56:78:9A:BC\n");
		exit(0);
	}
	
	// start stack
	run_loop_init(RUN_LOOP_POSIX);
	int err = bt_open();
	if (err) {
		printf("Failed to open connection to BTdaemon\n");
		return err;
	}
	
	printf("BTstack-in-the-Middle started, will pretend to be BOB (");
	print_bd_addr(bob_addr);
	printf(")\n");
	
	bt_register_packet_handler(packet_handler);
	bt_send_cmd(&btstack_set_power_mode, HCI_POWER_ON );
	run_loop_execute();
	bt_close();
}
예제 #4
0
void comm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
	bd_addr_t event_addr;
	
	static uint8_t msc_resp_send = 0;
	static uint8_t msc_resp_received = 0;
	static uint8_t credits_used = 0;
	static uint8_t credits_free = 0;
	uint8_t packet_processed = 0;
	
	switch (packet_type) {
			
		case L2CAP_DATA_PACKET:
			// rfcomm: data[8] = addr
			// rfcomm: data[9] = command
			
			// 	received 1. message BT_RF_COMM_UA
			if (size == 4 && packet[1] == BT_RFCOMM_UA && packet[0] == 0x03){
				packet_processed++;
				printf("Received RFCOMM unnumbered acknowledgement for channel 0 - multiplexer working\n");
				printf("Sending UIH Parameter Negotiation Command\n");
				_bt_rfcomm_send_uih_pn_command(source_cid, 1, RFCOMM_CHANNEL_ID, 100);
			}
			
			//  received UIH Parameter Negotiation Response
			if (size == 14 && packet[1] == BT_RFCOMM_UIH && packet[3] == BT_RFCOMM_PN_RSP){
				packet_processed++;
				printf("UIH Parameter Negotiation Response\n");
				printf("Sending SABM #%u\n", RFCOMM_CHANNEL_ID);
				_bt_rfcomm_send_sabm(source_cid, 1, RFCOMM_CHANNEL_ID);
			}
			
			// 	received 2. message BT_RF_COMM_UA
			if (size == 4 && packet[1] == BT_RFCOMM_UA && packet[0] == ((RFCOMM_CHANNEL_ID << 3) | 3) ){
				packet_processed++;
				printf("Received RFCOMM unnumbered acknowledgement for channel %u - channel opened\n", RFCOMM_CHANNEL_ID);
				printf("Sending MSC  'I'm ready'\n");
				_bt_rfcomm_send_uih_msc_cmd(source_cid, 1, RFCOMM_CHANNEL_ID, 0x8d);  // ea=1,fc=0,rtc=1,rtr=1,ic=0,dv=1
			}
			
			// received BT_RFCOMM_MSC_CMD
			if (size == 8 && packet[1] == BT_RFCOMM_UIH && packet[3] == BT_RFCOMM_MSC_CMD){
				packet_processed++;
				printf("Received BT_RFCOMM_MSC_CMD\n");
				printf("Responding to 'I'm ready'\n");
				// fine with this
				uint8_t address = packet[0] | 2; // set response 
				packet[3]  = BT_RFCOMM_MSC_RSP;  //  "      "
				rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH, 0x30, (uint8_t*)&packet[3], 4);
				msc_resp_send = 1;
			}
			
			// received BT_RFCOMM_MSC_RSP
			if (size == 8 && packet[1] == BT_RFCOMM_UIH && packet[3] == BT_RFCOMM_MSC_RSP){
				packet_processed++;
				msc_resp_received = 1;
			}
			
			if (packet[1] == BT_RFCOMM_UIH && packet[0] == ((RFCOMM_CHANNEL_ID<<3)|1)){
				packet_processed++;
				credits_used++;
				if(DEBUG){
					printf("RX: address %02x, control %02x: ", packet[0], packet[1]);
					hexdump( (uint8_t*) &packet[3], size-4);
				}
				int written = 0;
				int length = size-4;
				int start_of_data = 3;
				//write data to fifo
				while (length) {
					if ((written = write(fifo_fd, &packet[start_of_data], length)) == -1) {
						printf("Error writing to FIFO\n");
					} else {
						length -= written;
					}
				}
			}
			
			if (packet[1] == BT_RFCOMM_UIH_PF && packet[0] == ((RFCOMM_CHANNEL_ID<<3)|1)){
				packet_processed++;
				credits_used++;
				if (!credits_free) {
					printf("Got %u credits, can send!\n", packet[2]);
				}
				credits_free = packet[2];
				if(DEBUG){
					printf("RX: address %02x, control %02x: ", packet[0], packet[1]);
					hexdump( (uint8_t *) &packet[4], size-5);				
				}
				int written = 0;
				int length = size-5;
				int start_of_data = 4;
				//write data to fifo
				while (length) {
					if ((written = write(fifo_fd, &packet[start_of_data], length)) == -1) {
						printf("Error writing to FIFO\n");
					} else {
						length -= written;
					}
				}
			}
			
			uint8_t send_credits_packet = 0;
			
			if (credits_used >= NR_CREDITS ) {
				send_credits_packet = 1;
				credits_used -= NR_CREDITS;
			}
			
			if (msc_resp_send && msc_resp_received) {
				send_credits_packet = 1;
				msc_resp_send = msc_resp_received = 0;
				
				printf("RFCOMM up and running!\n");
			}
			
			if (send_credits_packet) {
				// send 0x30 credits
				uint8_t initiator = 1;
				uint8_t address = (1 << 0) | (initiator << 1) |  (initiator << 1) | (RFCOMM_CHANNEL_ID << 3); 
				rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH_PF, NR_CREDITS, NULL, 0);
			}
			
			if (!packet_processed){
				// just dump data for now
				printf("??: address %02x, control %02x: ", packet[0], packet[1]);
				hexdump( packet, size );
			}
			
			break;
			
		case HCI_EVENT_PACKET:
			
			switch (packet[0]) {
					
				case BTSTACK_EVENT_POWERON_FAILED:
					// handle HCI init failure
					printf("HCI Init failed - make sure you have turned off Bluetooth in the System Settings\n");
					exit(1);
					break;		
					
				case BTSTACK_EVENT_STATE:
					// bt stack activated, get started - use authentication yes/no
					if (packet[2] == HCI_STATE_WORKING) {
						bt_send_cmd(&hci_write_authentication_enable, 1);
					}
					break;
					
				case HCI_EVENT_LINK_KEY_REQUEST:
					// link key request
					bt_flip_addr(event_addr, &packet[2]);
					bt_send_cmd(&hci_link_key_request_negative_reply, &event_addr);
					break;
					
				case HCI_EVENT_PIN_CODE_REQUEST:
					// inform about pin code request
					bt_flip_addr(event_addr, &packet[2]); 
					bt_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, PIN);
					printf("Please enter PIN %s on remote device\n", PIN);
					break;
					
				case L2CAP_EVENT_CHANNEL_OPENED:
					// inform about new l2cap connection
					bt_flip_addr(event_addr, &packet[3]);
					uint16_t psm = READ_BT_16(packet, 11); 
					source_cid = READ_BT_16(packet, 13); 
					con_handle = READ_BT_16(packet, 9);
					if (packet[2] == 0) {
						printf("Channel successfully opened: ");
						print_bd_addr(event_addr);
						printf(", handle 0x%02x, psm 0x%02x, source cid 0x%02x, dest cid 0x%02x\n",
							   con_handle, psm, source_cid,  READ_BT_16(packet, 15));
						
						// send SABM command on dlci 0
						printf("Sending SABM #0\n");
						_bt_rfcomm_send_sabm(source_cid, 1, 0);
					} else {
						printf("L2CAP connection to device ");
						print_bd_addr(event_addr);
						printf(" failed. status code %u\n", packet[2]);
						exit(1);
					}
					break;
					
				case HCI_EVENT_DISCONNECTION_COMPLETE:
					// connection closed -> quit test app
					printf("Basebank connection closed, exit.\n");
					exit(0);
					break;
					
				case HCI_EVENT_COMMAND_COMPLETE:
					// connect to RFCOMM device (PSM 0x03) at addr
					if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) {
						bt_send_cmd(&l2cap_create_channel, addr, 0x03);
					}
					break;
					
				default:
					// unhandled event
					if(DEBUG) printf("unhandled event : %02x\n", packet[0]);
					break;
			}
			break;
		default:
			// unhandled packet type
			if(DEBUG) printf("unhandled packet type : %02x\n", packet_type);
			break;
	}
}
예제 #5
0
파일: test.c 프로젝트: darkfall/ArduinoBot
void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
	
	bd_addr_t event_addr;

	switch (packet_type) {
			
		case L2CAP_DATA_PACKET:
			// just dump data for now
			printf("source cid %x -- ", channel);
			hexdump( packet, size );
	
			// HOME => disconnect
			if (packet[0] == 0xA1) {							// Status report
				if (packet[1] == 0x30 || packet[1] == 0x31) {   // type 0x30 or 0x31
					if (packet[3] & 0x080) {                   // homne button pressed
						printf("Disconnect baseband\n");
						bt_send_cmd(&hci_disconnect, con_handle, 0x13); // remote closed connection
					}
				}
			}
			break;
			
		case HCI_EVENT_PACKET:
			
			switch (packet[0]) {

				case BTSTACK_EVENT_POWERON_FAILED:
					printf("HCI Init failed - make sure you have turned off Bluetooth in the System Settings\n");
					exit(1);
					break;
					
				case BTSTACK_EVENT_STATE:
					// bt stack activated, get started - disable pairing
					if (packet[2] == HCI_STATE_WORKING) {
						bt_send_cmd(&hci_write_authentication_enable, 0);
					}
					break;
					
				case HCI_EVENT_LINK_KEY_REQUEST:
					printf("HCI_EVENT_LINK_KEY_REQUEST \n");
					// link key request
					bt_flip_addr(event_addr, &packet[2]); 
					bt_send_cmd(&hci_link_key_request_negative_reply, &event_addr);
					break;
					
				case HCI_EVENT_PIN_CODE_REQUEST:
					// inform about pin code request
					printf("Please enter PIN 0000 on remote device\n");
					bt_flip_addr(event_addr, &packet[2]); 
					bt_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000");
					break;
					
				case L2CAP_EVENT_CHANNEL_OPENED:
					// inform about new l2cap connection
					// inform about new l2cap connection
					bt_flip_addr(event_addr, &packet[3]);
					uint16_t psm = READ_BT_16(packet, 11); 
					uint16_t source_cid = READ_BT_16(packet, 13); 
					con_handle = READ_BT_16(packet, 9);
					if (packet[2] == 0) {
						printf("Channel successfully opened: ");
						print_bd_addr(event_addr);
						printf(", handle 0x%02x, psm 0x%02x, source cid 0x%02x, dest cid 0x%02x\n",
							   con_handle, psm, source_cid,  READ_BT_16(packet, 15));
						
						if (psm == 0x13) {
							source_cid_interrupt = source_cid;
							// interupt channel openedn succesfully, now open control channel, too.
							bt_send_cmd(&l2cap_create_channel, event_addr, 0x11);
						} else {
							source_cid_control = source_cid;
							// request acceleration data..
							// uint8_t setMode31[] = { 0x52, 0x12, 0x00, 0x31 };
							// bt_send_l2cap( source_cid, setMode31, sizeof(setMode31));
							// stop blinking
							// uint8_t setLEDs[] = { 0x52, 0x11, 0x10 };
							// bt_send_l2cap( source_cid, setLEDs, sizeof(setLEDs));
						}
					} else {
						printf("L2CAP connection to device ");
						print_bd_addr(event_addr);
						printf(" failed. status code %u\n", packet[2]);
						exit(1);
					}
					break;
					
				case HCI_EVENT_DISCONNECTION_COMPLETE:
					// connection closed -> quit tes app
					printf("Basebank connection closed, exit.\n");
					exit(0);
					break;
					
				case HCI_EVENT_COMMAND_COMPLETE:
					// connect to HID device (PSM 0x13) at addr
					if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) {
						bt_send_cmd(&l2cap_create_channel, addr, 0x13);
						printf("Press 1+2 on WiiMote to make it discoverable - Press HOME to disconnect later :)\n");
					}
					break;
					
				default:
					// other event
					break;
			}
			break;
			
		default:
			// other packet type
			break;
	}
}
예제 #6
0
void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
	
	bd_addr_t event_addr;
	uint16_t handle;
	uint16_t psm;
	uint16_t local_cid;
	uint16_t remote_cid;
	char pin[20];
	int i;
	
	switch (packet_type) {
			
		case L2CAP_DATA_PACKET:
			// just dump data for now
			printf("source cid %x -- ", channel);
			hexdump( packet, size );
			break;
			
		case HCI_EVENT_PACKET:
			
			switch (packet[0]) {

				case BTSTACK_EVENT_POWERON_FAILED:
					printf("HCI Init failed - make sure you have turned off Bluetooth in the System Settings\n");
					exit(1);
					break;
					
				case BTSTACK_EVENT_STATE:
					// bt stack activated, get started - set local name
					if (packet[2] == HCI_STATE_WORKING) {
						bt_send_cmd(&hci_write_authentication_enable, 0);
					}
					break;
					
				case L2CAP_EVENT_INCOMING_CONNECTION:
					// data: event(8), len(8), address(48), handle (16),  psm (16), source cid(16) dest cid(16)
					bt_flip_addr(event_addr, &packet[2]);
					handle     = READ_BT_16(packet, 8); 
					psm        = READ_BT_16(packet, 10); 
					local_cid  = READ_BT_16(packet, 12); 
					remote_cid = READ_BT_16(packet, 14); 
					printf("L2CAP_EVENT_INCOMING_CONNECTION ");
					print_bd_addr(event_addr);
					printf(", handle 0x%02x, psm 0x%02x, local cid 0x%02x, remote cid 0x%02x\n",
						   handle, psm, local_cid, remote_cid);

					// accept
					bt_send_cmd(&l2cap_accept_connection, local_cid);
					break;
					
				case HCI_EVENT_LINK_KEY_REQUEST:
					// link key request
					bt_flip_addr(event_addr, &packet[2]); 
					bt_send_cmd(&hci_link_key_request_negative_reply, &event_addr);
					break;
					
				case HCI_EVENT_PIN_CODE_REQUEST:
					// inform about pin code request
					printf("Please enter PIN here: ");
					fgets(pin, 20, stdin);
					i = strlen(pin)-1;
					if( pin[i] == '\n') { 
						pin[i] = '\0';
					}
					printf("PIN = '%s'\n", pin);
					bt_flip_addr(event_addr, &packet[2]); 
					bt_send_cmd(&hci_pin_code_request_reply, &event_addr, strlen(pin), pin);
					break;
					
				case L2CAP_EVENT_CHANNEL_OPENED:
					// inform about new l2cap connection
					bt_flip_addr(event_addr, &packet[3]);
					psm = READ_BT_16(packet, 11); 
					local_cid = READ_BT_16(packet, 13); 
					handle = READ_BT_16(packet, 9);
					if (packet[2] == 0) {
						printf("Channel successfully opened: ");
						print_bd_addr(event_addr);
						printf(", handle 0x%02x, psm 0x%02x, local cid 0x%02x, remote cid 0x%02x\n",
							   handle, psm, local_cid,  READ_BT_16(packet, 15));
						
						if (psm == PSM_HID_CONTROL){
							hid_control = local_cid;
						}
						if (psm == PSM_HID_INTERRUPT){
							hid_interrupt = local_cid;
						}
						if (hid_control && hid_interrupt){
							bt_send_cmd(&hci_switch_role_command, &event_addr, 0);
						}
					} else {
						printf("L2CAP connection to device ");
						print_bd_addr(event_addr);
						printf(" failed. status code %u\n", packet[2]);
						exit(1);
					}
					break;
				
				case HCI_EVENT_ROLE_CHANGE: {
					//HID Control: 0x06 bytes - SET_FEATURE_REPORT [ 53 F4 42 03 00 00 ]
					uint8_t set_feature_report[] = { 0x53, 0xf4, 0x42, 0x03, 0x00, 0x00}; 
					bt_send_l2cap(hid_control, (uint8_t*) &set_feature_report, sizeof(set_feature_report));
					break;
				}
										
				case HCI_EVENT_DISCONNECTION_COMPLETE:
					// connection closed -> quit tes app
					printf("Basebank connection closed\n");
					
					// exit(0);
					break;
					
				case HCI_EVENT_COMMAND_COMPLETE:
					if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) {
						bt_send_cmd(&hci_write_class_of_device, 0x2540);
					}
				default:
					// other event
					break;
			}
			break;
			
		default:
			// other packet type
			break;
	}
}
예제 #7
0
/* LISTING_START(GAPLEAdvDataParsing): Parsing advertising data */
static void dump_advertisement_data(uint8_t * adv_data, uint8_t adv_size){
    ad_context_t context;
    bd_addr_t address;
    uint8_t uuid_128[16];
    for (ad_iterator_init(&context, adv_size, adv_data) ; ad_iterator_has_more(&context) ; ad_iterator_next(&context)){
        uint8_t data_type = ad_iterator_get_data_type(&context);
        uint8_t size      = ad_iterator_get_data_len(&context);
        uint8_t * data    = ad_iterator_get_data(&context);
        
        if (data_type > 0 && data_type < 0x1B){
            printf("    %s: ", ad_types[data_type]);
        } 
        int i;
        // Assigned Numbers GAP
    
        switch (data_type){
            case 0x01: // Flags
                // show only first octet, ignore rest
                for (i=0; i<8;i++){
                    if (data[0] & (1<<i)){
                        printf("%s; ", flags[i]);
                    }

                }
                break;
            case 0x02: // Incomplete List of 16-bit Service Class UUIDs
            case 0x03: // Complete List of 16-bit Service Class UUIDs
            case 0x14: // List of 16-bit Service Solicitation UUIDs
                for (i=0; i<size;i+=2){
                    printf("%02X ", READ_BT_16(data, i));
                }
                break;
            case 0x04: // Incomplete List of 32-bit Service Class UUIDs
            case 0x05: // Complete List of 32-bit Service Class UUIDs
                for (i=0; i<size;i+=4){
                    printf("%04X ", READ_BT_32(data, i));
                }
                break;
            case 0x06: // Incomplete List of 128-bit Service Class UUIDs
            case 0x07: // Complete List of 128-bit Service Class UUIDs
            case 0x15: // List of 128-bit Service Solicitation UUIDs
                swap128(data, uuid_128);
                printUUID128(uuid_128);
                break;
            case 0x08: // Shortened Local Name
            case 0x09: // Complete Local Name
                for (i=0; i<size;i++){
                    printf("%c", (char)(data[i]));
                }
                break;
            case 0x0A: // Tx Power Level 
                printf("%d dBm", *(int8_t*)data);
                break;
            case 0x12: // Slave Connection Interval Range 
                printf("Connection Interval Min = %u ms, Max = %u ms", READ_BT_16(data, 0) * 5/4, READ_BT_16(data, 2) * 5/4);
                break;
            case 0x16: // Service Data 
                printf_hexdump(data, size);
                break;
            case 0x17: // Public Target Address
            case 0x18: // Random Target Address
                bt_flip_addr(address, data);
                print_bd_addr(address);
                break;
            case 0x19: // Appearance 
                // https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
                printf("%02X", READ_BT_16(data, 0) );
                break;
            case 0x1A: // Advertising Interval 
                printf("%u ms", READ_BT_16(data, 0) * 5/8 );
                break;
            case 0x3D: // 3D Information Data 
                printf_hexdump(data, size);
                break;
            case 0xFF: // Manufacturer Specific Data 
                break;
            case 0x0D: // Class of Device (3B)
            case 0x0E: // Simple Pairing Hash C (16B)
            case 0x0F: // Simple Pairing Randomizer R (16B) 
            case 0x10: // Device ID 
            case 0x11: // Security Manager TK Value (16B)
            default:
                printf("Unknown Advertising Data Type"); 
                break;
        }        
        printf("\n");
    }
    printf("\n");
}
예제 #8
0
파일: mitm.c 프로젝트: darkfall/ArduinoBot
void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){

	hci_con_handle_t acl_in;
	hci_con_handle_t acl_out;
	
	switch (packet_type){

		case HCI_ACL_DATA_PACKET:
			acl_in = READ_ACL_CONNECTION_HANDLE(packet);
			acl_out = 0;
			if (acl_in == alice_handle) {
				printf("Alice: ");
				hexdump( packet, size );
				printf("\n\n");
				acl_out = bob_handle;
			}
			if (acl_in == bob_handle) {
				printf("Bob: ");
				hexdump( packet, size );
				printf("\n\n");
				acl_out = alice_handle;
			}
			if (acl_out){
				bt_store_16( packet, 0, (READ_BT_16(packet, 0) & 0xf000) | acl_out);
				bt_send_acl(packet, size);
			}
			break;
			
		case HCI_EVENT_PACKET:
			
			switch(packet[0]){
					
				case BTSTACK_EVENT_STATE:
					// bt stack activated, get started - set COD
					if (packet[2] == HCI_STATE_WORKING) {
						bt_send_cmd(&hci_write_class_of_device, 0x7A020C);  // used on iPhone
					}
					break;
					
				case HCI_EVENT_EXTENDED_INQUIRY_RESPONSE:
					// process EIR responses
					if (packet[17]) {
						bt_flip_addr(temp_addr, &packet[3]); 
						if (BD_ADDR_CMP(temp_addr, bob_addr)) {
							printf("2. Got BOB's EIR. ");
							int i, k;
							bzero(bob_EIR, EIR_LEN);
							for (i=17, k=0;i<EIR_LEN && packet[i]; i += packet[i] + 1, k += bob_EIR[k] + 1){
								if (packet[i+1] == 0x09) {
									// complete name id -- use own
									bob_EIR[k+0] = 1 + strlen(NAME);
									bob_EIR[k+1] = 0x09;
									memcpy(&bob_EIR[k+2], NAME, strlen(NAME));
								} else {
									// vendor specific
									if (packet[i+1] == 0x0ff ) {
										bob_got_EIR = 1;
									}
									memcpy(&bob_EIR[k], &packet[i], packet[i]+1);
								}
							}
							hexdump(&bob_EIR, k);
							printf("\n\n");
							bob_clock_offset = READ_BT_16(packet, 14);
							bob_page_scan_repetition_mode = packet[9];
						}
						
						// stop inquiry
						// bt_send_cmd(&hci_inquiry_cancel);
					}
					break;
					
				case HCI_EVENT_CONNECTION_REQUEST:
					// accept incoming connections
					bt_flip_addr(temp_addr, &packet[2]); 
					if (BD_ADDR_CMP(temp_addr, bob_addr) ){
						printf("-> Connection request from BOB. Denying\n");
						// bt_send_cmd(&hci_accept_connection_request, &temp_addr, 1);
					} else {
						printf("-> Connection request from Alice. Sending Accept\n");
						bt_send_cmd(&hci_accept_connection_request, &temp_addr, 1);
					}
					break;
					
				case HCI_EVENT_CONNECTION_COMPLETE:
					// handle connections
					bt_flip_addr(temp_addr, &packet[5]); 
					if (packet[2] == 0){
						hci_con_handle_t incoming_handle =  READ_BT_16(packet, 3);
						if (BD_ADDR_CMP(temp_addr, bob_addr)){
							bob_handle = incoming_handle;
							printf("7. Connected to BOB (handle %u). Relaying data!\n", bob_handle);
						} else {
							alice_handle = incoming_handle;
							printf("6. Alice connected (handle %u). Connecting to BOB.\n", alice_handle);
							bt_send_cmd(&hci_create_connection, &bob_addr, 0x18, bob_page_scan_repetition_mode, 0, 0x8000 || bob_clock_offset, 0);
						}
					} else {
						printf("Connection complete status %u for connection", packet[2]);
						print_bd_addr(temp_addr);
						printf("\n");
					}
					break;

				case HCI_EVENT_PIN_CODE_REQUEST:
					// inform about pin code request
					printf("Please enter PIN 1234 on remote device\n");
					break;

				case HCI_EVENT_DISCONNECTION_COMPLETE:
					// connection closed -> quit test app
					printf("Basebank connection closed, exit.\n");
					exit(0);
					break;

				case HCI_EVENT_COMMAND_COMPLETE:
					
					// use pairing yes/no
					if ( COMMAND_COMPLETE_EVENT(packet, hci_write_class_of_device) ) {
						bt_send_cmd(&hci_write_authentication_enable, 0);
					}
					
					// allow Extended Inquiry responses
					if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) {
						bt_send_cmd(&hci_write_inquiry_mode, 2);
					}
					
					// get all events, including EIRs
					if ( COMMAND_COMPLETE_EVENT(packet, hci_write_inquiry_mode) ) {
						bt_send_cmd(&hci_set_event_mask, 0xffffffff, 0x1fffffff);
					}
					
					// fine with us, too
					if ( COMMAND_COMPLETE_EVENT(packet, hci_set_event_mask) ) {
						bt_send_cmd(&hci_write_simple_pairing_mode, 1);
					}
					
					// start inquiry
					if ( COMMAND_COMPLETE_EVENT(packet, hci_write_simple_pairing_mode) ) {
						// enable capure
						bt_send_cmd(&btstack_set_acl_capture_mode, 1);
						
						printf("1. Started inquiry.\n");
						bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, 15, 0);
					}
						// Connect to BOB
					if ( COMMAND_COMPLETE_EVENT(packet, hci_write_extended_inquiry_response) ) {
						printf("5. Waiting for Alice!...\n");
						// bt_send_cmd(&hci_write_scan_enable, 3); // 3 inq scan + page scan
						// bt_send_cmd(&hci_create_connection, &addr, 0x18, page_scan_repetition_mode, 0, 0x8000 || clock_offset, 0);
					}
					break;
					
				default:
					// Inquiry done, set EIR
					if (packet[0] == HCI_EVENT_INQUIRY_COMPLETE || COMMAND_COMPLETE_EVENT(packet, hci_inquiry_cancel)){
						if (!inquiry_done){
							inquiry_done = 1;
							printf("3. Inquiry Complete\n");
							if (bob_got_EIR){
								printf("4. Set EIR to Bob's.\n");
								bt_send_cmd(&hci_write_extended_inquiry_response, 0, bob_EIR);	
							} else {
								// failed to get BOB's EIR
							}
						}
					}
				break;
			}

		default:
			break;
	}
	
	
}