Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of OmniWheels by
protocol_6lowpan.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 00018 #include "nsconfig.h" 00019 #include "string.h" 00020 #include "ns_types.h" 00021 #include "eventOS_event.h" 00022 #include "eventOS_scheduler.h" 00023 #include "ns_trace.h" 00024 #include "nsdynmemLIB.h" 00025 #include "Core/include/socket.h" 00026 #include "NWK_INTERFACE/Include/protocol.h" 00027 #include "Common_Protocols/udp.h" 00028 #include "Common_Protocols/ipv6.h" 00029 #include "Common_Protocols/icmpv6.h" 00030 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" 00031 #include "6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h" 00032 #include "6LoWPAN/ND/nd_router_object.h" 00033 #ifdef HAVE_RPL 00034 #include "RPL/rpl_control.h" 00035 #include "RPL/rpl_data.h" 00036 #include "RPL/rpl_protocol.h" 00037 #endif 00038 #include "6LoWPAN/IPHC_Decode/cipv6.h" 00039 #include "6LoWPAN/ND/nd_router_object.h" 00040 #ifndef NO_MLE 00041 #include "MLE/mle.h" 00042 #endif 00043 #include "6LoWPAN/Mesh/mesh.h" 00044 #include "6LoWPAN/Thread/thread_common.h" 00045 #include "6LoWPAN/Thread/thread_nd.h" 00046 #include "6LoWPAN/MAC/mac_helper.h" 00047 00048 #ifdef ECC 00049 #include "libX509_V3.h" 00050 #include "ecc.h" 00051 #endif 00052 #include "ccmLIB.h" 00053 #include "shalib.h" 00054 #include "Security/TLS/tls_lib.h" 00055 #include "Security/Common/sec_lib.h" 00056 #include "net_nvm_api.h" 00057 #include "Security/PANA/pana.h" 00058 #include "Security/PANA/pana_internal_api.h" 00059 #include "Common_Protocols/tcp.h" 00060 #include "randLIB.h" 00061 #include "6LoWPAN/ND/nd_router_object.h" 00062 #include "common_functions.h" 00063 #include "BorderRouter/border_router.h" 00064 #include "net_rpl.h" 00065 #ifdef HAVE_RPL 00066 #ifndef NO_MLE 00067 #include "NWK_INTERFACE/Include/protocol_stats.h" 00068 #endif 00069 #endif 00070 #include "sw_mac.h" 00071 #include "6LoWPAN/MAC/mac_data_poll.h" 00072 #include "6LoWPAN/lowpan_adaptation_interface.h" 00073 #include "6LoWPAN/Fragmentation/cipv6_fragmenter.h" 00074 00075 00076 #define TRACE_GROUP_LOWPAN "6lo" 00077 #define TRACE_GROUP "6lo" 00078 00079 #ifdef HAVE_RPL 00080 rpl_domain_t *protocol_6lowpan_rpl_domain; 00081 /* Having to sidestep old rpl_dodag_t type for the moment */ 00082 struct rpl_dodag *protocol_6lowpan_rpl_root_dodag; 00083 #endif 00084 00085 static uint8_t protocol_buffer_valid(buffer_t *b, protocol_interface_info_entry_t *cur) 00086 { 00087 uint8_t valid = 1; 00088 if (cur) { 00089 if ((b->info & B_TO_MAC_MLME_MASK) != B_TO_MAC_FROM_MAC) { 00090 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 00091 //if((power_save_state & (SLEEP_MODE_REQ | ICMP_ACTIVE)) == SLEEP_MODE_REQ) 00092 if (check_power_state(SLEEP_MODE_REQ | ICMP_ACTIVE) == SLEEP_MODE_REQ) { 00093 /* STill active but Sleep Req and ICMP is not ACTIVE */ 00094 valid = 0; 00095 } 00096 } else { 00097 /* Set Clean Core Becauce Protocol Is not Active */ 00098 valid = 0; 00099 } 00100 } 00101 } else { 00102 valid = 0; 00103 } 00104 return valid; 00105 } 00106 00107 void protocol_init(void) 00108 { 00109 tr_debug("P.Init\n"); 00110 #ifdef PANA 00111 sec_libray_init(); 00112 #endif 00113 #ifdef HAVE_RPL 00114 protocol_6lowpan_rpl_domain = rpl_control_create_domain(); 00115 #endif 00116 } 00117 00118 void protocol_6lowpan_stack(buffer_t *b) 00119 { 00120 protocol_interface_info_entry_t *cur = b->interface ; 00121 if (protocol_buffer_valid(b, cur) == 0) { 00122 tr_debug("Drop Packets\n"); 00123 buffer_free(b); 00124 return; 00125 } 00126 /* Protocol Buffer Handle until Buffer Go out from Stack */ 00127 while (b) { 00128 /* Buffer Direction Select Switch */ 00129 if ((b->info & B_DIR_MASK) == B_DIR_DOWN) { 00130 /* Direction DOWN */ 00131 switch (b->info & B_TO_MASK) { 00132 case B_TO_ICMP: 00133 /* Build ICMP Header */ 00134 b = icmpv6_down(b); 00135 break; 00136 case B_TO_UDP: 00137 /* Build UDP Header */ 00138 b = udp_down(b); 00139 break; 00140 00141 case B_TO_IPV6: 00142 /* Build IP header */ 00143 b = ipv6_down(b); 00144 break; 00145 00146 case B_TO_IPV6_FWD: 00147 /* IPv6 forwarding */ 00148 b = ipv6_forwarding_down(b); 00149 break; 00150 00151 case B_TO_IPV6_TXRX: 00152 /* Resolution, Compress IP header */ 00153 b = lowpan_down(b); 00154 break; 00155 #ifdef HAVE_MESH 00156 case B_TO_MESH_ROUTING: 00157 /* Add mesh header */ 00158 b = mesh_down(b); 00159 break; 00160 #endif 00161 00162 case B_TO_MAC: 00163 /* no break */ 00164 case B_TO_PHY: 00165 b = lowpan_adaptation_data_process_tx_preprocess(cur, b); 00166 if (lowpan_adaptation_interface_tx(cur, b) != 0) { 00167 tr_error("Adaptaion Layer Data req fail"); 00168 } 00169 b = NULL; 00170 break; 00171 00172 default: 00173 b = buffer_free(b); 00174 break; 00175 } 00176 } else { 00177 /* Direction UP */ 00178 switch (b->info & B_TO_MASK) { 00179 case B_TO_APP: 00180 /* Push Socket Interface */ 00181 socket_up(b); 00182 b = NULL; 00183 break; 00184 00185 case B_TO_ICMP: 00186 /* Parse ICMP Message */ 00187 b = icmpv6_up(b); 00188 break; 00189 00190 case B_TO_FRAGMENTATION: 00191 /* Packet Reasemley */ 00192 b = cipv6_frag_reassembly(cur->id, b); 00193 00194 break; 00195 00196 case B_TO_UDP: 00197 /* Parse UDP Message */ 00198 b = udp_up(b); 00199 break; 00200 case B_TO_IPV6_FWD: 00201 /* Handle IP Payload */ 00202 b = ipv6_forwarding_up(b); 00203 break; 00204 case B_TO_IPV6_TXRX: 00205 /* Handle MAC Payload */ 00206 b = lowpan_up(b); 00207 break; 00208 #ifdef HAVE_MESH 00209 case B_TO_MESH_ROUTING: 00210 /* Handle Mesh header */ 00211 b = mesh_up(b); 00212 break; 00213 #endif 00214 case B_TO_TCP: 00215 b = tcp_up(b); 00216 break; 00217 default: 00218 tr_debug("LLL\n"); 00219 b = buffer_free(b); 00220 break; 00221 } 00222 } 00223 if (b) { 00224 //Check If Stack forward packet to different interface 00225 if (b->interface != cur) { 00226 protocol_push(b); 00227 b = 0; 00228 } 00229 } 00230 } 00231 } 00232 00233 /* Return length of option always, and write option if opt_out != NULL */ 00234 static uint8_t protocol_6lowpan_llao_write(protocol_interface_info_entry_t *cur, uint8_t *opt_out, uint8_t opt_type, bool must, const uint8_t *ip_addr) 00235 { 00236 /* Don't bother including optional LLAO if it's a link-local address - 00237 * they should be mapping anyway. 00238 */ 00239 if (!must && addr_is_ipv6_link_local(ip_addr)) { 00240 return 0; 00241 } 00242 uint16_t mac16 = mac_helper_mac16_address_get(cur); 00243 00244 /* Even if we have a short address, use long address if the IP address's IID matches it */ 00245 if (mac16 >= 0xfffe || addr_iid_matches_eui64(ip_addr + 8, cur->mac)) { 00246 if (opt_out) { 00247 opt_out[0] = opt_type; 00248 opt_out[1] = 2; 00249 memcpy(opt_out + 2, cur->mac, 8); 00250 memset(opt_out + 10, 0, 6); 00251 } 00252 return 16; 00253 } else { 00254 if (opt_out) { 00255 opt_out[0] = opt_type; 00256 opt_out[1] = 1; 00257 common_write_16_bit(mac16, opt_out + 2); 00258 memset(opt_out + 4, 0, 4); 00259 } 00260 return 8; 00261 } 00262 } 00263 00264 /* Parse, and return actual size, or 0 if error */ 00265 static uint8_t protocol_6lowpan_llao_parse(protocol_interface_info_entry_t *cur, const uint8_t *opt_in, sockaddr_t *ll_addr_out) 00266 { 00267 common_write_16_bit(cur->mac_parameters->pan_id, ll_addr_out->address + 0); 00268 00269 switch (opt_in[1]) { 00270 case 1: 00271 ll_addr_out->addr_type = ADDR_802_15_4_SHORT ; 00272 memcpy(ll_addr_out->address + 2, opt_in + 2, 2); 00273 return 2 + 2; 00274 case 2: 00275 ll_addr_out->addr_type = ADDR_802_15_4_LONG ; 00276 memcpy(ll_addr_out->address + 2, opt_in + 2, 8); 00277 return 2 + 8; 00278 default: 00279 return 0; 00280 } 00281 } 00282 00283 static bool protocol_6lowpan_map_ip_to_link_addr(protocol_interface_info_entry_t *cur, const uint8_t *ip_addr, addrtype_t *ll_type, const uint8_t **ll_addr_out) 00284 { 00285 static uint8_t ll_addr[10]; 00286 *ll_type = ADDR_NONE ; 00287 00288 /* RFC 6775 says link-local addresses are based on extended MAC (LL64) */ 00289 /* ZigBee IP and Thread both also have link-local addresses based on short MAC (LL16) */ 00290 /* Our old IP stack assumed all addresses were based on MAC; this is available as an option */ 00291 if (cur->iids_map_to_mac || addr_is_ipv6_link_local(ip_addr)) { 00292 if (memcmp(&ip_addr[8], ADDR_SHORT_ADR_SUFFIC, 6) == 0) { 00293 *ll_type = ADDR_802_15_4_SHORT ; 00294 memcpy(&ll_addr[2], &ip_addr[14], 2); 00295 } else { 00296 *ll_type = ADDR_802_15_4_LONG ; 00297 memcpy(&ll_addr[2], &ip_addr[8], 8); 00298 ll_addr[2] ^= 2; 00299 } 00300 } else if (thread_addr_is_mesh_local(ip_addr, cur)) { 00301 if (memcmp(&ip_addr[8], ADDR_SHORT_ADR_SUFFIC, 6) == 0) { 00302 /* Thread ML16s map directly to MAC (mesh) short */ 00303 *ll_type = ADDR_802_15_4_SHORT ; 00304 memcpy(&ll_addr[2], &ip_addr[14], 2); 00305 } 00306 } 00307 00308 if (*ll_type != ADDR_NONE ) { 00309 common_write_16_bit(cur->mac_parameters->pan_id, &ll_addr[0]); 00310 *ll_addr_out = ll_addr; 00311 return true; 00312 } else { 00313 return false; 00314 } 00315 00316 } 00317 00318 static bool protocol_6lowpan_map_link_addr_to_ip(protocol_interface_info_entry_t *cur, addrtype_t ll_type, const uint8_t *ll_addr, uint8_t *ip_addr_out) 00319 { 00320 (void)cur; 00321 00322 switch (ll_type) { 00323 case ADDR_802_15_4_LONG : 00324 memcpy(ip_addr_out, ADDR_LINK_LOCAL_PREFIX, 8); 00325 memcpy(ip_addr_out + 8, ll_addr + 2, 8); 00326 ip_addr_out[8] ^= 0x02; 00327 return true; 00328 case ADDR_802_15_4_SHORT : 00329 if (common_read_16_bit(ll_addr + 2) > 0xfffd) { 00330 return false; 00331 } 00332 memcpy(ip_addr_out, ADDR_LINK_LOCAL_PREFIX, 8); 00333 memcpy(ip_addr_out + 8, ADDR_SHORT_ADR_SUFFIC, 6); 00334 memcpy(ip_addr_out + 14, ll_addr + 2, 2); 00335 return true; 00336 default: 00337 return false; 00338 } 00339 } 00340 00341 void protocol_6lowpan_host_init(protocol_interface_info_entry_t *cur, bool sleepy_host) 00342 { 00343 if (sleepy_host) { 00344 cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_SLEEPY_HOST; 00345 } else { 00346 cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_HOST; 00347 } 00348 //Clear always INTERFACE_NWK_ROUTER_DEVICE, INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE 00349 cur->lowpan_info &= ~(INTERFACE_NWK_ROUTER_DEVICE | INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE); 00350 mle_class_mode_set(cur->id, MLE_CLASS_END_DEVICE); 00351 mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true); 00352 mac_data_poll_init(cur); 00353 arm_nwk_6lowpan_borderrouter_data_free(cur); 00354 } 00355 00356 void protocol_6lowpan_router_init(protocol_interface_info_entry_t *cur) 00357 { 00358 cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_ROUTER; 00359 cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE; 00360 cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; 00361 mle_class_mode_set(cur->id, MLE_CLASS_ROUTER); 00362 mac_data_poll_init(cur); 00363 arm_nwk_6lowpan_borderrouter_data_free(cur); 00364 } 00365 00366 00367 void protocol_6lowpan_configure_core(protocol_interface_info_entry_t *cur) { 00368 cur->dup_addr_detect_transmits = 0; 00369 cur->ipv6_neighbour_cache.max_ll_len = 2 + 8; 00370 cur->ipv6_neighbour_cache.link_mtu = LOWPAN_MTU; 00371 #ifdef HAVE_6LOWPAN_ND 00372 cur->ipv6_neighbour_cache.send_nud_probes = nd_params.send_nud_probes; 00373 cur->iids_map_to_mac = nd_params.iids_map_to_mac; 00374 #endif 00375 cur->ip_multicast_as_mac_unicast_to_parent = false; 00376 cur->max_link_mtu = LOWPAN_MAX_MTU; 00377 cur->send_mld = false; 00378 #ifdef HAVE_6LOWPAN_ND 00379 nd_6lowpan_set_radv_params(cur); 00380 #endif 00381 } 00382 00383 void protocol_6lowpan_register_handlers(protocol_interface_info_entry_t *cur) 00384 { 00385 cur->if_stack_buffer_handler = protocol_6lowpan_stack; 00386 cur->if_llao_parse = protocol_6lowpan_llao_parse; 00387 cur->if_llao_write = protocol_6lowpan_llao_write; 00388 cur->if_map_ip_to_link_addr = protocol_6lowpan_map_ip_to_link_addr; 00389 cur->if_map_link_addr_to_ip = protocol_6lowpan_map_link_addr_to_ip; 00390 00391 if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER || 00392 cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_ROUTER) { 00393 cur->ipv6_neighbour_cache.recv_addr_reg = true; 00394 cur->ipv6_neighbour_cache.recv_ns_aro = true; 00395 } 00396 00397 /* Always send AROs, (compulsory for hosts, and "SHOULD" in RFC 6557 6.5.5 00398 * for routers, as RPL doesn't deal with it) */ 00399 cur->ipv6_neighbour_cache.send_addr_reg = true; 00400 cur->ipv6_neighbour_cache.recv_na_aro = true; 00401 } 00402 void protocol_6lowpan_release_short_link_address_from_neighcache(protocol_interface_info_entry_t *cur, uint16_t shortAddress) 00403 { 00404 uint8_t temp_ll[4]; 00405 uint8_t *ptr = temp_ll; 00406 ptr = common_write_16_bit(cur->mac_parameters->pan_id, ptr); 00407 ptr = common_write_16_bit(shortAddress, ptr); 00408 ipv6_neighbour_invalidate_ll_addr(&cur->ipv6_neighbour_cache, 00409 ADDR_802_15_4_SHORT , temp_ll); 00410 if (thread_info(cur)) { 00411 thread_nd_address_remove(cur, ADDR_802_15_4_SHORT , temp_ll); 00412 } else { 00413 nd_remove_registration(cur, ADDR_802_15_4_SHORT , temp_ll); 00414 } 00415 } 00416 00417 void protocol_6lowpan_release_long_link_address_from_neighcache(protocol_interface_info_entry_t *cur, uint8_t *mac64) 00418 { 00419 uint8_t temp_ll[10]; 00420 uint8_t *ptr = temp_ll; 00421 ptr = common_write_16_bit(cur->mac_parameters->pan_id, ptr); 00422 memcpy(ptr, mac64, 8); 00423 ipv6_neighbour_invalidate_ll_addr(&cur->ipv6_neighbour_cache, 00424 ADDR_802_15_4_LONG , temp_ll); 00425 if (thread_info(cur)) { 00426 thread_nd_address_remove(cur, ADDR_802_15_4_LONG , temp_ll); 00427 } else { 00428 nd_remove_registration(cur, ADDR_802_15_4_LONG , temp_ll); 00429 } 00430 } 00431 #ifdef HAVE_6LOWPAN_ND 00432 00433 static int8_t mle_set_link_priority(int8_t interface_id, const uint8_t *address, bool priority) 00434 { 00435 uint8_t mac64[8]; 00436 mle_neigh_table_entry_t *mle_entry; 00437 00438 if (!memcmp(address, ADDR_SHORT_ADR_SUFFIC, 6)) { 00439 mle_entry = mle_class_get_by_link_address(interface_id, address + 6, ADDR_802_15_4_SHORT ); 00440 } else { 00441 00442 memcpy(mac64, address, 8); 00443 mac64[0] ^= 2; 00444 mle_entry = mle_class_get_by_link_address(interface_id, mac64, ADDR_802_15_4_LONG ); 00445 } 00446 00447 if (!mle_entry) { 00448 return -1; 00449 } 00450 00451 if (priority) { 00452 mle_entry->priorityFlag = 1; 00453 } else { 00454 mle_entry->priorityFlag = 0; 00455 } 00456 return 0; 00457 } 00458 00459 void protocol_6lowpan_neighbor_priority_update(protocol_interface_info_entry_t *cur, uint8_t *removed_priority, uint8_t *updated_priority) 00460 { 00461 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 00462 #ifndef NO_MLE 00463 if (removed_priority) { 00464 mle_set_link_priority(cur->id,removed_priority, false); 00465 } 00466 00467 if (updated_priority) { 00468 mle_set_link_priority(cur->id, updated_priority, true); 00469 } 00470 #endif 00471 } 00472 } 00473 00474 #ifdef HAVE_RPL 00475 #ifndef NO_MLE 00476 00477 uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr) 00478 { 00479 mle_neigh_table_entry_t *neigh_table_ptr; 00480 00481 if (!addr_ptr) { 00482 return 0; 00483 } 00484 00485 neigh_table_ptr = mle_class_get_by_link_address(interface_id, addr_ptr + PAN_ID_LEN, addr_type); 00486 00487 if (neigh_table_ptr) { 00488 // If primary parent has changed clears priority from previous parent 00489 if (!neigh_table_ptr->priorityFlag) { 00490 protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_1ST); 00491 } 00492 neigh_table_ptr->priorityFlag = 1; 00493 00494 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00495 if (cur) { 00496 uint8_t temp[2]; 00497 common_write_16_bit(neigh_table_ptr->short_adr, temp); 00498 mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT , temp); 00499 mac_helper_coordinator_address_set(cur, ADDR_802_15_4_LONG , neigh_table_ptr->mac64); 00500 } 00501 00502 protocol_stats_update(STATS_ETX_1ST_PARENT, neigh_table_ptr->etx >> 4); 00503 return 1; 00504 } else { 00505 return 0; 00506 } 00507 } 00508 00509 uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr) 00510 { 00511 mle_neigh_table_entry_t *neigh_table_ptr; 00512 00513 if (!addr_ptr) { 00514 return 0; 00515 } 00516 00517 neigh_table_ptr = mle_class_get_by_link_address(interface_id, addr_ptr + PAN_ID_LEN, addr_type); 00518 00519 if (neigh_table_ptr) { 00520 // If secondary parent has changed clears priority from previous parent 00521 if (neigh_table_ptr->second_priority_flag == 0) { 00522 protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_2ND); 00523 } 00524 neigh_table_ptr->second_priority_flag = 1; 00525 protocol_stats_update(STATS_ETX_2ND_PARENT, neigh_table_ptr->etx >> 4); 00526 return 1; 00527 } else { 00528 return 0; 00529 } 00530 } 00531 00532 void protocol_6lowpan_neighbor_priority_clear_all(int8_t interface_id, neighbor_priority priority) 00533 { 00534 mle_neigh_table_list_t *mle_neigh_table; 00535 00536 mle_neigh_table = mle_class_active_list_get(interface_id); 00537 if (!mle_neigh_table) { 00538 return; 00539 } 00540 00541 ns_list_foreach(mle_neigh_table_entry_t, entry, mle_neigh_table) { 00542 if (priority == PRIORITY_1ST) { 00543 entry->priorityFlag = 0; 00544 } else { 00545 if (entry->second_priority_flag) { 00546 protocol_stats_update(STATS_ETX_2ND_PARENT, 0); 00547 } 00548 entry->second_priority_flag = 0; 00549 } 00550 } 00551 } 00552 00553 #endif 00554 #endif 00555 00556 #endif 00557 00558 int8_t protocol_6lowpan_neighbor_address_state_synch(protocol_interface_info_entry_t *cur, const uint8_t eui64[8], const uint8_t iid[8]) 00559 { 00560 int8_t ret_val = -1; 00561 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 00562 #ifndef NO_MLE 00563 mle_neigh_table_entry_t *mle_entry = 0; 00564 mle_entry = mle_class_get_by_link_address(cur->id, eui64, ADDR_802_15_4_LONG ); 00565 if (mle_entry && !mle_entry->threadNeighbor) { 00566 if (memcmp(iid, ADDR_SHORT_ADR_SUFFIC, 6) == 0) { 00567 iid += 6; 00568 //Set Short Address to MLE 00569 mle_entry->short_adr = common_read_16_bit(iid); 00570 } 00571 if ((mle_entry->mode & MLE_DEV_MASK) == MLE_RFD_DEV) { 00572 if (mle_entry->handshakeReady) { 00573 mle_entry_timeout_refresh(mle_entry); 00574 } 00575 ret_val = 1; 00576 } else { 00577 ret_val = 0; 00578 } 00579 } 00580 #endif 00581 } else { 00582 ret_val = 0; 00583 } 00584 return ret_val; 00585 } 00586 00587 int8_t protocol_6lowpan_neighbor_remove(protocol_interface_info_entry_t *cur, uint8_t *address_ptr, addrtype_t type) 00588 { 00589 int8_t ret_val = 0; 00590 if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { 00591 #ifndef NO_MLE 00592 mle_class_remove_neighbour(cur->id, address_ptr, type); 00593 #endif 00594 } else { 00595 //REMOVE Something else 00596 } 00597 return ret_val; 00598 } 00599 00600 void protocol_6lowpan_allocate_mac16(protocol_interface_info_entry_t *cur) 00601 { 00602 if (cur) { 00603 cur->lowpan_desired_short_address = (randLIB_get_16bit() & 0x7fff); 00604 } 00605 } 00606 00607 void protocol_6lowpan_interface_common_init(protocol_interface_info_entry_t *cur) 00608 { 00609 cur->lowpan_info |= INTERFACE_NWK_ACTIVE; 00610 protocol_6lowpan_register_handlers(cur); 00611 ipv6_route_add(ADDR_LINK_LOCAL_PREFIX, 64, cur->id, NULL, ROUTE_STATIC, 0xFFFFFFFF, 0); 00612 // Putting a multicast route to ff00::/8 makes sure we can always transmit multicast. 00613 // Interface metric will determine which interface is actually used, if we have multiple. 00614 ipv6_route_add(ADDR_LINK_LOCAL_ALL_NODES, 8, cur->id, NULL, ROUTE_STATIC, 0xFFFFFFFF, -1); 00615 } 00616 00617 int8_t protocol_6lowpan_interface_compare_cordinator_netid(protocol_interface_info_entry_t *cur, uint8_t *adr_ptr) 00618 { 00619 int8_t ret_val = -1; 00620 00621 if (cur) { 00622 addrtype_t addrType; 00623 uint8_t tempAddress[8]; 00624 addrType = mac_helper_coordinator_address_get(cur, tempAddress); 00625 00626 if (addrType == ADDR_802_15_4_LONG ) { 00627 tempAddress[0] ^= 2; 00628 if (memcmp(adr_ptr, tempAddress, 8) == 0) { 00629 ret_val = 0; 00630 } 00631 } else if (addrType == ADDR_802_15_4_SHORT ) { 00632 if (adr_ptr[6] == tempAddress[0] && adr_ptr[7] == tempAddress[1]) { 00633 ret_val = 0; 00634 } 00635 } 00636 } 00637 return ret_val; 00638 } 00639 00640 int8_t protocol_6lowpan_interface_get_link_local_cordinator_address(protocol_interface_info_entry_t *cur, uint8_t *adr_ptr) 00641 { 00642 addrtype_t addrType; 00643 uint8_t tempAddress[8]; 00644 00645 addrType = mac_helper_coordinator_address_get(cur, tempAddress); 00646 if (addrType == ADDR_NONE ) { 00647 return -1; 00648 } 00649 memcpy(adr_ptr, ADDR_LINK_LOCAL_PREFIX, 8); 00650 adr_ptr += 8; 00651 if (addrType == ADDR_802_15_4_LONG ) { 00652 tempAddress[0] ^= 2; 00653 memcpy(adr_ptr, tempAddress, 8); 00654 } else { 00655 memcpy(adr_ptr, ADDR_SHORT_ADR_SUFFIC, 6); 00656 adr_ptr += 6; 00657 *adr_ptr++ = tempAddress[0]; 00658 *adr_ptr = tempAddress[1]; 00659 } 00660 return 0; 00661 } 00662 00663 int8_t protocol_6lowpan_interface_get_mac_coordinator_address(protocol_interface_info_entry_t *cur, sockaddr_t *adr_ptr) 00664 { 00665 common_write_16_bit(cur->mac_parameters->pan_id, adr_ptr->address + 0); 00666 00667 adr_ptr->addr_type = mac_helper_coordinator_address_get(cur, adr_ptr->address + 2); 00668 if (adr_ptr->addr_type == ADDR_NONE ) { 00669 return -1; 00670 } 00671 return 0; 00672 } 00673 00674 int16_t protocol_6lowpan_rpl_global_priority_get(void) 00675 { 00676 #ifdef HAVE_RPL 00677 uint8_t instance_id_list[10]; 00678 uint8_t rpl_instance_count; 00679 uint8_t instance_id = RPL_INSTANCE_LOCAL; 00680 uint8_t instance_id_new; 00681 uint8_t instance_index; 00682 rpl_instance_count = rpl_instance_list_read(&instance_id_list[0], sizeof(instance_id_list)); 00683 00684 /* Find lowest global instance ID (assumption: RPL instance with lowest instance ID has 00685 most generic routing rule and its rank should be indicated in beacon) */ 00686 for (instance_index = 0; instance_index < rpl_instance_count; instance_index++) { 00687 instance_id_new = instance_id_list[instance_index]; 00688 00689 if ((instance_id_new & RPL_INSTANCE_LOCAL) == RPL_INSTANCE_LOCAL) { 00690 break; 00691 } else { 00692 if (instance_id_new < instance_id) { 00693 instance_id = instance_id_new; 00694 } 00695 } 00696 } 00697 00698 // Get DAG rank 00699 if (instance_id == RPL_INSTANCE_LOCAL) { 00700 return 255; 00701 } 00702 00703 rpl_dodag_info_t rpl_dodag_info; 00704 if (!rpl_read_dodag_info(&rpl_dodag_info, instance_id)) { 00705 return 255; 00706 } 00707 00708 if (rpl_dodag_info.curent_rank == RPL_RANK_INFINITE) { 00709 return 255; 00710 } 00711 00712 // Default implementation is 00713 // 32 * (7 - DODAGPreference) + 3 * (DAGRank - 1) 00714 int16_t priority; 00715 priority = 32 * (7 - RPL_DODAG_PREF(rpl_dodag_info.flags)); 00716 priority += 3 * (rpl_dodag_info.curent_rank / rpl_dodag_info.dag_min_hop_rank_inc - 1); 00717 00718 return priority; 00719 #else 00720 return 255; 00721 #endif 00722 } 00723 00724 uint8_t protocol_6lowpan_beacon_join_priority_tx(int8_t interface_id) 00725 { 00726 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00727 if (!cur) { 00728 return 255; 00729 } 00730 00731 int16_t priority = 0; 00732 #ifdef HAVE_RPL 00733 if (cur->rpl_domain) { 00734 priority = protocol_6lowpan_rpl_global_priority_get(); 00735 } 00736 #endif 00737 00738 #ifndef NO_MLE 00739 mle_6lowpan_data_t *mle_6lowpan_data = protocol_6lowpan_mle_data_get(); 00740 00741 if (mle_6lowpan_data && mle_6lowpan_data->nbr_of_neigh_max != 0) { 00742 uint16_t mle_neigh_cnt = mle_class_active_neigh_counter(interface_id); 00743 00744 if (mle_neigh_cnt > mle_6lowpan_data->nbr_of_neigh_lower_threshold) { 00745 uint16_t mle_neigh_limit; 00746 mle_neigh_cnt -= mle_6lowpan_data->nbr_of_neigh_lower_threshold; 00747 mle_neigh_limit = 32 * mle_neigh_cnt / (mle_6lowpan_data->nbr_of_neigh_max - mle_6lowpan_data->nbr_of_neigh_lower_threshold); 00748 priority += mle_neigh_limit; 00749 } 00750 } 00751 #endif 00752 00753 if (priority < 0) { 00754 priority = 0; 00755 } else if (priority > 255) { 00756 priority = 255; 00757 } 00758 00759 return priority; 00760 } 00761 00762 uint8_t protocol_6lowpan_beacon_compare_rx(int8_t interface_id, uint8_t join_priority, uint8_t link_quality) 00763 { 00764 (void)interface_id; // not used, perhaps should be removed completely 00765 00766 uint16_t conn_to_pref; 00767 00768 conn_to_pref = ((256 - join_priority) * (uint16_t) link_quality) >> 8; 00769 00770 return conn_to_pref; 00771 }
Generated on Fri Jul 22 2022 04:53:59 by
1.7.2
