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