takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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     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 }