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 uint16_t short_addr = common_read_16_bit(interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address); 00437 set_req.attr = macCoordShortAddress; 00438 set_req.value_pointer = &short_addr; 00439 set_req.value_size = 2; 00440 } else if (adr_type == ADDR_802_15_4_LONG ) { 00441 memcpy(interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address, adr_ptr, 8); 00442 interface->mac_parameters->mac_cordinator_info.cord_adr_mode = MAC_ADDR_MODE_64_BIT; 00443 set_req.attr = macCoordExtendedAddress; 00444 set_req.value_pointer = &interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address; 00445 set_req.value_size = 8; 00446 } 00447 00448 if (interface->mac_api) { 00449 interface->mac_api->mlme_req(interface->mac_api, MLME_SET , &set_req); 00450 } 00451 } 00452 00453 addrtype_t mac_helper_coordinator_address_get(protocol_interface_info_entry_t *interface, uint8_t *adr_ptr) 00454 { 00455 addrtype_t ret = ADDR_NONE ; 00456 if (!interface) { 00457 return ret; 00458 } 00459 00460 if (interface->mac_parameters->mac_cordinator_info.cord_adr_mode == MAC_ADDR_MODE_16_BIT) { 00461 memcpy(adr_ptr,interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address, 2); 00462 ret = ADDR_802_15_4_SHORT ; 00463 } else if (interface->mac_parameters->mac_cordinator_info.cord_adr_mode == MAC_ADDR_MODE_64_BIT) { 00464 memcpy(adr_ptr,interface->mac_parameters->mac_cordinator_info.mac_mlme_coord_address, 8); 00465 ret = ADDR_802_15_4_LONG ; 00466 } 00467 return ret; 00468 } 00469 00470 #define MIN(a, b) (((a) <= (b)) ? (a) : (b)) 00471 00472 static void mac_helper_beacon_payload_length_set_to_mac(protocol_interface_info_entry_t *interface, uint8_t len) 00473 { 00474 if (interface->mac_api) { 00475 mlme_set_t set_req; 00476 set_req.attr = macBeaconPayloadLength; 00477 set_req.attr_index = 0; 00478 set_req.value_pointer = &len; 00479 set_req.value_size = 1; 00480 interface->mac_api->mlme_req(interface->mac_api,MLME_SET , &set_req); 00481 } 00482 } 00483 00484 static void mac_helper_beacon_payload_set_to_mac(protocol_interface_info_entry_t *interface, const uint8_t *payload, uint8_t length) 00485 { 00486 if (interface->mac_api) { 00487 mlme_set_t set_req; 00488 set_req.attr = macBeaconPayload; 00489 set_req.attr_index = 0; 00490 set_req.value_pointer = payload; 00491 set_req.value_size = length; 00492 interface->mac_api->mlme_req(interface->mac_api,MLME_SET , &set_req); 00493 } 00494 } 00495 00496 00497 00498 // XXX: a ns_dyn_mem_realloc() would be nice to have 00499 uint8_t *mac_helper_beacon_payload_reallocate(protocol_interface_info_entry_t *interface, uint8_t len) 00500 { 00501 00502 if (len == interface->mac_parameters->mac_beacon_payload_size) { 00503 // no change to size, return the existing buff 00504 //Set allways length to zero for safe beacon payload manipulate 00505 mac_helper_beacon_payload_length_set_to_mac(interface,0); 00506 return interface->mac_parameters->mac_beacon_payload; 00507 } 00508 00509 if (len == 0) { 00510 //SET MAC beacon payload to length to zero 00511 mac_helper_beacon_payload_length_set_to_mac(interface,0); 00512 ns_dyn_mem_free(interface->mac_parameters->mac_beacon_payload); 00513 interface->mac_parameters->mac_beacon_payload = NULL; 00514 interface->mac_parameters->mac_beacon_payload_size = 0; 00515 return NULL; 00516 } 00517 00518 tr_debug("mac_helper_beacon_payload_reallocate, old len: %d, new: %d", interface->mac_parameters->mac_beacon_payload_size, len); 00519 00520 uint8_t* temp_buff = ns_dyn_mem_alloc(len); 00521 00522 if (temp_buff == NULL) { 00523 // no need to proceed, could not allocate more space 00524 return NULL; 00525 } 00526 00527 //SET MAC beacon payload to length to zero 00528 mac_helper_beacon_payload_length_set_to_mac(interface,0); 00529 00530 // copy data into new buffer before freeing old one 00531 if (interface->mac_parameters->mac_beacon_payload_size > 0) { 00532 const uint8_t min_len = MIN(len, interface->mac_parameters->mac_beacon_payload_size); 00533 00534 memcpy(temp_buff, interface->mac_parameters->mac_beacon_payload, min_len); 00535 ns_dyn_mem_free(interface->mac_parameters->mac_beacon_payload); 00536 } 00537 00538 //Set New Length and pointer to MAC 00539 00540 interface->mac_parameters->mac_beacon_payload = temp_buff; 00541 interface->mac_parameters->mac_beacon_payload_size = len; 00542 00543 return interface->mac_parameters->mac_beacon_payload; 00544 } 00545 00546 int8_t mac_helper_beacon_payload_register(protocol_interface_info_entry_t *interface) 00547 { 00548 mac_helper_beacon_payload_set_to_mac(interface, interface->mac_parameters->mac_beacon_payload, interface->mac_parameters->mac_beacon_payload_size); 00549 mac_helper_beacon_payload_length_set_to_mac(interface, interface->mac_parameters->mac_beacon_payload_size); 00550 00551 return 0; 00552 } 00553 00554 uint8_t *mac_helper_beacon_payload_pointer_get(protocol_interface_info_entry_t *interface) 00555 { 00556 return interface->mac_parameters->mac_beacon_payload; 00557 } 00558 00559 uint8_t mac_helper_beacon_payload_length_get(protocol_interface_info_entry_t *interface) 00560 { 00561 return interface->mac_parameters->mac_beacon_payload_size; 00562 } 00563 00564 int8_t mac_helper_pib_boolean_set(protocol_interface_info_entry_t *interface, mlme_attr_t attribute, bool value) 00565 { 00566 00567 switch (attribute) { 00568 case macSecurityEnabled: 00569 interface->mac_parameters->SecurityEnabled = value; 00570 break; 00571 00572 case macRxOnWhenIdle: 00573 interface->mac_parameters->RxOnWhenIdle = value; 00574 break; 00575 00576 case macPromiscuousMode: 00577 interface->mac_parameters->PromiscuousMode = value; 00578 break; 00579 00580 case macGTSPermit: 00581 interface->mac_parameters->GTSPermit = value; 00582 break; 00583 00584 case macAssociationPermit: 00585 interface->mac_parameters->AssociationPermit = value; 00586 break; 00587 00588 case macAssociatedPANCoord: 00589 interface->mac_parameters->AssociatedPANCoord = value; 00590 break; 00591 00592 case macTimestampSupported: 00593 interface->mac_parameters->TimestampSupported = value; 00594 break; 00595 00596 case macBattLifeExt: 00597 interface->mac_parameters->BattLifeExt = value; 00598 break; 00599 00600 case macAutoRequest: 00601 interface->mac_parameters->AutoRequest = value; 00602 break; 00603 case macThreadForceLongAddressForBeacon: 00604 break; 00605 default: 00606 return -1; 00607 } 00608 if (interface->mac_api && interface->mac_api->mlme_req) { 00609 mlme_set_t set_req; 00610 set_req.attr = attribute; 00611 set_req.attr_index = 0; 00612 set_req.value_pointer = &value; 00613 set_req.value_size = sizeof(bool); 00614 interface->mac_api->mlme_req(interface->mac_api,MLME_SET , &set_req); 00615 } 00616 00617 return 0; 00618 } 00619 00620 int8_t mac_helper_mac_channel_set(protocol_interface_info_entry_t *interface, uint8_t new_channel) 00621 { 00622 00623 if (interface->mac_parameters->mac_channel != new_channel) { 00624 00625 interface->mac_parameters->mac_channel = new_channel; 00626 if (interface->mac_api && interface->mac_api->mlme_req ) { 00627 mlme_set_t set_req; 00628 set_req.attr = phyCurrentChannel; 00629 set_req.attr_index = 0; 00630 set_req.value_pointer = &new_channel; 00631 set_req.value_size = 1; 00632 interface->mac_api->mlme_req(interface->mac_api,MLME_SET , &set_req); 00633 } 00634 } 00635 return 0; 00636 } 00637 00638 static bool mac_helper_write_16bit(uint16_t temp16, uint8_t *addrPtr) 00639 { 00640 common_write_16_bit(temp16, addrPtr); 00641 return temp16 != 0xffff; 00642 } 00643 00644 /* Write functions return "false" if they write an "odd" address, true if they 00645 * write a "normal" address. They still write odd addresses, as certain special 00646 * packets may want them, but this allows normal data paths to check and block 00647 * odd cases. 00648 * "Odd" is currently defined as PAN ID == 0xffff, or short address > 0xfffd. 00649 */ 00650 bool mac_helper_write_our_addr(protocol_interface_info_entry_t *interface, sockaddr_t *ptr) 00651 { 00652 bool normal = true; 00653 00654 //Set First PANID 00655 normal &= mac_helper_write_16bit(interface->mac_parameters->pan_id, ptr->address ); 00656 00657 if (ptr->addr_type != ADDR_802_15_4_LONG && ptr->addr_type != ADDR_802_15_4_SHORT ) { 00658 if (interface->mac_parameters->shortAdressValid) { 00659 ptr->addr_type = ADDR_802_15_4_SHORT ; 00660 } else { 00661 ptr->addr_type = ADDR_802_15_4_LONG ; 00662 } 00663 } 00664 00665 if (ptr->addr_type == ADDR_802_15_4_SHORT ) { 00666 normal &= mac_helper_write_16bit(interface->mac_parameters->mac_short_address, &ptr->address [2]); 00667 } else { 00668 memcpy(&ptr->address [2], interface->mac, 8); 00669 } 00670 00671 return normal; 00672 } 00673 00674 int8_t mac_helper_mac64_set(protocol_interface_info_entry_t *interface, const uint8_t *mac64) 00675 { 00676 memcpy(interface->mac, mac64, 8); 00677 if (interface->mac_api ) { 00678 interface->mac_api->mac64_set(interface->mac_api, mac64); 00679 } 00680 return 0; 00681 } 00682 00683 00684 /* 00685 * Given a buffer, with address and security flags set, compute the maximum 00686 * MAC payload that could be put in that buffer. 00687 */ 00688 uint_fast16_t mac_helper_max_payload_size(protocol_interface_info_entry_t *cur, uint_fast8_t frame_overhead) 00689 { 00690 uint16_t max; 00691 00692 max = cur->mac_api->phyMTU - frame_overhead; 00693 00694 /* But if we want IEEE 802.15.4-2003 compatibility (and it looks like a 00695 * standard PHY), limit ourselves to the 2003 maximum */ 00696 if (cur->mac_parameters->MacUnsusecured_2003_cab && max > MAC_IEEE_802_15_4_MAX_MAC_SAFE_PAYLOAD_SIZE && 00697 cur->mac_api->phyMTU == MAC_IEEE_802_15_4_MAX_PHY_PACKET_SIZE) { 00698 max = MAC_IEEE_802_15_4_MAX_MAC_SAFE_PAYLOAD_SIZE; 00699 } 00700 return max; 00701 } 00702 00703 /* 00704 * Given a buffer, with address and security flags set, compute the MAC overhead 00705 * size once MAC header and footer are added. 00706 * May not be accurate if MAC_MAX_PHY_PACKET_SIZE isn't set, implying a 00707 * non-standard MAC. 00708 */ 00709 uint_fast8_t mac_helper_frame_overhead(protocol_interface_info_entry_t *cur, const buffer_t *buf) 00710 { 00711 uint_fast8_t length = 15; 00712 00713 /*8bytes src address, 2 frame control, 1 sequence, 2 pan-id, 2 FCS*/ 00714 if (buf->src_sa .addr_type == ADDR_NONE ) { 00715 if (cur->mac_parameters->shortAdressValid) { 00716 length -= 6; //Cut 6 bytes from src address 00717 } 00718 } else if (buf->src_sa .addr_type == ADDR_802_15_4_SHORT ) { 00719 length -= 6; //Cut 6 bytes from src address 00720 } 00721 00722 if (memcmp(buf->dst_sa .address , buf->src_sa .address , 2) == 0) { 00723 length -= 2; // Cut Pan-id 00724 } 00725 00726 if (buf->dst_sa .addr_type == ADDR_802_15_4_LONG ) { 00727 length += 10; 00728 } else if (buf->dst_sa .addr_type == ADDR_802_15_4_SHORT || buf->dst_sa .addr_type == ADDR_BROADCAST ) { 00729 length += 4; 00730 } 00731 00732 if (cur->mac_parameters->mac_security_level && (!buf->options .ll_security_bypass_tx )) { 00733 length += mac_helper_header_security_aux_header_length(cur->mac_parameters->mac_key_id_mode); 00734 length += mac_helper_security_mic_length_get(cur->mac_parameters->mac_security_level); 00735 } 00736 00737 return length; 00738 } 00739 00740 static uint8_t mac_helper_security_mic_length_get(uint8_t security_level) { 00741 uint8_t mic_length; 00742 switch (security_level) { 00743 case SEC_MIC32: 00744 case SEC_ENC_MIC32: 00745 mic_length = 4; 00746 break; 00747 case SEC_MIC64: 00748 case SEC_ENC_MIC64: 00749 mic_length = 8; 00750 break; 00751 case SEC_MIC128: 00752 case SEC_ENC_MIC128: 00753 mic_length = 16; 00754 break; 00755 case SEC_NONE: 00756 case SEC_ENC: 00757 default: 00758 mic_length = 0; 00759 break; 00760 } 00761 00762 return mic_length; 00763 } 00764 00765 static uint8_t mac_helper_header_security_aux_header_length(uint8_t keyIdmode) { 00766 00767 uint8_t header_length = 5; //Header + 32-bit counter 00768 switch (keyIdmode) { 00769 case MAC_KEY_ID_MODE_SRC8_IDX: 00770 header_length += 4; //64-bit key source first part 00771 /* fall through */ 00772 case MAC_KEY_ID_MODE_SRC4_IDX: 00773 header_length += 4; //32-bit key source inline 00774 /* fall through */ 00775 case MAC_KEY_ID_MODE_IDX: 00776 header_length += 1; 00777 break; 00778 default: 00779 break; 00780 } 00781 return header_length; 00782 } 00783 00784 int8_t mac_helper_link_frame_counter_read(int8_t interface_id, uint32_t *seq_ptr) 00785 { 00786 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00787 00788 if (!cur || !cur->mac_api || !seq_ptr) { 00789 return -1; 00790 } 00791 mlme_get_t get_req; 00792 get_req.attr = macFrameCounter; 00793 get_req.attr_index = 0; 00794 cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req); 00795 *seq_ptr = cur->mac_parameters->security_frame_counter; 00796 00797 return 0; 00798 } 00799 00800 00801 int8_t mac_helper_link_frame_counter_set(int8_t interface_id, uint32_t seq_ptr) 00802 { 00803 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00804 00805 if (!cur || !cur->mac_api) { 00806 return -1; 00807 } 00808 mlme_set_t set_req; 00809 set_req.attr = macFrameCounter; 00810 set_req.attr_index = 0; 00811 set_req.value_pointer = &seq_ptr; 00812 set_req.value_size = 4; 00813 cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req); 00814 00815 return 0; 00816 } 00817 00818 void mac_helper_devicetable_remove(mac_api_t *mac_api, uint8_t attribute_index) 00819 { 00820 if (!mac_api) { 00821 return; 00822 } 00823 00824 mlme_device_descriptor_t device_desc; 00825 mlme_set_t set_req; 00826 memset(&device_desc, 0xff, sizeof(mlme_device_descriptor_t)); 00827 00828 set_req.attr = macDeviceTable; 00829 set_req.attr_index = attribute_index; 00830 set_req.value_pointer = (void*)&device_desc; 00831 set_req.value_size = sizeof(mlme_device_descriptor_t); 00832 tr_debug("unRegister Device"); 00833 mac_api->mlme_req(mac_api,MLME_SET , &set_req); 00834 } 00835 00836 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, bool force_set) 00837 { 00838 if (!cur->mac_api) { 00839 return; 00840 } 00841 00842 if (!force_set && cur->mac_parameters->SecurityEnabled && cur->mac_parameters->mac_default_key_index != keyID) { 00843 tr_debug("Do not set counter by index %u != %u", cur->mac_parameters->mac_default_key_index, keyID); 00844 return; 00845 } 00846 00847 mlme_device_descriptor_t device_desc; 00848 mlme_set_t set_req; 00849 device_desc.FrameCounter = frame_counter; 00850 device_desc.Exempt = false; 00851 device_desc.ShortAddress = entry_temp->short_adr; 00852 memcpy(device_desc.ExtAddress, entry_temp->mac64, 8); 00853 device_desc.PANId = mac_helper_panid_get(cur); 00854 00855 00856 set_req.attr = macDeviceTable; 00857 set_req.attr_index = entry_temp->attribute_index; 00858 set_req.value_pointer = (void*)&device_desc; 00859 set_req.value_size = sizeof(mlme_device_descriptor_t); 00860 tr_debug("Register Device"); 00861 cur->mac_api->mlme_req(cur->mac_api,MLME_SET , &set_req); 00862 } 00863 00864 00865 int8_t mac_helper_mac_mlme_max_retry_set(int8_t interface_id, uint8_t mac_retry_set) 00866 { 00867 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00868 00869 if (!cur || !cur->mac_api) { 00870 return -1; 00871 } 00872 mlme_set_t set_req; 00873 set_req.attr = macMaxFrameRetries; 00874 set_req.attr_index = 0; 00875 set_req.value_pointer = &mac_retry_set; 00876 set_req.value_size = 1; 00877 cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req); 00878 00879 return 0; 00880 }
Generated on Tue Jul 12 2022 12:44:54 by
