Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mac_helper.c Source File

mac_helper.c

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