Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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), mac_ptr->pan_id);
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         if (mac_ptr->indirect_pd_data_request_queue) {
00152             tr_error("Wrongly dropped");
00153         }
00154         //Free Buffer
00155         return 1;
00156     }
00157 
00158     uint8_t address_cmp_ok = 0;
00159     uint8_t len;
00160     mac_pre_build_frame_t *b_prev = NULL;
00161 
00162     if (buf->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_16_BIT) {
00163         len = 2;
00164     } else {
00165         len = 8;
00166     }
00167 
00168     mac_pre_build_frame_t *b = mac_ptr->indirect_pd_data_request_queue;
00169     while (b) {
00170 
00171         if (buf->neigh_info) {
00172             uint16_t compare_short;
00173             if (b->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_16_BIT) {
00174 
00175                 compare_short = common_read_16_bit(b->DstAddr);
00176                 if (compare_short == buf->neigh_info->ShortAddress) {
00177                     address_cmp_ok = 1;
00178                 }
00179             } else {
00180                 if (memcmp(b->DstAddr, buf->neigh_info->ExtAddress, 8) == 0) {
00181                     address_cmp_ok = 1;
00182                 }
00183             }
00184         } else {
00185             if (b->fcf_dsn.DstAddrMode == buf->fcf_dsn.SrcAddrMode) {
00186                 if (memcmp(b->DstAddr, srcAddress, len) == 0) {
00187                     address_cmp_ok = 1;
00188                 }
00189             }
00190         }
00191 
00192         if (address_cmp_ok) {
00193             if (b_prev) {
00194                 b_prev->next = b->next;
00195 
00196             } else {
00197                 mac_ptr->indirect_pd_data_request_queue = b->next;
00198             }
00199             b->next = NULL;
00200             b->priority = MAC_PD_DATA_MEDIUM_PRIORITY;
00201             mcps_sap_pd_req_queue_write(mac_ptr, b);
00202             return 1;
00203         } else {
00204             b_prev = b;
00205             b = b->next;
00206         }
00207     }
00208     return 0;
00209 }
00210 
00211 void mac_indirect_queue_write(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
00212 {
00213     if (!rf_mac_setup || ! buffer) {
00214         return;
00215     }
00216     rf_mac_setup->indirect_pending_bytes += buffer->mac_payload_length;
00217     buffer->next = NULL;
00218     buffer->buffer_ttl = 7100;
00219     //Push to queue
00220     if (!rf_mac_setup->indirect_pd_data_request_queue) {
00221         rf_mac_setup->indirect_pd_data_request_queue = buffer;
00222         //Trig timer and set pending flag to radio
00223         eventOS_callback_timer_stop(rf_mac_setup->mac_mcps_timer);
00224         eventOS_callback_timer_start(rf_mac_setup->mac_mcps_timer, MAC_INDIRECT_TICK_IN_MS * 20);
00225         rf_mac_setup->mac_frame_pending = true;
00226         if (rf_mac_setup->dev_driver->phy_driver->extension) {
00227             uint8_t value = 1;
00228             rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_CTRL_PENDING_BIT, &value);
00229         }
00230         return;
00231     }
00232 
00233     mac_pre_build_frame_t *cur = rf_mac_setup->indirect_pd_data_request_queue;
00234     while (cur) {
00235         if (cur->next == NULL) {
00236             cur->next = buffer;
00237             cur = NULL;
00238         } else {
00239             cur = cur->next;
00240         }
00241     }
00242 }