bool wpan_mlme_associate_req(uint8_t LogicalChannel, uint8_t ChannelPage, wpan_addr_spec_t *CoordAddrSpec, uint8_t CapabilityInformation) { buffer_t *buffer_header; mlme_associate_req_t *mlme_associate_req; /* Allocate a buffer for mlme associate request */ buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE); /* Check for buffer availability */ if (NULL == buffer_header) { return false; } /* Get the buffer body from buffer header */ mlme_associate_req = (mlme_associate_req_t *)BMM_BUFFER_POINTER( buffer_header); /* Construct mlme_associate_req_t message */ mlme_associate_req->cmdcode = MLME_ASSOCIATE_REQUEST; /* Operating channel */ mlme_associate_req->LogicalChannel = LogicalChannel; /* Coordinator address spec */ mlme_associate_req->CoordAddrMode = CoordAddrSpec->AddrMode; #ifdef TEST_HARNESS_BIG_ENDIAN mlme_associate_req->CoordPANId = CPU_ENDIAN_TO_LE16(CoordAddrSpec->PANId); #else mlme_associate_req->CoordPANId = CoordAddrSpec->PANId; #endif ADDR_COPY_DST_SRC_64(mlme_associate_req->CoordAddress.long_address, CoordAddrSpec->Addr.long_address); /* Other fields */ mlme_associate_req->CapabilityInformation = CapabilityInformation; mlme_associate_req->ChannelPage = ChannelPage; /* Insert service message into NHLE MLME queue */ #ifdef ENABLE_QUEUE_CAPACITY if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) { /* * MLME-ASSOCIATE.request is not appended into NHLE MAC * queue, hence free the buffer allocated */ bmm_buffer_free(buffer_header); return false; } #else qmm_queue_append(&nhle_mac_q, buffer_header); #endif /* ENABLE_QUEUE_CAPACITY */ return true; }
void mac_process_gts_request(buffer_t *gts_req) { /* Use the frame reception buffer for association indication. */ mlme_gts_ind_t *mgi = (mlme_gts_ind_t *)BMM_BUFFER_POINTER( gts_req); mgi->DeviceAddr = mac_parse_data.src_addr.short_address; mgi->GtsChar = mac_parse_data.mac_payload_data.gts_req_data; mgi->cmdcode = MLME_GTS_INDICATION; if (GTS_ALLOCATE == (mgi->GtsChar).GtsCharType) { if (mac_gts_allocate(mgi->GtsChar, mgi->DeviceAddr)) { /* Append the MLME GTS indication to the MAC-NHLE queue. **/ qmm_queue_append(&mac_nhle_q, gts_req); } else { bmm_buffer_free(gts_req); } } else { if (mac_gts_deallocate(mgi->GtsChar, mgi->DeviceAddr, false)) { /* Append the MLME GTS indication to the MAC-NHLE queue. **/ qmm_queue_append(&mac_nhle_q, gts_req); } else { bmm_buffer_free(gts_req); } } }
/** * @brief Frees up a buffer. * * This function frees up a buffer. The pointer passed to this function * should be the pointer returned during buffer allocation. The result is * unpredictable if an incorrect pointer is passed. * * @param pbuffer Pointer to buffer that has to be freed. */ void bmm_buffer_free(buffer_t *pbuffer) { if (NULL == pbuffer) { /* If the buffer pointer is NULL abort free operation */ return; } #if (TOTAL_NUMBER_OF_SMALL_BUFS > 0) if (IS_SMALL_BUF(pbuffer)) { /* Append the buffer into free small buffer queue */ qmm_queue_append(&free_small_buffer_q, pbuffer); } else { /* Append the buffer into free large buffer queue */ qmm_queue_append(&free_large_buffer_q, pbuffer); } #else /* no small buffers available at all */ /* Append the buffer into free large buffer queue */ qmm_queue_append(&free_large_buffer_q, pbuffer); #endif }
/** * @brief Initializes the buffer module. * * This function initializes the buffer module. * This function should be called before using any other functionality * of buffer module. */ void bmm_buffer_init(void) { uint8_t index; /* Initialize free buffer queue for large buffers */ #if (TOTAL_NUMBER_OF_LARGE_BUFS > 0) #ifdef ENABLE_QUEUE_CAPACITY qmm_queue_init(&free_large_buffer_q, TOTAL_NUMBER_OF_LARGE_BUFS); #else qmm_queue_init(&free_large_buffer_q); #endif /* ENABLE_QUEUE_CAPACITY */ #endif /* Initialize free buffer queue for small buffers */ #if (TOTAL_NUMBER_OF_SMALL_BUFS > 0) #ifdef ENABLE_QUEUE_CAPACITY qmm_queue_init(&free_small_buffer_q, TOTAL_NUMBER_OF_SMALL_BUFS); #else qmm_queue_init(&free_small_buffer_q); #endif /* ENABLE_QUEUE_CAPACITY */ #endif #if (TOTAL_NUMBER_OF_LARGE_BUFS > 0) for (index = 0; index < TOTAL_NUMBER_OF_LARGE_BUFS; index++) { /* * Initialize the buffer body pointer with address of the * buffer body */ buf_header[index].body = buf_pool + (index * LARGE_BUFFER_SIZE); /* Append the buffer to free large buffer queue */ qmm_queue_append(&free_large_buffer_q, &buf_header[index]); } #endif #if (TOTAL_NUMBER_OF_SMALL_BUFS > 0) for (index = 0; index < TOTAL_NUMBER_OF_SMALL_BUFS; index++) { /* * Initialize the buffer body pointer with address of the * buffer body */ buf_header[index + TOTAL_NUMBER_OF_LARGE_BUFS].body \ = buf_pool + (TOTAL_NUMBER_OF_LARGE_BUFS * LARGE_BUFFER_SIZE) + \ (index * SMALL_BUFFER_SIZE); /* Append the buffer to free small buffer queue */ qmm_queue_append(&free_small_buffer_q, &buf_header[index + \ TOTAL_NUMBER_OF_LARGE_BUFS]); } #endif }
bool wpan_mlme_associate_resp(uint64_t DeviceAddress, uint16_t AssocShortAddress, uint8_t status) { buffer_t *buffer_header; mlme_associate_resp_t *mlme_associate_resp; /* Allocate a small buffer for association response */ buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE); if (NULL == buffer_header) { /* Buffer is not available */ return false; } /* Get the buffer body from buffer header */ mlme_associate_resp = (mlme_associate_resp_t *)BMM_BUFFER_POINTER( buffer_header); /* Construct mlme_associate_resp_t message */ mlme_associate_resp->cmdcode = MLME_ASSOCIATE_RESPONSE; /* Other fields */ #ifdef TEST_HARNESS_BIG_ENDIAN mlme_associate_resp->DeviceAddress = CPU_ENDIAN_TO_LE64(DeviceAddress); mlme_associate_resp->AssocShortAddress = CPU_ENDIAN_TO_LE16( AssocShortAddress); #else mlme_associate_resp->DeviceAddress = DeviceAddress; mlme_associate_resp->AssocShortAddress = AssocShortAddress; #endif mlme_associate_resp->status = status; /* Insert mlme_associate_resp_t into NHLE MAC queue */ #ifdef ENABLE_QUEUE_CAPACITY if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) { /* * MLME-ASSOCIATE.response is not appended into NHLE MAC * queue, hence free the buffer allocated */ bmm_buffer_free(buffer_header); return false; } #else qmm_queue_append(&nhle_mac_q, buffer_header); #endif /* ENABLE_QUEUE_CAPACITY */ return true; }
bool wpan_mlme_poll_req(wpan_addr_spec_t *CoordAddrSpec) { buffer_t *buffer_header; mlme_poll_req_t *mlme_poll_req; /* Allocate a small buffer for poll request */ buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE); if (NULL == buffer_header) { /* Buffer is not available */ return false; } /* Get the buffer body from buffer header */ mlme_poll_req = (mlme_poll_req_t *)BMM_BUFFER_POINTER(buffer_header); /* construct mlme_poll_req_t message */ mlme_poll_req->cmdcode = MLME_POLL_REQUEST; /* Other fileds. */ mlme_poll_req->CoordAddrMode = CoordAddrSpec->AddrMode; #ifdef TEST_HARNESS_BIG_ENDIAN mlme_poll_req->CoordPANId = CPU_ENDIAN_TO_LE16(CoordAddrSpec->PANId); #else mlme_poll_req->CoordPANId = CoordAddrSpec->PANId; #endif if (WPAN_ADDRMODE_SHORT == CoordAddrSpec->AddrMode) { ADDR_COPY_DST_SRC_16(mlme_poll_req->CoordAddress, CoordAddrSpec->Addr.short_address); } else { ADDR_COPY_DST_SRC_64(mlme_poll_req->CoordAddress, CoordAddrSpec->Addr.long_address); } #ifdef ENABLE_QUEUE_CAPACITY if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) { /* * MLME-POLL.request is not appended into NHLE MAC * queue, hence free the buffer allocated and return false */ bmm_buffer_free(buffer_header); return false; } #else qmm_queue_append(&nhle_mac_q, buffer_header); #endif /* ENABLE_QUEUE_CAPACITY */ return true; }
bool wpan_mlme_disassociate_req(wpan_addr_spec_t *DeviceAddrSpec, uint8_t DisassociateReason, bool TxIndirect) { buffer_t *buffer_header; mlme_disassociate_req_t *mlme_disassociate_req; /* Allocate a small buffer for disassociation request */ buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE); if (NULL == buffer_header) { /* Buffer is not available */ return false; } /* Get the buffer body from buffer header */ mlme_disassociate_req = (mlme_disassociate_req_t *)BMM_BUFFER_POINTER( buffer_header); /* Update the disassociate request structure */ mlme_disassociate_req->cmdcode = MLME_DISASSOCIATE_REQUEST; mlme_disassociate_req->DisassociateReason = DisassociateReason; mlme_disassociate_req->DeviceAddrMode = DeviceAddrSpec->AddrMode; #ifdef TEST_HARNESS_BIG_ENDIAN mlme_disassociate_req->DevicePANId = CPU_ENDIAN_TO_LE16( DeviceAddrSpec->PANId); #else mlme_disassociate_req->DevicePANId = DeviceAddrSpec->PANId; #endif ADDR_COPY_DST_SRC_64(mlme_disassociate_req->DeviceAddress, DeviceAddrSpec->Addr.long_address); mlme_disassociate_req->TxIndirect = TxIndirect; #ifdef ENABLE_QUEUE_CAPACITY if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) { /* * MLME-DISASSOCIATE.request is not appended into NHLE MAC * queue, hence free the buffer allocated and return false */ bmm_buffer_free(buffer_header); return false; } #else qmm_queue_append(&nhle_mac_q, buffer_header); #endif /* ENABLE_QUEUE_CAPACITY */ return true; }
/** * @brief Handles an MLME-GET.request * * This function handles an MLME-GET.request. * The MLME-GET.request primitive requests information about a * given PIB attribute. * * @param m Pointer to the request structure */ void mlme_get_request(uint8_t *m) { /* Use the mlme get request buffer for mlme get confirmation */ mlme_get_conf_t *mgc = (mlme_get_conf_t *)BMM_BUFFER_POINTER( (buffer_t *)m); #if ((defined MAC_SECURITY_ZIP) || (defined MAC_SECURITY_2006)) uint8_t attribute_index = ((mlme_get_req_t *)mgc)->PIBAttributeIndex; #endif /* (MAC_SECURITY_ZIP || MAC_SECURITY_2006) */ /* Do actual PIB attribute reading */ { pib_value_t *attribute_value = &mgc->PIBAttributeValue; uint8_t status = MAC_SUCCESS; #if ((defined MAC_SECURITY_ZIP) || (defined MAC_SECURITY_2006)) status = mlme_get(((mlme_get_req_t *)mgc)->PIBAttribute, attribute_value, attribute_index); mgc->PIBAttributeIndex = attribute_index; #else status = mlme_get(((mlme_get_req_t *)mgc)->PIBAttribute, attribute_value); #endif /* (MAC_SECURITY_ZIP || MAC_SECURITY_2006) */ mgc->PIBAttribute = ((mlme_get_req_t *)mgc)->PIBAttribute; mgc->cmdcode = MLME_GET_CONFIRM; mgc->status = status; } /* Append the mlme get confirmation to MAC-NHLE queue */ qmm_queue_append(&mac_nhle_q, (buffer_t *)m); }
void rtb_process_data_ind(uint8_t *msg) { buffer_t *buf_ptr = (buffer_t *)msg; frame_info_t *frameptr = (frame_info_t *)BMM_BUFFER_POINTER(buf_ptr); mac_parse_data.mpdu_length = frameptr->mpdu[0]; /* First extract LQI. */ mac_parse_data.ppdu_link_quality = frameptr->mpdu[mac_parse_data.mpdu_length + LQI_LEN]; #ifdef RTB_WITHOUT_MAC /* Handle the received frame in case the frame is an RTB frame. */ handle_rx_rtb_frame_type(frameptr); /* * Release buffer in any case, since it is not forwarded * to any higher layer. */ bmm_buffer_free(buf_ptr); #else /* #ifdef RTB_WITHOUT_MAC */ /* Handle the received frame in case the frame is an RTB frame. */ if (!handle_rx_rtb_frame_type(frameptr)) { /* This is a not an RTB frame, so it is forwarded to the MAC. */ frameptr->msg_type = (frame_msgtype_t)TAL_DATA_INDICATION; qmm_queue_append(&tal_mac_q, buf_ptr); } else { bmm_buffer_free(buf_ptr); } #endif /* #ifdef RTB_WITHOUT_MAC */ }
/* * @brief Internal function to initiate rx enable confirm message. * * This function creates the rx enable confirm structure, * and appends it into internal event queue. * * @param buf Buffer for rx enable confirmation. * @param status Status of attempt to switch receiver on. */ static void gen_rx_enable_conf(buffer_t *buf, uint8_t status) { mlme_rx_enable_conf_t *rec = (mlme_rx_enable_conf_t *)BMM_BUFFER_POINTER(buf); rec->cmdcode = MLME_RX_ENABLE_CONFIRM; rec->status = status; qmm_queue_append(&mac_nhle_q, buf); }
bool wpan_mlme_orphan_resp(uint64_t OrphanAddress, uint16_t ShortAddress, bool AssociatedMember) { buffer_t *buffer_header; mlme_orphan_resp_t *mlme_orphan_resp; /* Allocate a small buffer for orphan response */ buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE); if (NULL == buffer_header) { /* Buffer is not available */ return false; } /* Get the buffer body from buffer header */ mlme_orphan_resp = (mlme_orphan_resp_t *)BMM_BUFFER_POINTER( buffer_header); /* Update the orphan response structure */ mlme_orphan_resp->cmdcode = MLME_ORPHAN_RESPONSE; #ifdef TEST_HARNESS_BIG_ENDIAN mlme_orphan_resp->OrphanAddress = CPU_ENDIAN_TO_LE64(OrphanAddress); mlme_orphan_resp->ShortAddress = CPU_ENDIAN_TO_LE16(ShortAddress); #else mlme_orphan_resp->OrphanAddress = OrphanAddress; mlme_orphan_resp->ShortAddress = ShortAddress; #endif mlme_orphan_resp->AssociatedMember = AssociatedMember; #ifdef ENABLE_QUEUE_CAPACITY if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) { /* * MLME-ORPHAN.response is not appended into NHLE MAC * queue, hence free the buffer allocated and return false */ bmm_buffer_free(buffer_header); return false; } #else qmm_queue_append(&nhle_mac_q, buffer_header); #endif /* ENABLE_QUEUE_CAPACITY */ return true; }
/** * @brief Function to initiate MLME-SYNC-LOSS.indication to NHLE. * * @param loss_reason MAC_REALIGNMENT if sync loss is due to receiving * coordinator realignment command and MAC_BEACON_LOSS if beacon was * lost following a sync request. */ void mac_sync_loss(uint8_t loss_reason) { /* * Static buffer used to give sync loss indication. This buffer is used in two * instances * 1) when the device looses sync with the parents beacons * 2) when the device receives a coordinator realignment command from his * parent * The buffer pointer is stored into the begin of the same static buffer. */ static uint8_t mac_sync_loss_buffer[sizeof(buffer_t) + sizeof(mlme_sync_loss_ind_t)]; mlme_sync_loss_ind_t *sync_loss_ind; buffer_t *msg_ptr; /* Update static buffer allocated for sync loss indication. */ msg_ptr = (buffer_t *)mac_sync_loss_buffer; msg_ptr->body = &mac_sync_loss_buffer[sizeof(buffer_t)]; // begin of message sync_loss_ind = (mlme_sync_loss_ind_t *)(msg_ptr->body); sync_loss_ind->cmdcode = MLME_SYNC_LOSS_INDICATION; sync_loss_ind->LossReason = loss_reason; #if (MAC_SCAN_SUPPORT == 1) if (MAC_SCAN_IDLE != mac_scan_state) { #if ((MAC_SCAN_ACTIVE_REQUEST_CONFIRM == 1) || (MAC_SCAN_PASSIVE_REQUEST_CONFIRM == 1)) sync_loss_ind->PANId = mac_scan_orig_panid; #else sync_loss_ind->PANId = tal_pib.PANId; #endif /* ((MAC_SCAN_ACTIVE_REQUEST_CONFIRM == 1) || (MAC_SCAN_PASSIVE_REQUEST_CONFIRM == 1)) */ sync_loss_ind->LogicalChannel = mac_scan_orig_channel; sync_loss_ind->ChannelPage = mac_scan_orig_page; } else #endif /* (MAC_SCAN_SUPPORT == 1) */ { sync_loss_ind->PANId = tal_pib.PANId; sync_loss_ind->LogicalChannel = tal_pib.CurrentChannel; sync_loss_ind->ChannelPage = tal_pib.CurrentPage; } /* Append the associate confirm message to MAC-NHLE queue. */ qmm_queue_append(&mac_nhle_q, msg_ptr); /* A device that is neither scanning nor polling shall go to sleep now. */ if ((MAC_IDLE == mac_state) || (MAC_ASSOCIATED == mac_state)) { if ((MAC_SCAN_IDLE == mac_scan_state) && (MAC_POLL_IDLE == mac_poll_state)) { /* Set radio to sleep if allowed */ mac_sleep_trans(); } } mac_sync_state = MAC_SYNC_NEVER; }
bool wpan_mlme_scan_req(uint8_t ScanType, uint32_t ScanChannels, uint8_t ScanDuration, uint8_t ChannelPage) { buffer_t *buffer_header; mlme_scan_req_t *mlme_scan_req; /* Allocate a small buffer for scan request */ buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE); if (NULL == buffer_header) { /* Buffer is not available */ return false; } /* Get the buffer body from buffer header */ mlme_scan_req = (mlme_scan_req_t *)BMM_BUFFER_POINTER(buffer_header); /* Update the scan request structure */ mlme_scan_req->cmdcode = MLME_SCAN_REQUEST; mlme_scan_req->ScanType = ScanType; mlme_scan_req->ScanChannels = ScanChannels; mlme_scan_req->ScanDuration = ScanDuration; mlme_scan_req->ChannelPage = ChannelPage; #ifdef ENABLE_QUEUE_CAPACITY if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) { /* * MLME-SCAN.request is not appended into NHLE MAC * queue, hence free the buffer allocated and return false */ bmm_buffer_free(buffer_header); return false; } #else qmm_queue_append(&nhle_mac_q, buffer_header); #endif /* ENABLE_QUEUE_CAPACITY */ return true; }
/** * @brief Handles an orphan notification * * This function processes an incoming orphan notification command. * A PAN coordinator gets to this function through a TAL data indication * message. * * @param msg Frame reception buffer */ void mac_process_orphan_notification(buffer_t *msg) { mlme_orphan_ind_t *moi = (mlme_orphan_ind_t *)BMM_BUFFER_POINTER(msg); moi->cmdcode = MLME_ORPHAN_INDICATION; ADDR_COPY_DST_SRC_64(moi->OrphanAddress, mac_parse_data.src_addr.long_address); /* Append the MLME orphan indication message to MAC-NHLE queue */ qmm_queue_append(&mac_nhle_q, msg); }
bool wpan_mlme_rx_enable_req(bool DeferPermit, uint32_t RxOnTime, uint32_t RxOnDuration) { buffer_t *buffer_header; mlme_rx_enable_req_t *mlme_rx_enable_req; /* Allocate a small buffer for rx enable request */ buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE); if (NULL == buffer_header) { /* Buffer is not available */ return false; } /* Get the buffer body from buffer header */ mlme_rx_enable_req = (mlme_rx_enable_req_t *)BMM_BUFFER_POINTER( buffer_header); /* Update the rx enable request structure */ mlme_rx_enable_req->cmdcode = MLME_RX_ENABLE_REQUEST; mlme_rx_enable_req->DeferPermit = DeferPermit; mlme_rx_enable_req->RxOnTime = RxOnTime; mlme_rx_enable_req->RxOnDuration = RxOnDuration; #ifdef ENABLE_QUEUE_CAPACITY if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) { /* * MLME-RX-ENABLE.request is not appended into NHLE MAC * queue, hence free the buffer allocated and return false */ bmm_buffer_free(buffer_header); return false; } #else qmm_queue_append(&nhle_mac_q, buffer_header); #endif /* ENABLE_QUEUE_CAPACITY */ return true; }
bool wpan_mlme_get_req(uint8_t PIBAttribute) #endif /* (MAC_SECURITY_ZIP || MAC_SECURITY_2006) */ { buffer_t *buffer_header; mlme_get_req_t *mlme_get_req; /* Allocate a large buffer for get request as maximum beacon payload * should be accommodated */ buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE); /* Check for buffer availability */ if (NULL == buffer_header) { return false; } /* Get the buffer body from buffer header */ mlme_get_req = (mlme_get_req_t *)BMM_BUFFER_POINTER(buffer_header); /* Update the get request structure */ mlme_get_req->cmdcode = MLME_GET_REQUEST; mlme_get_req->PIBAttribute = PIBAttribute; #if ((defined MAC_SECURITY_ZIP) || (defined MAC_SECURITY_2006)) mlme_get_req->PIBAttributeIndex = PIBAttributeIndex; #endif /* (MAC_SECURITY_ZIP || MAC_SECURITY_2006) */ #ifdef ENABLE_QUEUE_CAPACITY if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) { /* * MLME-GET.request is not appended into NHLE MAC * queue, hence free the buffer allocated and return false */ bmm_buffer_free(buffer_header); return false; } #else qmm_queue_append(&nhle_mac_q, buffer_header); #endif /* ENABLE_QUEUE_CAPACITY */ return true; }
/* * @brief Sends mlme reset confirm * * @param m Buffer for reset confirm * @param status Status of MAC reset operation */ static void send_reset_conf(buffer_t *buf_ptr, uint8_t status) { mlme_reset_conf_t *mrc; mrc = (mlme_reset_conf_t *)BMM_BUFFER_POINTER(buf_ptr); mrc->status = status; mrc->cmdcode = MLME_RESET_CONFIRM; /* Append the mlme reset confirm to the MAC-NHLE queue */ qmm_queue_append(&mac_nhle_q, buf_ptr); }
void mac_gen_mlme_gts_conf(buffer_t *buf_ptr, uint8_t status, gts_char_t gts_char) { mlme_gts_conf_t *gts_conf = (mlme_gts_conf_t *)BMM_BUFFER_POINTER(buf_ptr); gts_conf->cmdcode = MLME_GTS_CONFIRM; gts_conf->status = status; gts_conf->GtsChar = gts_char; /* Append the associate confirm message to MAC-NHLE queue. */ qmm_queue_append(&mac_nhle_q, buf_ptr); }
bool wpan_mlme_sync_req(uint8_t LogicalChannel, uint8_t ChannelPage, bool TrackBeacon) { buffer_t *buffer_header; mlme_sync_req_t *mlme_sync_req; /* Allocate a small buffer for sync request */ buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE); if (NULL == buffer_header) { /* Buffer is not available */ return false; } /* Get the buffer body from buffer header */ mlme_sync_req = (mlme_sync_req_t *)BMM_BUFFER_POINTER(buffer_header); /* Update the sync request structure */ mlme_sync_req->cmdcode = MLME_SYNC_REQUEST; mlme_sync_req->LogicalChannel = LogicalChannel; mlme_sync_req->ChannelPage = ChannelPage; mlme_sync_req->TrackBeacon = TrackBeacon; #ifdef ENABLE_QUEUE_CAPACITY if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) { /* * MLME-SYNC.request is not appended into NHLE MAC * queue, hence free the buffer allocated and return false */ bmm_buffer_free(buffer_header); return false; } #else qmm_queue_append(&nhle_mac_q, buffer_header); #endif /* ENABLE_QUEUE_CAPACITY */ return true; }
/* * @brief Internal function to generate confirmation * for MLME_START.request * * @param start_buf_ptr Pointer to MLME_START.request * @param start_req_status Status of the MLME_START.request */ static void gen_mlme_start_conf(buffer_t *start_buf_ptr, uint8_t start_req_status) { /* Use the same start request buffer for start confirm */ mlme_start_conf_t *msc = (mlme_start_conf_t *)BMM_BUFFER_POINTER(start_buf_ptr); msc->cmdcode = MLME_START_CONFIRM; msc->status = start_req_status; /* The confirmation message is appended to the MAC-NHLE queue */ qmm_queue_append(&mac_nhle_q, start_buf_ptr); }
bool wpan_mlme_gts_req(uint16_t DevShortAddr, gts_char_t GtsChar) { #ifdef GTS_SUPPORT buffer_t *buffer_header; mlme_gts_req_t *mlme_gts_req; /* Allocate a small buffer for gts request */ buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE); if (NULL == buffer_header) { /* Buffer is not available */ return false; } /* Get the buffer body from buffer header */ mlme_gts_req = (mlme_gts_req_t *)BMM_BUFFER_POINTER(buffer_header); /* construct mlme_gts_req_t message */ mlme_gts_req->cmdcode = MLME_GTS_REQUEST; mlme_gts_req->DeviceShortAddr = CPU_ENDIAN_TO_LE16(DevShortAddr); /* Other fields. */ mlme_gts_req->GtsChar = GtsChar; #ifdef ENABLE_QUEUE_CAPACITY if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) { /* * MLME-POLL.request is not appended into NHLE MAC * queue, hence free the buffer allocated and return false */ bmm_buffer_free(buffer_header); return false; } #else qmm_queue_append(&nhle_mac_q, buffer_header); #endif /* ENABLE_QUEUE_CAPACITY */ return true; #endif /* GTS_SUPPORT */ }
void mac_gts_table_update(void) { uint8_t table_index; for (table_index = 0; table_index < mac_pan_gts_table_len; table_index++) { if (mac_pan_gts_table[table_index].ExpiryCount > 0 && --mac_pan_gts_table[table_index].ExpiryCount == 0) { gts_char_t gts_char; uint16_t dev_addr = mac_pan_gts_table[table_index].DevShortAddr; gts_char.GtsDirection = mac_pan_gts_table[table_index].GtsDesc .GtsDirection; gts_char.GtsLength = mac_pan_gts_table[table_index].GtsDesc .GtsLength; gts_char.GtsCharType = GTS_DEALLOCATE; gts_char.Reserved = 0; if (mac_gts_deallocate(gts_char, mac_pan_gts_table[table_index]. DevShortAddr, true)) { buffer_t *buffer_header; mlme_gts_ind_t *mgi; buffer_header = bmm_buffer_alloc( LARGE_BUFFER_SIZE); if (NULL == buffer_header) { /* Buffer is not available */ return; } mgi = (mlme_gts_ind_t *)BMM_BUFFER_POINTER( buffer_header); mgi->DeviceAddr = dev_addr; mgi->GtsChar = gts_char; mgi->cmdcode = MLME_GTS_INDICATION; /* Append the MLME GTS indication to the *MAC-NHLE queue. */ qmm_queue_append(&mac_nhle_q, buffer_header); --table_index; } } } }
void mac_gen_mcps_data_conf(buffer_t *buf, uint8_t status, uint8_t handle) #endif /* ENABLE_TSTAMP */ { mcps_data_conf_t *mdc = (mcps_data_conf_t *)BMM_BUFFER_POINTER(buf); mdc->cmdcode = MCPS_DATA_CONFIRM; mdc->msduHandle = handle; mdc->status = status; #ifdef ENABLE_TSTAMP mdc->Timestamp = timestamp; #endif /* ENABLE_TSTAMP */ qmm_queue_append(&mac_nhle_q, buf); }
/** * @brief Callback function called by TAL on frame reception if RTB is used. * * This function pushes an event into the TAL-RTB queue, indicating a * frame reception. * * @param frame Pointer to recived frame */ void rtb_rx_frame_cb(frame_info_t *frame) { frame->msg_type = (frame_msgtype_t)RTB_DATA_INDICATION; if (NULL == frame->buffer_header) { #if (DEBUG > 0) ASSERT("Null frame From TAL" == 0); #endif return; } qmm_queue_append(&tal_rtb_q, frame->buffer_header); }
bool wpan_mlme_reset_req(bool SetDefaultPib) { buffer_t *buffer_header; mlme_reset_req_t *mlme_reset_req; /* Allocate a small buffer for reset request */ buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE); if (NULL == buffer_header) { /* Buffer is not available */ return false; } /* Get the buffer body from buffer header */ mlme_reset_req = (mlme_reset_req_t *)BMM_BUFFER_POINTER(buffer_header); /* Update the reset request structure */ mlme_reset_req->cmdcode = MLME_RESET_REQUEST; mlme_reset_req->SetDefaultPIB = SetDefaultPib; #ifdef ENABLE_QUEUE_CAPACITY if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) { /* * MLME-RESET.request is not appended into NHLE MAC * queue, hence free the buffer allocated and return false */ bmm_buffer_free(buffer_header); return false; } #else qmm_queue_append(&nhle_mac_q, buffer_header); #endif /* ENABLE_QUEUE_CAPACITY */ return true; }
bool wpan_mcps_purge_req(uint8_t msduHandle) { buffer_t *buffer_header; mcps_purge_req_t *mcps_purge_req; /* Allocate small buffer for mcps purge request */ buffer_header = bmm_buffer_alloc(LARGE_BUFFER_SIZE); if (NULL == buffer_header) { /* Buffer is not available */ return false; } /* Get the buffer body from buffer header */ mcps_purge_req = (mcps_purge_req_t *)BMM_BUFFER_POINTER(buffer_header); /* Update the purge request structure */ mcps_purge_req->cmdcode = MCPS_PURGE_REQUEST; mcps_purge_req->msduHandle = msduHandle; #ifdef ENABLE_QUEUE_CAPACITY if (MAC_SUCCESS != qmm_queue_append(&nhle_mac_q, buffer_header)) { /* * MCPS-PURGE.request is not appended into NHLE MAC * queue, hence free the buffer allocated and return false */ bmm_buffer_free(buffer_header); return false; } #else qmm_queue_append(&nhle_mac_q, buffer_header); #endif /* ENABLE_QUEUE_CAPACITY */ return true; }
/* * @brief Internal function to initiate mlme poll confirm message. * * @param buf_ptr Buffer to send poll confirmation to NHLE. * @param status MLME Poll request status. */ static void gen_mlme_poll_conf(buffer_t *buf_ptr, uint8_t status) { mlme_poll_conf_t *mpc = (mlme_poll_conf_t *)BMM_BUFFER_POINTER(buf_ptr); mpc->cmdcode = MLME_POLL_CONFIRM; mpc->status = status; /* * Only go to sleep if poll is not successful, * otherwise stay awake until subsequent evaluation of data frame */ if (MAC_SUCCESS != status) { /* Set radio to sleep if allowed */ mac_sleep_trans(); } qmm_queue_append(&mac_nhle_q, buf_ptr); }
/** * @brief Completes Rx transaction * * @param trx_id Transceiver identifier */ void complete_rx_transaction(trx_id_t trx_id) { /* Get energy of received frame */ uint16_t reg_offset = RF_BASE_ADDR_OFFSET * trx_id; uint8_t ed = trx_reg_read(reg_offset + RG_RF09_EDV); uint16_t ed_pos = rx_frm_info[trx_id]->len_no_crc + 1 + tal_pib[trx_id].FCSLen; rx_frm_info[trx_id]->mpdu[ed_pos] = ed; /* PSDU, LQI, ED */ /* Append received frame to incoming_frame_queue and get new rx buffer. **/ qmm_queue_append(&tal_incoming_frame_queue[trx_id], tal_rx_buffer[trx_id]); /* The previous buffer is eaten up and a new buffer is not assigned yet. **/ tal_rx_buffer[trx_id] = bmm_buffer_alloc(LARGE_BUFFER_SIZE); /* Switch to rx again to handle buffer shortage */ switch_to_rx(trx_id); }
/** * @brief Handles an MLME-SET.request primitive * * This function handles the MLME-SET.request. The MLME-SET.request primitive * attempts to write the given value to the indicated PIB attribute. * * @param m Pointer to the request structure */ void mlme_set_request(uint8_t *m) { mlme_set_req_t *msr = (mlme_set_req_t *)BMM_BUFFER_POINTER((buffer_t *)m); /* Do the actual PIB attribute set operation */ { pib_value_t *attribute_value = &msr->PIBAttributeValue; retval_t status = MAC_SUCCESS; mlme_set_conf_t *msc; #if ((defined MAC_SECURITY_ZIP) || (defined MAC_SECURITY_2006)) /* * Store attribute index in local var, because * it will be overwritten later. */ uint8_t attribute_index = msr->PIBAttributeIndex; #endif /* (MAC_SECURITY_ZIP || MAC_SECURITY_2006) */ /* * Call internal PIB attribute handling function. Always force * the trx back to sleep when using request primitives via the * MLME queue. */ #if ((defined MAC_SECURITY_ZIP) || (defined MAC_SECURITY_2006)) status = mlme_set(msr->PIBAttribute, msr->PIBAttributeIndex, attribute_value, true); #else status = mlme_set(msr->PIBAttribute, attribute_value, true); #endif msc = (mlme_set_conf_t *)msr; msc->PIBAttribute = msr->PIBAttribute; #ifdef MAC_SECURITY_ZIP msc->PIBAttributeIndex = attribute_index; #endif /* MAC_SECURITY_ZIP */ msc->cmdcode = MLME_SET_CONFIRM; msc->status = status; } /* Append the mlme set confirmation message to the MAC-NHLE queue */ qmm_queue_append(&mac_nhle_q, (buffer_t *)m); }
/** * @brief Creates a Communication Status Indication message to the upper layer * * @param status Status of the last operation * @param buf_ptr Buffer for Communication Status Indication to the NHLE */ void mac_mlme_comm_status(uint8_t status, buffer_t *buf_ptr) { /* * The pointer to the destination address (received as one of the * function * paramters) points to a location in buf_ptr. * As the same buffer is used to generate the comm status * indication, it is typecasted to the 'mlme_comm_status_ind_t'. This * may * result in loosing destination address (which is still a part of this * buffer), hence the destination address is backed up in a stack * variable. */ frame_info_t *frame_ptr = (frame_info_t *)BMM_BUFFER_POINTER(buf_ptr); uint64_t destination_address; memcpy(&destination_address, &frame_ptr->mpdu[PL_POS_DST_ADDR_START], sizeof(uint64_t)); mlme_comm_status_ind_t *csi = (mlme_comm_status_ind_t *)BMM_BUFFER_POINTER(buf_ptr); csi->cmdcode = MLME_COMM_STATUS_INDICATION; csi->PANId = tal_pib.PANId; csi->SrcAddrMode = FCF_LONG_ADDR; /* Initialize the source address */ csi->SrcAddr = tal_pib.IeeeAddress; csi->DstAddrMode = FCF_LONG_ADDR; /* Initialize the destination address */ csi->DstAddr = destination_address; csi->status = status; qmm_queue_append(&mac_nhle_q, buf_ptr); }