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