diff --git a/nanostack/platform/arm_hal_phy.h b/nanostack/platform/arm_hal_phy.h index 61a85d7b9aa..602b5a54c7e 100644 --- a/nanostack/platform/arm_hal_phy.h +++ b/nanostack/platform/arm_hal_phy.h @@ -54,6 +54,12 @@ typedef enum { PHY_LINK_CCA_PREPARE, /**< Prepare for CCA after CSMA-CA: changes to CCA channel and gives permission to TX. See PHY_LINK_CCA_PREPARE status definitions for return values */ } phy_link_tx_status_e; +/** MAC filtering modes. Set corresponding bit to 1 (1 << MAC_FRAME_VERSION_X) in PHY_EXTENSION_FILTERING_SUPPORT request when PHY can handle the filtering of this frame type. + * NOTE: Currently MAC supports filtering and Acking only 802.15.4-2015 frames. Any other frame version must be filtered and Acked by PHY with either HW or SW solution. */ +typedef enum { + MAC_FRAME_VERSION_2 = 2 /**< 802.15.4-2015 */ +} phy_link_filters_e; + /** Extension types */ typedef enum { PHY_EXTENSION_CTRL_PENDING_BIT, /**< Control MAC pending bit for indirect data. */ @@ -70,7 +76,8 @@ typedef enum { PHY_EXTENSION_GET_TIMESTAMP, /**< Read 32-bit constant monotonic time stamp in us */ PHY_EXTENSION_SET_CSMA_PARAMETERS, /**< CSMA parameter's are given by phy_csma_params_t structure remember type cast uint8_t pointer to structure type*/ PHY_EXTENSION_GET_SYMBOLS_PER_SECOND, /**< Read Symbols per seconds which will help to convert symbol time to real time */ - PHY_EXTENSION_SET_RF_CONFIGURATION /**< Set RF configuration using phy_rf_channel_parameters_s structure */ + PHY_EXTENSION_SET_RF_CONFIGURATION, /**< Set RF configuration using phy_rf_channel_parameters_s structure */ + PHY_EXTENSION_FILTERING_SUPPORT /**< Return filtering modes that can be supported by the PHY driver. See phy_link_filters_e */ } phy_extension_type_e; /** Address types */ diff --git a/source/MAC/IEEE802_15_4/mac_defines.h b/source/MAC/IEEE802_15_4/mac_defines.h index 315dacb6e74..232496c1dd3 100644 --- a/source/MAC/IEEE802_15_4/mac_defines.h +++ b/source/MAC/IEEE802_15_4/mac_defines.h @@ -192,6 +192,7 @@ typedef struct protocol_interface_rf_mac_setup { unsigned macCurrentBE: 4; uint8_t macMaxCSMABackoffs; uint8_t backoff_period_in_10us; // max 2550us - it's 320us for standard 250kbps + uint8_t mac_frame_filters; /* MAC channel parameters */ channel_list_s mac_channel_list; uint8_t scan_duration; //Needed??? diff --git a/source/MAC/IEEE802_15_4/mac_header_helper_functions.c b/source/MAC/IEEE802_15_4/mac_header_helper_functions.c index 7865cc7cf70..5f8273bb6b7 100644 --- a/source/MAC/IEEE802_15_4/mac_header_helper_functions.c +++ b/source/MAC/IEEE802_15_4/mac_header_helper_functions.c @@ -267,6 +267,9 @@ const uint8_t *mac_header_parse_fcf_dsn(mac_fcf_sequence_t *header, const uint8_ } else { header->DSN = 0; } + //Check PanID presents at header + header->DstPanPresents = mac_dst_panid_present(header); + header->SrcPanPresents = mac_src_panid_present(header); return ptr; } diff --git a/source/MAC/IEEE802_15_4/mac_mcps_sap.c b/source/MAC/IEEE802_15_4/mac_mcps_sap.c index 60f0fdb16ff..4035ec7ddf0 100644 --- a/source/MAC/IEEE802_15_4/mac_mcps_sap.c +++ b/source/MAC/IEEE802_15_4/mac_mcps_sap.c @@ -362,8 +362,6 @@ static int8_t mac_virtual_data_req_handler(protocol_interface_rf_mac_setup_s *rf } mac_header_parse_fcf_dsn(&buffer->fcf_dsn, data_ptr); - buffer->fcf_dsn.DstPanPresents = mac_dst_panid_present(&buffer->fcf_dsn); - buffer->fcf_dsn.SrcPanPresents = mac_src_panid_present(&buffer->fcf_dsn); // Use MAC sequence as handle buffer->msduHandle = buffer->fcf_dsn.DSN; memcpy(buffer->mac_payload, data_ptr, data_length); @@ -982,11 +980,6 @@ static void mac_data_interface_frame_handler(mac_pre_parsed_frame_t *buf) mcps_sap_pre_parsed_frame_buffer_free(buf); return; } - - if (mac_filter_modify_link_quality(rf_mac_setup->mac_interface_id, buf) == 1) { - mcps_sap_pre_parsed_frame_buffer_free(buf); - return; - } /* push data to stack if sniffer mode is enabled */ if (rf_mac_setup->macProminousMode) { mac_nap_tun_data_handler(buf, rf_mac_setup); @@ -1607,9 +1600,8 @@ static int8_t mcps_generic_packet_build(protocol_interface_rf_mac_setup_s *rf_pt return 0; } -int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf, const uint8_t *data_ptr, const mcps_ack_data_payload_t *ack_payload, uint32_t rx_time) +int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf, const uint8_t *data_ptr, const mcps_ack_data_payload_t *ack_payload) { - (void)rx_time; phy_device_driver_s *dev_driver = rf_ptr->dev_driver->phy_driver; dev_driver_tx_buffer_s *tx_buf = &rf_ptr->dev_driver_tx_buffer; diff --git a/source/MAC/IEEE802_15_4/mac_mcps_sap.h b/source/MAC/IEEE802_15_4/mac_mcps_sap.h index ea8acee933d..a4f4baeb73c 100644 --- a/source/MAC/IEEE802_15_4/mac_mcps_sap.h +++ b/source/MAC/IEEE802_15_4/mac_mcps_sap.h @@ -214,6 +214,6 @@ uint8_t mcps_sap_purge_reg_handler(struct protocol_interface_rf_mac_setup *rf_ma int8_t mcps_pd_data_rebuild(struct protocol_interface_rf_mac_setup *rf_ptr, mac_pre_build_frame_t *buffer); -int8_t mcps_generic_ack_build(struct protocol_interface_rf_mac_setup *rf_ptr, const mac_fcf_sequence_t *fcf, const uint8_t *data_ptr, const mcps_ack_data_payload_t *ack_payload, uint32_t rx_time); +int8_t mcps_generic_ack_build(struct protocol_interface_rf_mac_setup *rf_ptr, const mac_fcf_sequence_t *fcf, const uint8_t *data_ptr, const mcps_ack_data_payload_t *ack_payload); #endif /* MAC_IEEE802_15_4_MAC_MCPS_SAP_H_ */ diff --git a/source/MAC/IEEE802_15_4/mac_mlme.c b/source/MAC/IEEE802_15_4/mac_mlme.c index 0e88b3c6434..bea62f26763 100644 --- a/source/MAC/IEEE802_15_4/mac_mlme.c +++ b/source/MAC/IEEE802_15_4/mac_mlme.c @@ -1154,6 +1154,10 @@ protocol_interface_rf_mac_setup_s *mac_mlme_data_base_allocate(uint8_t *mac64, a bool rf_support = false; dev_driver->phy_driver->extension(PHY_EXTENSION_DYNAMIC_RF_SUPPORTED, (uint8_t *)&rf_support); entry->rf_csma_extension_supported = rf_support; + dev_driver->phy_driver->extension(PHY_EXTENSION_FILTERING_SUPPORT, (uint8_t *)&entry->mac_frame_filters); + if (entry->mac_frame_filters & (1 << MAC_FRAME_VERSION_2)) { + tr_debug("PHY supports 802.15.4-2015 frame filtering"); + } mac_mlme_set_symbol_rate(entry); //How many 10us ticks backoff period is for waiting 20symbols which is typically 10 bytes time diff --git a/source/MAC/IEEE802_15_4/mac_pd_sap.c b/source/MAC/IEEE802_15_4/mac_pd_sap.c index 9a0e02c32cd..9157c444545 100644 --- a/source/MAC/IEEE802_15_4/mac_pd_sap.c +++ b/source/MAC/IEEE802_15_4/mac_pd_sap.c @@ -252,6 +252,9 @@ void mac_pd_sap_set_phy_tx_time(protocol_interface_rf_mac_setup_s *rf_mac_setup, */ static uint32_t mac_pd_sap_get_phy_rx_time(protocol_interface_rf_mac_setup_s *rf_mac_setup) { + if (!rf_mac_setup->rf_csma_extension_supported) { + return 0; + } uint8_t rx_time_buffer[4]; rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_READ_RX_TIME, rx_time_buffer); return common_read_32_bit(rx_time_buffer); @@ -569,7 +572,7 @@ static int8_t mac_data_interface_tx_done_by_ack_cb(protocol_interface_rf_mac_set return 0; } -static bool mac_pd_sap_ack_validation(protocol_interface_rf_mac_setup_s *rf_ptr, mac_fcf_sequence_t *fcf_dsn, const uint8_t *data_ptr) +static bool mac_pd_sap_ack_validation(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf_dsn, const uint8_t *data_ptr) { if (!rf_ptr->active_pd_data_request || !rf_ptr->active_pd_data_request->fcf_dsn.ackRequested) { return false; //No active Data request anymore or no ACK request for current TX @@ -625,198 +628,286 @@ static bool mac_pd_sap_ack_validation(protocol_interface_rf_mac_setup_s *rf_ptr, return true; } -int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message) +static int8_t mac_pd_sap_validate_fcf(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf_read, arm_pd_sap_generic_ind_t *pd_data_ind) { - protocol_interface_rf_mac_setup_s *rf_ptr = (protocol_interface_rf_mac_setup_s *)identifier; - mac_pre_parsed_frame_t *buffer = NULL; + switch (fcf_read->frametype) { + case FC_DATA_FRAME: + if (fcf_read->SrcAddrMode == MAC_ADDR_MODE_NONE) { + return -1; + } else if (fcf_read->DstAddrMode == MAC_ADDR_MODE_NONE && fcf_read->frameVersion != MAC_FRAME_VERSION_2015) { + return -1; + } + break; + case FC_BEACON_FRAME: + if (fcf_read->SrcAddrMode == MAC_ADDR_MODE_NONE || fcf_read->DstAddrMode != MAC_ADDR_MODE_NONE) { + return -1; + } + break; + case FC_ACK_FRAME: + // Only accept version 2015 Acks + if (fcf_read->frameVersion != MAC_FRAME_VERSION_2015) { + return -1; + } + //Validate Ack doesn't request Ack + if (fcf_read->ackRequested) { + return -1; + } + //Validate ACK + if (!mac_pd_sap_ack_validation(rf_ptr, fcf_read, pd_data_ind->data_ptr)) { + return -1; + } + break; + case FC_CMD_FRAME: + break; + default: + return -1; + } + return 0; +} - if (!rf_ptr || !message) { - return -1; +static bool mac_pd_sap_panid_filter_common(const uint8_t *mac_header, const mac_fcf_sequence_t *fcf_read, uint16_t own_pan_id) +{ + // Beacon frames shouldn't be dropped as they might be used by load balancing + if (fcf_read->frametype == MAC_FRAME_BEACON) { + return true; + } + if (own_pan_id == 0xffff) { + return true; + } + uint16_t dst_pan_id = mac_header_get_dst_panid(fcf_read, mac_header, 0xffff); + if (dst_pan_id == 0xffff) { + return true; + } + if (own_pan_id == dst_pan_id) { + return true; } + return false; +} - if (!rf_ptr->macUpState) { - return -2; +static bool mac_pd_sap_panid_v2_filter(const uint8_t *ptr, const mac_fcf_sequence_t *fcf_read, uint16_t pan_id) +{ + if ((fcf_read->DstAddrMode == MAC_ADDR_MODE_NONE) && (fcf_read->frametype == FC_DATA_FRAME || fcf_read->frametype == FC_CMD_FRAME)) { + return true; + } + if ((fcf_read->DstAddrMode == MAC_ADDR_MODE_64_BIT) && (fcf_read->SrcAddrMode == MAC_ADDR_MODE_64_BIT) && fcf_read->intraPan) { + return true; + } + return mac_pd_sap_panid_filter_common(ptr, fcf_read, pan_id); +} + +static bool mac_pd_sap_addr_filter_common(const uint8_t *mac_header, const mac_fcf_sequence_t *fcf_read, uint8_t *mac_64bit_addr, uint16_t mac_16bit_addr) +{ + uint8_t cmp_table[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + uint8_t dst_addr[8]; + mac_header_get_dst_address(fcf_read, mac_header, dst_addr); + + switch (fcf_read->DstAddrMode) { + case MAC_ADDR_MODE_16_BIT: + if (!memcmp(dst_addr, cmp_table, 2)) { + return true; + } + uint8_t temp[2]; + common_write_16_bit(mac_16bit_addr, temp); + if (!memcmp(temp, dst_addr, 2)) { + return true; + } + break; + case MAC_ADDR_MODE_64_BIT: + if (!memcmp(dst_addr, cmp_table, 8)) { + return true; + } + if (!memcmp(mac_64bit_addr, dst_addr, 8)) { + return true; + } + break; + case MAC_ADDR_MODE_NONE: + return true; + break; + default: + break; } + return false; +} - if (message->id == MAC15_4_PD_SAP_DATA_IND) { - const uint8_t *ptr; - arm_pd_sap_generic_ind_t *pd_data_ind = &(message->message.generic_data_ind); +static bool mac_pd_sap_addr_v2_filter(const uint8_t *mac_header, const mac_fcf_sequence_t *fcf_read, uint8_t *mac_64bit_addr, uint16_t mac_16bit_addr) +{ + return mac_pd_sap_addr_filter_common(mac_header, fcf_read, mac_64bit_addr, mac_16bit_addr); +} - if (pd_data_ind->data_len < 3) { - return -1; - } - ptr = pd_data_ind->data_ptr; +static bool mac_pd_sap_rx_filter(const uint8_t *mac_header, const mac_fcf_sequence_t *fcf_read, uint8_t phy_filter_mask, uint8_t *mac_64bit_addr, uint16_t mac_16bit_addr, uint16_t pan_id) +{ + uint8_t version = fcf_read->frameVersion; - uint32_t time_stamp = 0; - if (rf_ptr->rf_csma_extension_supported) { - time_stamp = mac_pd_sap_get_phy_rx_time(rf_ptr); + if (version == MAC_FRAME_VERSION_2015 && !(phy_filter_mask & (1 << MAC_FRAME_VERSION_2))) { + if (!mac_pd_sap_panid_v2_filter(mac_header, fcf_read, pan_id)) { + return false; } - mac_fcf_sequence_t fcf_read; - ptr = mac_header_parse_fcf_dsn(&fcf_read, ptr); - //Check PanID presents at header - fcf_read.DstPanPresents = mac_dst_panid_present(&fcf_read); - fcf_read.SrcPanPresents = mac_src_panid_present(&fcf_read); - int16_t length = pd_data_ind->data_len; - if (!rf_ptr->macProminousMode) { + if (!mac_pd_sap_addr_v2_filter(mac_header, fcf_read, mac_64bit_addr, mac_16bit_addr)) { + return false; + } + } + return true; +} - //Unsupported Frame - if (fcf_read.frametype > FC_CMD_FRAME || (fcf_read.frametype == FC_ACK_FRAME && fcf_read.frameVersion != MAC_FRAME_VERSION_2015)) { - goto ERROR_HANDLER; - } +static int8_t mac_pd_sap_generate_ack(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf_read, arm_pd_sap_generic_ind_t *pd_data_ind) +{ + //Generate ACK when Extension is enabled and ACK is requested only for version 2 frames. + if (!rf_ptr->mac_extension_enabled || !fcf_read->ackRequested || (fcf_read->frameVersion != MAC_FRAME_VERSION_2015)) { + return 0; + } + if (rf_ptr->mac_ack_tx_active) { + return -1; + } - switch (fcf_read.frametype) { - case FC_DATA_FRAME: - if (fcf_read.SrcAddrMode == MAC_ADDR_MODE_NONE) { - return -1; - } else if (fcf_read.DstAddrMode == MAC_ADDR_MODE_NONE && fcf_read.frameVersion != MAC_FRAME_VERSION_2015) { - return -1; - } - break; - case FC_BEACON_FRAME: - if (fcf_read.SrcAddrMode == MAC_ADDR_MODE_NONE || fcf_read.DstAddrMode != MAC_ADDR_MODE_NONE) { - return -1; - } - break; - case FC_ACK_FRAME: - //Validate here that we are waiting ack - if (fcf_read.ackRequested) { - return -1; - } + mcps_ack_data_payload_t ack_payload; + mac_api_t *mac_api = get_sw_mac_api(rf_ptr); + mac_api->enhanced_ack_data_req_cb(mac_api, &ack_payload, pd_data_ind->dbm, pd_data_ind->link_quality); + //Calculate Delta time - //Validate ACK - if (!mac_pd_sap_ack_validation(rf_ptr, &fcf_read, pd_data_ind->data_ptr)) { - return -1; - } - break; + return mcps_generic_ack_build(rf_ptr, fcf_read, pd_data_ind->data_ptr, &ack_payload); +} - default: - break; - } +static mac_pre_parsed_frame_t *mac_pd_sap_allocate_receive_buffer(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf_read, arm_pd_sap_generic_ind_t *pd_data_ind) +{ + mac_pre_parsed_frame_t *buffer = mcps_sap_pre_parsed_frame_buffer_get(pd_data_ind->data_ptr, pd_data_ind->data_len); + if (!buffer) { + return NULL; + } + + //Copy Pre Parsed values + buffer->fcf_dsn = *fcf_read; + buffer->timestamp = mac_pd_sap_get_phy_rx_time(rf_ptr); + buffer->ack_pendinfg_status = mac_data_interface_read_last_ack_pending_status(rf_ptr); + /* Set default flags */ + buffer->dbm = pd_data_ind->dbm; + buffer->LQI = pd_data_ind->link_quality; + buffer->mac_class_ptr = rf_ptr; + return buffer; +} - //Generate ACK when Extension is enabled and ACK is requested - if (rf_ptr->mac_extension_enabled && fcf_read.ackRequested && fcf_read.frameVersion == MAC_FRAME_VERSION_2015) { - //SEND ACK here - if (rf_ptr->mac_ack_tx_active) { - return -1; - } +static int8_t mac_pd_sap_parse_length_fields(mac_pre_parsed_frame_t *buffer, arm_pd_sap_generic_ind_t *pd_data_ind, const uint8_t *parse_ptr) +{ + if (buffer->fcf_dsn.frametype > FC_CMD_FRAME) { + return -1; + } + buffer->mac_header_length = parse_ptr - pd_data_ind->data_ptr; + int16_t length = pd_data_ind->data_len; + buffer->mac_header_length += mac_header_address_length(&buffer->fcf_dsn); + length -= buffer->mac_header_length; + if (length < 0) { + return -1; + } - mcps_ack_data_payload_t ack_payload; - mac_api_t *mac_api = get_sw_mac_api(rf_ptr); - mac_api->enhanced_ack_data_req_cb(mac_api, &ack_payload, pd_data_ind->dbm, pd_data_ind->link_quality); - //Calculate Delta time + buffer->mac_payload_length = (buffer->frameLength - buffer->mac_header_length); - if (mcps_generic_ack_build(rf_ptr, &fcf_read, pd_data_ind->data_ptr, &ack_payload, time_stamp) != 0) { - return -1; + if (buffer->fcf_dsn.securityEnabled) { + //Read KEYID Mode + uint8_t key_id_mode, security_level, mic_len; + uint8_t *security_ptr = &buffer->buf[buffer->mac_header_length]; + uint8_t auxBaseHeader = *security_ptr; + key_id_mode = (auxBaseHeader >> 3) & 3; + security_level = auxBaseHeader & 7; + + switch (key_id_mode) { + case MAC_KEY_ID_MODE_IMPLICIT: + if (security_level) { + buffer->security_aux_header_length = 5; + } else { + buffer->security_aux_header_length = 1; } - } + break; + case MAC_KEY_ID_MODE_IDX: + buffer->security_aux_header_length = 6; + break; + case MAC_KEY_ID_MODE_SRC4_IDX: + buffer->security_aux_header_length = 10; + break; + default: + buffer->security_aux_header_length = 14; + break; } - buffer = mcps_sap_pre_parsed_frame_buffer_get(pd_data_ind->data_ptr, pd_data_ind->data_len); + length -= buffer->security_aux_header_length; + mic_len = mac_security_mic_length_get(security_level); - if (!buffer) { - sw_mac_stats_update(rf_ptr, STAT_MAC_RX_DROP, 0); - return -3; + length -= mic_len; + + //Verify that data length is not negative + if (length < 0) { + return -1; } - //Copy Pre Parsed values - buffer->fcf_dsn = fcf_read; - buffer->timestamp = time_stamp; + buffer->mac_payload_length -= (buffer->security_aux_header_length + mic_len); + } + //Do not accept command frame with length 0 + if (buffer->fcf_dsn.frametype == FC_CMD_FRAME && length == 0) { + return -1; + } + return 0; +} + +int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message) +{ + protocol_interface_rf_mac_setup_s *rf_ptr = (protocol_interface_rf_mac_setup_s *)identifier; - buffer->ack_pendinfg_status = mac_data_interface_read_last_ack_pending_status(rf_ptr); + if (!rf_ptr || !message) { + return -1; + } + if (!rf_ptr->macUpState) { + return -2; + } - // Upward direction functions assume no headroom and are trusting that removed bytes are still valid. - // see mac.c:655 + if (message->id == MAC15_4_PD_SAP_DATA_IND) { + arm_pd_sap_generic_ind_t *pd_data_ind = &(message->message.generic_data_ind); + if (pd_data_ind->data_len < 3) { + return -1; + } - /* Set default flags */ - buffer->dbm = pd_data_ind->dbm; - buffer->LQI = pd_data_ind->link_quality; - buffer->mac_class_ptr = rf_ptr; - //Dnamic calculation for FCF + SEQ parse - buffer->mac_header_length = ptr - pd_data_ind->data_ptr; + mac_fcf_sequence_t fcf_read; + const uint8_t *ptr = mac_header_parse_fcf_dsn(&fcf_read, pd_data_ind->data_ptr); + mac_pre_parsed_frame_t *buffer = mac_pd_sap_allocate_receive_buffer(rf_ptr, &fcf_read, pd_data_ind); + if (buffer && mac_filter_modify_link_quality(rf_ptr->mac_interface_id, buffer) == 1) { + goto ERROR_HANDLER; + } if (!rf_ptr->macProminousMode) { - - if (buffer->fcf_dsn.frametype > FC_CMD_FRAME) { + if (mac_pd_sap_validate_fcf(rf_ptr, &fcf_read, pd_data_ind)) { goto ERROR_HANDLER; } - - buffer->mac_header_length += mac_header_address_length(&buffer->fcf_dsn); - - length -= buffer->mac_header_length; - - if (length < 0) { + if (!mac_pd_sap_rx_filter(pd_data_ind->data_ptr, &fcf_read, rf_ptr->mac_frame_filters, rf_ptr->mac64, rf_ptr->mac_short_address, rf_ptr->pan_id)) { goto ERROR_HANDLER; } - - buffer->mac_payload_length = (buffer->frameLength - buffer->mac_header_length); - - if (buffer->fcf_dsn.securityEnabled) { - //Read KEYID Mode - uint8_t key_id_mode, security_level, mic_len; - uint8_t *security_ptr = &buffer->buf[buffer->mac_header_length]; - uint8_t auxBaseHeader = *security_ptr; - key_id_mode = (auxBaseHeader >> 3) & 3; - security_level = auxBaseHeader & 7; - - switch (key_id_mode) { - case MAC_KEY_ID_MODE_IMPLICIT: - if (security_level) { - buffer->security_aux_header_length = 5; - } else { - buffer->security_aux_header_length = 1; - } - break; - case MAC_KEY_ID_MODE_IDX: - buffer->security_aux_header_length = 6; - break; - case MAC_KEY_ID_MODE_SRC4_IDX: - buffer->security_aux_header_length = 10; - break; - default: - buffer->security_aux_header_length = 14; - break; + if (mac_pd_sap_generate_ack(rf_ptr, &fcf_read, pd_data_ind)) { + goto ERROR_HANDLER; + } + if (buffer) { + if (mac_pd_sap_parse_length_fields(buffer, pd_data_ind, ptr)) { + goto ERROR_HANDLER; } - - length -= buffer->security_aux_header_length; - mic_len = mac_security_mic_length_get(security_level); - - length -= mic_len; - - //Verify that data length is not negative - if (length < 0) { + if (!mac_header_information_elements_parse(buffer)) { goto ERROR_HANDLER; } - - buffer->mac_payload_length -= (buffer->security_aux_header_length + mic_len); - } - - //Do not accept command frame with length 0 - if (fcf_read.frametype == FC_CMD_FRAME && length == 0) { - goto ERROR_HANDLER; - } - - //Parse IE Elements - if (!mac_header_information_elements_parse(buffer)) { - goto ERROR_HANDLER; + if (buffer->fcf_dsn.frametype == FC_ACK_FRAME) { + if (mac_data_interface_tx_done_by_ack_cb(rf_ptr, buffer)) { + mcps_sap_pre_parsed_frame_buffer_free(buffer); + } + return 0; + } } } - - if (!rf_ptr->macProminousMode && buffer->fcf_dsn.frametype == FC_ACK_FRAME) { - if (mac_data_interface_tx_done_by_ack_cb(rf_ptr, buffer)) { - mcps_sap_pre_parsed_frame_buffer_free(buffer); - } + if (!buffer) { + sw_mac_stats_update(rf_ptr, STAT_MAC_RX_DROP, 0); + return -3; + } + if (mcps_sap_pd_ind(buffer) == 0) { return 0; - } else { - if (mcps_sap_pd_ind(buffer) == 0) { - return 0; - } } ERROR_HANDLER: mcps_sap_pre_parsed_frame_buffer_free(buffer); + sw_mac_stats_update(rf_ptr, STAT_MAC_RX_DROP, 0); return -1; - } else if (message->id == MAC15_4_PD_SAP_DATA_TX_CONFIRM) { arm_pd_sap_15_4_confirm_with_params_t *pd_data_cnf = &(message->message.mac15_4_pd_sap_confirm); return mac_data_interface_tx_done_cb(rf_ptr, pd_data_cnf->status, pd_data_cnf->cca_retry, pd_data_cnf->tx_retry); diff --git a/test/nanostack/unittest/mac/mac_mcps_sap/test_mac_mcps_sap.c b/test/nanostack/unittest/mac/mac_mcps_sap/test_mac_mcps_sap.c index 745f9b136c0..a793d0a527a 100644 --- a/test/nanostack/unittest/mac/mac_mcps_sap/test_mac_mcps_sap.c +++ b/test/nanostack/unittest/mac/mac_mcps_sap/test_mac_mcps_sap.c @@ -2342,7 +2342,7 @@ bool test_mcps_sap_data_req_ext_handler() mcps_pd_data_rebuild(rf_mac_setup, rf_mac_setup->active_pd_data_request); mcps_ack_data_payload_t ack_data; memset(&ack_data, 0, sizeof(mcps_ack_data_payload_t)); - mcps_generic_ack_build(rf_mac_setup, &rf_mac_setup->active_pd_data_request->fcf_dsn, rf_mac_setup->active_pd_data_request->mac_payload, &ack_data, 100); + mcps_generic_ack_build(rf_mac_setup, &rf_mac_setup->active_pd_data_request->fcf_dsn, rf_mac_setup->active_pd_data_request->mac_payload, &ack_data); mac_mcps_buffer_queue_free(rf_mac_setup); diff --git a/test/nanostack/unittest/mac/mac_pd_sap/Makefile b/test/nanostack/unittest/mac/mac_pd_sap/Makefile index 7e5ff73b6fd..31f5fd35b85 100644 --- a/test/nanostack/unittest/mac/mac_pd_sap/Makefile +++ b/test/nanostack/unittest/mac/mac_pd_sap/Makefile @@ -19,6 +19,7 @@ TEST_SRC_FILES = \ ../../stub/mac_mcps_sap_stub.c \ ../../stub/mac_header_helper_functions_stub.c \ ../../stub/mac_timer_stub.c \ + ../../stub/mac_filter_stub.c \ ../../stub/protocol_core_stub.c \ ../../stub/randLIB_stub.c \ ../../stub/mac_mlme_stub.c \ diff --git a/test/nanostack/unittest/stub/mac_mcps_sap_stub.c b/test/nanostack/unittest/stub/mac_mcps_sap_stub.c index a436e6d5c97..ebe3d72f510 100644 --- a/test/nanostack/unittest/stub/mac_mcps_sap_stub.c +++ b/test/nanostack/unittest/stub/mac_mcps_sap_stub.c @@ -167,7 +167,7 @@ int8_t mcps_pd_data_rebuild(struct protocol_interface_rf_mac_setup *rf_ptr, mac_ return mac_mcps_sap_stub.int8_value; } -int8_t mcps_generic_ack_build(struct protocol_interface_rf_mac_setup *rf_ptr, const mac_fcf_sequence_t *fcf, const uint8_t *data_ptr, const mcps_ack_data_payload_t *ack_payload, uint32_t rx_time) +int8_t mcps_generic_ack_build(struct protocol_interface_rf_mac_setup *rf_ptr, const mac_fcf_sequence_t *fcf, const uint8_t *data_ptr, const mcps_ack_data_payload_t *ack_payload) { return 0; }