BA / Mbed OS BaBoRo1
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers whiteboard.c Source File

whiteboard.c

00001 /*
00002  * Copyright (c) 2013-2017, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 #include "nsconfig.h"
00018 #include <stdint.h>
00019 #include "string.h"
00020 #include "nsdynmemLIB.h"
00021 #include "ns_list.h"
00022 #include "Common_Protocols/icmpv6.h"
00023 #include "Service_Libs/whiteboard/whiteboard.h"
00024 #include "platform/os_whiteboard.h"
00025 
00026 #ifdef WHITEBOARD
00027 static uint16_t whiteboard_device_limit = 0;
00028 static uint16_t whiteboard_size = 0;
00029 
00030 /* Separate internal version to avoid exporting ns_list.h unnecessarily */
00031 typedef struct whiteboard_entry_int_t {
00032     whiteboard_entry_t entry;
00033     ns_list_link_t link;
00034 } whiteboard_entry_int_t;
00035 
00036 static NS_LIST_DEFINE(whiteboard_info, whiteboard_entry_int_t, link);
00037 static NS_LIST_DEFINE(whiteboard_interface_list, whiteboard_entry_int_t, link);
00038 
00039 static void whiteboard_remove_entry(whiteboard_entry_int_t *entry);
00040 
00041 static void whiteboard_remove_entry(whiteboard_entry_int_t *entry)
00042 {
00043     ns_list_remove(&whiteboard_info, entry);
00044     ns_dyn_mem_free(entry);
00045     whiteboard_size--;
00046 }
00047 
00048 void whiteboard_init(int8_t id)
00049 {
00050     ns_list_foreach_safe(whiteboard_entry_int_t, cur, &whiteboard_info) {
00051         if (cur->entry.interface_index == id) {
00052             whiteboard_remove_entry(cur);
00053         }
00054     }
00055 }
00056 
00057 
00058 void whiteboard_init_by_prefix(int8_t id, const uint8_t address[static 8])
00059 {
00060     ns_list_foreach_safe(whiteboard_entry_int_t, cur, &whiteboard_info) {
00061         if (cur->entry.interface_index == id) {
00062             if (memcmp(cur->entry.address,address,8 ) == 0) {
00063                 whiteboard_remove_entry(cur);
00064             }
00065         }
00066     }
00067 }
00068 
00069 void whiteboard_rm_entry(int8_t id, const uint8_t address[static 16])
00070 {
00071     ns_list_foreach_safe(whiteboard_entry_int_t, cur, &whiteboard_info) {
00072         if (cur->entry.interface_index == id) {
00073             if (memcmp(cur->entry.address,address,16 ) == 0) {
00074 
00075                 whiteboard_remove_entry(cur);
00076                 return;
00077             }
00078         }
00079     }
00080 }
00081 
00082 whiteboard_entry_t *whiteboard_table_check_address(const uint8_t address[static 16])
00083 {
00084     ns_list_foreach(whiteboard_entry_int_t, cur, &whiteboard_info) {
00085         if (memcmp(cur->entry.address, address, 16) == 0) {
00086             return &cur->entry;
00087         }
00088     }
00089     return 0;
00090 }
00091 
00092 whiteboard_entry_t *whiteboard_get(whiteboard_entry_t *cur)
00093 {
00094     whiteboard_entry_int_t *entry = (whiteboard_entry_int_t *) cur;
00095     if (entry) {
00096         entry = ns_list_get_next(&whiteboard_info, entry);
00097     } else {
00098         entry = ns_list_get_first(&whiteboard_info);
00099     }
00100 
00101     if (entry) {
00102         return &entry->entry;
00103     } else {
00104         return NULL;
00105     }
00106 }
00107 
00108 void whiteboard_set_device_hard_limit(uint16_t limit)
00109 {
00110     whiteboard_device_limit = limit;
00111 }
00112 
00113 uint16_t whiteboard_size_get(void)
00114 {
00115     return whiteboard_size;
00116 }
00117 
00118 // XXX what is this doing? I believe it only returns entries that do NOT
00119 // appear to be based on the EUI-64 (with a sloppy check). So given entries:
00120 //
00121 // 2002:db8::2345:2345:2345:2345    03:45:23:45:23:45:23:45
00122 // 2002:db8::1                      03:45:23:45:23:45:23:45
00123 //
00124 // it returns the 2002:db8::1 entry, not the EUI-64-based one.
00125 //
00126 // But why?
00127 static whiteboard_entry_t *whiteboard_table_check_eui64(const uint8_t eui64[static 8])
00128 {
00129     ns_list_foreach(whiteboard_entry_int_t, cur, &whiteboard_info) {
00130         /*Compare latter 7 bytes and eui64*/
00131         if (memcmp(cur->entry.address + 9, eui64 + 1, 7) != 0) {
00132             if (memcmp(cur->entry.eui64, eui64, 8) == 0) {
00133                 return &cur->entry;
00134             }
00135         }
00136     }
00137     return 0;
00138 }
00139 
00140 
00141 int8_t whiteboard_interface_register(const uint8_t address[static 16], int8_t nwk_id)
00142 {
00143     ns_list_foreach(whiteboard_entry_int_t, cur, &whiteboard_interface_list) {
00144         if (memcmp(cur->entry.address, address, 16) == 0) {
00145             if (cur->entry.interface_index != nwk_id) {
00146                 return -2;
00147             } else {
00148                 return 0;
00149             }
00150         }
00151     }
00152 
00153     whiteboard_entry_int_t *new = ns_dyn_mem_alloc(sizeof(whiteboard_entry_int_t));
00154     if (!new) {
00155         return -1;
00156     }
00157     memcpy(new->entry.address, address, 16);
00158     new->entry.interface_index = nwk_id;
00159     whiteboard_os_modify(address, ADD);
00160     ns_list_add_to_start(&whiteboard_interface_list, new);
00161 
00162     return 0;
00163 }
00164 
00165 int8_t whiteboard_interface_unregister_all_address(int8_t nwk_id)
00166 {
00167     ns_list_foreach_safe(whiteboard_entry_int_t, cur, &whiteboard_interface_list) {
00168         if (cur->entry.interface_index == nwk_id) {
00169             whiteboard_os_modify(cur->entry.address, REMOVE);
00170             whiteboard_remove_entry(cur);
00171         }
00172     }
00173     return 0;
00174 }
00175 
00176 bool whiteboard_interface_address_cmp(const uint8_t address[static 16])
00177 {
00178     ns_list_foreach(whiteboard_entry_int_t, cur, &whiteboard_interface_list) {
00179         if (memcmp(cur->entry.address, address, 16) == 0) {
00180             return true;
00181         }
00182     }
00183     return false;
00184 }
00185 
00186 whiteboard_entry_t *whiteboard_table_update(const uint8_t address[static 16], const uint8_t eui64[static 8], uint8_t *status)
00187 {
00188     whiteboard_entry_t *ret_val = 0;
00189     if (ns_list_is_empty(&whiteboard_interface_list)) {
00190         return 0;
00191     }
00192 
00193     if (whiteboard_interface_address_cmp(address)) {
00194         *status = ARO_DUPLICATE;
00195         return 0;
00196     }
00197 
00198     ret_val = whiteboard_table_check_address(address);
00199     if (ret_val) {
00200         if (memcmp(ret_val->eui64, eui64, 8) == 0) {
00201             *status = ARO_SUCCESS;
00202         } else {
00203             *status = ARO_DUPLICATE;
00204             return 0;
00205         }
00206     } else {
00207         /*Compare latter 7 bytes and eui64 (XXX why?) */
00208         if (memcmp((address + 9), (eui64 + 1), 7) != 0) {
00209             ret_val = whiteboard_table_check_eui64(eui64);
00210             if (ret_val) {
00211                 memcpy(ret_val->address, address, 16);
00212                 *status = ARO_SUCCESS;
00213             }
00214         }
00215     }
00216 
00217     //allocate new
00218     if (ret_val == 0) {
00219         /* Check Limiter */
00220         if (whiteboard_device_limit && whiteboard_size == whiteboard_device_limit) {
00221             *status = ARO_FULL;
00222             return 0;
00223         }
00224 
00225         whiteboard_entry_int_t *new = ns_dyn_mem_alloc(sizeof(whiteboard_entry_int_t));
00226         if (new) {
00227             ns_list_add_to_start(&whiteboard_info, new);
00228             ret_val = &new->entry;
00229             whiteboard_os_modify(address, ADD);
00230             memcpy(ret_val->address, address, 16);
00231             memcpy(ret_val->eui64, eui64, 8);
00232             *status = ARO_SUCCESS;
00233             whiteboard_size++;
00234         } else {
00235             *status = ARO_FULL;
00236         }
00237     }
00238 
00239     return ret_val;
00240 }
00241 
00242 void whiteboard_ttl_update(uint16_t ttl_time)
00243 {
00244     ns_list_foreach_safe(whiteboard_entry_int_t, cur, &whiteboard_info) {
00245         if (cur->entry.ttl > ttl_time) {
00246             cur->entry.ttl -= ttl_time;
00247         } else {
00248             whiteboard_os_modify(cur->entry.address, REMOVE);
00249             whiteboard_remove_entry(cur);
00250         }
00251     }
00252 }
00253 #else
00254 
00255 void whiteboard_set_device_hard_limit(uint16_t limit)
00256 {
00257     (void)limit;
00258 }
00259 
00260 whiteboard_entry_t *whiteboard_get(whiteboard_entry_t *cur)
00261 {
00262     (void)cur;
00263     return NULL;
00264 }
00265 
00266 #endif