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