Example #1
0
static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
    if (packet_type != ATT_DATA_PACKET) return;
    
    att_response_handle = handle;
    att_response_size = att_handle_request(&att_connection, packet, size, att_response_buffer);
    att_try_respond();
}
Example #2
0
// enable LE, setup ADV data
static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
    uint8_t adv_data[] = { 02, 01, 05,   03, 02, 0xf0, 0xff }; 

    sm_run();

    switch (packet_type) {
            
		case HCI_EVENT_PACKET:
			switch (packet[0]) {
				
                case BTSTACK_EVENT_STATE:
					// bt stack activated, get started
					if (packet[2] == HCI_STATE_WORKING) {
                        printf("Working!\n");
                        hci_send_cmd(&hci_le_set_advertising_data, sizeof(adv_data), adv_data);
					}
					break;
                
                case DAEMON_EVENT_HCI_PACKET_SENT:
                    att_try_respond();
                    break;
                    
                case HCI_EVENT_LE_META:
                    switch (packet[2]) {
                        case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
                            sm_response_handle = READ_BT_16(packet, 4);
                            sm_m_addr_type = packet[7];
                            BD_ADDR_COPY(sm_m_address, &packet[8]);
                            // TODO use non-null TK if appropriate
                            sm_reset_tk();
                            // TODO support private addresses
                            sm_s_addr_type = 0;
                            BD_ADDR_COPY(sm_s_address, hci_local_bd_addr());

                            // request security
                            sm_send_security_request = 1;

                            // reset connection MTU
                            att_connection.mtu = 23;
                            break;

                        case HCI_SUBEVENT_LE_LONG_TERM_KEY_REQUEST:
                            sm_s1(sm_tk, sm_m_random, sm_m_random, sm_s_ltk);
                            hci_send_cmd(&hci_le_long_term_key_request_reply, READ_BT_16(packet, 3), sm_s_ltk);
                            break;

                        default:
                            break;
                    }
                    break;

                case HCI_EVENT_ENCRYPTION_CHANGE:                
                    // distribute keys as requested by initiator
                    // TODO: handle initiator case here
                    if (sm_key_distribution_set & SM_KEYDIST_ENC_KEY)
                        sm_send_encryption_information = 1;
                    sm_send_master_identification = 1;
                    if (sm_key_distribution_set & SM_KEYDIST_ID_KEY)
                        sm_send_identity_information = 1;
                    sm_send_identity_address_information = 1;
                    if (sm_key_distribution_set & SM_KEYDIST_SIGN)
                        sm_send_signing_identification = 1;                
                    break;

                case HCI_EVENT_DISCONNECTION_COMPLETE:
                    att_response_handle = 0;
                    att_response_size = 0;
                    
                    // restart advertising
                    hci_send_cmd(&hci_le_set_advertise_enable, 1);
                    break;
                    
				case HCI_EVENT_COMMAND_COMPLETE:
				    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_parameters)){
                        // only needed for BLE Peripheral
                        hci_send_cmd(&hci_le_set_advertising_data, sizeof(adv_data), adv_data);
                        break;
					}
				    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_data)){
                        // only needed for BLE Peripheral
					   hci_send_cmd(&hci_le_set_scan_response_data, 10, adv_data);
					   break;
					}
				    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_scan_response_data)){
                        // only needed for BLE Peripheral
					   hci_send_cmd(&hci_le_set_advertise_enable, 1);
					   break;
					}
                    if (COMMAND_COMPLETE_EVENT(packet, hci_le_rand)){
                        switch (sm_state_responding){
                            case SM_STATE_C1_W4_RANDOM_A:
                                memcpy(&sm_s_random[0], &packet[6], 8);
                                hci_send_cmd(&hci_le_rand);
                                sm_state_responding++;
                                break;
                            case SM_STATE_C1_W4_RANDOM_B:
                                memcpy(&sm_s_random[8], &packet[6], 8);

                                // calculate s_confirm
                                sm_c1(sm_tk, sm_s_random, sm_preq, sm_pres, sm_m_addr_type, sm_s_addr_type, sm_m_address, sm_s_address, sm_s_confirm);
                                // send data
                                sm_state_responding = SM_STATE_C1_SEND;
                                break;
                            default:
                                break;
                        }
                        break;
                    }
			}
	}

    sm_run();
}
Example #3
0
// enable LE, setup ADV data
static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
    bd_addr_t addr;
    uint8_t adv_data[] = { 02, 01, 05,   03, 02, 0xf0, 0xff }; 
    switch (packet_type) {
            
		case HCI_EVENT_PACKET:
			switch (packet[0]) {
				
                case BTSTACK_EVENT_STATE:
					// bt stack activated, get started - set local name
					if (packet[2] == HCI_STATE_WORKING) {
					   printf("Working!\n");
						hci_send_cmd(&hci_read_local_supported_features);
					}
					break;
                
                case DAEMON_EVENT_HCI_PACKET_SENT:
                    att_try_respond();
                    break;
                    
                case HCI_EVENT_LE_META:
                    switch (packet[2]) {
                        case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
                            // reset connection MTU
                            att_connection.mtu = 23;
                            break;
                        default:
                            break;
                    }
                    break;

                case BTSTACK_EVENT_NR_CONNECTIONS_CHANGED:
				    if (packet[2]) {
                        printf("Connected.\n");
                    } else {
				        printf("Not connected.\n");
                    }
                    break;
                    
                case HCI_EVENT_DISCONNECTION_COMPLETE:
                    att_response_handle =0;
                    att_response_size = 0;
                    
                    // restart advertising
                    hci_send_cmd(&hci_le_set_advertise_enable, 1);
                    break;
                    
				case HCI_EVENT_COMMAND_COMPLETE:
					if (COMMAND_COMPLETE_EVENT(packet, hci_read_bd_addr)){
    					bt_flip_addr(addr, &packet[6]);
					    printf("BD ADDR: %s\n", bd_addr_to_str(addr));
						break;
					}
					if (COMMAND_COMPLETE_EVENT(packet, hci_read_local_supported_features)){
					     printf("Local supported features: %04X%04X\n", READ_BT_32(packet, 10), READ_BT_32(packet, 6));
                        hci_send_cmd(&hci_set_event_mask, 0xffffffff, 0x20001fff);
						break;
					}
					if (COMMAND_COMPLETE_EVENT(packet, hci_set_event_mask)){
                        hci_send_cmd(&hci_write_le_host_supported, 1, 1);
						break;
					}
					if (COMMAND_COMPLETE_EVENT(packet, hci_write_le_host_supported)){
				        hci_send_cmd(&hci_le_set_event_mask, 0xffffffff, 0xffffffff);
                    	break;
					}
					if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_event_mask)){
				        hci_send_cmd(&hci_le_read_buffer_size);
                    	break;
					}
				    if (COMMAND_COMPLETE_EVENT(packet, hci_le_read_buffer_size)){
					    printf("LE buffer size: %u, count %u\n", READ_BT_16(packet,6), packet[8]);
					   hci_send_cmd(&hci_le_read_supported_states);
					   break;
					}
				    if (COMMAND_COMPLETE_EVENT(packet, hci_le_read_supported_states)){
					   hci_send_cmd(&hci_le_set_advertising_parameters,  0x0400, 0x0800, 0, 0, 0, &addr, 0x07, 0);
					   break;
					}
				    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_parameters)){
					   hci_send_cmd(&hci_le_set_advertising_data, sizeof(adv_data), adv_data);
					   break;
					}
				    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_data)){
					   hci_send_cmd(&hci_le_set_scan_response_data, 10, adv_data);
					   break;
					}
				    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_scan_response_data)){
					   hci_send_cmd(&hci_le_set_advertise_enable, 1);
					   break;
					}
				    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertise_enable)){
                        hci_discoverable_control(1);
                        break;
					}
                    
			}
	}
}