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-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 /*
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         return;
00059     }
00060     mac_pre_build_frame_t *buf, *buf_prev = 0, *buf_temp = 0;
00061 
00062     mac_api_t *api = get_sw_mac_api(cur);
00063     if( !api ){
00064         return;
00065     }
00066 
00067     buf = cur->indirect_pd_data_request_queue;
00068 
00069     tick_value /= 20; //Covert time ms
00070     if (tick_value == 0) {
00071         tick_value = 1;
00072     }
00073 
00074     while (buf) {
00075         if (buf->buffer_ttl > tick_value) {
00076             buf->buffer_ttl -= tick_value;
00077             buf_prev = buf;
00078             buf = buf->next;
00079         } else {
00080             buf->buffer_ttl = 0;
00081             if (buf_prev) {
00082                 buf_prev->next = buf->next;
00083             } else {
00084                 cur->indirect_pd_data_request_queue = buf->next;
00085             }
00086 
00087             confirm.msduHandle = buf->msduHandle;
00088             buf_temp = buf;
00089             buf = buf->next;
00090             buf_temp->next = NULL;
00091             cur->indirect_pending_bytes -= buf_temp->mac_payload_length;
00092 
00093             confirm.status = MLME_TRANSACTION_EXPIRED;
00094 
00095             mcps_sap_prebuild_frame_buffer_free(buf_temp);
00096             if( api->data_conf_cb ) {
00097                 api->data_conf_cb(api, &confirm);
00098             }
00099         }
00100     }
00101 
00102     eventOS_callback_timer_stop(cur->mac_mcps_timer);
00103     eventOS_callback_timer_start(cur->mac_mcps_timer, MAC_INDIRECT_TICK_IN_MS * 20);
00104 }
00105 
00106 uint8_t mac_indirect_data_req_handle(mac_pre_parsed_frame_t *buf, protocol_interface_rf_mac_setup_s *mac_ptr)
00107 {
00108 
00109     if (!mac_ptr || !buf) {
00110         return 1;
00111     }
00112 
00113     if (buf->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_NONE || buf->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_NONE) {
00114         return 1;
00115     }
00116 
00117     uint8_t srcAddress[8];
00118     memset(&srcAddress, 0, 8);
00119 
00120     mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), srcAddress);
00121 
00122     //Call COMM status
00123     mac_api_t *mac_api = get_sw_mac_api(mac_ptr);
00124     if (mac_api) {
00125         mlme_comm_status_t comm_status;
00126         memset(&comm_status, 0, sizeof(mlme_comm_status_t));
00127 
00128         comm_status.status = MLME_DATA_POLL_NOTIFICATION;
00129         //Call com status
00130         comm_status.PANId = mac_header_get_dst_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf));
00131         comm_status.DstAddrMode = buf->fcf_dsn.DstAddrMode;;
00132         mac_header_get_dst_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), comm_status.DstAddr);
00133         comm_status.SrcAddrMode = buf->fcf_dsn.SrcAddrMode;
00134         mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), comm_status.SrcAddr);
00135         mac_header_security_components_read(buf, &comm_status.Key);
00136         if( mac_api->mlme_ind_cb ){
00137             mac_api->mlme_ind_cb(mac_api, MLME_COMM_STATUS, &comm_status);
00138         }
00139     }
00140 
00141 
00142     /* If the Ack we sent for the Data Request didn't have frame pending set, we shouldn't transmit - child may have slept */
00143     if (!buf->ack_pendinfg_status) {
00144         //tr_debug("Drop by pending");
00145         if (mac_ptr->indirect_pd_data_request_queue) {
00146             tr_error("Wrongly dropped");
00147         }
00148         //Free Buffer
00149         return 1;
00150     }
00151 
00152     uint8_t address_cmp_ok = 0;
00153     uint8_t len;
00154     mac_pre_build_frame_t *b_prev = NULL;
00155 
00156     if (buf->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_16_BIT) {
00157         len = 2;
00158     } else {
00159         len = 8;
00160     }
00161 
00162     mac_pre_build_frame_t *b = mac_ptr->indirect_pd_data_request_queue;
00163     while (b) {
00164 
00165         if (buf->neigh_info) {
00166             uint16_t compare_short;
00167             if (b->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_16_BIT) {
00168 
00169                 compare_short = common_read_16_bit(b->DstAddr);
00170                 if (compare_short == buf->neigh_info->ShortAddress) {
00171                     address_cmp_ok = 1;
00172                 }
00173             } else {
00174                 if (memcmp(b->DstAddr, buf->neigh_info->ExtAddress, 8) == 0) {
00175                     address_cmp_ok = 1;
00176                 }
00177             }
00178         } else {
00179             if (b->fcf_dsn.DstAddrMode == buf->fcf_dsn.SrcAddrMode) {
00180                 if (memcmp(b->DstAddr, srcAddress, len) == 0) {
00181                     address_cmp_ok = 1;
00182                 }
00183             }
00184         }
00185 
00186         if (address_cmp_ok) {
00187             if (b_prev) {
00188                 b_prev->next = b->next;
00189 
00190             } else {
00191                 mac_ptr->indirect_pd_data_request_queue = b->next;
00192             }
00193             b->next = NULL;
00194             b->priority = MAC_PD_DATA_MEDIUM_PRIORITY;
00195             mcps_sap_pd_req_queue_write(mac_ptr, b);
00196             return 1;
00197         } else {
00198             b_prev = b;
00199             b = b->next;
00200         }
00201     }
00202     return 0;
00203 }
00204 
00205 void mac_indirect_queue_write(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
00206 {
00207     if( !rf_mac_setup || ! buffer ){
00208         return;
00209     }
00210     rf_mac_setup->indirect_pending_bytes += buffer->mac_payload_length;
00211     buffer->next = NULL;
00212     buffer->buffer_ttl = 7100;
00213     //Push to queue
00214     if (!rf_mac_setup->indirect_pd_data_request_queue) {
00215         rf_mac_setup->indirect_pd_data_request_queue = buffer;
00216         //Trig timer and set pending flag to radio
00217         eventOS_callback_timer_stop(rf_mac_setup->mac_mcps_timer);
00218         eventOS_callback_timer_start(rf_mac_setup->mac_mcps_timer, MAC_INDIRECT_TICK_IN_MS * 20);
00219         if (rf_mac_setup->dev_driver->phy_driver->extension)
00220         {
00221             uint8_t value = 1;
00222             rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_CTRL_PENDING_BIT, &value);
00223         }
00224         return;
00225     }
00226 
00227     mac_pre_build_frame_t *cur = rf_mac_setup->indirect_pd_data_request_queue;
00228     while(cur) {
00229         if( cur->next == NULL) {
00230             cur->next = buffer;
00231             cur = NULL;
00232         } else {
00233             cur = cur->next;
00234         }
00235     }
00236 }