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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
mac_helper.c
00001 /* 00002 * Copyright (c) 2016-2018, 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 "NWK_INTERFACE/Include/protocol.h" 00021 #include "mlme.h" 00022 #include "mac_helper.h" 00023 #include "mac_common_defines.h" 00024 #include "nsdynmemLIB.h" 00025 #include "net_nwk_scan.h" 00026 #include "ns_trace.h" 00027 #include "common_functions.h" 00028 #include "mac_api.h" 00029 00030 #define TRACE_GROUP "MACh" 00031 00032 static const uint8_t mac_helper_default_key_source[8] = {0xff, 0, 0, 0, 0, 0, 0, 0}; 00033 00034 static uint8_t mac_helper_header_security_aux_header_length(uint8_t keyIdmode); 00035 static uint8_t mac_helper_security_mic_length_get(uint8_t security_level); 00036 static void mac_helper_keytable_pairwise_descriptor_set(struct mac_api_s *api, const uint8_t *key, const uint8_t *mac64, uint8_t attribute_id); 00037 00038 static int8_t mac_helper_pib_8bit_set(protocol_interface_info_entry_t *interface, mlme_attr_t attribute, uint8_t value) 00039 { 00040 switch (attribute) { 00041 case macAutoRequestKeyIdMode: 00042 interface->mac_parameters->mac_key_id_mode = value; 00043 break; 00044 case macAutoRequestKeyIndex: 00045 interface->mac_parameters->mac_default_key_index = value; 00046 break; 00047 00048 case macAutoRequestSecurityLevel: 00049 default: 00050 interface->mac_parameters->mac_security_level = value; 00051 break; 00052 } 00053 00054 if (interface->mac_api && interface->mac_api->mlme_req) { 00055 mlme_set_t set_req; 00056 set_req.attr = attribute; 00057 set_req.attr_index = 0; 00058 set_req.value_pointer = &value; 00059 set_req.value_size = 1; 00060 interface->mac_api->mlme_req(interface->mac_api, MLME_SET, &set_req); 00061 } 00062 00063 return 0; 00064 } 00065 00066 void mac_create_scan_request(mac_scan_type_t type, channel_list_s *chanlist, uint8_t scan_duration, mlme_scan_t *request) 00067 { 00068 if (!chanlist || !request) { 00069 return; 00070 } 00071 00072 memset(request, 0, sizeof(mlme_scan_t)); 00073 00074 request->ScanType = type; 00075 request->ScanChannels = *chanlist; 00076 00077 request->ScanDuration = scan_duration; 00078 } 00079 00080 nwk_pan_descriptor_t *mac_helper_select_best_lqi(nwk_pan_descriptor_t *list) 00081 { 00082 nwk_pan_descriptor_t *best = list; 00083 //Analyze Best Result 00084 while (list) { 00085 tr_debug("LinkQuality: %i, LogicalCh: %i", list->pan_descriptor->LinkQuality, list->pan_descriptor->LogicalChannel); 00086 if (best->pan_descriptor->LinkQuality < list->pan_descriptor->LinkQuality) { 00087 best = list; 00088 } 00089 list = list->next; 00090 } 00091 return best; 00092 } 00093 00094 void mac_helper_drop_selected_from_the_scanresult(nwk_scan_params_t *scanParams, nwk_pan_descriptor_t *selected) 00095 { 00096 if (!scanParams || !selected) { 00097 return; 00098 } 00099 nwk_pan_descriptor_t *cur; 00100 nwk_pan_descriptor_t *prev = 0; 00101 cur = scanParams->nwk_response_info; 00102 00103 while (cur) { 00104 if (cur == selected) { 00105 tr_debug("Clean Selected out from the list"); 00106 if (prev) { 00107 prev->next = cur->next; 00108 } else { 00109 scanParams->nwk_response_info = cur->next; 00110 00111 } 00112 scanParams->nwk_scan_res_size--; 00113 cur = 0; 00114 00115 } 00116 if (cur) { 00117 prev = cur; 00118 cur = cur->next; 00119 } 00120 } 00121 } 00122 00123 void mac_helper_free_scan_confirm(nwk_scan_params_t *params) 00124 { 00125 if (!params) { 00126 return; 00127 } 00128 if (params->nwk_scan_res_size) { 00129 nwk_pan_descriptor_t *cur = params->nwk_response_info; 00130 nwk_pan_descriptor_t *tmp; 00131 tr_debug("Scanned Results"); 00132 while (cur) { 00133 tmp = cur; 00134 cur = cur->next; 00135 tr_debug("Free NWK Structure"); 00136 mac_helper_free_pan_descriptions(tmp); 00137 } 00138 00139 params->nwk_response_info = 0; 00140 params->nwk_scan_res_size = 0; 00141 } 00142 params->nwk_cur_active = mac_helper_free_pan_descriptions(params->nwk_cur_active); 00143 } 00144 00145 nwk_pan_descriptor_t *mac_helper_free_pan_descriptions(nwk_pan_descriptor_t *nwk_cur_active) 00146 { 00147 if (nwk_cur_active) { 00148 ns_dyn_mem_free(nwk_cur_active->pan_descriptor); 00149 ns_dyn_mem_free(nwk_cur_active->beacon_payload); 00150 ns_dyn_mem_free(nwk_cur_active); 00151 } 00152 return NULL; 00153 } 00154 00155 int8_t mac_helper_nwk_id_filter_set(const uint8_t *nw_id, nwk_filter_params_s *filter) 00156 { 00157 if (!filter) { 00158 return -1; 00159 } 00160 int8_t ret_val = 0; 00161 if (nw_id) { 00162 if (filter->beacon_nwk_id_filter == 0) { 00163 filter->beacon_nwk_id_filter = ns_dyn_mem_alloc(16); 00164 } 00165 if (filter->beacon_nwk_id_filter) { 00166 memcpy(filter->beacon_nwk_id_filter, nw_id, 16); 00167 } else { 00168 ret_val = -1; 00169 } 00170 } else { 00171 ns_dyn_mem_free(filter->beacon_nwk_id_filter); 00172 filter->beacon_nwk_id_filter = 0; 00173 } 00174 return ret_val; 00175 } 00176 00177 void mac_helper_panid_set(protocol_interface_info_entry_t *interface, uint16_t panId) 00178 { 00179 interface->mac_parameters->pan_id = panId; 00180 mlme_set_t set_req; 00181 set_req.attr = macPANId; 00182 set_req.attr_index = 0; 00183 set_req.value_pointer = &panId; 00184 set_req.value_size = 2; 00185 interface->mac_api->mlme_req(interface->mac_api, MLME_SET, &set_req); 00186 } 00187 00188 void mac_helper_mac16_address_set(protocol_interface_info_entry_t *interface, uint16_t mac16) 00189 { 00190 interface->mac_parameters->mac_short_address = mac16; 00191 if (mac16 < 0xfffe) { 00192 interface->mac_parameters->shortAdressValid = true; 00193 } else { 00194 interface->mac_parameters->shortAdressValid = false; 00195 } 00196 mlme_set_t set_req; 00197 set_req.attr = macShortAddress; 00198 set_req.attr_index = 0; 00199 set_req.value_pointer = &mac16; 00200 set_req.value_size = 2; 00201 interface->mac_api->mlme_req(interface->mac_api, MLME_SET, &set_req); 00202 } 00203 00204 uint16_t mac_helper_mac16_address_get(const protocol_interface_info_entry_t *interface) 00205 { 00206 uint16_t shortAddress = 0xfffe; 00207 if (interface) { 00208 shortAddress = interface->mac_parameters->mac_short_address; 00209 } 00210 return shortAddress; 00211 } 00212 00213 uint16_t mac_helper_panid_get(const protocol_interface_info_entry_t *interface) 00214 { 00215 uint16_t panId = 0xffff; 00216 if (interface) { 00217 panId = interface->mac_parameters->pan_id; 00218 } 00219 return panId; 00220 } 00221 00222 void mac_helper_default_key_index_set(protocol_interface_info_entry_t *interface, uint8_t keyIndex) 00223 { 00224 interface->mac_parameters->mac_default_key_index = keyIndex; 00225 } 00226 00227 uint8_t mac_helper_default_key_index_get(protocol_interface_info_entry_t *interface) 00228 { 00229 return interface->mac_parameters->mac_default_key_index; 00230 } 00231 00232 void mac_helper_set_default_key_source(protocol_interface_info_entry_t *interface) 00233 { 00234 mlme_set_t set_req; 00235 set_req.attr_index = 0; 00236 set_req.value_pointer = (void *)mac_helper_default_key_source; 00237 set_req.value_size = 8; 00238 //Set first default key source 00239 set_req.attr = macDefaultKeySource; 00240 interface->mac_api->mlme_req(interface->mac_api, MLME_SET, &set_req); 00241 //Set first default key source 00242 set_req.attr = macAutoRequestKeySource; 00243 interface->mac_api->mlme_req(interface->mac_api, MLME_SET, &set_req); 00244 00245 } 00246 00247 void mac_helper_default_security_level_set(protocol_interface_info_entry_t *interface, uint8_t securityLevel) 00248 { 00249 bool security_enabled; 00250 if (securityLevel) { 00251 security_enabled = true; 00252 } else { 00253 security_enabled = false; 00254 } 00255 mac_helper_pib_8bit_set(interface, macAutoRequestSecurityLevel, securityLevel); 00256 mac_helper_pib_boolean_set(interface, macSecurityEnabled, security_enabled); 00257 00258 } 00259 00260 uint8_t mac_helper_default_security_level_get(protocol_interface_info_entry_t *interface) 00261 { 00262 return interface->mac_parameters->mac_security_level; 00263 } 00264 00265 void mac_helper_default_security_key_id_mode_set(protocol_interface_info_entry_t *interface, uint8_t keyIdMode) 00266 { 00267 mac_helper_pib_8bit_set(interface, macAutoRequestKeyIdMode, keyIdMode); 00268 } 00269 00270 uint8_t mac_helper_default_security_key_id_mode_get(protocol_interface_info_entry_t *interface) 00271 { 00272 return interface->mac_parameters->mac_key_id_mode; 00273 } 00274 00275 static void mac_helper_key_lookup_set(mlme_key_id_lookup_descriptor_t *lookup, uint8_t id) 00276 { 00277 memcpy(lookup->LookupData, mac_helper_default_key_source, 8); 00278 lookup->LookupData[8] = id; 00279 lookup->LookupDataSize = 1; 00280 } 00281 00282 00283 static void mac_helper_keytable_descriptor_set(struct mac_api_s *api, const uint8_t *key, uint8_t id, uint8_t attribute_id) 00284 { 00285 mlme_set_t set_req; 00286 mlme_key_id_lookup_descriptor_t lookup_description; 00287 mlme_key_descriptor_entry_t key_description; 00288 if (key) { 00289 mac_helper_key_lookup_set(&lookup_description, id); 00290 memset(&key_description, 0, sizeof(mlme_key_descriptor_entry_t)); 00291 memcpy(key_description.Key, key, 16); 00292 key_description.KeyIdLookupList = &lookup_description; 00293 key_description.KeyIdLookupListEntries = 1; 00294 } else { 00295 memset(&key_description, 0, sizeof(mlme_key_descriptor_entry_t)); 00296 } 00297 set_req.attr = macKeyTable; 00298 set_req.attr_index = attribute_id; 00299 set_req.value_pointer = &key_description; 00300 set_req.value_size = sizeof(mlme_key_descriptor_entry_t); 00301 00302 api->mlme_req(api, MLME_SET, &set_req); 00303 } 00304 00305 static void mac_helper_keytable_pairwise_descriptor_set(struct mac_api_s *api, const uint8_t *key, const uint8_t *mac64, uint8_t attribute_id) 00306 { 00307 mlme_set_t set_req; 00308 mlme_key_id_lookup_descriptor_t lookup_description; 00309 mlme_key_descriptor_entry_t key_description; 00310 if (key) { 00311 memcpy(lookup_description.LookupData, mac64, 8); 00312 lookup_description.LookupData[8] = 0; 00313 lookup_description.LookupDataSize = 1; 00314 tr_debug("Key add %u index %s", attribute_id, trace_array(lookup_description.LookupData, 9)); 00315 memset(&key_description, 0, sizeof(mlme_key_descriptor_entry_t)); 00316 memcpy(key_description.Key, key, 16); 00317 key_description.KeyIdLookupList = &lookup_description; 00318 key_description.KeyIdLookupListEntries = 1; 00319 } else { 00320 memset(&key_description, 0, sizeof(mlme_key_descriptor_entry_t)); 00321 } 00322 set_req.attr = macKeyTable; 00323 set_req.attr_index = attribute_id; 00324 set_req.value_pointer = &key_description; 00325 set_req.value_size = sizeof(mlme_key_descriptor_entry_t); 00326 00327 api->mlme_req(api, MLME_SET, &set_req); 00328 } 00329 00330 00331 int8_t mac_helper_security_default_key_set(protocol_interface_info_entry_t *interface, const uint8_t *key, uint8_t id, uint8_t keyid_mode) 00332 { 00333 if (id == 0 || keyid_mode > 3) { 00334 return -1; 00335 } 00336 00337 mac_helper_pib_8bit_set(interface, macAutoRequestKeyIndex, id); 00338 mac_helper_keytable_descriptor_set(interface->mac_api, key, id, interface->mac_parameters->mac_default_key_attribute_id); 00339 return 0; 00340 } 00341 00342 int8_t mac_helper_security_default_recv_key_set(protocol_interface_info_entry_t *interface, const uint8_t *key, uint8_t id, uint8_t keyid_mode) 00343 { 00344 if (id == 0 || keyid_mode > 3) { 00345 return -1; 00346 } 00347 00348 mac_helper_keytable_descriptor_set(interface->mac_api, key, id, interface->mac_parameters->mac_default_key_attribute_id); 00349 return 0; 00350 } 00351 00352 int8_t mac_helper_security_auto_request_key_index_set(protocol_interface_info_entry_t *interface, uint8_t key_attibute_index, uint8_t id) 00353 { 00354 if (id == 0) { 00355 return -1; 00356 } 00357 interface->mac_parameters->mac_default_key_attribute_id = key_attibute_index; 00358 mac_helper_pib_8bit_set(interface, macAutoRequestKeyIndex, id); 00359 return 0; 00360 } 00361 00362 00363 int8_t mac_helper_security_pairwisekey_set(protocol_interface_info_entry_t *interface, const uint8_t *key, const uint8_t *mac_64, uint8_t key_attribute) 00364 { 00365 if (key && !mac_64) { 00366 return -1; 00367 } 00368 00369 mac_helper_keytable_pairwise_descriptor_set(interface->mac_api, key, mac_64, key_attribute); 00370 return 0; 00371 } 00372 00373 int8_t mac_helper_security_next_key_set(protocol_interface_info_entry_t *interface, uint8_t *key, uint8_t id, uint8_t keyid_mode) 00374 { 00375 if (id == 0 || keyid_mode > 3) { 00376 return -1; 00377 } 00378 00379 interface->mac_parameters->mac_next_key_index = id; 00380 mac_helper_keytable_descriptor_set(interface->mac_api, key, id, interface->mac_parameters->mac_next_key_attribute_id); 00381 return 0; 00382 00383 } 00384 00385 int8_t mac_helper_security_prev_key_set(protocol_interface_info_entry_t *interface, uint8_t *key, uint8_t id, uint8_t keyid_mode) 00386 { 00387 if (id == 0 || keyid_mode > 3) { 00388 return -1; 00389 } 00390 00391 interface->mac_parameters->mac_prev_key_index = id; 00392 mac_helper_keytable_descriptor_set(interface->mac_api, key, id, interface->mac_parameters->mac_prev_key_attribute_id); 00393 return 0; 00394 00395 } 00396 00397 int8_t mac_helper_security_key_to_descriptor_set(protocol_interface_info_entry_t *interface, const uint8_t *key, uint8_t id, uint8_t descriptor) 00398 { 00399 if (id == 0) { 00400 return -1; 00401 } 00402 00403 mac_helper_keytable_descriptor_set(interface->mac_api, key, id, descriptor); 00404 return 0; 00405 } 00406 00407 int8_t mac_helper_security_key_descriptor_clear(protocol_interface_info_entry_t *interface, uint8_t descriptor) 00408 { 00409 if (!interface->mac_api) { 00410 return -1; 00411 } 00412 00413 mlme_set_t set_req; 00414 mlme_key_descriptor_entry_t key_description; 00415 memset(&key_description, 0, sizeof(mlme_key_descriptor_entry_t)); 00416 00417 set_req.attr = macKeyTable; 00418 set_req.value_pointer = &key_description; 00419 set_req.value_size = sizeof(mlme_key_descriptor_entry_t); 00420 set_req.attr_index = descriptor; 00421 interface->mac_api->mlme_req(interface->mac_api, MLME_SET, &set_req); 00422 return 0; 00423 } 00424 00425 void mac_helper_security_key_swap_next_to_default(protocol_interface_info_entry_t *interface) 00426 { 00427 //Free old prev key 00428 /* 00429 * Update key setup next way 00430 * 00431 * Current Key -> Prev key 00432 * Next Key -> Current key 00433 * Prev Key ->Overwrite by for next Purpose 00434 */ 00435 00436 00437 //Free current prev 00438 mac_helper_keytable_descriptor_set(interface->mac_api, NULL, 0, interface->mac_parameters->mac_prev_key_attribute_id); 00439 00440 uint8_t prev_attribute = interface->mac_parameters->mac_prev_key_attribute_id; //save current pre for next purpose 00441 00442 interface->mac_parameters->mac_prev_key_index = interface->mac_parameters->mac_default_key_index; 00443 interface->mac_parameters->mac_prev_key_attribute_id = interface->mac_parameters->mac_default_key_attribute_id; 00444 00445 mac_helper_security_auto_request_key_index_set(interface, interface->mac_parameters->mac_next_key_attribute_id, interface->mac_parameters->mac_next_key_index); 00446 00447 interface->mac_parameters->mac_next_key_index = 0; 00448 interface->mac_parameters->mac_next_key_attribute_id = prev_attribute; 00449 00450 } 00451 00452 void mac_helper_security_key_clean(protocol_interface_info_entry_t *interface) 00453 { 00454 if (interface->mac_api) { 00455 mlme_set_t set_req; 00456 mlme_key_descriptor_entry_t key_description; 00457 memset(&key_description, 0, sizeof(mlme_key_descriptor_entry_t)); 00458 00459 set_req.attr = macKeyTable; 00460 00461 set_req.value_pointer = &key_description; 00462 set_req.value_size = sizeof(mlme_key_descriptor_entry_t); 00463 set_req.attr_index = interface->mac_parameters->mac_prev_key_attribute_id; 00464 interface->mac_api->mlme_req(interface->mac_api, MLME_SET, &set_req); 00465 set_req.attr_index = interface->mac_parameters->mac_default_key_attribute_id; 00466 interface->mac_api->mlme_req(interface->mac_api, MLME_SET, &set_req); 00467 set_req.attr_index = interface->mac_parameters->mac_next_key_attribute_id; 00468 interface->mac_api->mlme_req(interface->mac_api, MLME_SET, &set_req); 00469 } 00470 interface->mac_parameters->mac_prev_key_index = 0; 00471 interface->mac_parameters->mac_default_key_index = 0; 00472 interface->mac_parameters->mac_next_key_index = 0; 00473 } 00474 00475 void mac_helper_coordinator_address_set(protocol_interface_info_entry_t *interface, addrtype_t adr_type, uint8_t *adr_ptr) 00476 { 00477 mlme_set_t set_req; 00478 set_req.attr_index = 0; 00479 00480 if (adr_type == ADDR_802_15_4_SHORT ) { 00481 memcpy(interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address, adr_ptr, 2); 00482 interface->mac_parameters->mac_cordinator_info.cord_adr_mode = MAC_ADDR_MODE_16_BIT; 00483 uint16_t short_addr = common_read_16_bit(interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address); 00484 set_req.attr = macCoordShortAddress; 00485 set_req.value_pointer = &short_addr; 00486 set_req.value_size = 2; 00487 } else if (adr_type == ADDR_802_15_4_LONG ) { 00488 memcpy(interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address, adr_ptr, 8); 00489 interface->mac_parameters->mac_cordinator_info.cord_adr_mode = MAC_ADDR_MODE_64_BIT; 00490 set_req.attr = macCoordExtendedAddress; 00491 set_req.value_pointer = &interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address; 00492 set_req.value_size = 8; 00493 } 00494 00495 if (interface->mac_api) { 00496 interface->mac_api->mlme_req(interface->mac_api, MLME_SET, &set_req); 00497 } 00498 } 00499 00500 addrtype_t mac_helper_coordinator_address_get(protocol_interface_info_entry_t *interface, uint8_t *adr_ptr) 00501 { 00502 addrtype_t ret = ADDR_NONE ; 00503 if (!interface) { 00504 return ret; 00505 } 00506 00507 if (interface->mac_parameters->mac_cordinator_info.cord_adr_mode == MAC_ADDR_MODE_16_BIT) { 00508 memcpy(adr_ptr, interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address, 2); 00509 ret = ADDR_802_15_4_SHORT ; 00510 } else if (interface->mac_parameters->mac_cordinator_info.cord_adr_mode == MAC_ADDR_MODE_64_BIT) { 00511 memcpy(adr_ptr, interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address, 8); 00512 ret = ADDR_802_15_4_LONG ; 00513 } 00514 return ret; 00515 } 00516 00517 #define MIN(a, b) (((a) <= (b)) ? (a) : (b)) 00518 00519 static void mac_helper_beacon_payload_length_set_to_mac(protocol_interface_info_entry_t *interface, uint8_t len) 00520 { 00521 if (interface->mac_api) { 00522 mlme_set_t set_req; 00523 set_req.attr = macBeaconPayloadLength; 00524 set_req.attr_index = 0; 00525 set_req.value_pointer = &len; 00526 set_req.value_size = 1; 00527 interface->mac_api->mlme_req(interface->mac_api, MLME_SET, &set_req); 00528 } 00529 } 00530 00531 static void mac_helper_beacon_payload_set_to_mac(protocol_interface_info_entry_t *interface, const uint8_t *payload, uint8_t length) 00532 { 00533 if (interface->mac_api) { 00534 mlme_set_t set_req; 00535 set_req.attr = macBeaconPayload; 00536 set_req.attr_index = 0; 00537 set_req.value_pointer = payload; 00538 set_req.value_size = length; 00539 interface->mac_api->mlme_req(interface->mac_api, MLME_SET, &set_req); 00540 } 00541 } 00542 00543 00544 00545 // XXX: a ns_dyn_mem_realloc() would be nice to have 00546 uint8_t *mac_helper_beacon_payload_reallocate(protocol_interface_info_entry_t *interface, uint8_t len) 00547 { 00548 00549 if (len == interface->mac_parameters->mac_beacon_payload_size) { 00550 // no change to size, return the existing buff 00551 //Set allways length to zero for safe beacon payload manipulate 00552 mac_helper_beacon_payload_length_set_to_mac(interface, 0); 00553 return interface->mac_parameters->mac_beacon_payload; 00554 } 00555 00556 if (len == 0) { 00557 //SET MAC beacon payload to length to zero 00558 mac_helper_beacon_payload_length_set_to_mac(interface, 0); 00559 ns_dyn_mem_free(interface->mac_parameters->mac_beacon_payload); 00560 interface->mac_parameters->mac_beacon_payload = NULL; 00561 interface->mac_parameters->mac_beacon_payload_size = 0; 00562 return NULL; 00563 } 00564 00565 tr_debug("mac_helper_beacon_payload_reallocate, old len: %d, new: %d", interface->mac_parameters->mac_beacon_payload_size, len); 00566 00567 uint8_t *temp_buff = ns_dyn_mem_alloc(len); 00568 00569 if (temp_buff == NULL) { 00570 // no need to proceed, could not allocate more space 00571 return NULL; 00572 } 00573 00574 //SET MAC beacon payload to length to zero 00575 mac_helper_beacon_payload_length_set_to_mac(interface, 0); 00576 00577 // copy data into new buffer before freeing old one 00578 if (interface->mac_parameters->mac_beacon_payload_size > 0) { 00579 const uint8_t min_len = MIN(len, interface->mac_parameters->mac_beacon_payload_size); 00580 00581 memcpy(temp_buff, interface->mac_parameters->mac_beacon_payload, min_len); 00582 ns_dyn_mem_free(interface->mac_parameters->mac_beacon_payload); 00583 } 00584 00585 //Set New Length and pointer to MAC 00586 00587 interface->mac_parameters->mac_beacon_payload = temp_buff; 00588 interface->mac_parameters->mac_beacon_payload_size = len; 00589 00590 return interface->mac_parameters->mac_beacon_payload; 00591 } 00592 00593 int8_t mac_helper_beacon_payload_register(protocol_interface_info_entry_t *interface) 00594 { 00595 mac_helper_beacon_payload_set_to_mac(interface, interface->mac_parameters->mac_beacon_payload, interface->mac_parameters->mac_beacon_payload_size); 00596 mac_helper_beacon_payload_length_set_to_mac(interface, interface->mac_parameters->mac_beacon_payload_size); 00597 00598 return 0; 00599 } 00600 00601 uint8_t *mac_helper_beacon_payload_pointer_get(protocol_interface_info_entry_t *interface) 00602 { 00603 return interface->mac_parameters->mac_beacon_payload; 00604 } 00605 00606 uint8_t mac_helper_beacon_payload_length_get(protocol_interface_info_entry_t *interface) 00607 { 00608 return interface->mac_parameters->mac_beacon_payload_size; 00609 } 00610 00611 int8_t mac_helper_pib_boolean_set(protocol_interface_info_entry_t *interface, mlme_attr_t attribute, bool value) 00612 { 00613 00614 switch (attribute) { 00615 case macSecurityEnabled: 00616 interface->mac_parameters->SecurityEnabled = value; 00617 break; 00618 00619 case macRxOnWhenIdle: 00620 interface->mac_parameters->RxOnWhenIdle = value; 00621 break; 00622 00623 case macPromiscuousMode: 00624 interface->mac_parameters->PromiscuousMode = value; 00625 break; 00626 00627 case macGTSPermit: 00628 interface->mac_parameters->GTSPermit = value; 00629 break; 00630 00631 case macAssociationPermit: 00632 interface->mac_parameters->AssociationPermit = value; 00633 break; 00634 00635 case macAssociatedPANCoord: 00636 interface->mac_parameters->AssociatedPANCoord = value; 00637 break; 00638 00639 case macTimestampSupported: 00640 interface->mac_parameters->TimestampSupported = value; 00641 break; 00642 00643 case macBattLifeExt: 00644 interface->mac_parameters->BattLifeExt = value; 00645 break; 00646 00647 case macAutoRequest: 00648 interface->mac_parameters->AutoRequest = value; 00649 break; 00650 case macThreadForceLongAddressForBeacon: 00651 break; 00652 default: 00653 return -1; 00654 } 00655 if (interface->mac_api && interface->mac_api->mlme_req) { 00656 mlme_set_t set_req; 00657 set_req.attr = attribute; 00658 set_req.attr_index = 0; 00659 set_req.value_pointer = &value; 00660 set_req.value_size = sizeof(bool); 00661 interface->mac_api->mlme_req(interface->mac_api, MLME_SET, &set_req); 00662 } 00663 00664 return 0; 00665 } 00666 00667 int8_t mac_helper_mac_channel_set(protocol_interface_info_entry_t *interface, uint8_t new_channel) 00668 { 00669 00670 if (interface->mac_parameters->mac_channel != new_channel) { 00671 00672 interface->mac_parameters->mac_channel = new_channel; 00673 if (interface->mac_api && interface->mac_api->mlme_req) { 00674 mlme_set_t set_req; 00675 set_req.attr = phyCurrentChannel; 00676 set_req.attr_index = 0; 00677 set_req.value_pointer = &new_channel; 00678 set_req.value_size = 1; 00679 interface->mac_api->mlme_req(interface->mac_api, MLME_SET, &set_req); 00680 } 00681 } 00682 return 0; 00683 } 00684 00685 static bool mac_helper_write_16bit(uint16_t temp16, uint8_t *addrPtr) 00686 { 00687 common_write_16_bit(temp16, addrPtr); 00688 return temp16 != 0xffff; 00689 } 00690 00691 /* Write functions return "false" if they write an "odd" address, true if they 00692 * write a "normal" address. They still write odd addresses, as certain special 00693 * packets may want them, but this allows normal data paths to check and block 00694 * odd cases. 00695 * "Odd" is currently defined as PAN ID == 0xffff, or short address > 0xfffd. 00696 */ 00697 bool mac_helper_write_our_addr(protocol_interface_info_entry_t *interface, sockaddr_t *ptr) 00698 { 00699 bool normal = true; 00700 00701 //Set First PANID 00702 normal &= mac_helper_write_16bit(interface->mac_parameters->pan_id, ptr->address ); 00703 00704 if (ptr->addr_type != ADDR_802_15_4_LONG && ptr->addr_type != ADDR_802_15_4_SHORT ) { 00705 if (interface->mac_parameters->shortAdressValid) { 00706 ptr->addr_type = ADDR_802_15_4_SHORT ; 00707 } else { 00708 ptr->addr_type = ADDR_802_15_4_LONG ; 00709 } 00710 } 00711 00712 if (ptr->addr_type == ADDR_802_15_4_SHORT ) { 00713 normal &= mac_helper_write_16bit(interface->mac_parameters->mac_short_address, &ptr->address [2]); 00714 } else { 00715 memcpy(&ptr->address [2], interface->mac, 8); 00716 } 00717 00718 return normal; 00719 } 00720 00721 int8_t mac_helper_mac64_set(protocol_interface_info_entry_t *interface, const uint8_t *mac64) 00722 { 00723 memcpy(interface->mac, mac64, 8); 00724 if (interface->mac_api) { 00725 interface->mac_api->mac64_set(interface->mac_api, mac64); 00726 } 00727 return 0; 00728 } 00729 00730 00731 /* 00732 * Given a buffer, with address and security flags set, compute the maximum 00733 * MAC payload that could be put in that buffer. 00734 */ 00735 uint_fast16_t mac_helper_max_payload_size(protocol_interface_info_entry_t *cur, uint_fast16_t frame_overhead) 00736 { 00737 uint16_t max; 00738 00739 max = cur->mac_api->phyMTU - frame_overhead; 00740 00741 /* But if we want IEEE 802.15.4-2003 compatibility (and it looks like a 00742 * standard PHY), limit ourselves to the 2003 maximum */ 00743 if (cur->mac_parameters->MacUnsusecured_2003_cab && max > MAC_IEEE_802_15_4_MAX_MAC_SAFE_PAYLOAD_SIZE && 00744 cur->mac_api->phyMTU == MAC_IEEE_802_15_4_MAX_PHY_PACKET_SIZE) { 00745 max = MAC_IEEE_802_15_4_MAX_MAC_SAFE_PAYLOAD_SIZE; 00746 } 00747 return max; 00748 } 00749 00750 /* 00751 * Given a buffer, with address and security flags set, compute the MAC overhead 00752 * size once MAC header and footer are added. 00753 * May not be accurate if MAC_MAX_PHY_PACKET_SIZE isn't set, implying a 00754 * non-standard MAC. 00755 */ 00756 uint_fast8_t mac_helper_frame_overhead(protocol_interface_info_entry_t *cur, const buffer_t *buf) 00757 { 00758 uint_fast8_t length = 15; 00759 00760 /*8bytes src address, 2 frame control, 1 sequence, 2 pan-id, 2 FCS*/ 00761 if (buf->src_sa .addr_type == ADDR_NONE ) { 00762 if (cur->mac_parameters->shortAdressValid) { 00763 length -= 6; //Cut 6 bytes from src address 00764 } 00765 } else if (buf->src_sa .addr_type == ADDR_802_15_4_SHORT ) { 00766 length -= 6; //Cut 6 bytes from src address 00767 } 00768 00769 if (memcmp(buf->dst_sa .address , buf->src_sa .address , 2) == 0) { 00770 length -= 2; // Cut Pan-id 00771 } 00772 00773 if (buf->dst_sa .addr_type == ADDR_802_15_4_LONG ) { 00774 length += 10; 00775 } else if (buf->dst_sa .addr_type == ADDR_802_15_4_SHORT || buf->dst_sa .addr_type == ADDR_BROADCAST ) { 00776 length += 4; 00777 } 00778 00779 if (cur->mac_parameters->mac_security_level && (!buf->options .ll_security_bypass_tx )) { 00780 length += mac_helper_header_security_aux_header_length(cur->mac_parameters->mac_key_id_mode); 00781 length += mac_helper_security_mic_length_get(cur->mac_parameters->mac_security_level); 00782 } 00783 00784 return length; 00785 } 00786 00787 static uint8_t mac_helper_security_mic_length_get(uint8_t security_level) 00788 { 00789 uint8_t mic_length; 00790 switch (security_level) { 00791 case SEC_MIC32: 00792 case SEC_ENC_MIC32: 00793 mic_length = 4; 00794 break; 00795 case SEC_MIC64: 00796 case SEC_ENC_MIC64: 00797 mic_length = 8; 00798 break; 00799 case SEC_MIC128: 00800 case SEC_ENC_MIC128: 00801 mic_length = 16; 00802 break; 00803 case SEC_NONE: 00804 case SEC_ENC: 00805 default: 00806 mic_length = 0; 00807 break; 00808 } 00809 00810 return mic_length; 00811 } 00812 00813 static uint8_t mac_helper_header_security_aux_header_length(uint8_t keyIdmode) 00814 { 00815 00816 uint8_t header_length = 5; //Header + 32-bit counter 00817 switch (keyIdmode) { 00818 case MAC_KEY_ID_MODE_SRC8_IDX: 00819 header_length += 4; //64-bit key source first part 00820 /* fall through */ 00821 case MAC_KEY_ID_MODE_SRC4_IDX: 00822 header_length += 4; //32-bit key source inline 00823 /* fall through */ 00824 case MAC_KEY_ID_MODE_IDX: 00825 header_length += 1; 00826 break; 00827 default: 00828 break; 00829 } 00830 return header_length; 00831 } 00832 00833 int8_t mac_helper_link_frame_counter_read(int8_t interface_id, uint32_t *seq_ptr) 00834 { 00835 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00836 00837 if (!cur || !cur->mac_api || !seq_ptr) { 00838 return -1; 00839 } 00840 00841 return mac_helper_key_link_frame_counter_read(interface_id, seq_ptr, cur->mac_parameters->mac_default_key_attribute_id); 00842 } 00843 00844 int8_t mac_helper_link_frame_counter_set(int8_t interface_id, uint32_t seq_ptr) 00845 { 00846 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00847 00848 if (!cur || !cur->mac_api) { 00849 return -1; 00850 } 00851 00852 return mac_helper_key_link_frame_counter_set(interface_id, seq_ptr, cur->mac_parameters->mac_default_key_attribute_id); 00853 } 00854 00855 int8_t mac_helper_key_link_frame_counter_read(int8_t interface_id, uint32_t *seq_ptr, uint8_t descriptor) 00856 { 00857 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00858 00859 if (!cur || !cur->mac_api || !seq_ptr) { 00860 return -1; 00861 } 00862 mlme_get_t get_req; 00863 get_req.attr = macFrameCounter; 00864 get_req.attr_index = descriptor; 00865 cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req); 00866 *seq_ptr = cur->mac_parameters->security_frame_counter; 00867 00868 return 0; 00869 } 00870 00871 int8_t mac_helper_key_link_frame_counter_set(int8_t interface_id, uint32_t seq_ptr, uint8_t descriptor) 00872 { 00873 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00874 00875 if (!cur || !cur->mac_api) { 00876 return -1; 00877 } 00878 mlme_set_t set_req; 00879 set_req.attr = macFrameCounter; 00880 set_req.attr_index = descriptor; 00881 set_req.value_pointer = &seq_ptr; 00882 set_req.value_size = 4; 00883 cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req); 00884 00885 return 0; 00886 } 00887 00888 void mac_helper_devicetable_remove(mac_api_t *mac_api, uint8_t attribute_index, uint8_t *mac64) 00889 { 00890 if (!mac_api) { 00891 return; 00892 } 00893 00894 mlme_device_descriptor_t device_desc; 00895 mlme_set_t set_req; 00896 memset(&device_desc, 0xff, sizeof(mlme_device_descriptor_t)); 00897 00898 set_req.attr = macDeviceTable; 00899 set_req.attr_index = attribute_index; 00900 set_req.value_pointer = (void *)&device_desc; 00901 set_req.value_size = sizeof(mlme_device_descriptor_t); 00902 tr_debug("Unregister Device %u, mac64: %s", attribute_index, trace_array(mac64, 8)); 00903 mac_api->mlme_req(mac_api, MLME_SET, &set_req); 00904 } 00905 00906 void mac_helper_device_description_write(protocol_interface_info_entry_t *cur, mlme_device_descriptor_t *device_desc, uint8_t *mac64, uint16_t mac16, uint32_t frame_counter, bool exempt) 00907 { 00908 memcpy(device_desc->ExtAddress, mac64, 8); 00909 device_desc->ShortAddress = mac16; 00910 device_desc->PANId = mac_helper_panid_get(cur); 00911 device_desc->Exempt = exempt; 00912 device_desc->FrameCounter = frame_counter; 00913 } 00914 00915 void mac_helper_devicetable_set(const mlme_device_descriptor_t *device_desc, protocol_interface_info_entry_t *cur, uint8_t attribute_index, uint8_t keyID, bool force_set) 00916 00917 { 00918 if (!cur->mac_api) { 00919 return; 00920 } 00921 00922 if (!force_set && cur->mac_parameters->SecurityEnabled && cur->mac_parameters->mac_default_key_index != keyID) { 00923 tr_debug("Do not set counter by index %u != %u", cur->mac_parameters->mac_default_key_index, keyID); 00924 return; 00925 } 00926 00927 mlme_set_t set_req; 00928 set_req.attr = macDeviceTable; 00929 set_req.attr_index = attribute_index; 00930 set_req.value_pointer = (void *)device_desc; 00931 set_req.value_size = sizeof(mlme_device_descriptor_t); 00932 tr_debug("Register Device %u, mac16 %x mac64: %s, %"PRIu32, attribute_index, device_desc->ShortAddress, trace_array(device_desc->ExtAddress, 8), device_desc->FrameCounter); 00933 cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req); 00934 } 00935 00936 00937 int8_t mac_helper_mac_mlme_max_retry_set(int8_t interface_id, uint8_t mac_retry_set) 00938 { 00939 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00940 00941 if (!cur || !cur->mac_api) { 00942 return -1; 00943 } 00944 mlme_set_t set_req; 00945 set_req.attr = macMaxFrameRetries; 00946 set_req.attr_index = 0; 00947 set_req.value_pointer = &mac_retry_set; 00948 set_req.value_size = 1; 00949 cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req); 00950 00951 return 0; 00952 } 00953 00954 00955 int8_t mac_helper_mac_device_description_pan_id_update(int8_t interface_id, uint16_t pan_id) 00956 { 00957 protocol_interface_info_entry_t *cur; 00958 cur = protocol_stack_interface_info_get_by_id(interface_id); 00959 if (!cur || !cur->mac_api) { 00960 return -1; 00961 } 00962 mlme_set_t set_req; 00963 set_req.attr = macDeviceDescriptionPanIDUpdate; 00964 set_req.attr_index = 0; 00965 set_req.value_pointer = &pan_id; 00966 set_req.value_size = sizeof(pan_id); 00967 cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req); 00968 return 0; 00969 }
Generated on Tue Jul 12 2022 13:54:31 by
