takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mac_indirect_data.c Source File

mac_indirect_data.c

00001 /*
00002  * Copyright (c) 2014-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 /*
00019  * \file mac_indirect_data.c
00020  * \brief Add short description about this file!!!
00021  *
00022  */
00023 #include "nsconfig.h"
00024 #include "string.h"
00025 #include "ns_types.h"
00026 #include "ns_trace.h"
00027 #include "eventOS_event.h"
00028 #include "eventOS_scheduler.h"
00029 #include "eventOS_callback_timer.h"
00030 #include "nsdynmemLIB.h"
00031 #include "common_functions.h"
00032 #include "sw_mac.h"
00033 #include "mac_api.h"
00034 #include "MAC/IEEE802_15_4/sw_mac_internal.h"
00035 #include "MAC/IEEE802_15_4/mac_defines.h"
00036 #include "MAC/IEEE802_15_4/mac_indirect_data.h"
00037 #include "MAC/IEEE802_15_4/mac_header_helper_functions.h"
00038 #include "MAC/IEEE802_15_4/mac_mcps_sap.h"
00039 #include "MAC/rf_driver_storage.h"
00040 
00041 #define TRACE_GROUP_MAC_INDIR "mInD"
00042 #define TRACE_GROUP "mInD"
00043 
00044 void mac_indirect_data_ttl_handle(protocol_interface_rf_mac_setup_s *cur, uint16_t tick_value)
00045 {
00046     if (!cur || !cur->dev_driver ) {
00047         return;
00048     }
00049     mcps_data_conf_t confirm;
00050     memset(&confirm, 0, sizeof(mcps_data_conf_t));
00051 
00052     phy_device_driver_s *dev_driver = cur->dev_driver->phy_driver;
00053     if (!cur->indirect_pd_data_request_queue) {
00054         uint8_t value = 0;
00055         if( dev_driver && dev_driver->extension ){
00056             dev_driver->extension(PHY_EXTENSION_CTRL_PENDING_BIT, &value);
00057         }
00058         cur->mac_frame_pending = false;
00059         return;
00060     }
00061     mac_pre_build_frame_t *buf, *buf_prev = 0, *buf_temp = 0;
00062 
00063     mac_api_t *api = get_sw_mac_api(cur);
00064     if( !api ){
00065         return;
00066     }
00067 
00068     buf = cur->indirect_pd_data_request_queue;
00069 
00070     tick_value /= 20; //Covert time ms
00071     if (tick_value == 0) {
00072         tick_value = 1;
00073     }
00074 
00075     while (buf) {
00076         if (buf->buffer_ttl > tick_value) {
00077             buf->buffer_ttl -= tick_value;
00078             buf_prev = buf;
00079             buf = buf->next;
00080         } else {
00081             buf->buffer_ttl = 0;
00082             if (buf_prev) {
00083                 buf_prev->next = buf->next;
00084             } else {
00085                 cur->indirect_pd_data_request_queue = buf->next;
00086             }
00087 
00088             confirm.msduHandle = buf->msduHandle;
00089             buf_temp = buf;
00090             buf = buf->next;
00091             buf_temp->next = NULL;
00092             cur->indirect_pending_bytes -= buf_temp->mac_payload_length;
00093 
00094             confirm.status = MLME_TRANSACTION_EXPIRED;
00095 
00096             mcps_sap_prebuild_frame_buffer_free(buf_temp);
00097 
00098             if (cur->mac_extension_enabled) {
00099                 mcps_data_conf_payload_t data_conf;
00100                 memset(&data_conf, 0, sizeof(mcps_data_conf_payload_t));
00101                 //Check Payload Here
00102                 api->data_conf_ext_cb(api, &confirm, &data_conf);
00103             } else {
00104                 api->data_conf_cb(api, &confirm);
00105             }
00106         }
00107     }
00108 
00109     eventOS_callback_timer_stop(cur->mac_mcps_timer);
00110     eventOS_callback_timer_start(cur->mac_mcps_timer, MAC_INDIRECT_TICK_IN_MS * 20);
00111 }
00112 
00113 uint8_t mac_indirect_data_req_handle(mac_pre_parsed_frame_t *buf, protocol_interface_rf_mac_setup_s *mac_ptr)
00114 {
00115 
00116     if (!mac_ptr || !buf) {
00117         return 1;
00118     }
00119 
00120     if (buf->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_NONE || buf->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_NONE) {
00121         return 1;
00122     }
00123 
00124     uint8_t srcAddress[8];
00125     memset(&srcAddress, 0, 8);
00126 
00127     mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), srcAddress);
00128 
00129     //Call COMM status
00130     mac_api_t *mac_api = get_sw_mac_api(mac_ptr);
00131     if (mac_api) {
00132         mlme_comm_status_t comm_status;
00133         memset(&comm_status, 0, sizeof(mlme_comm_status_t));
00134 
00135         comm_status.status = MLME_DATA_POLL_NOTIFICATION;
00136         //Call com status
00137         comm_status.PANId = mac_header_get_dst_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf));
00138         comm_status.DstAddrMode = buf->fcf_dsn.DstAddrMode;;
00139         mac_header_get_dst_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), comm_status.DstAddr);
00140         comm_status.SrcAddrMode = buf->fcf_dsn.SrcAddrMode;
00141         mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), comm_status.SrcAddr);
00142         mac_header_security_components_read(buf, &comm_status.Key);
00143         if( mac_api->mlme_ind_cb ){
00144             mac_api->mlme_ind_cb(mac_api, MLME_COMM_STATUS, &comm_status);
00145         }
00146     }
00147 
00148 
00149     /* If the Ack we sent for the Data Request didn't have frame pending set, we shouldn't transmit - child may have slept */
00150     if (!buf->ack_pendinfg_status) {
00151         //tr_debug("Drop by pending");
00152         if (mac_ptr->indirect_pd_data_request_queue) {
00153             tr_error("Wrongly dropped");
00154         }
00155         //Free Buffer
00156         return 1;
00157     }
00158 
00159     uint8_t address_cmp_ok = 0;
00160     uint8_t len;
00161     mac_pre_build_frame_t *b_prev = NULL;
00162 
00163     if (buf->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_16_BIT) {
00164         len = 2;
00165     } else {
00166         len = 8;
00167     }
00168 
00169     mac_pre_build_frame_t *b = mac_ptr->indirect_pd_data_request_queue;
00170     while (b) {
00171 
00172         if (buf->neigh_info) {
00173             uint16_t compare_short;
00174             if (b->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_16_BIT) {
00175 
00176                 compare_short = common_read_16_bit(b->DstAddr);
00177                 if (compare_short == buf->neigh_info->ShortAddress) {
00178                     address_cmp_ok = 1;
00179                 }
00180             } else {
00181                 if (memcmp(b->DstAddr, buf->neigh_info->ExtAddress, 8) == 0) {
00182                     address_cmp_ok = 1;
00183                 }
00184             }
00185         } else {
00186             if (b->fcf_dsn.DstAddrMode == buf->fcf_dsn.SrcAddrMode) {
00187                 if (memcmp(b->DstAddr, srcAddress, len) == 0) {
00188                     address_cmp_ok = 1;
00189                 }
00190             }
00191         }
00192 
00193         if (address_cmp_ok) {
00194             if (b_prev) {
00195                 b_prev->next = b->next;
00196 
00197             } else {
00198                 mac_ptr->indirect_pd_data_request_queue = b->next;
00199             }
00200             b->next = NULL;
00201             b->priority = MAC_PD_DATA_MEDIUM_PRIORITY;
00202             mcps_sap_pd_req_queue_write(mac_ptr, b);
00203             return 1;
00204         } else {
00205             b_prev = b;
00206             b = b->next;
00207         }
00208     }
00209     return 0;
00210 }
00211 
00212 void mac_indirect_queue_write(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
00213 {
00214     if( !rf_mac_setup || ! buffer ){
00215         return;
00216     }
00217     rf_mac_setup->indirect_pending_bytes += buffer->mac_payload_length;
00218     buffer->next = NULL;
00219     buffer->buffer_ttl = 7100;
00220     //Push to queue
00221     if (!rf_mac_setup->indirect_pd_data_request_queue) {
00222         rf_mac_setup->indirect_pd_data_request_queue = buffer;
00223         //Trig timer and set pending flag to radio
00224         eventOS_callback_timer_stop(rf_mac_setup->mac_mcps_timer);
00225         eventOS_callback_timer_start(rf_mac_setup->mac_mcps_timer, MAC_INDIRECT_TICK_IN_MS * 20);
00226         rf_mac_setup->mac_frame_pending = true;
00227         if (rf_mac_setup->dev_driver->phy_driver->extension)
00228         {
00229             uint8_t value = 1;
00230             rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_CTRL_PENDING_BIT, &value);
00231         }
00232         return;
00233     }
00234 
00235     mac_pre_build_frame_t *cur = rf_mac_setup->indirect_pd_data_request_queue;
00236     while(cur) {
00237         if( cur->next == NULL) {
00238             cur->next = buffer;
00239             cur = NULL;
00240         } else {
00241             cur = cur->next;
00242         }
00243     }
00244 }