1*77ba3d3fSMatthias Ringwald /* 2*77ba3d3fSMatthias Ringwald * Copyright (C) 2018 BlueKitchen GmbH 3*77ba3d3fSMatthias Ringwald * 4*77ba3d3fSMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5*77ba3d3fSMatthias Ringwald * modification, are permitted provided that the following conditions 6*77ba3d3fSMatthias Ringwald * are met: 7*77ba3d3fSMatthias Ringwald * 8*77ba3d3fSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9*77ba3d3fSMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10*77ba3d3fSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11*77ba3d3fSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12*77ba3d3fSMatthias Ringwald * documentation and/or other materials provided with the distribution. 13*77ba3d3fSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14*77ba3d3fSMatthias Ringwald * contributors may be used to endorse or promote products derived 15*77ba3d3fSMatthias Ringwald * from this software without specific prior written permission. 16*77ba3d3fSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17*77ba3d3fSMatthias Ringwald * personal benefit and not for any commercial purpose or for 18*77ba3d3fSMatthias Ringwald * monetary gain. 19*77ba3d3fSMatthias Ringwald * 20*77ba3d3fSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21*77ba3d3fSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*77ba3d3fSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*77ba3d3fSMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24*77ba3d3fSMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25*77ba3d3fSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26*77ba3d3fSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27*77ba3d3fSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28*77ba3d3fSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29*77ba3d3fSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30*77ba3d3fSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*77ba3d3fSMatthias Ringwald * SUCH DAMAGE. 32*77ba3d3fSMatthias Ringwald * 33*77ba3d3fSMatthias Ringwald * Please inquire about commercial licensing options at 34*77ba3d3fSMatthias Ringwald * [email protected] 35*77ba3d3fSMatthias Ringwald * 36*77ba3d3fSMatthias Ringwald */ 37*77ba3d3fSMatthias Ringwald 38*77ba3d3fSMatthias Ringwald #ifndef __MESH_NETWORK 39*77ba3d3fSMatthias Ringwald #define __MESH_NETWORK 40*77ba3d3fSMatthias Ringwald 41*77ba3d3fSMatthias Ringwald #include "btstack_linked_list.h" 42*77ba3d3fSMatthias Ringwald #include "provisioning.h" 43*77ba3d3fSMatthias Ringwald #include "btstack_run_loop.h" 44*77ba3d3fSMatthias Ringwald 45*77ba3d3fSMatthias Ringwald #if defined __cplusplus 46*77ba3d3fSMatthias Ringwald extern "C" { 47*77ba3d3fSMatthias Ringwald #endif 48*77ba3d3fSMatthias Ringwald 49*77ba3d3fSMatthias Ringwald #define MESH_DEVICE_KEY_INDEX 0xffff 50*77ba3d3fSMatthias Ringwald 51*77ba3d3fSMatthias Ringwald #define MESH_NETWORK_PAYLOAD_MAX 29 52*77ba3d3fSMatthias Ringwald #define MESH_ACCESS_PAYLOAD_MAX 384 53*77ba3d3fSMatthias Ringwald 54*77ba3d3fSMatthias Ringwald #define MESH_ADDRESS_UNSASSIGNED 0x0000u 55*77ba3d3fSMatthias Ringwald #define MESH_ADDRESS_ALL_PROXIES 0xFFFCu 56*77ba3d3fSMatthias Ringwald #define MESH_ADDRESS_ALL_FRIENDS 0xFFFDu 57*77ba3d3fSMatthias Ringwald #define MESH_ADDRESS_ALL_RELAYS 0xFFFEu 58*77ba3d3fSMatthias Ringwald #define MESH_ADDRESS_ALL_NODES 0xFFFFu 59*77ba3d3fSMatthias Ringwald 60*77ba3d3fSMatthias Ringwald typedef enum { 61*77ba3d3fSMatthias Ringwald MESH_NETWORK_PDU_RECEIVED, 62*77ba3d3fSMatthias Ringwald MESH_NETWORK_PDU_SENT, 63*77ba3d3fSMatthias Ringwald } mesh_network_callback_type_t; 64*77ba3d3fSMatthias Ringwald 65*77ba3d3fSMatthias Ringwald typedef enum { 66*77ba3d3fSMatthias Ringwald MESH_PDU_TYPE_NETWORK = 0, 67*77ba3d3fSMatthias Ringwald MESH_PDU_TYPE_TRANSPORT, 68*77ba3d3fSMatthias Ringwald } mesh_pdu_type_t; 69*77ba3d3fSMatthias Ringwald 70*77ba3d3fSMatthias Ringwald typedef struct mesh_pdu { 71*77ba3d3fSMatthias Ringwald // allow for linked lists 72*77ba3d3fSMatthias Ringwald btstack_linked_item_t item; 73*77ba3d3fSMatthias Ringwald // type 74*77ba3d3fSMatthias Ringwald mesh_pdu_type_t pdu_type; 75*77ba3d3fSMatthias Ringwald } mesh_pdu_t; 76*77ba3d3fSMatthias Ringwald 77*77ba3d3fSMatthias Ringwald typedef struct mesh_network_pdu { 78*77ba3d3fSMatthias Ringwald mesh_pdu_t pdu_header; 79*77ba3d3fSMatthias Ringwald 80*77ba3d3fSMatthias Ringwald // callback 81*77ba3d3fSMatthias Ringwald void (*callback)(struct mesh_network_pdu * network_pdu); 82*77ba3d3fSMatthias Ringwald 83*77ba3d3fSMatthias Ringwald // meta data network layer 84*77ba3d3fSMatthias Ringwald uint16_t netkey_index; 85*77ba3d3fSMatthias Ringwald // meta data transport layer 86*77ba3d3fSMatthias Ringwald uint16_t appkey_index; 87*77ba3d3fSMatthias Ringwald // flags: bit 0 indicates Proxy PDU 88*77ba3d3fSMatthias Ringwald uint16_t flags; 89*77ba3d3fSMatthias Ringwald 90*77ba3d3fSMatthias Ringwald // pdu 91*77ba3d3fSMatthias Ringwald uint16_t len; 92*77ba3d3fSMatthias Ringwald uint8_t data[MESH_NETWORK_PAYLOAD_MAX]; 93*77ba3d3fSMatthias Ringwald } mesh_network_pdu_t; 94*77ba3d3fSMatthias Ringwald 95*77ba3d3fSMatthias Ringwald typedef struct { 96*77ba3d3fSMatthias Ringwald mesh_pdu_t pdu_header; 97*77ba3d3fSMatthias Ringwald 98*77ba3d3fSMatthias Ringwald // rx/tx: acknowledgement timer / segment transmission timer 99*77ba3d3fSMatthias Ringwald btstack_timer_source_t acknowledgement_timer; 100*77ba3d3fSMatthias Ringwald // rx: incomplete timer / tx: resend timer 101*77ba3d3fSMatthias Ringwald btstack_timer_source_t incomplete_timer; 102*77ba3d3fSMatthias Ringwald // block access 103*77ba3d3fSMatthias Ringwald uint32_t block_ack; 104*77ba3d3fSMatthias Ringwald // meta data network layer 105*77ba3d3fSMatthias Ringwald uint16_t netkey_index; 106*77ba3d3fSMatthias Ringwald // meta data transport layer 107*77ba3d3fSMatthias Ringwald uint16_t appkey_index; 108*77ba3d3fSMatthias Ringwald // transmic size 109*77ba3d3fSMatthias Ringwald uint8_t transmic_len; 110*77ba3d3fSMatthias Ringwald // akf - aid 111*77ba3d3fSMatthias Ringwald uint8_t akf_aid; 112*77ba3d3fSMatthias Ringwald // network pdu header 113*77ba3d3fSMatthias Ringwald uint8_t network_header[9]; 114*77ba3d3fSMatthias Ringwald // acknowledgement timer active 115*77ba3d3fSMatthias Ringwald uint8_t acknowledgement_timer_active; 116*77ba3d3fSMatthias Ringwald // incomplete timer active 117*77ba3d3fSMatthias Ringwald uint8_t incomplete_timer_active; 118*77ba3d3fSMatthias Ringwald // message complete 119*77ba3d3fSMatthias Ringwald uint8_t message_complete; 120*77ba3d3fSMatthias Ringwald // seq_zero for segmented messages 121*77ba3d3fSMatthias Ringwald uint16_t seq_zero; 122*77ba3d3fSMatthias Ringwald // pdu 123*77ba3d3fSMatthias Ringwald uint16_t len; 124*77ba3d3fSMatthias Ringwald uint8_t data[MESH_ACCESS_PAYLOAD_MAX]; 125*77ba3d3fSMatthias Ringwald } mesh_transport_pdu_t; 126*77ba3d3fSMatthias Ringwald 127*77ba3d3fSMatthias Ringwald 128*77ba3d3fSMatthias Ringwald /** 129*77ba3d3fSMatthias Ringwald * @brief Init Mesh Network Layer 130*77ba3d3fSMatthias Ringwald */ 131*77ba3d3fSMatthias Ringwald void mesh_network_init(void); 132*77ba3d3fSMatthias Ringwald 133*77ba3d3fSMatthias Ringwald /** 134*77ba3d3fSMatthias Ringwald * @brief Set higher layer Network PDU handler 135*77ba3d3fSMatthias Ringwald * @param packet_handler 136*77ba3d3fSMatthias Ringwald */ 137*77ba3d3fSMatthias Ringwald void mesh_network_set_higher_layer_handler(void (*packet_handler)(mesh_network_callback_type_t callback_type, mesh_network_pdu_t * network_pdu)); 138*77ba3d3fSMatthias Ringwald 139*77ba3d3fSMatthias Ringwald /** 140*77ba3d3fSMatthias Ringwald * @brief Set higher layer Proxy PDU handler 141*77ba3d3fSMatthias Ringwald * @param packet_handler 142*77ba3d3fSMatthias Ringwald */ 143*77ba3d3fSMatthias Ringwald void mesh_network_set_proxy_message_handler(void (*packet_handler)(mesh_network_callback_type_t callback_type, mesh_network_pdu_t * network_pdu)); 144*77ba3d3fSMatthias Ringwald 145*77ba3d3fSMatthias Ringwald /** 146*77ba3d3fSMatthias Ringwald * @brief Mark packet as processed 147*77ba3d3fSMatthias Ringwald * @param newtork_pdu received via call packet_handler 148*77ba3d3fSMatthias Ringwald */ 149*77ba3d3fSMatthias Ringwald void mesh_network_message_processed_by_higher_layer(mesh_network_pdu_t * network_pdu); 150*77ba3d3fSMatthias Ringwald 151*77ba3d3fSMatthias Ringwald /** 152*77ba3d3fSMatthias Ringwald * @brief Configure address filter 153*77ba3d3fSMatthias Ringwald */ 154*77ba3d3fSMatthias Ringwald void mesh_network_set_primary_element_address(uint16_t addr); 155*77ba3d3fSMatthias Ringwald 156*77ba3d3fSMatthias Ringwald /** 157*77ba3d3fSMatthias Ringwald * @brief Send network_pdu after encryption 158*77ba3d3fSMatthias Ringwald * @param network_pdu 159*77ba3d3fSMatthias Ringwald */ 160*77ba3d3fSMatthias Ringwald void mesh_network_send_pdu(mesh_network_pdu_t * network_pdu); 161*77ba3d3fSMatthias Ringwald 162*77ba3d3fSMatthias Ringwald /* 163*77ba3d3fSMatthias Ringwald * @brief Setup network pdu header 164*77ba3d3fSMatthias Ringwald * @param netkey_index 165*77ba3d3fSMatthias Ringwald * @param nid 166*77ba3d3fSMatthias Ringwald * @param ctl 167*77ba3d3fSMatthias Ringwald * @param ttl 168*77ba3d3fSMatthias Ringwald * @param seq 169*77ba3d3fSMatthias Ringwald * @param dst 170*77ba3d3fSMatthias Ringwald * @param transport_pdu_data 171*77ba3d3fSMatthias Ringwald * @param transport_pdu_len 172*77ba3d3fSMatthias Ringwald */ 173*77ba3d3fSMatthias Ringwald void mesh_network_setup_pdu(mesh_network_pdu_t * network_pdu, uint16_t netkey_index, uint8_t nid, uint8_t ctl, uint8_t ttl, uint32_t seq, uint16_t src, uint16_t dst, const uint8_t * transport_pdu_data, uint8_t transport_pdu_len); 174*77ba3d3fSMatthias Ringwald 175*77ba3d3fSMatthias Ringwald /** 176*77ba3d3fSMatthias Ringwald * Setup network pdu header without modifying len or payload 177*77ba3d3fSMatthias Ringwald * @param network_pdu 178*77ba3d3fSMatthias Ringwald * @param netkey_index 179*77ba3d3fSMatthias Ringwald * @param nid 180*77ba3d3fSMatthias Ringwald * @param ctl 181*77ba3d3fSMatthias Ringwald * @param ttl 182*77ba3d3fSMatthias Ringwald * @param seq 183*77ba3d3fSMatthias Ringwald * @param src 184*77ba3d3fSMatthias Ringwald * @param dest 185*77ba3d3fSMatthias Ringwald */ 186*77ba3d3fSMatthias Ringwald void mesh_network_setup_pdu_header(mesh_network_pdu_t * network_pdu, uint16_t netkey_index, uint8_t nid, uint8_t ctl, uint8_t ttl, uint32_t seq, uint16_t src, uint16_t dest); 187*77ba3d3fSMatthias Ringwald 188*77ba3d3fSMatthias Ringwald /** 189*77ba3d3fSMatthias Ringwald * @brief Validate network addresses 190*77ba3d3fSMatthias Ringwald * @param ctl 191*77ba3d3fSMatthias Ringwald * @param src 192*77ba3d3fSMatthias Ringwald * @param dst 193*77ba3d3fSMatthias Ringwald * @returns 1 if valid, 194*77ba3d3fSMatthias Ringwald */ 195*77ba3d3fSMatthias Ringwald int mesh_network_addresses_valid(uint8_t ctl, uint16_t src, uint16_t dst); 196*77ba3d3fSMatthias Ringwald 197*77ba3d3fSMatthias Ringwald /** 198*77ba3d3fSMatthias Ringwald * @brief Check if Unicast address 199*77ba3d3fSMatthias Ringwald * @param addr 200*77ba3d3fSMatthias Ringwald * @returns 1 if unicast 201*77ba3d3fSMatthias Ringwald */ 202*77ba3d3fSMatthias Ringwald int mesh_network_address_unicast(uint16_t addr); 203*77ba3d3fSMatthias Ringwald 204*77ba3d3fSMatthias Ringwald /** 205*77ba3d3fSMatthias Ringwald * @brief Check if Unicast address 206*77ba3d3fSMatthias Ringwald * @param addr 207*77ba3d3fSMatthias Ringwald * @returns 1 if unicast 208*77ba3d3fSMatthias Ringwald */ 209*77ba3d3fSMatthias Ringwald int mesh_network_address_group(uint16_t addr); 210*77ba3d3fSMatthias Ringwald 211*77ba3d3fSMatthias Ringwald /** 212*77ba3d3fSMatthias Ringwald * @brief Check if All Proxies address 213*77ba3d3fSMatthias Ringwald * @param addr 214*77ba3d3fSMatthias Ringwald * @returns 1 if all proxies 215*77ba3d3fSMatthias Ringwald */ 216*77ba3d3fSMatthias Ringwald int mesh_network_address_all_proxies(uint16_t addr); 217*77ba3d3fSMatthias Ringwald 218*77ba3d3fSMatthias Ringwald /** 219*77ba3d3fSMatthias Ringwald * @brief Check if All Nodes address 220*77ba3d3fSMatthias Ringwald * @param addr 221*77ba3d3fSMatthias Ringwald * @returns 1 if all nodes 222*77ba3d3fSMatthias Ringwald */ 223*77ba3d3fSMatthias Ringwald int mesh_network_address_all_nodes(uint16_t addr); 224*77ba3d3fSMatthias Ringwald 225*77ba3d3fSMatthias Ringwald /** 226*77ba3d3fSMatthias Ringwald * @brief Check if All Friends address 227*77ba3d3fSMatthias Ringwald * @param addr 228*77ba3d3fSMatthias Ringwald * @returns 1 if all friends 229*77ba3d3fSMatthias Ringwald */ 230*77ba3d3fSMatthias Ringwald int mesh_network_address_all_friends(uint16_t addr); 231*77ba3d3fSMatthias Ringwald 232*77ba3d3fSMatthias Ringwald /** 233*77ba3d3fSMatthias Ringwald * @brief Check if All Relays address 234*77ba3d3fSMatthias Ringwald * @param addr 235*77ba3d3fSMatthias Ringwald * @returns 1 if all relays 236*77ba3d3fSMatthias Ringwald */ 237*77ba3d3fSMatthias Ringwald int mesh_network_address_all_relays(uint16_t addr); 238*77ba3d3fSMatthias Ringwald 239*77ba3d3fSMatthias Ringwald 240*77ba3d3fSMatthias Ringwald /** 241*77ba3d3fSMatthias Ringwald * @brief Check if Virtual address 242*77ba3d3fSMatthias Ringwald * @param addr 243*77ba3d3fSMatthias Ringwald * @returns 1 if virtual 244*77ba3d3fSMatthias Ringwald */ 245*77ba3d3fSMatthias Ringwald int mesh_network_address_virtual(uint16_t addr); 246*77ba3d3fSMatthias Ringwald 247*77ba3d3fSMatthias Ringwald // buffer pool 248*77ba3d3fSMatthias Ringwald mesh_network_pdu_t * mesh_network_pdu_get(void); 249*77ba3d3fSMatthias Ringwald void mesh_network_pdu_free(mesh_network_pdu_t * network_pdu); 250*77ba3d3fSMatthias Ringwald 251*77ba3d3fSMatthias Ringwald // Mesh Network PDU Getter 252*77ba3d3fSMatthias Ringwald uint16_t mesh_network_control(mesh_network_pdu_t * network_pdu); 253*77ba3d3fSMatthias Ringwald uint8_t mesh_network_nid(mesh_network_pdu_t * network_pdu); 254*77ba3d3fSMatthias Ringwald uint8_t mesh_network_ttl(mesh_network_pdu_t * network_pdu); 255*77ba3d3fSMatthias Ringwald uint32_t mesh_network_seq(mesh_network_pdu_t * network_pdu); 256*77ba3d3fSMatthias Ringwald uint16_t mesh_network_src(mesh_network_pdu_t * network_pdu); 257*77ba3d3fSMatthias Ringwald uint16_t mesh_network_dst(mesh_network_pdu_t * network_pdu); 258*77ba3d3fSMatthias Ringwald int mesh_network_segmented(mesh_network_pdu_t * network_pdu); 259*77ba3d3fSMatthias Ringwald uint8_t * mesh_network_pdu_data(mesh_network_pdu_t * network_pdu); 260*77ba3d3fSMatthias Ringwald uint8_t mesh_network_pdu_len(mesh_network_pdu_t * network_pdu); 261*77ba3d3fSMatthias Ringwald 262*77ba3d3fSMatthias Ringwald void mesh_set_iv_index(uint32_t iv_index); 263*77ba3d3fSMatthias Ringwald uint32_t mesh_get_iv_index(void); 264*77ba3d3fSMatthias Ringwald 265*77ba3d3fSMatthias Ringwald // Testing only 266*77ba3d3fSMatthias Ringwald void mesh_network_received_message(const uint8_t * pdu_data, uint8_t pdu_len); 267*77ba3d3fSMatthias Ringwald void mesh_network_process_proxy_message(const uint8_t * pdu_data, uint8_t pdu_len); 268*77ba3d3fSMatthias Ringwald void mesh_network_encrypt_proxy_message(mesh_network_pdu_t * network_pdu, void (* callback)(mesh_network_pdu_t * callback)); 269*77ba3d3fSMatthias Ringwald void mesh_network_dump(void); 270*77ba3d3fSMatthias Ringwald void mesh_network_reset(void); 271*77ba3d3fSMatthias Ringwald 272*77ba3d3fSMatthias Ringwald void mesh_gatt_handle_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); 273*77ba3d3fSMatthias Ringwald 274*77ba3d3fSMatthias Ringwald #if defined __cplusplus 275*77ba3d3fSMatthias Ringwald } 276*77ba3d3fSMatthias Ringwald #endif 277*77ba3d3fSMatthias Ringwald 278*77ba3d3fSMatthias Ringwald #endif 279