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-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 mlme_set_t set_req; 00285 mlme_key_id_lookup_descriptor_t lookup_description; 00286 mlme_key_descriptor_entry_t key_description; 00287 if (key) { 00288 mac_helper_key_lookup_set(&lookup_description, id); 00289 memset(&key_description, 0, sizeof(mlme_key_descriptor_entry_t)); 00290 memcpy(key_description.Key, key, 16); 00291 key_description.KeyIdLookupList = &lookup_description; 00292 key_description.KeyIdLookupListEntries = 1; 00293 } else { 00294 memset(&key_description, 0, sizeof(mlme_key_descriptor_entry_t)); 00295 } 00296 set_req.attr = macKeyTable; 00297 set_req.attr_index = attribute_id; 00298 set_req.value_pointer = &key_description; 00299 set_req.value_size = sizeof(mlme_key_descriptor_entry_t); 00300 00301 api->mlme_req(api, MLME_SET, &set_req); 00302 } 00303 00304 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) { 00305 mlme_set_t set_req; 00306 mlme_key_id_lookup_descriptor_t lookup_description; 00307 mlme_key_descriptor_entry_t key_description; 00308 if (key) { 00309 memcpy(lookup_description.LookupData, mac64, 8); 00310 lookup_description.LookupData[8] = 0; 00311 lookup_description.LookupDataSize = 1; 00312 tr_debug("Key add %u index %s", attribute_id,trace_array(lookup_description.LookupData, 9)); 00313 memset(&key_description, 0, sizeof(mlme_key_descriptor_entry_t)); 00314 memcpy(key_description.Key, key, 16); 00315 key_description.KeyIdLookupList = &lookup_description; 00316 key_description.KeyIdLookupListEntries = 1; 00317 } else { 00318 memset(&key_description, 0, sizeof(mlme_key_descriptor_entry_t)); 00319 } 00320 set_req.attr = macKeyTable; 00321 set_req.attr_index = attribute_id; 00322 set_req.value_pointer = &key_description; 00323 set_req.value_size = sizeof(mlme_key_descriptor_entry_t); 00324 00325 api->mlme_req(api,MLME_SET , &set_req); 00326 } 00327 00328 00329 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) 00330 { 00331 if (id == 0 || keyid_mode > 3) { 00332 return -1; 00333 } 00334 00335 mac_helper_pib_8bit_set(interface,macAutoRequestKeyIndex, id); 00336 mac_helper_keytable_descriptor_set(interface->mac_api, key, id, interface->mac_parameters->mac_default_key_attribute_id); 00337 return 0; 00338 } 00339 00340 00341 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) 00342 { 00343 if (key && !mac_64) { 00344 return -1; 00345 } 00346 00347 mac_helper_keytable_pairwise_descriptor_set(interface->mac_api, key, mac_64, key_attribute); 00348 return 0; 00349 } 00350 00351 int8_t mac_helper_security_next_key_set(protocol_interface_info_entry_t *interface, uint8_t *key, uint8_t id, uint8_t keyid_mode) 00352 { 00353 if (id == 0 || keyid_mode > 3) { 00354 return -1; 00355 } 00356 00357 interface->mac_parameters->mac_next_key_index = id; 00358 mac_helper_keytable_descriptor_set(interface->mac_api, key, id, interface->mac_parameters->mac_next_key_attribute_id); 00359 return 0; 00360 00361 } 00362 00363 int8_t mac_helper_security_prev_key_set(protocol_interface_info_entry_t *interface, uint8_t *key, uint8_t id, uint8_t keyid_mode) 00364 { 00365 if (id == 0 || keyid_mode > 3) { 00366 return -1; 00367 } 00368 00369 interface->mac_parameters->mac_prev_key_index = id; 00370 mac_helper_keytable_descriptor_set(interface->mac_api, key, id, interface->mac_parameters->mac_prev_key_attribute_id); 00371 return 0; 00372 00373 } 00374 00375 00376 void mac_helper_security_key_swap_next_to_default(protocol_interface_info_entry_t *interface) 00377 { 00378 //Free old prev key 00379 /* 00380 * Update key setup next way 00381 * 00382 * Current Key -> Prev key 00383 * Next Key -> Current key 00384 * Prev Key ->Overwrite by for next Purpose 00385 */ 00386 00387 00388 //Free current prev 00389 mac_helper_keytable_descriptor_set(interface->mac_api, NULL, 0, interface->mac_parameters->mac_prev_key_attribute_id); 00390 00391 uint8_t prev_attribute = interface->mac_parameters->mac_prev_key_attribute_id; //save current pre for next purpose 00392 00393 interface->mac_parameters->mac_prev_key_index = interface->mac_parameters->mac_default_key_index; 00394 interface->mac_parameters->mac_prev_key_attribute_id = interface->mac_parameters->mac_default_key_attribute_id; 00395 00396 interface->mac_parameters->mac_default_key_index = interface->mac_parameters->mac_next_key_index; 00397 interface->mac_parameters->mac_default_key_attribute_id = interface->mac_parameters->mac_next_key_attribute_id; 00398 interface->mac_parameters->mac_next_key_index = 0; 00399 interface->mac_parameters->mac_next_key_attribute_id = prev_attribute; 00400 00401 mac_helper_pib_8bit_set(interface,macAutoRequestKeyIndex, interface->mac_parameters->mac_default_key_index); 00402 00403 } 00404 00405 void mac_helper_security_key_clean(protocol_interface_info_entry_t *interface) { 00406 if (interface->mac_api ) { 00407 mlme_set_t set_req; 00408 mlme_key_descriptor_entry_t key_description; 00409 memset(&key_description, 0, sizeof(mlme_key_descriptor_entry_t)); 00410 00411 set_req.attr = macKeyTable; 00412 00413 set_req.value_pointer = &key_description; 00414 set_req.value_size = sizeof(mlme_key_descriptor_entry_t); 00415 set_req.attr_index = interface->mac_parameters->mac_prev_key_attribute_id; 00416 interface->mac_api->mlme_req(interface->mac_api,MLME_SET , &set_req); 00417 set_req.attr_index = interface->mac_parameters->mac_default_key_attribute_id; 00418 interface->mac_api->mlme_req(interface->mac_api,MLME_SET , &set_req); 00419 set_req.attr_index = interface->mac_parameters->mac_next_key_attribute_id; 00420 interface->mac_api->mlme_req(interface->mac_api,MLME_SET , &set_req); 00421 } 00422 interface->mac_parameters->mac_prev_key_index = 0; 00423 interface->mac_parameters->mac_default_key_index = 0; 00424 interface->mac_parameters->mac_next_key_index = 0; 00425 } 00426 00427 void mac_helper_coordinator_address_set(protocol_interface_info_entry_t *interface, addrtype_t adr_type, uint8_t *adr_ptr) 00428 { 00429 mlme_set_t set_req; 00430 set_req.attr_index = 0; 00431 00432 if (adr_type == ADDR_802_15_4_SHORT ) { 00433 memcpy(interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address, adr_ptr, 2); 00434 interface->mac_parameters->mac_cordinator_info.cord_adr_mode = MAC_ADDR_MODE_16_BIT; 00435 uint16_t short_addr = common_read_16_bit(interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address); 00436 set_req.attr = macCoordShortAddress; 00437 set_req.value_pointer = &short_addr; 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_fast16_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 /* fall through */ 00771 case MAC_KEY_ID_MODE_SRC4_IDX: 00772 header_length += 4; //32-bit key source inline 00773 /* fall through */ 00774 case MAC_KEY_ID_MODE_IDX: 00775 header_length += 1; 00776 break; 00777 default: 00778 break; 00779 } 00780 return header_length; 00781 } 00782 00783 int8_t mac_helper_link_frame_counter_read(int8_t interface_id, uint32_t *seq_ptr) 00784 { 00785 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00786 00787 if (!cur || !cur->mac_api || !seq_ptr) { 00788 return -1; 00789 } 00790 mlme_get_t get_req; 00791 get_req.attr = macFrameCounter; 00792 get_req.attr_index = 0; 00793 cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req); 00794 *seq_ptr = cur->mac_parameters->security_frame_counter; 00795 00796 return 0; 00797 } 00798 00799 00800 int8_t mac_helper_link_frame_counter_set(int8_t interface_id, uint32_t seq_ptr) 00801 { 00802 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00803 00804 if (!cur || !cur->mac_api) { 00805 return -1; 00806 } 00807 mlme_set_t set_req; 00808 set_req.attr = macFrameCounter; 00809 set_req.attr_index = 0; 00810 set_req.value_pointer = &seq_ptr; 00811 set_req.value_size = 4; 00812 cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req); 00813 00814 return 0; 00815 } 00816 00817 void mac_helper_devicetable_remove(mac_api_t *mac_api, uint8_t attribute_index) 00818 { 00819 if (!mac_api) { 00820 return; 00821 } 00822 00823 mlme_device_descriptor_t device_desc; 00824 mlme_set_t set_req; 00825 memset(&device_desc, 0xff, sizeof(mlme_device_descriptor_t)); 00826 00827 set_req.attr = macDeviceTable; 00828 set_req.attr_index = attribute_index; 00829 set_req.value_pointer = (void*)&device_desc; 00830 set_req.value_size = sizeof(mlme_device_descriptor_t); 00831 tr_debug("unRegister Device"); 00832 mac_api->mlme_req(mac_api,MLME_SET , &set_req); 00833 } 00834 00835 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) 00836 { 00837 memcpy(device_desc->ExtAddress, mac64, 8); 00838 device_desc->ShortAddress = mac16; 00839 device_desc->PANId = mac_helper_panid_get(cur); 00840 device_desc->Exempt = exempt; 00841 device_desc->FrameCounter = frame_counter; 00842 } 00843 00844 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) 00845 00846 { 00847 if (!cur->mac_api) { 00848 return; 00849 } 00850 00851 if (!force_set && cur->mac_parameters->SecurityEnabled && cur->mac_parameters->mac_default_key_index != keyID) { 00852 tr_debug("Do not set counter by index %u != %u", cur->mac_parameters->mac_default_key_index, keyID); 00853 return; 00854 } 00855 00856 mlme_set_t set_req; 00857 set_req.attr = macDeviceTable; 00858 set_req.attr_index = attribute_index; 00859 set_req.value_pointer = (void*)device_desc; 00860 set_req.value_size = sizeof(mlme_device_descriptor_t); 00861 tr_debug("Register Device"); 00862 cur->mac_api->mlme_req(cur->mac_api,MLME_SET , &set_req); 00863 } 00864 00865 00866 int8_t mac_helper_mac_mlme_max_retry_set(int8_t interface_id, uint8_t mac_retry_set) 00867 { 00868 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00869 00870 if (!cur || !cur->mac_api) { 00871 return -1; 00872 } 00873 mlme_set_t set_req; 00874 set_req.attr = macMaxFrameRetries; 00875 set_req.attr_index = 0; 00876 set_req.value_pointer = &mac_retry_set; 00877 set_req.value_size = 1; 00878 cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req); 00879 00880 return 0; 00881 }
Generated on Tue Aug 9 2022 00:37:12 by
1.7.2