1*f4854a5eSMatthias Ringwald /* 2*f4854a5eSMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 3*f4854a5eSMatthias Ringwald * 4*f4854a5eSMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5*f4854a5eSMatthias Ringwald * modification, are permitted provided that the following conditions 6*f4854a5eSMatthias Ringwald * are met: 7*f4854a5eSMatthias Ringwald * 8*f4854a5eSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9*f4854a5eSMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10*f4854a5eSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11*f4854a5eSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12*f4854a5eSMatthias Ringwald * documentation and/or other materials provided with the distribution. 13*f4854a5eSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14*f4854a5eSMatthias Ringwald * contributors may be used to endorse or promote products derived 15*f4854a5eSMatthias Ringwald * from this software without specific prior written permission. 16*f4854a5eSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17*f4854a5eSMatthias Ringwald * personal benefit and not for any commercial purpose or for 18*f4854a5eSMatthias Ringwald * monetary gain. 19*f4854a5eSMatthias Ringwald * 20*f4854a5eSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21*f4854a5eSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*f4854a5eSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*f4854a5eSMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24*f4854a5eSMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25*f4854a5eSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26*f4854a5eSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27*f4854a5eSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28*f4854a5eSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29*f4854a5eSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30*f4854a5eSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*f4854a5eSMatthias Ringwald * SUCH DAMAGE. 32*f4854a5eSMatthias Ringwald * 33*f4854a5eSMatthias Ringwald * Please inquire about commercial licensing options at 34*f4854a5eSMatthias Ringwald * [email protected] 35*f4854a5eSMatthias Ringwald * 36*f4854a5eSMatthias Ringwald */ 37*f4854a5eSMatthias Ringwald 38*f4854a5eSMatthias Ringwald #define __BTSTACK_FILE__ "mesh_iv_index_seq_number.c" 39*f4854a5eSMatthias Ringwald 40*f4854a5eSMatthias Ringwald #include "mesh/mesh_iv_index_seq_number.h" 41*f4854a5eSMatthias Ringwald 42*f4854a5eSMatthias Ringwald #include "btstack_debug.h" 43*f4854a5eSMatthias Ringwald 44*f4854a5eSMatthias Ringwald static uint32_t global_iv_index; 45*f4854a5eSMatthias Ringwald static int global_iv_update_active; 46*f4854a5eSMatthias Ringwald 47*f4854a5eSMatthias Ringwald static uint32_t sequence_number_current; 48*f4854a5eSMatthias Ringwald 49*f4854a5eSMatthias Ringwald void mesh_set_iv_index(uint32_t iv_index){ 50*f4854a5eSMatthias Ringwald global_iv_index = iv_index; 51*f4854a5eSMatthias Ringwald } 52*f4854a5eSMatthias Ringwald 53*f4854a5eSMatthias Ringwald uint32_t mesh_get_iv_index(void){ 54*f4854a5eSMatthias Ringwald return global_iv_index; 55*f4854a5eSMatthias Ringwald } 56*f4854a5eSMatthias Ringwald 57*f4854a5eSMatthias Ringwald uint32_t mesh_get_iv_index_for_tx(void){ 58*f4854a5eSMatthias Ringwald if (global_iv_update_active){ 59*f4854a5eSMatthias Ringwald return global_iv_index - 1; 60*f4854a5eSMatthias Ringwald } else { 61*f4854a5eSMatthias Ringwald return global_iv_index; 62*f4854a5eSMatthias Ringwald } 63*f4854a5eSMatthias Ringwald } 64*f4854a5eSMatthias Ringwald 65*f4854a5eSMatthias Ringwald int mesh_iv_update_active(void){ 66*f4854a5eSMatthias Ringwald return global_iv_update_active; 67*f4854a5eSMatthias Ringwald } 68*f4854a5eSMatthias Ringwald 69*f4854a5eSMatthias Ringwald void mesh_trigger_iv_update(void){ 70*f4854a5eSMatthias Ringwald if (global_iv_update_active) return; 71*f4854a5eSMatthias Ringwald 72*f4854a5eSMatthias Ringwald // "A node shall not start an IV Update procedure more often than once every 192 hours." 73*f4854a5eSMatthias Ringwald // Unless triggered by user application, it will automatically triggered if sequene numbers are about to roll over 74*f4854a5eSMatthias Ringwald 75*f4854a5eSMatthias Ringwald // "A node shall defer state change from IV Update in Progress to Normal Operation, as defined by this procedure, 76*f4854a5eSMatthias Ringwald // when the node has transmitted a Segmented Access message or a Segmented Control message without receiving the 77*f4854a5eSMatthias Ringwald // corresponding Segment Acknowledgment messages. The deferred change of the state shall be executed when the appropriate 78*f4854a5eSMatthias Ringwald // Segment Acknowledgment message is received or timeout for the delivery of this message is reached. 79*f4854a5eSMatthias Ringwald // 80*f4854a5eSMatthias Ringwald // Note: This requirement is necessary because upon completing the IV Update procedure the sequence number is reset 81*f4854a5eSMatthias Ringwald // to 0x000000 and the SeqAuth value would not be valid." 82*f4854a5eSMatthias Ringwald 83*f4854a5eSMatthias Ringwald // set IV Update in Progress 84*f4854a5eSMatthias Ringwald global_iv_update_active = 1; 85*f4854a5eSMatthias Ringwald // increase IV index 86*f4854a5eSMatthias Ringwald global_iv_index++; 87*f4854a5eSMatthias Ringwald } 88*f4854a5eSMatthias Ringwald 89*f4854a5eSMatthias Ringwald void mesh_iv_update_completed(void){ 90*f4854a5eSMatthias Ringwald if (!global_iv_update_active) return; 91*f4854a5eSMatthias Ringwald // set Normal mode 92*f4854a5eSMatthias Ringwald global_iv_update_active = 0; 93*f4854a5eSMatthias Ringwald } 94*f4854a5eSMatthias Ringwald 95*f4854a5eSMatthias Ringwald void mesh_iv_index_recovered(uint8_t iv_update_active, uint32_t iv_index){ 96*f4854a5eSMatthias Ringwald log_info("mesh_iv_index_recovered: active %u, index %u", iv_update_active, (int) iv_index); 97*f4854a5eSMatthias Ringwald global_iv_index = iv_index; 98*f4854a5eSMatthias Ringwald global_iv_update_active = iv_update_active; 99*f4854a5eSMatthias Ringwald } 100*f4854a5eSMatthias Ringwald 101*f4854a5eSMatthias Ringwald // 102*f4854a5eSMatthias Ringwald 103*f4854a5eSMatthias Ringwald static void (*seq_num_callback)(void); 104*f4854a5eSMatthias Ringwald 105*f4854a5eSMatthias Ringwald void mesh_sequence_number_set_update_callback(void (*callback)(void)){ 106*f4854a5eSMatthias Ringwald seq_num_callback = callback; 107*f4854a5eSMatthias Ringwald } 108*f4854a5eSMatthias Ringwald 109*f4854a5eSMatthias Ringwald void mesh_sequence_number_set(uint32_t seq){ 110*f4854a5eSMatthias Ringwald sequence_number_current = seq; 111*f4854a5eSMatthias Ringwald } 112*f4854a5eSMatthias Ringwald 113*f4854a5eSMatthias Ringwald uint32_t mesh_sequence_number_next(void){ 114*f4854a5eSMatthias Ringwald uint32_t seq_number = sequence_number_current++; 115*f4854a5eSMatthias Ringwald 116*f4854a5eSMatthias Ringwald if (seq_num_callback){ 117*f4854a5eSMatthias Ringwald (*seq_num_callback)(); 118*f4854a5eSMatthias Ringwald } 119*f4854a5eSMatthias Ringwald 120*f4854a5eSMatthias Ringwald return seq_number; 121*f4854a5eSMatthias Ringwald } 122*f4854a5eSMatthias Ringwald 123*f4854a5eSMatthias Ringwald uint32_t mesh_sequence_number_peek(void){ 124*f4854a5eSMatthias Ringwald return sequence_number_current; 125*f4854a5eSMatthias Ringwald } 126*f4854a5eSMatthias Ringwald 127*f4854a5eSMatthias Ringwald 128