1*3deb3ec6SMatthias Ringwald /* 2*3deb3ec6SMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 3*3deb3ec6SMatthias Ringwald * 4*3deb3ec6SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5*3deb3ec6SMatthias Ringwald * modification, are permitted provided that the following conditions 6*3deb3ec6SMatthias Ringwald * are met: 7*3deb3ec6SMatthias Ringwald * 8*3deb3ec6SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9*3deb3ec6SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10*3deb3ec6SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11*3deb3ec6SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12*3deb3ec6SMatthias Ringwald * documentation and/or other materials provided with the distribution. 13*3deb3ec6SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14*3deb3ec6SMatthias Ringwald * contributors may be used to endorse or promote products derived 15*3deb3ec6SMatthias Ringwald * from this software without specific prior written permission. 16*3deb3ec6SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17*3deb3ec6SMatthias Ringwald * personal benefit and not for any commercial purpose or for 18*3deb3ec6SMatthias Ringwald * monetary gain. 19*3deb3ec6SMatthias Ringwald * 20*3deb3ec6SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21*3deb3ec6SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*3deb3ec6SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*3deb3ec6SMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24*3deb3ec6SMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25*3deb3ec6SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26*3deb3ec6SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27*3deb3ec6SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28*3deb3ec6SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29*3deb3ec6SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30*3deb3ec6SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*3deb3ec6SMatthias Ringwald * SUCH DAMAGE. 32*3deb3ec6SMatthias Ringwald * 33*3deb3ec6SMatthias Ringwald * Please inquire about commercial licensing options at 34*3deb3ec6SMatthias Ringwald * [email protected] 35*3deb3ec6SMatthias Ringwald * 36*3deb3ec6SMatthias Ringwald */ 37*3deb3ec6SMatthias Ringwald 38*3deb3ec6SMatthias Ringwald /* 39*3deb3ec6SMatthias Ringwald * bnep.h 40*3deb3ec6SMatthias Ringwald * Author: Ole Reinhardt <[email protected]> 41*3deb3ec6SMatthias Ringwald * 42*3deb3ec6SMatthias Ringwald */ 43*3deb3ec6SMatthias Ringwald 44*3deb3ec6SMatthias Ringwald #ifndef __BNEP_H 45*3deb3ec6SMatthias Ringwald #define __BNEP_H 46*3deb3ec6SMatthias Ringwald 47*3deb3ec6SMatthias Ringwald #include "utils.h" 48*3deb3ec6SMatthias Ringwald 49*3deb3ec6SMatthias Ringwald #include <stdint.h> 50*3deb3ec6SMatthias Ringwald 51*3deb3ec6SMatthias Ringwald #if defined __cplusplus 52*3deb3ec6SMatthias Ringwald extern "C" { 53*3deb3ec6SMatthias Ringwald #endif 54*3deb3ec6SMatthias Ringwald 55*3deb3ec6SMatthias Ringwald #ifndef ETHER_ADDR_LEN 56*3deb3ec6SMatthias Ringwald #define ETHER_ADDR_LEN sizeof(bd_addr_t) 57*3deb3ec6SMatthias Ringwald #endif 58*3deb3ec6SMatthias Ringwald 59*3deb3ec6SMatthias Ringwald #ifndef ETHERTYPE_VLAN 60*3deb3ec6SMatthias Ringwald #define ETHERTYPE_VLAN 0x8100 /* IEEE 802.1Q VLAN tag */ 61*3deb3ec6SMatthias Ringwald #endif 62*3deb3ec6SMatthias Ringwald 63*3deb3ec6SMatthias Ringwald #define BNEP_MTU_MIN 1691 64*3deb3ec6SMatthias Ringwald 65*3deb3ec6SMatthias Ringwald #define MAX_BNEP_NETFILTER 8 66*3deb3ec6SMatthias Ringwald #define MAX_BNEP_MULTICAST_FILTER 8 67*3deb3ec6SMatthias Ringwald #define MAX_BNEP_NETFILTER_OUT 421 68*3deb3ec6SMatthias Ringwald #define MAX_BNEP_MULTICAST_FULTER_OUT 140 69*3deb3ec6SMatthias Ringwald 70*3deb3ec6SMatthias Ringwald #define BNEP_EXT_FLAG 0x80 71*3deb3ec6SMatthias Ringwald #define BNEP_TYPE_MASK 0x7F 72*3deb3ec6SMatthias Ringwald #define BNEP_TYPE(header) ((header) & BNEP_TYPE_MASK) 73*3deb3ec6SMatthias Ringwald #define BNEP_HEADER_HAS_EXT(x) (((x) & BNEP_EXT_FLAG) == BNEP_EXT_FLAG) 74*3deb3ec6SMatthias Ringwald 75*3deb3ec6SMatthias Ringwald /* BNEP packet types */ 76*3deb3ec6SMatthias Ringwald #define BNEP_PKT_TYPE_GENERAL_ETHERNET 0x00 77*3deb3ec6SMatthias Ringwald #define BNEP_PKT_TYPE_CONTROL 0x01 78*3deb3ec6SMatthias Ringwald #define BNEP_PKT_TYPE_COMPRESSED_ETHERNET 0x02 79*3deb3ec6SMatthias Ringwald #define BNEP_PKT_TYPE_COMPRESSED_ETHERNET_SOURCE_ONLY 0x03 80*3deb3ec6SMatthias Ringwald #define BNEP_PKT_TYPE_COMPRESSED_ETHERNET_DEST_ONLY 0x04 81*3deb3ec6SMatthias Ringwald 82*3deb3ec6SMatthias Ringwald /* BNEP control types */ 83*3deb3ec6SMatthias Ringwald #define BNEP_CONTROL_TYPE_COMMAND_NOT_UNDERSTOOD 0x00 84*3deb3ec6SMatthias Ringwald #define BNEP_CONTROL_TYPE_SETUP_CONNECTION_REQUEST 0x01 85*3deb3ec6SMatthias Ringwald #define BNEP_CONTROL_TYPE_SETUP_CONNECTION_RESPONSE 0x02 86*3deb3ec6SMatthias Ringwald #define BNEP_CONTROL_TYPE_FILTER_NET_TYPE_SET 0x03 87*3deb3ec6SMatthias Ringwald #define BNEP_CONTROL_TYPE_FILTER_NET_TYPE_RESPONSE 0x04 88*3deb3ec6SMatthias Ringwald #define BNEP_CONTROL_TYPE_FILTER_MULTI_ADDR_SET 0x05 89*3deb3ec6SMatthias Ringwald #define BNEP_CONTROL_TYPE_FILTER_MULTI_ADDR_RESPONSE 0x06 90*3deb3ec6SMatthias Ringwald 91*3deb3ec6SMatthias Ringwald /* BNEP extension header types */ 92*3deb3ec6SMatthias Ringwald #define BNEP_EXT_HEADER_TYPE_EXTENSION_CONTROL 0x00 93*3deb3ec6SMatthias Ringwald 94*3deb3ec6SMatthias Ringwald /* BNEP setup response codes */ 95*3deb3ec6SMatthias Ringwald #define BNEP_RESP_SETUP_SUCCESS 0x0000 96*3deb3ec6SMatthias Ringwald #define BNEP_RESP_SETUP_INVALID_DEST_UUID 0x0001 97*3deb3ec6SMatthias Ringwald #define BNEP_RESP_SETUP_INVALID_SOURCE_UUID 0x0002 98*3deb3ec6SMatthias Ringwald #define BNEP_RESP_SETUP_INVALID_SERVICE_UUID_SIZE 0x0003 99*3deb3ec6SMatthias Ringwald #define BNEP_RESP_SETUP_CONNECTION_NOT_ALLOWED 0x0004 100*3deb3ec6SMatthias Ringwald 101*3deb3ec6SMatthias Ringwald /* BNEP filter response codes */ 102*3deb3ec6SMatthias Ringwald #define BNEP_RESP_FILTER_SUCCESS 0x0000 103*3deb3ec6SMatthias Ringwald #define BNEP_RESP_FILTER_UNSUPPORTED_REQUEST 0x0001 104*3deb3ec6SMatthias Ringwald #define BNEP_RESP_FILTER_ERR_INVALID_RANGE 0x0002 105*3deb3ec6SMatthias Ringwald #define BNEP_RESP_FILTER_ERR_TOO_MANY_FILTERS 0x0003 106*3deb3ec6SMatthias Ringwald #define BNEP_RESP_FILTER_ERR_SECURITY 0x0004 107*3deb3ec6SMatthias Ringwald 108*3deb3ec6SMatthias Ringwald typedef enum { 109*3deb3ec6SMatthias Ringwald BNEP_CHANNEL_STATE_CLOSED = 1, 110*3deb3ec6SMatthias Ringwald BNEP_CHANNEL_STATE_WAIT_FOR_CONNECTION_REQUEST, 111*3deb3ec6SMatthias Ringwald BNEP_CHANNEL_STATE_WAIT_FOR_CONNECTION_RESPONSE, 112*3deb3ec6SMatthias Ringwald BNEP_CHANNEL_STATE_CONNECTED, 113*3deb3ec6SMatthias Ringwald } BNEP_CHANNEL_STATE; 114*3deb3ec6SMatthias Ringwald 115*3deb3ec6SMatthias Ringwald typedef enum { 116*3deb3ec6SMatthias Ringwald BNEP_CHANNEL_STATE_VAR_NONE = 0, 117*3deb3ec6SMatthias Ringwald BNEP_CHANNEL_STATE_VAR_SND_NOT_UNDERSTOOD = 1 << 0, 118*3deb3ec6SMatthias Ringwald BNEP_CHANNEL_STATE_VAR_SND_CONNECTION_REQUEST = 1 << 1, 119*3deb3ec6SMatthias Ringwald BNEP_CHANNEL_STATE_VAR_SND_CONNECTION_RESPONSE = 1 << 2, 120*3deb3ec6SMatthias Ringwald BNEP_CHANNEL_STATE_VAR_SND_FILTER_NET_TYPE_SET = 1 << 3, 121*3deb3ec6SMatthias Ringwald BNEP_CHANNEL_STATE_VAR_SND_FILTER_NET_TYPE_RESPONSE = 1 << 4, 122*3deb3ec6SMatthias Ringwald BNEP_CHANNEL_STATE_VAR_SND_FILTER_MULTI_ADDR_SET = 1 << 5, 123*3deb3ec6SMatthias Ringwald BNEP_CHANNEL_STATE_VAR_SND_FILTER_MULTI_ADDR_RESPONSE = 1 << 6, 124*3deb3ec6SMatthias Ringwald } BNEP_CHANNEL_STATE_VAR; 125*3deb3ec6SMatthias Ringwald 126*3deb3ec6SMatthias Ringwald typedef enum { 127*3deb3ec6SMatthias Ringwald BNEP_CH_EVT_READY_TO_SEND, 128*3deb3ec6SMatthias Ringwald } BNEP_CHANNEL_EVENT; 129*3deb3ec6SMatthias Ringwald 130*3deb3ec6SMatthias Ringwald typedef struct bnep_channel_event { 131*3deb3ec6SMatthias Ringwald BNEP_CHANNEL_EVENT type; 132*3deb3ec6SMatthias Ringwald } bnep_channel_event_t; 133*3deb3ec6SMatthias Ringwald 134*3deb3ec6SMatthias Ringwald /* network protocol type filter */ 135*3deb3ec6SMatthias Ringwald typedef struct { 136*3deb3ec6SMatthias Ringwald uint16_t range_start; 137*3deb3ec6SMatthias Ringwald uint16_t range_end; 138*3deb3ec6SMatthias Ringwald } bnep_net_filter_t; 139*3deb3ec6SMatthias Ringwald 140*3deb3ec6SMatthias Ringwald /* multicast address filter */ 141*3deb3ec6SMatthias Ringwald typedef struct { 142*3deb3ec6SMatthias Ringwald uint8_t addr_start[ETHER_ADDR_LEN]; 143*3deb3ec6SMatthias Ringwald uint8_t addr_end[ETHER_ADDR_LEN]; 144*3deb3ec6SMatthias Ringwald } bnep_multi_filter_t; 145*3deb3ec6SMatthias Ringwald 146*3deb3ec6SMatthias Ringwald 147*3deb3ec6SMatthias Ringwald // info regarding multiplexer 148*3deb3ec6SMatthias Ringwald // note: spec mandates single multplexer per device combination 149*3deb3ec6SMatthias Ringwald typedef struct { 150*3deb3ec6SMatthias Ringwald // linked list - assert: first field 151*3deb3ec6SMatthias Ringwald linked_item_t item; 152*3deb3ec6SMatthias Ringwald 153*3deb3ec6SMatthias Ringwald BNEP_CHANNEL_STATE state; // Channel state 154*3deb3ec6SMatthias Ringwald 155*3deb3ec6SMatthias Ringwald BNEP_CHANNEL_STATE_VAR state_var; // State flag variable. Needed for asynchronous packet sending 156*3deb3ec6SMatthias Ringwald 157*3deb3ec6SMatthias Ringwald uint16_t max_frame_size; // incomming max. frame size 158*3deb3ec6SMatthias Ringwald void *connection; // client connection 159*3deb3ec6SMatthias Ringwald bd_addr_t local_addr; // locale drvice address 160*3deb3ec6SMatthias Ringwald bd_addr_t remote_addr; // remote device address 161*3deb3ec6SMatthias Ringwald uint16_t l2cap_cid; // l2cap channel id 162*3deb3ec6SMatthias Ringwald hci_con_handle_t con_handle; // hci connection handle 163*3deb3ec6SMatthias Ringwald 164*3deb3ec6SMatthias Ringwald uint16_t uuid_source; // Source UUID 165*3deb3ec6SMatthias Ringwald uint16_t uuid_dest; // Destination UUID 166*3deb3ec6SMatthias Ringwald 167*3deb3ec6SMatthias Ringwald uint8_t last_control_type; // type of last control package 168*3deb3ec6SMatthias Ringwald uint16_t response_code; // response code of last action (temp. storage for state machine) 169*3deb3ec6SMatthias Ringwald 170*3deb3ec6SMatthias Ringwald bnep_net_filter_t net_filter[MAX_BNEP_NETFILTER]; // network protocol filter, define fixed size for now 171*3deb3ec6SMatthias Ringwald uint16_t net_filter_count; 172*3deb3ec6SMatthias Ringwald 173*3deb3ec6SMatthias Ringwald bnep_net_filter_t *net_filter_out; // outgoint network protocol filter, must be statically allocated in the application 174*3deb3ec6SMatthias Ringwald uint16_t net_filter_out_count; 175*3deb3ec6SMatthias Ringwald 176*3deb3ec6SMatthias Ringwald bnep_multi_filter_t multicast_filter[MAX_BNEP_MULTICAST_FILTER]; // multicast address filter, define fixed size for now 177*3deb3ec6SMatthias Ringwald uint16_t multicast_filter_count; 178*3deb3ec6SMatthias Ringwald 179*3deb3ec6SMatthias Ringwald bnep_multi_filter_t *multicast_filter_out; // outgoing multicast address filter, must be statically allocated in the application 180*3deb3ec6SMatthias Ringwald uint16_t multicast_filter_out_count; 181*3deb3ec6SMatthias Ringwald 182*3deb3ec6SMatthias Ringwald 183*3deb3ec6SMatthias Ringwald timer_source_t timer; // Timeout timer 184*3deb3ec6SMatthias Ringwald int timer_active; // Is a timer running? 185*3deb3ec6SMatthias Ringwald int retry_count; // number of retries for CONTROL SETUP MSG 186*3deb3ec6SMatthias Ringwald // l2cap packet handler 187*3deb3ec6SMatthias Ringwald btstack_packet_handler_t packet_handler; 188*3deb3ec6SMatthias Ringwald } bnep_channel_t; 189*3deb3ec6SMatthias Ringwald 190*3deb3ec6SMatthias Ringwald /* Internal BNEP service descriptor */ 191*3deb3ec6SMatthias Ringwald typedef struct { 192*3deb3ec6SMatthias Ringwald linked_item_t item; // linked list - assert: first field 193*3deb3ec6SMatthias Ringwald void *connection; // client connection 194*3deb3ec6SMatthias Ringwald uint16_t service_uuid; // Service class: PANU, NAP, GN 195*3deb3ec6SMatthias Ringwald uint16_t max_frame_size; // incomming max. frame size 196*3deb3ec6SMatthias Ringwald 197*3deb3ec6SMatthias Ringwald // internal connection 198*3deb3ec6SMatthias Ringwald btstack_packet_handler_t packet_handler; 199*3deb3ec6SMatthias Ringwald } bnep_service_t; 200*3deb3ec6SMatthias Ringwald 201*3deb3ec6SMatthias Ringwald 202*3deb3ec6SMatthias Ringwald void bnep_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); 203*3deb3ec6SMatthias Ringwald 204*3deb3ec6SMatthias Ringwald /* API_START */ 205*3deb3ec6SMatthias Ringwald 206*3deb3ec6SMatthias Ringwald /** 207*3deb3ec6SMatthias Ringwald * @brief Set up BNEP. 208*3deb3ec6SMatthias Ringwald */ 209*3deb3ec6SMatthias Ringwald void bnep_init(void); 210*3deb3ec6SMatthias Ringwald 211*3deb3ec6SMatthias Ringwald /** 212*3deb3ec6SMatthias Ringwald * @brief Check if a data packet can be send out. 213*3deb3ec6SMatthias Ringwald */ 214*3deb3ec6SMatthias Ringwald int bnep_can_send_packet_now(uint16_t bnep_cid); 215*3deb3ec6SMatthias Ringwald 216*3deb3ec6SMatthias Ringwald /** 217*3deb3ec6SMatthias Ringwald * @brief Send a data packet. 218*3deb3ec6SMatthias Ringwald */ 219*3deb3ec6SMatthias Ringwald int bnep_send(uint16_t bnep_cid, uint8_t *packet, uint16_t len); 220*3deb3ec6SMatthias Ringwald 221*3deb3ec6SMatthias Ringwald /** 222*3deb3ec6SMatthias Ringwald * @brief Set the network protocol filter. 223*3deb3ec6SMatthias Ringwald */ 224*3deb3ec6SMatthias Ringwald int bnep_set_net_type_filter(uint16_t bnep_cid, bnep_net_filter_t *filter, uint16_t len); 225*3deb3ec6SMatthias Ringwald 226*3deb3ec6SMatthias Ringwald /** 227*3deb3ec6SMatthias Ringwald * @brief Set the multicast address filter. 228*3deb3ec6SMatthias Ringwald */ 229*3deb3ec6SMatthias Ringwald int bnep_set_multicast_filter(uint16_t bnep_cid, bnep_multi_filter_t *filter, uint16_t len); 230*3deb3ec6SMatthias Ringwald 231*3deb3ec6SMatthias Ringwald /** 232*3deb3ec6SMatthias Ringwald * @brief Set security level required for incoming connections, need to be called before registering services. 233*3deb3ec6SMatthias Ringwald */ 234*3deb3ec6SMatthias Ringwald void bnep_set_required_security_level(gap_security_level_t security_level); 235*3deb3ec6SMatthias Ringwald 236*3deb3ec6SMatthias Ringwald /** 237*3deb3ec6SMatthias Ringwald * @brief Register packet handler. 238*3deb3ec6SMatthias Ringwald */ 239*3deb3ec6SMatthias Ringwald void bnep_register_packet_handler(void (*handler)(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)); 240*3deb3ec6SMatthias Ringwald 241*3deb3ec6SMatthias Ringwald /** 242*3deb3ec6SMatthias Ringwald * @brief Creates BNEP connection (channel) to a given server on a remote device with baseband address. A new baseband connection will be initiated if necessary. 243*3deb3ec6SMatthias Ringwald */ 244*3deb3ec6SMatthias Ringwald int bnep_connect(void * connection, bd_addr_t addr, uint16_t l2cap_psm, uint16_t uuid_src, uint16_t uuid_dest); 245*3deb3ec6SMatthias Ringwald 246*3deb3ec6SMatthias Ringwald /** 247*3deb3ec6SMatthias Ringwald * @brief Disconnects BNEP channel with given identifier. 248*3deb3ec6SMatthias Ringwald */ 249*3deb3ec6SMatthias Ringwald void bnep_disconnect(bd_addr_t addr); 250*3deb3ec6SMatthias Ringwald 251*3deb3ec6SMatthias Ringwald /** 252*3deb3ec6SMatthias Ringwald * @brief Registers BNEP service, set a maximum frame size and assigns a packet handler. On embedded systems, use NULL for connection parameter. 253*3deb3ec6SMatthias Ringwald */ 254*3deb3ec6SMatthias Ringwald void bnep_register_service(void * connection, uint16_t service_uuid, uint16_t max_frame_size); 255*3deb3ec6SMatthias Ringwald 256*3deb3ec6SMatthias Ringwald /** 257*3deb3ec6SMatthias Ringwald * @brief Unregister BNEP service. 258*3deb3ec6SMatthias Ringwald */ 259*3deb3ec6SMatthias Ringwald void bnep_unregister_service(uint16_t service_uuid); 260*3deb3ec6SMatthias Ringwald /* API_END */ 261*3deb3ec6SMatthias Ringwald 262*3deb3ec6SMatthias Ringwald #if defined __cplusplus 263*3deb3ec6SMatthias Ringwald } 264*3deb3ec6SMatthias Ringwald #endif 265*3deb3ec6SMatthias Ringwald 266*3deb3ec6SMatthias Ringwald #endif // __BNEP_H 267