2014-12-12 10:28:37 +00:00
/*
* Copyright ( C ) 2014 BlueKitchen GmbH
2015-02-06 11:25:18 +00:00
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
*
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission .
* 4. Any redistribution , use , or modification is done solely for
* personal benefit and not for any commercial purpose or for
* monetary gain .
*
* THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
* ` ` AS IS ' ' AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL MATTHIAS
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING ,
* BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS
* OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY ,
* OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE .
*
* Please inquire about commercial licensing options at
* contact @ bluekitchen - gmbh . com
*
*/
/*
* bnep_test . c
2014-12-12 10:28:37 +00:00
* based on panu_demo implemented by Ole Reinhardt < ole . reinhardt @ kernelconcepts . de >
*/
2016-01-21 15:41:16 +01:00
# include "btstack_config.h"
2014-12-12 10:28:37 +00:00
# include <stdint.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <sys/socket.h>
# include <net/if_arp.h>
# include <sys/ioctl.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <unistd.h>
# include <errno.h>
2016-04-01 14:50:10 +02:00
# include "btstack_event.h"
# include "btstack_memory.h"
2016-01-20 15:08:39 +01:00
# include "btstack_run_loop.h"
2016-04-01 14:50:10 +02:00
# include "classic/sdp_server.h"
2015-11-13 15:04:41 +01:00
# include "classic/sdp_util.h"
2014-12-12 10:28:37 +00:00
# include "hci.h"
2016-04-01 14:50:10 +02:00
# include "hci_cmd.h"
2014-12-12 10:28:37 +00:00
# include "hci_dump.h"
# include "l2cap.h"
# include "pan.h"
2017-05-25 22:26:15 +02:00
# include "btstack_stdin.h"
2014-12-12 10:28:37 +00:00
2015-07-16 14:57:16 +02:00
# define HARDWARE_TYPE_ETHERNET 0x0001
2015-07-16 12:25:28 +02:00
# define NETWORK_TYPE_IPv4 0x0800
# define NETWORK_TYPE_ARP 0x0806
2015-07-15 15:51:21 +02:00
# define NETWORK_TYPE_IPv6 0x86DD
2015-07-16 14:57:16 +02:00
2015-08-03 14:16:35 +02:00
# define IP_PROTOCOL_ICMP_IPv4 0x0001
# define IP_PROTOCOL_ICMP_IPv6 0x003a
# define IP_PROTOCOL_UDP 0x0011
# define IPv4_
2015-07-16 16:51:21 +02:00
2015-07-16 14:57:16 +02:00
# define ICMP_V4_TYPE_PING_REQUEST 0x08
# define ICMP_V4_TYPE_PING_RESPONSE 0x00
# define ICMP_V6_TYPE_PING_REQUEST 0x80
# define ICMP_V6_TYPE_PING_RESPONSE 0x81
# define ICMP_V6_TYPE_NEIGHBOR_SOLICITATION 0x87
# define ICMP_V6_TYPE_NEIGHBOR_ADVERTISEMENT 0x88
# define ARP_OPERATION_REQUEST 1
# define ARP_OPERATION_REPLY 2
2015-07-15 15:51:21 +02:00
2014-12-12 10:28:37 +00:00
// prototypes
2016-03-28 11:54:38 +02:00
static void show_usage ( void ) ;
2016-04-01 14:50:10 +02:00
static void packet_handler ( uint8_t packet_type , uint16_t channel , uint8_t * packet , uint16_t size ) ;
2014-12-12 10:28:37 +00:00
// Configuration for PTS
2015-01-04 00:19:23 +00:00
static bd_addr_t pts_addr = { 0x00 , 0x1b , 0xDC , 0x07 , 0x32 , 0xEF } ;
//static bd_addr_t pts_addr = {0xE0,0x06,0xE6,0xBB,0x95,0x79}; // Ole Thinkpad
2015-03-06 11:52:55 +00:00
// static bd_addr_t other_addr = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x16};
2014-12-12 13:57:03 +00:00
static bd_addr_t other_addr = { 0 , 0 , 0 , 0 , 0 , 0 } ;
2015-08-03 14:16:35 +02:00
2015-02-05 22:49:56 +00:00
// broadcast
static bd_addr_t broadcast_addr = { 0xff , 0xff , 0xff , 0xff , 0xff , 0xff } ;
2015-08-03 14:16:35 +02:00
// static bd_addr_t broadcast_addr = { 0x33, 0x33, 0x00, 0x01, 0x00, 0x03 };
2014-12-12 10:28:37 +00:00
2015-07-10 17:02:25 +02:00
// Outgoing: Must match PTS TSPX_UUID_src_addresss
static uint16_t bnep_src_uuid = 0x1115 ;
// Outgoing: Must match PTS TSPX_UUID_dest_address
static uint32_t bnep_dest_uuid = 0x1116 ;
// Incoming: Must macht PTS TSPX_UUID_dest_address
static uint16_t bnep_local_service_uuid = 0x1116 ;
2015-01-02 01:14:00 +00:00
// Sample network protocol type filter set:
// Ethernet type/length values the range 0x0000 - 0x05dc (Length), 0x05dd - 0x05ff (Reserved in IEEE 802.3)
// Ethernet type 0x0600-0xFFFF
static bnep_net_filter_t network_protocol_filter [ 3 ] = { { 0x0000 , 0x05dc } , { 0x05dd , 0x05ff } , { 0x0600 , 0xFFFF } } ;
// Sample multicast filter set:
// Multicast filter range set to 00:00:00:00:00:00 - 00:00:00:00:00:00 means: We do not want to receive any multicast traffic
// Ethernet type 0x0600-0xFFFF
static bnep_multi_filter_t multicast_filter [ 1 ] = { { { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } } } ;
2015-07-10 17:02:25 +02:00
2014-12-12 10:28:37 +00:00
// state
2014-12-12 13:57:03 +00:00
static bd_addr_t local_addr ;
static uint16_t bnep_l2cap_psm = 0x000f ;
2014-12-12 10:28:37 +00:00
static uint16_t bnep_cid = 0 ;
static uint8_t network_buffer [ BNEP_MTU_MIN ] ;
static size_t network_buffer_len = 0 ;
2015-07-16 12:25:28 +02:00
static uint8_t panu_sdp_record [ 200 ] ;
2016-02-03 21:55:36 +01:00
static btstack_packet_callback_registration_t hci_event_callback_registration ;
2016-02-11 14:37:22 +01:00
static void hexdumpf ( const void * data , int size ) {
char buffer [ 6 * 16 + 1 ] ;
int i , j ;
uint8_t low = 0x0F ;
uint8_t high = 0xF0 ;
j = 0 ;
for ( i = 0 ; i < size ; i + + ) {
uint8_t byte = ( ( uint8_t * ) data ) [ i ] ;
buffer [ j + + ] = ' 0 ' ;
buffer [ j + + ] = ' x ' ;
buffer [ j + + ] = char_for_nibble ( ( byte & high ) > > 4 ) ;
buffer [ j + + ] = char_for_nibble ( byte & low ) ;
buffer [ j + + ] = ' , ' ;
buffer [ j + + ] = ' ' ;
if ( j > = 6 * 16 ) {
buffer [ j ] = 0 ;
printf ( " %s \n " , buffer ) ;
j = 0 ;
}
}
if ( j ! = 0 ) {
buffer [ j ] = 0 ;
printf ( " %s \n " , buffer ) ;
}
}
2015-02-05 22:49:56 +00:00
static uint16_t setup_ethernet_header ( int src_compressed , int dst_compressed , int broadcast , uint16_t network_protocol_type ) {
2014-12-12 13:57:03 +00:00
// setup packet
int pos = 0 ;
2015-02-05 22:49:56 +00:00
// destination
if ( broadcast ) {
2016-02-10 17:09:24 +01:00
bd_addr_copy ( & network_buffer [ pos ] , broadcast_addr ) ;
2015-02-05 22:49:56 +00:00
} else {
2016-02-10 17:09:24 +01:00
bd_addr_copy ( & network_buffer [ pos ] , dst_compressed ? pts_addr : other_addr ) ;
2015-02-05 22:49:56 +00:00
}
2014-12-12 13:57:03 +00:00
pos + = 6 ;
2015-02-05 22:49:56 +00:00
// source
2016-02-10 17:09:24 +01:00
bd_addr_copy ( & network_buffer [ pos ] , src_compressed ? local_addr : other_addr ) ;
2014-12-12 13:57:03 +00:00
pos + = 6 ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( network_buffer , pos , network_protocol_type ) ;
2014-12-12 13:57:03 +00:00
pos + = 2 ;
2015-02-05 22:49:56 +00:00
return pos ;
}
static void send_buffer ( uint16_t pos ) {
network_buffer_len = pos ;
if ( bnep_can_send_packet_now ( bnep_cid ) ) {
bnep_send ( bnep_cid , network_buffer , network_buffer_len ) ;
network_buffer_len = 0 ;
}
}
2014-12-12 13:57:03 +00:00
2015-02-05 22:49:56 +00:00
static void send_ethernet_packet ( int src_compressed , int dst_compressed ) {
2015-07-15 15:51:21 +02:00
int pos = setup_ethernet_header ( src_compressed , dst_compressed , 0 , NETWORK_TYPE_IPv4 ) ; // IPv4
2014-12-12 13:57:03 +00:00
// dummy data Ethernet packet
int i ;
for ( i = 60 ; i > = 0 ; i - - ) {
network_buffer [ pos + + ] = i ;
}
// test data payload
for ( i = 0 ; i < 0x5a0 ; i + + ) {
network_buffer [ pos + + ] = i ;
}
2015-02-05 22:49:56 +00:00
send_buffer ( pos ) ;
2014-12-12 13:57:03 +00:00
}
2015-05-13 10:30:46 +02:00
static void set_network_protocol_filter ( void ) {
2015-01-02 01:14:00 +00:00
bnep_set_net_type_filter ( bnep_cid , network_protocol_filter , 3 ) ;
}
2015-05-13 10:30:46 +02:00
static void set_multicast_filter ( void ) {
2015-01-02 01:14:00 +00:00
bnep_set_multicast_filter ( bnep_cid , multicast_filter , 1 ) ;
}
2015-02-05 22:49:56 +00:00
/* From RFC 5227 - 2.1.1
A host probes to see if an address is already in use by broadcasting
an ARP Request for the desired address . The client MUST fill in the
' sender hardware address ' field of the ARP Request with the hardware
address of the interface through which it is sending the packet . The
' sender IP address ' field MUST be set to all zeroes ; this is to avoid
polluting ARP caches in other hosts on the same link in the case
where the address turns out to be already in use by another host .
The ' target hardware address ' field is ignored and SHOULD be set to
all zeroes . The ' target IP address ' field MUST be set to the address
being probed . An ARP Request constructed this way , with an all - zero
' sender IP address ' , is referred to as an ' ARP Probe ' .
*/
2015-07-16 12:53:09 +02:00
2015-05-13 10:30:46 +02:00
static void send_arp_probe_ipv4 ( void ) {
2015-02-05 22:49:56 +00:00
// "random address"
static uint8_t requested_address [ 4 ] = { 169 , 254 , 1 , 0 } ;
requested_address [ 3 ] + + ;
2015-07-16 14:57:16 +02:00
int pos = setup_ethernet_header ( 1 , 0 , 1 , NETWORK_TYPE_IPv4 ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( network_buffer , pos , HARDWARE_TYPE_ETHERNET ) ;
2015-02-05 22:49:56 +00:00
pos + = 2 ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( network_buffer , pos , NETWORK_TYPE_IPv4 ) ;
2015-02-05 22:49:56 +00:00
pos + = 2 ;
2015-07-16 12:53:09 +02:00
network_buffer [ pos + + ] = 6 ; // Hardware length (HLEN) - 6 MAC Address
network_buffer [ pos + + ] = 4 ; // Protocol length (PLEN) - 4 IPv4 Address
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( network_buffer , pos , ARP_OPERATION_REQUEST ) ;
2015-02-05 22:49:56 +00:00
pos + = 2 ;
2016-02-10 17:09:24 +01:00
bd_addr_copy ( & network_buffer [ pos ] , local_addr ) ; // Sender Hardware Address (SHA)
2015-02-05 22:49:56 +00:00
pos + = 6 ;
2016-03-27 22:49:03 +02:00
memset ( & network_buffer [ pos ] , 0 , 4 ) ; // Sender Protocol Adress (SPA)
2015-02-05 22:49:56 +00:00
pos + = 4 ;
2016-02-10 17:09:24 +01:00
bd_addr_copy ( & network_buffer [ pos ] , other_addr ) ; // Target Hardware Address (THA) (ignored for requests)
2015-02-05 22:49:56 +00:00
pos + = 6 ;
memcpy ( & network_buffer [ pos ] , requested_address , 4 ) ;
pos + = 4 ;
2015-03-06 11:52:55 +00:00
// magically, add some extra bytes for Ethernet padding
pos + = 18 ;
2015-02-05 22:49:56 +00:00
send_buffer ( pos ) ;
}
2015-07-15 16:44:26 +02:00
static uint16_t sum_ones_complement ( uint16_t a , uint16_t b ) {
uint32_t sum = a + b ;
while ( sum > 0xffff ) {
sum = ( sum & 0xffff ) + 1 ;
}
return sum ;
}
2015-07-15 15:51:21 +02:00
static uint16_t calc_internet_checksum ( uint8_t * data , int size ) {
uint32_t checksum = 0 ;
while ( size ) {
// add 16-bit value
2016-01-31 00:07:32 +01:00
checksum = sum_ones_complement ( checksum , big_endian_read_16 ( data , 0 ) ) ;
2015-07-15 15:51:21 +02:00
data + = 2 ;
size - = 2 ;
}
return checksum ;
}
2015-07-15 16:15:14 +02:00
static void send_ping_request_ipv4 ( void ) {
2015-08-03 14:16:35 +02:00
uint8_t ipv4_header [ ] = {
2015-07-15 16:15:14 +02:00
// ip
0x45 , 0x00 , 0x00 , 0x00 , // version + ihl, dscp } ecn, total len
0x00 , 0x00 , 0x00 , 0x00 , // identification (16), flags + fragment offset
0x01 , 0x01 , 0x00 , 0x00 , // time to live, procotol: icmp, checksum (16),
0x00 , 0x00 , 0x00 , 0x00 , // source IP address
0x00 , 0x00 , 0x00 , 0x00 , // destination IP address
} ;
uint8_t icmp_packet [ ] = {
// icmp
0x08 , 0x00 , 0x00 , 0x00 , // type: 0x08 PING Request
0x00 , 0x00 , 0x00 , 0x00
} ;
// ethernet header
int pos = setup_ethernet_header ( 1 , 0 , 0 , NETWORK_TYPE_IPv4 ) ; // IPv4
// ipv4
2015-08-03 14:16:35 +02:00
int total_length = sizeof ( ipv4_header ) + sizeof ( icmp_packet ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( ipv4_header , 2 , total_length ) ;
2015-08-03 14:16:35 +02:00
uint16_t ipv4_checksum = calc_internet_checksum ( ipv4_header , sizeof ( ipv4_header ) ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( ipv4_header , 10 , ipv4_checksum ) ;
2015-07-15 16:15:14 +02:00
// TODO: also set src/dest ip address
2015-08-03 14:16:35 +02:00
memcpy ( & network_buffer [ pos ] , ipv4_header , sizeof ( ipv4_header ) ) ;
pos + = sizeof ( ipv4_header ) ;
2015-07-15 16:15:14 +02:00
// icmp
uint16_t icmp_checksum = calc_internet_checksum ( icmp_packet , sizeof ( icmp_packet ) ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( icmp_packet , 2 , icmp_checksum ) ;
2015-07-15 16:15:14 +02:00
memcpy ( & network_buffer [ pos ] , icmp_packet , sizeof ( icmp_packet ) ) ;
pos + = sizeof ( icmp_packet ) ;
// send
send_buffer ( pos ) ;
}
2015-07-16 14:57:16 +02:00
static void send_ping_response_ipv4 ( void ) {
2015-08-03 14:16:35 +02:00
uint8_t ipv4_header [ ] = {
2015-07-16 14:57:16 +02:00
// ip
0x45 , 0x00 , 0x00 , 0x00 , // version + ihl, dscp } ecn, total len
0x00 , 0x00 , 0x00 , 0x00 , // identification (16), flags + fragment offset
0x01 , 0x01 , 0x00 , 0x00 , // time to live, procotol: icmp, checksum (16),
0x00 , 0x00 , 0x00 , 0x00 , // source IP address
0x00 , 0x00 , 0x00 , 0x00 , // destination IP address
} ;
uint8_t icmp_packet [ ] = {
// icmp
0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00
} ;
// ethernet header
int pos = setup_ethernet_header ( 1 , 0 , 0 , NETWORK_TYPE_IPv4 ) ; // IPv4
// ipv4
2015-08-03 14:16:35 +02:00
int total_length = sizeof ( ipv4_header ) + sizeof ( icmp_packet ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( ipv4_header , 2 , total_length ) ;
2015-08-03 14:16:35 +02:00
uint16_t ipv4_checksum = calc_internet_checksum ( ipv4_header , sizeof ( ipv4_header ) ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( ipv4_header , 10 , ipv4_checksum ) ;
2015-07-16 14:57:16 +02:00
// TODO: also set src/dest ip address
2015-08-03 14:16:35 +02:00
memcpy ( & network_buffer [ pos ] , ipv4_header , sizeof ( ipv4_header ) ) ;
pos + = sizeof ( ipv4_header ) ;
2015-07-16 14:57:16 +02:00
// icmp
uint16_t icmp_checksum = calc_internet_checksum ( icmp_packet , sizeof ( icmp_packet ) ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( icmp_packet , 2 , icmp_checksum ) ;
2015-07-16 14:57:16 +02:00
memcpy ( & network_buffer [ pos ] , icmp_packet , sizeof ( icmp_packet ) ) ;
pos + = sizeof ( icmp_packet ) ;
// send
send_buffer ( pos ) ;
}
2015-08-03 14:34:09 +02:00
/* Untested */
2015-07-15 16:44:26 +02:00
static void send_ping_request_ipv6 ( void ) {
2015-08-03 14:16:35 +02:00
uint8_t ipv6_header [ ] = {
2015-07-15 16:44:26 +02:00
// ip
0x60 , 0x00 , 0x00 , 0x00 , // version (4) + traffic class (8) + flow label (24)
0x00 , 0x00 , 58 , 0x01 , // payload length(16), next header = IPv6-ICMP, hop limit
0x00 , 0x00 , 0x00 , 0x00 , // source IP address
0x00 , 0x00 , 0x00 , 0x00 , // source IP address
0x00 , 0x00 , 0x00 , 0x00 , // source IP address
0x00 , 0x00 , 0x00 , 0x00 , // source IP address
0x00 , 0x00 , 0x00 , 0x00 , // destination IP address
0x00 , 0x00 , 0x00 , 0x00 , // destination IP address
0x00 , 0x00 , 0x00 , 0x00 , // destination IP address
0x00 , 0x00 , 0x00 , 0x00 , // destination IP address
} ;
uint8_t icmp_packet [ ] = {
// icmp
2015-07-16 14:57:16 +02:00
0x80 , 0x00 , 0x00 , 0x00 , // type: 0x80 PING Request, codde = 0, checksum(16)
2015-07-15 16:44:26 +02:00
0x00 , 0x00 , 0x00 , 0x00 // message
} ;
// ethernet header
int pos = setup_ethernet_header ( 1 , 0 , 0 , NETWORK_TYPE_IPv4 ) ; // IPv4
// ipv6
int payload_length = sizeof ( icmp_packet ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( ipv6_header , 4 , payload_length ) ;
2015-07-15 16:44:26 +02:00
// TODO: also set src/dest ip address
2015-08-03 14:16:35 +02:00
int checksum = calc_internet_checksum ( & ipv6_header [ 8 ] , 32 ) ;
2015-08-03 14:34:09 +02:00
checksum = sum_ones_complement ( checksum , payload_length ) ;
2015-07-15 16:44:26 +02:00
checksum = sum_ones_complement ( checksum , 58 < < 8 ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( icmp_packet , 2 , checksum ) ;
2015-08-03 14:16:35 +02:00
memcpy ( & network_buffer [ pos ] , ipv6_header , sizeof ( ipv6_header ) ) ;
pos + = sizeof ( ipv6_header ) ;
2015-07-15 16:44:26 +02:00
// icmp
uint16_t icmp_checksum = calc_internet_checksum ( icmp_packet , sizeof ( icmp_packet ) ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( icmp_packet , 2 , icmp_checksum ) ;
2015-07-15 16:44:26 +02:00
memcpy ( & network_buffer [ pos ] , icmp_packet , sizeof ( icmp_packet ) ) ;
pos + = sizeof ( icmp_packet ) ;
// send
send_buffer ( pos ) ;
}
2015-07-16 14:57:16 +02:00
static void send_ndp_probe_ipv6 ( void ) {
2015-07-15 15:51:21 +02:00
2015-08-03 14:16:35 +02:00
uint8_t ipv6_header [ ] = {
2015-07-15 15:51:21 +02:00
// ip
2015-08-03 14:34:09 +02:00
0x60 , 0x00 , 0x00 , 0x00 , // version (6) + traffic class (8) + flow label (24)
2015-07-16 14:57:16 +02:00
0x00 , 0x00 , 58 , 0x01 , // payload length(16), next header = IPv6-ICMP, hop limit
0x00 , 0x00 , 0x00 , 0x00 , // source IP address
0x00 , 0x00 , 0x00 , 0x00 , // source IP address
0x00 , 0x00 , 0x00 , 0x00 , // source IP address
2015-07-15 15:51:21 +02:00
0x00 , 0x00 , 0x00 , 0x00 , // source IP address
2015-07-16 14:57:16 +02:00
0xfe , 0x80 , 0x00 , 0x00 , // destination IP address
0x00 , 0x00 , 0x00 , 0x00 , // destination IP address
0x00 , 0x00 , 0x00 , 0x00 , // destination IP address
2015-07-15 15:51:21 +02:00
0x00 , 0x00 , 0x00 , 0x00 , // destination IP address
} ;
uint8_t icmp_packet [ ] = {
// icmp
2015-07-16 14:57:16 +02:00
0x87 , 0x00 , 0x00 , 0x00 , // type: 0x80 PING Request, code = 0, checksum(16)
0x00 , 0x00 , 0x00 , 0x00 // message
2015-07-15 15:51:21 +02:00
} ;
// ethernet header
2015-07-16 14:57:16 +02:00
int pos = setup_ethernet_header ( 1 , 0 , 0 , NETWORK_TYPE_IPv6 ) ;
// ipv6
int payload_length = sizeof ( icmp_packet ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( ipv6_header , 4 , payload_length ) ;
2015-07-16 14:57:16 +02:00
// source address ::
// dest addresss - Modified EUI-64
2015-08-03 14:16:35 +02:00
// ipv6_header[24..31] = FE80::
ipv6_header [ 32 ] = local_addr [ 0 ] ^ 0x2 ;
ipv6_header [ 33 ] = local_addr [ 1 ] ;
ipv6_header [ 34 ] = local_addr [ 2 ] ;
ipv6_header [ 35 ] = 0xff ;
ipv6_header [ 36 ] = 0xfe ;
ipv6_header [ 37 ] = local_addr [ 3 ] ;
ipv6_header [ 38 ] = local_addr [ 4 ] ;
ipv6_header [ 39 ] = local_addr [ 5 ] ;
int checksum = calc_internet_checksum ( & ipv6_header [ 8 ] , 32 ) ;
2015-08-03 14:34:09 +02:00
checksum = sum_ones_complement ( checksum , payload_length ) ;
checksum = sum_ones_complement ( checksum , ipv6_header [ 6 ] < < 8 ) ;
2015-08-03 14:16:35 +02:00
memcpy ( & network_buffer [ pos ] , ipv6_header , sizeof ( ipv6_header ) ) ;
pos + = sizeof ( ipv6_header ) ;
2015-07-15 15:51:21 +02:00
// icmp
uint16_t icmp_checksum = calc_internet_checksum ( icmp_packet , sizeof ( icmp_packet ) ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( icmp_packet , 2 , icmp_checksum ) ;
2015-07-15 15:51:21 +02:00
memcpy ( & network_buffer [ pos ] , icmp_packet , sizeof ( icmp_packet ) ) ;
pos + = sizeof ( icmp_packet ) ;
// send
2015-07-16 14:57:16 +02:00
send_buffer ( pos ) ;
2015-07-15 15:51:21 +02:00
}
2015-07-16 16:51:21 +02:00
static void send_llmnr_request_ipv4 ( void ) {
uint8_t ipv4_header [ ] = {
2015-08-03 14:16:35 +02:00
0x45 , 0x00 , 0x00 , 0x00 , // version + ihl, dscp } ecn, total len
2015-07-16 16:51:21 +02:00
0x00 , 0x00 , 0x00 , 0x00 , // identification (16), flags + fragment offset
0x01 , 0x11 , 0x00 , 0x00 , // time to live, procotol: UDP, checksum (16),
192 , 168 , 167 , 152 , // source IP address
2015-08-03 14:16:35 +02:00
224 , 0 , 0 , 252 , // destination IP address
2015-07-16 16:51:21 +02:00
} ;
uint8_t udp_header [ 8 ] ;
uint8_t llmnr_packet [ 12 ] ;
2015-08-03 14:40:47 +02:00
uint8_t dns_data [ ] = { 0x08 , 0x61 , 0x61 , 0x70 , 0x70 , 0x6c , 0x65 , 0x74 , 0x76 ,
0x05 , 0x6c , 0x6f , 0x63 , 0x61 , 0x6c , 0x00 , 0x00 ,
0x01 , 0x00 , 0x01 } ;
2015-07-16 16:51:21 +02:00
// ethernet header
int pos = setup_ethernet_header ( 1 , 0 , 0 , NETWORK_TYPE_IPv4 ) ; // IPv4
// ipv4
2015-08-03 14:40:47 +02:00
int total_length = sizeof ( ipv4_header ) + sizeof ( udp_header ) + sizeof ( llmnr_packet ) + sizeof ( dns_data ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( ipv4_header , 2 , total_length ) ;
2015-07-16 16:51:21 +02:00
uint16_t ipv4_checksum = calc_internet_checksum ( ipv4_header , sizeof ( ipv4_header ) ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( ipv4_header , 10 , ~ ipv4_checksum ) ;
2015-07-16 16:51:21 +02:00
// TODO: also set src/dest ip address
memcpy ( & network_buffer [ pos ] , ipv4_header , sizeof ( ipv4_header ) ) ;
pos + = sizeof ( ipv4_header ) ;
// udp packet
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( udp_header , 0 , 5355 ) ; // source port
big_endian_store_16 ( udp_header , 2 , 5355 ) ; // destination port
big_endian_store_16 ( udp_header , 4 , sizeof ( udp_header ) + sizeof ( llmnr_packet ) + sizeof ( dns_data ) ) ;
big_endian_store_16 ( udp_header , 6 , 0 ) ; // no checksum
2015-07-16 16:51:21 +02:00
memcpy ( & network_buffer [ pos ] , udp_header , sizeof ( udp_header ) ) ;
pos + = sizeof ( udp_header ) ;
// llmnr packet
2016-03-27 22:49:03 +02:00
memset ( llmnr_packet , 0 , sizeof ( llmnr_packet ) ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( llmnr_packet , 0 , 0x1234 ) ; // transaction id
big_endian_store_16 ( llmnr_packet , 4 , 1 ) ; // one query
2015-07-16 16:51:21 +02:00
memcpy ( & network_buffer [ pos ] , llmnr_packet , sizeof ( llmnr_packet ) ) ;
pos + = sizeof ( llmnr_packet ) ;
2015-08-03 14:40:47 +02:00
memcpy ( & network_buffer [ pos ] , dns_data , sizeof ( dns_data ) ) ;
pos + = sizeof ( dns_data ) ;
2015-07-16 16:51:21 +02:00
// send
send_buffer ( pos ) ;
}
2015-08-03 14:16:35 +02:00
static void send_llmnr_request_ipv6 ( void ) {
// https://msdn.microsoft.com/en-us/library/dd240361.aspx
uint8_t ipv6_header [ ] = {
0x60 , 0x00 , 0x00 , 0x00 , // version (6) + traffic class (8) + flow label (24)
0x00 , 0x00 , 17 , 0x01 , // payload length(16), next header = UDP, hop limit
0xfe , 0x80 , 0x00 , 0x00 , // source IP address
0x00 , 0x00 , 0x00 , 0x00 , // source IP address
0xd9 , 0xf6 , 0xce , 0x2e , // source IP address
0x48 , 0x75 , 0xab , 0x03 , // source IP address
0xff , 0x02 , 0x00 , 0x00 , // destination IP address
0x00 , 0x00 , 0x00 , 0x00 , // destination IP address
0x00 , 0x00 , 0x00 , 0x00 , // destination IP address
0x00 , 0x01 , 0x00 , 0x03 , // destination IP address
} ;
uint8_t udp_header [ 8 ] ;
uint8_t llmnr_packet [ 12 ] ;
uint8_t dns_data [ ] = { 0x08 , 0x61 , 0x61 , 0x70 , 0x70 , 0x6c , 0x65 , 0x74 , 0x76 ,
0x05 , 0x6c , 0x6f , 0x63 , 0x61 , 0x6c , 0x00 , 0x00 ,
0x01 , 0x00 , 0x01 } ;
int payload_length = sizeof ( udp_header ) + sizeof ( llmnr_packet ) + sizeof ( dns_data ) ;
// llmnr header
2016-03-27 22:49:03 +02:00
memset ( llmnr_packet , 0 , sizeof ( llmnr_packet ) ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( llmnr_packet , 0 , 0x1235 ) ; // transaction id
big_endian_store_16 ( llmnr_packet , 4 , 1 ) ; // one query
2015-08-03 14:16:35 +02:00
// ipv6 header
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( ipv6_header , 4 , payload_length ) ;
2015-08-03 14:16:35 +02:00
// udp header
2016-03-27 22:49:03 +02:00
memset ( udp_header , 0 , sizeof ( udp_header ) ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( udp_header , 0 , 5355 ) ; // source port
big_endian_store_16 ( udp_header , 2 , 5355 ) ; // destination port
big_endian_store_16 ( udp_header , 4 , payload_length ) ;
2015-08-03 14:16:35 +02:00
int checksum = calc_internet_checksum ( & ipv6_header [ 8 ] , 32 ) ;
2015-08-03 14:34:09 +02:00
checksum = sum_ones_complement ( checksum , payload_length ) ; // payload len
2015-08-03 14:16:35 +02:00
checksum = sum_ones_complement ( checksum , ipv6_header [ 6 ] < < 8 ) ; // next header
checksum = sum_ones_complement ( checksum , calc_internet_checksum ( udp_header , sizeof ( udp_header ) ) ) ;
checksum = sum_ones_complement ( checksum , calc_internet_checksum ( llmnr_packet , sizeof ( llmnr_packet ) ) ) ;
checksum = sum_ones_complement ( checksum , calc_internet_checksum ( dns_data , sizeof ( dns_data ) ) ) ;
2016-01-31 00:07:32 +01:00
big_endian_store_16 ( udp_header , 6 , ~ checksum ) ;
2015-08-03 14:16:35 +02:00
// ethernet header
int pos = setup_ethernet_header ( 1 , 0 , 1 , NETWORK_TYPE_IPv6 ) ; // IPv6
memcpy ( & network_buffer [ pos ] , ipv6_header , sizeof ( ipv6_header ) ) ;
pos + = sizeof ( ipv6_header ) ;
memcpy ( & network_buffer [ pos ] , udp_header , sizeof ( udp_header ) ) ;
pos + = sizeof ( udp_header ) ;
memcpy ( & network_buffer [ pos ] , llmnr_packet , sizeof ( llmnr_packet ) ) ;
pos + = sizeof ( llmnr_packet ) ;
memcpy ( & network_buffer [ pos ] , dns_data , sizeof ( dns_data ) ) ;
pos + = sizeof ( dns_data ) ;
// send
send_buffer ( pos ) ;
}
2015-07-16 16:51:21 +02:00
2015-05-13 10:30:46 +02:00
static void show_usage ( void ) {
2014-12-12 10:28:37 +00:00
printf ( " \n --- Bluetooth BNEP Test Console --- \n " ) ;
2015-07-10 17:02:25 +02:00
printf ( " Source UUID %04x (== TSPX_UUID_src_address) \n " , bnep_src_uuid ) ;
printf ( " Destination UUID %04x (== TSPX_UUID_dest_address) \n " , bnep_dest_uuid ) ;
printf ( " Local service UUID %04x (== TSPX_UUID_dest_address) \n " , bnep_local_service_uuid ) ;
2014-12-12 10:28:37 +00:00
printf ( " --- \n " ) ;
printf ( " p - connect to PTS \n " ) ;
printf ( " e - send general Ethernet packet \n " ) ;
printf ( " c - send compressed Ethernet packet \n " ) ;
printf ( " s - send source only compressed Ethernet packet \n " ) ;
printf ( " d - send destination only compressed Ethernet packet \n " ) ;
printf ( " f - set network filter \n " ) ;
printf ( " m - set multicast network filter \n " ) ;
printf ( " --- \n " ) ;
2015-07-15 16:15:14 +02:00
printf ( " 1 - send ICMP Ping Request IPv4 \n " ) ;
2015-07-15 16:44:26 +02:00
printf ( " 2 - send ICMP Ping Request IPv6 \n " ) ;
2015-07-16 12:53:09 +02:00
printf ( " 4 - send IPv4 ARP request \n " ) ;
2015-07-16 14:57:16 +02:00
printf ( " 6 - send IPv6 NDP request \n " ) ;
2015-07-16 16:51:21 +02:00
printf ( " 7 - send IPv4 LLMNR request \n " ) ;
printf ( " 8 - send IPv6 LLMNR request \n " ) ;
2015-02-05 22:49:56 +00:00
printf ( " --- \n " ) ;
2014-12-12 10:28:37 +00:00
printf ( " Ctrl-c - exit \n " ) ;
printf ( " --- \n " ) ;
}
2017-05-26 21:52:29 +02:00
static void stdin_process ( char c ) {
switch ( c ) {
2014-12-12 10:28:37 +00:00
case ' p ' :
2014-12-12 13:57:03 +00:00
printf ( " Connecting to PTS at %s... \n " , bd_addr_to_str ( pts_addr ) ) ;
2016-04-01 14:50:10 +02:00
bnep_connect ( & packet_handler , pts_addr , bnep_l2cap_psm , bnep_src_uuid , bnep_dest_uuid ) ;
2014-12-12 10:28:37 +00:00
break ;
case ' e ' :
2014-12-12 13:57:03 +00:00
printf ( " Sending general ethernet packet \n " ) ;
send_ethernet_packet ( 0 , 0 ) ;
2014-12-12 10:28:37 +00:00
break ;
case ' c ' :
2014-12-12 13:57:03 +00:00
printf ( " Sending compressed ethernet packet \n " ) ;
send_ethernet_packet ( 1 , 1 ) ;
2014-12-12 10:28:37 +00:00
break ;
case ' s ' :
2014-12-12 13:57:03 +00:00
printf ( " Sending src only compressed ethernet packet \n " ) ;
2015-07-10 16:21:56 +02:00
send_ethernet_packet ( 0 , 1 ) ;
2014-12-12 10:28:37 +00:00
break ;
case ' d ' :
2014-12-12 13:57:03 +00:00
printf ( " Sending dst only ethernet packet \n " ) ;
2015-07-10 16:21:56 +02:00
send_ethernet_packet ( 1 , 0 ) ;
2014-12-12 10:28:37 +00:00
break ;
case ' f ' :
2015-01-02 01:14:00 +00:00
printf ( " Setting network protocol filter \n " ) ;
set_network_protocol_filter ( ) ;
2014-12-12 10:28:37 +00:00
break ;
case ' m ' :
2015-01-02 01:14:00 +00:00
printf ( " Setting multicast filter \n " ) ;
set_multicast_filter ( ) ;
2014-12-12 10:28:37 +00:00
break ;
2015-07-15 16:15:14 +02:00
case ' 1 ' :
printf ( " Sending ICMP Ping via IPv4 \n " ) ;
send_ping_request_ipv4 ( ) ;
break ;
2015-07-15 16:44:26 +02:00
case ' 2 ' :
printf ( " Sending ICMP Ping via IPv6 \n " ) ;
send_ping_request_ipv6 ( ) ;
break ;
2015-02-05 22:49:56 +00:00
case ' 4 ' :
printf ( " Sending IPv4 ARP Probe \n " ) ;
send_arp_probe_ipv4 ( ) ;
break ;
case ' 6 ' :
printf ( " Sending IPv6 ARP Probe \n " ) ;
2015-07-16 14:57:16 +02:00
send_ndp_probe_ipv6 ( ) ;
2015-02-05 22:49:56 +00:00
break ;
2015-07-16 16:51:21 +02:00
case ' 7 ' :
printf ( " Sending IPv4 LLMNR Request \n " ) ;
send_llmnr_request_ipv4 ( ) ;
2015-03-06 11:52:55 +00:00
break ;
2015-07-16 16:51:21 +02:00
case ' 8 ' :
printf ( " Sending IPv6 LLMNR Request \n " ) ;
2015-08-03 14:16:35 +02:00
send_llmnr_request_ipv6 ( ) ;
2015-03-06 11:52:55 +00:00
break ;
2014-12-12 10:28:37 +00:00
default :
show_usage ( ) ;
break ;
}
}
/*************** PANU client routines *********************/
2015-11-13 22:03:53 +01:00
static void packet_handler ( uint8_t packet_type , uint16_t channel , uint8_t * packet , uint16_t size )
2014-12-12 10:28:37 +00:00
{
uint8_t event ;
bd_addr_t event_addr ;
2015-07-15 15:51:21 +02:00
bd_addr_t src_addr ;
bd_addr_t dst_addr ;
2014-12-12 10:28:37 +00:00
uint16_t uuid_source ;
uint16_t uuid_dest ;
uint16_t mtu ;
2015-07-15 15:51:21 +02:00
uint16_t network_type ;
2015-07-16 16:51:21 +02:00
uint8_t protocol_type ;
2015-07-15 15:51:21 +02:00
uint8_t icmp_type ;
int ihl ;
int payload_offset ;
2014-12-12 10:28:37 +00:00
switch ( packet_type ) {
case HCI_EVENT_PACKET :
event = packet [ 0 ] ;
switch ( event ) {
case BTSTACK_EVENT_STATE :
/* BT Stack activated, get started */
2016-04-01 12:27:13 +02:00
if ( btstack_event_state_get_state ( packet ) = = HCI_STATE_WORKING ) {
2014-12-12 10:28:37 +00:00
printf ( " BNEP Test ready \n " ) ;
2015-07-10 17:02:25 +02:00
show_usage ( ) ;
2014-12-12 10:28:37 +00:00
}
break ;
case HCI_EVENT_COMMAND_COMPLETE :
2016-02-11 16:12:55 +01:00
if ( HCI_EVENT_IS_COMMAND_COMPLETE ( packet , hci_read_bd_addr ) ) {
reverse_bd_addr ( & packet [ 6 ] , local_addr ) ;
2014-12-12 13:57:03 +00:00
printf ( " BD-ADDR: %s \n " , bd_addr_to_str ( local_addr ) ) ;
2014-12-12 10:28:37 +00:00
break ;
}
break ;
case HCI_EVENT_USER_CONFIRMATION_REQUEST :
// inform about user confirmation request
2016-01-31 00:07:32 +01:00
printf ( " SSP User Confirmation Request with numeric value '%06u' \n " , little_endian_read_32 ( packet , 8 ) ) ;
2014-12-12 10:28:37 +00:00
printf ( " SSP User Confirmation Auto accept \n " ) ;
break ;
2016-04-01 14:49:31 +02:00
2016-04-01 11:41:58 +02:00
case BNEP_EVENT_CHANNEL_OPENED :
2016-04-01 14:49:31 +02:00
if ( bnep_event_channel_opened_get_status ( packet ) ) {
printf ( " BNEP channel open failed, status %02x \n " , bnep_event_channel_opened_get_status ( packet ) ) ;
2014-12-12 10:28:37 +00:00
} else {
// data: event(8), len(8), status (8), bnep source uuid (16), bnep destination uuid (16), remote_address (48)
2016-04-01 16:07:44 +02:00
bnep_cid = bnep_event_channel_opened_get_bnep_cid ( packet ) ;
2016-04-01 14:49:31 +02:00
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 ) ;
2014-12-12 10:28:37 +00:00
//bt_flip_addr(event_addr, &packet[9]);
2016-04-01 14:50:10 +02:00
memcpy ( & event_addr , & packet [ 11 ] , sizeof ( bd_addr_t ) ) ;
2014-12-12 10:28:37 +00:00
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 ;
2016-03-31 15:18:39 +02:00
case BNEP_EVENT_CAN_SEND_NOW :
2014-12-12 10:28:37 +00:00
/* Check for parked network packets and send it out now */
2017-05-26 21:52:29 +02:00
if ( network_c_len > 0 ) {
2014-12-12 10:28:37 +00:00
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
2015-07-15 16:44:26 +02:00
// TODO: fix BNEP to return BD ADDR in little endian, to use these lines
2015-07-15 15:51:21 +02:00
// bt_flip_addr(dst_addr, &packet[0]);
// bt_flip_addr(src_addr, &packet[6]);
2015-07-15 16:44:26 +02:00
// instead of these
2015-07-15 15:51:21 +02:00
memcpy ( dst_addr , & packet [ 0 ] , 6 ) ;
memcpy ( src_addr , & packet [ 6 ] , 6 ) ;
2015-07-15 16:44:26 +02:00
// END TOOD
2016-01-31 00:07:32 +01:00
network_type = big_endian_read_16 ( packet , 12 ) ;
2014-12-12 10:28:37 +00:00
printf ( " BNEP packet received \n " ) ;
2015-07-15 16:44:26 +02:00
printf ( " Dst Addr: %s \n " , bd_addr_to_str ( dst_addr ) ) ;
printf ( " Src Addr: %s \n " , bd_addr_to_str ( src_addr ) ) ;
2015-07-15 15:51:21 +02:00
printf ( " Net Type: %04x \n " , network_type ) ;
2014-12-12 10:28:37 +00:00
// ignore the next 60 bytes
2015-07-16 16:51:21 +02:00
// hexdumpf(&packet[74], size - 74);
2015-07-15 15:51:21 +02:00
switch ( network_type ) {
case NETWORK_TYPE_IPv4 :
ihl = packet [ 14 ] & 0x0f ;
payload_offset = 14 + ( ihl < < 2 ) ;
2015-07-16 16:51:21 +02:00
// 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
2015-08-03 14:16:35 +02:00
printf ( " UDP IPv4 packet \n " ) ;
2015-07-16 16:51:21 +02:00
hexdumpf ( & packet [ payload_offset ] , size - payload_offset ) ;
break ;
default :
printf ( " Unknown IPv4 protocol type %x " , protocol_type ) ;
2015-07-15 15:51:21 +02:00
break ;
}
2015-07-16 16:51:21 +02:00
break ;
case NETWORK_TYPE_IPv6 :
2015-08-03 14:16:35 +02:00
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 ;
}
2015-07-16 16:51:21 +02:00
break ;
default :
printf ( " Unknown network type %x " , network_type ) ;
break ;
2015-07-15 15:51:21 +02:00
}
2014-12-12 10:28:37 +00:00
break ;
default :
break ;
}
}
int btstack_main ( int argc , const char * argv [ ] ) ;
int btstack_main ( int argc , const char * argv [ ] ) {
2016-02-03 21:55:36 +01:00
/* Register for HCI events */
2016-02-12 16:41:58 +01:00
hci_event_callback_registration . callback = & packet_handler ;
2016-02-03 21:55:36 +01:00
hci_add_event_handler ( & hci_event_callback_registration ) ;
2015-07-16 12:25:28 +02:00
2014-12-12 10:28:37 +00:00
/* Initialize L2CAP */
l2cap_init ( ) ;
/* Initialise BNEP */
bnep_init ( ) ;
2016-04-01 14:50:10 +02:00
bnep_register_service ( & packet_handler , bnep_local_service_uuid , 1691 ) ; /* Minimum L2CAP MTU for bnep is 1691 bytes */
2014-12-12 10:28:37 +00:00
2015-07-16 12:25:28 +02:00
/* Initialize SDP and add PANU record */
sdp_init ( ) ;
uint16_t network_packet_types [ ] = { NETWORK_TYPE_IPv4 , NETWORK_TYPE_ARP , 0 } ; // 0 as end of list
2016-03-17 11:28:46 +01:00
pan_create_panu_sdp_record ( panu_sdp_record , 0x10002 , network_packet_types , NULL , NULL , BNEP_SECURITY_NONE ) ;
2015-07-16 12:25:28 +02:00
printf ( " SDP service record size: %u \n " , de_get_len ( ( uint8_t * ) panu_sdp_record ) ) ;
2015-11-15 20:56:59 +01:00
sdp_register_service ( ( uint8_t * ) panu_sdp_record ) ;
2015-07-16 12:25:28 +02:00
2014-12-12 10:28:37 +00:00
/* Turn on the device */
hci_power_control ( HCI_POWER_ON ) ;
2016-02-18 17:12:57 +01:00
gap_discoverable_control ( 1 ) ;
2014-12-12 10:28:37 +00:00
2015-03-06 11:52:55 +00:00
btstack_stdin_setup ( stdin_process ) ;
2014-12-12 13:57:03 +00:00
2014-12-12 10:28:37 +00:00
return 0 ;
}
2015-02-06 11:25:18 +00:00
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */