Nicolas Borla / Mbed OS BBR_1Ebene
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mac_helper.c Source File

mac_helper.c

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