forked from 0xha0/df_datalink
mitigate: 整个地检和节点工程, 增加自动编译
更新了AD9361的profile
This commit is contained in:
@@ -0,0 +1,431 @@
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @file scan.c
|
||||
* @author FanHao ([email protected])
|
||||
* @brief DF Linklayer scan implementation file.
|
||||
* @version 0.1
|
||||
* @date 2023-05-06
|
||||
*
|
||||
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
|
||||
* Lab of Communication and Network
|
||||
*
|
||||
******************************************************************************/
|
||||
/**
|
||||
* @addtogroup LinkLayer
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup LinkLayer_Scan
|
||||
* @{
|
||||
*/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include <string.h>
|
||||
#include "link_layer.h"
|
||||
#include "link_layer_types.h"
|
||||
#include "msg_def.h"
|
||||
#include "node_list.h"
|
||||
#include "error.h"
|
||||
#include "common.h"
|
||||
#include "../phy_layer/phy_layer.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
#define ACK_FRAME_SLOTS 4
|
||||
/***************** Macros (In-line Functions) Definitions *********************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
static int32_t ScanMsg_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dstId);
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Packing Scan message to a bit array.
|
||||
*
|
||||
* @param bitarr pointer to bit array buffer.
|
||||
* @param msgType message type.
|
||||
*
|
||||
* @return EPARAM
|
||||
* SUCCESS
|
||||
*
|
||||
******************************************************************************/
|
||||
static int32_t ScanMsg_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dstId)
|
||||
{
|
||||
ASSERT(instPtr != NULL);
|
||||
int32_t Status;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case L2_FRAME_ADV:
|
||||
{
|
||||
L2_MSG_ADV *message = (L2_MSG_ADV *)(instPtr->sendPktData);
|
||||
|
||||
// Common section of link layer package
|
||||
message->common.frameNum = L2_GetNextFrameNum(instPtr);
|
||||
message->common.slotNum = L2_GetNextSlotNum(instPtr);
|
||||
message->common.src = L2_GetNodeId(instPtr);
|
||||
message->common.dst = dstId;
|
||||
message->common.msgType = L2_FRAME_ADV;
|
||||
|
||||
// insert position and speed info
|
||||
SysMonitor_GetSysinfo(&(instPtr->sysInfo));
|
||||
message->srcPosX = instPtr->sysInfo.posX;
|
||||
message->srcPosY = instPtr->sysInfo.posY;
|
||||
message->srcPosZ = instPtr->sysInfo.posZ;
|
||||
|
||||
// Insert net start time
|
||||
message->srcNetStatTime = instPtr->netStartTime;
|
||||
|
||||
// Packing extra payload
|
||||
SysMonitor_GetSendPayload(message->advData, &(message->advDataId), L2_PAYLOAD_LEN_ADV);
|
||||
if (message->advDataId == DATA_ID_NONE)
|
||||
{
|
||||
memset(message->advData, 0xAA, L2_PAYLOAD_LEN_ADV);
|
||||
}
|
||||
|
||||
// Append CRC
|
||||
uint32_t crcVal;
|
||||
Status = L2_CrcGen((uint8_t *)message, sizeof(L2_MSG_ADV) - L2_MSG_CRC_LEN, L2_CRC8_31, &crcVal);
|
||||
if (Status != SUCCESS)
|
||||
{
|
||||
DBG_ERROR("Fail to generate CRC, error code: %" PRId32 ".\n", Status);
|
||||
return Status;
|
||||
}
|
||||
message->crc = crcVal;
|
||||
|
||||
// Logging...
|
||||
memcpy(instPtr->log.txLog.data, message, sizeof(L2_MSG_ADV));
|
||||
instPtr->log.txLog.dataId = message->advDataId;
|
||||
|
||||
break;
|
||||
}
|
||||
case L2_FRAME_ACK:
|
||||
{
|
||||
L2_MSG_ACK *message = (L2_MSG_ACK *)(instPtr->sendPktData);
|
||||
|
||||
// Common section of link layer package
|
||||
message->common.frameNum = L2_GetNextFrameNum(instPtr);
|
||||
message->common.slotNum = L2_GetNextSlotNum(instPtr);
|
||||
message->common.src = L2_GetNodeId(instPtr);
|
||||
message->common.dst = dstId;
|
||||
message->common.msgType = L2_FRAME_ADV;
|
||||
|
||||
// insert position and speed info
|
||||
SysMonitor_GetSysinfo(&(instPtr->sysInfo));
|
||||
message->srcPosX = instPtr->sysInfo.posX;
|
||||
message->srcPosY = instPtr->sysInfo.posY;
|
||||
message->srcPosZ = instPtr->sysInfo.posZ;
|
||||
message->srcSpeedX = instPtr->sysInfo.vX;
|
||||
message->srcSpeedY = instPtr->sysInfo.vY;
|
||||
message->srcSpeedZ = instPtr->sysInfo.vZ;
|
||||
|
||||
// Packing extra payload
|
||||
SysMonitor_GetSendPayload(message->ackData, &(message->ackDataId), L2_PAYLOAD_LEN_ACK);
|
||||
if (message->ackDataId == DATA_ID_NONE)
|
||||
{
|
||||
memset(message->ackData, 0xAA, L2_PAYLOAD_LEN_ACK);
|
||||
}
|
||||
|
||||
// Append CRC
|
||||
uint32_t crcVal;
|
||||
Status = L2_CrcGen((uint8_t *)message, sizeof(L2_MSG_ACK) - L2_MSG_CRC_LEN, L2_CRC8_31, &crcVal);
|
||||
if (Status != SUCCESS)
|
||||
{
|
||||
DBG_ERROR("Fail to generate CRC, error code: %" PRId32 ".\n", Status);
|
||||
return Status;
|
||||
}
|
||||
message->crc = crcVal;
|
||||
|
||||
// Logging...
|
||||
memcpy(instPtr->log.txLog.data, message, sizeof(L2_MSG_ACK));
|
||||
instPtr->log.txLog.dataId = message->ackDataId;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
DBG_ERROR("Unexpected frame type: %" PRId8 ".\n", type);
|
||||
return EPARAM;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Scan net packet handler.
|
||||
*
|
||||
* @param instPtr a pointer to linklayer layer instance
|
||||
* @param msg A pointer to frame data buffer.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
|
||||
{
|
||||
ASSERT(instPtr != NULL);
|
||||
ASSERT(msg != NULL);
|
||||
int32_t Status;
|
||||
L2_FRAME_TYPE frameType = L2_FRAME_NONE;
|
||||
L2_FrameGetChunk(msg, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &frameType);
|
||||
|
||||
switch (frameType)
|
||||
{
|
||||
case L2_FRAME_ADV:
|
||||
{
|
||||
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
|
||||
{
|
||||
DBG_ERROR("Unexpected call from head node, only member Node can handle L2_FRAME_ADV.\n");
|
||||
Status = EUNEXP;
|
||||
break;
|
||||
}
|
||||
|
||||
L2_MSG_ADV *message = (L2_MSG_ADV *)msg;
|
||||
|
||||
// Update node status.
|
||||
uint8_t nodeId = message->common.src;
|
||||
NODE_ENTRY *node;
|
||||
node = L2_GetNodeById(instPtr->nodeList, nodeId);
|
||||
if (node == NULL)
|
||||
{
|
||||
node = L2_AppendNode(instPtr->nodeList, nodeId, L2_NODE_HEAD);
|
||||
if (node == NULL)
|
||||
{
|
||||
DBG_ERROR("Failed to append new node [id: %" PRId8 "]", nodeId);
|
||||
Status = ENOMEM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Update node info.
|
||||
node->nodeInfo.pos.x = message->srcPosX;
|
||||
node->nodeInfo.pos.y = message->srcPosY;
|
||||
node->nodeInfo.pos.z = message->srcPosZ;
|
||||
node->nodeInfo.antIndex = Phy_ReceiveAntIndex(instPtr->config.phyInstPtr);
|
||||
|
||||
// Reset node ttl
|
||||
node->ttlCnt = 0;
|
||||
|
||||
// Update net start time.
|
||||
uint32_t netstartTime = message->srcNetStatTime;
|
||||
L2_EVENT netSetupDoneEvent =
|
||||
{
|
||||
.event = L2_EV_NET_ADV_UPDATE,
|
||||
.msg = &netstartTime
|
||||
};
|
||||
AssertL2Event(instPtr, &netSetupDoneEvent);
|
||||
|
||||
// Calculate time deviation
|
||||
uint32_t frameNum = message->common.frameNum;
|
||||
uint32_t slotNum = (uint32_t)message->common.slotNum;
|
||||
Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev));
|
||||
if (Status != SUCCESS)
|
||||
{
|
||||
DBG_ERROR("Failed to compute time deviation.\n")
|
||||
break;
|
||||
}
|
||||
|
||||
// check if net setup finished.
|
||||
if (L2_isCxn2Net(instPtr) == false)
|
||||
{
|
||||
// Assert Net-Setup Done.
|
||||
L2_EVENT l2Event = {
|
||||
.event = L2_EV_NET_SETUP_DONE,
|
||||
.msg = NULL
|
||||
};
|
||||
(void)AssertL2Event(instPtr, &l2Event);
|
||||
}
|
||||
// Time sync.
|
||||
L2_TimeAdjust(instPtr, &(instPtr->log.timeDev));
|
||||
|
||||
// Get data payload
|
||||
uint32_t dataId = message->advDataId;
|
||||
SysMonitor_UpdateRecvPayload(message->advData, dataId, L2_PAYLOAD_LEN_ADV);
|
||||
|
||||
// Logging...
|
||||
memcpy(instPtr->log.rxLog.data, msg, sizeof(L2_MSG_ADV));
|
||||
instPtr->log.rxLog.dataId = dataId;
|
||||
|
||||
Status = SUCCESS;
|
||||
break;
|
||||
}
|
||||
case L2_FRAME_ACK:
|
||||
{
|
||||
if (L2_GetNodeType(instPtr) == L2_NODE_MEMBER)
|
||||
{
|
||||
DBG_ERROR("Unexpected call from member node, only head Node can handle L2_FRAME_ACK.\n");
|
||||
Status = EUNEXP;
|
||||
break;
|
||||
}
|
||||
|
||||
L2_MSG_ACK *message = (L2_MSG_ACK *)msg;
|
||||
|
||||
// Update node status.
|
||||
uint8_t nodeId = message->common.src;
|
||||
NODE_ENTRY *node;
|
||||
node = L2_GetNodeById(instPtr->nodeList, nodeId);
|
||||
if (node == NULL)
|
||||
{
|
||||
node = L2_AppendNode(instPtr->nodeList, nodeId, L2_NODE_MEMBER);
|
||||
if (node == NULL)
|
||||
{
|
||||
DBG_ERROR("Failed to append new node [id: %" PRId8 "]", nodeId);
|
||||
Status = ENOMEM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Update node info.
|
||||
node->nodeInfo.pos.x = message->srcPosX;
|
||||
node->nodeInfo.pos.y = message->srcPosY;
|
||||
node->nodeInfo.pos.z = message->srcPosZ;
|
||||
node->nodeInfo.speed.x = message->srcSpeedX;
|
||||
node->nodeInfo.speed.y = message->srcSpeedY;
|
||||
node->nodeInfo.speed.z = message->srcSpeedZ;
|
||||
node->nodeInfo.antIndex = Phy_ReceiveAntIndex(instPtr->config.phyInstPtr);
|
||||
|
||||
// Reset node ttl
|
||||
node->ttlCnt = 0;
|
||||
|
||||
// Calculate time deviation
|
||||
uint32_t frameNum = message->common.frameNum;
|
||||
uint32_t slotNum = (uint32_t)message->common.slotNum;
|
||||
Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev));
|
||||
if (Status != SUCCESS)
|
||||
{
|
||||
DBG_ERROR("Failed to compute time deviation.\n")
|
||||
break;
|
||||
}
|
||||
|
||||
if (L2_GetMainState(instPtr) == L2_INIT_STATE) // FIXME: state switch should follow routing table
|
||||
{
|
||||
// Assert Net-Setup Done.
|
||||
L2_EVENT l2Event;
|
||||
L2_NODE_STATE newState = L2_NORMAL_STATE;
|
||||
l2Event.event = L2_EV_MAIN_STATE_UPDATE;
|
||||
l2Event.msg = &newState;
|
||||
(void)AssertL2Event(instPtr, &l2Event);
|
||||
}
|
||||
|
||||
// Get data payload
|
||||
uint32_t dataId = message->ackDataId;
|
||||
SysMonitor_UpdateRecvPayload(message->ackData, dataId, L2_PAYLOAD_LEN_ACK);
|
||||
|
||||
// Logging...
|
||||
memcpy(instPtr->log.rxLog.data, msg, sizeof(L2_MSG_ACK));
|
||||
instPtr->log.rxLog.dataId = dataId;
|
||||
|
||||
Status = SUCCESS;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
DBG_ERROR("Unsupported frame type: %" PRId8 ".\n", frameType);
|
||||
Status = EUNEXP;
|
||||
break;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Execute a scan net Routine procedure.
|
||||
*
|
||||
* @param rtneEntry Routine configuration
|
||||
*
|
||||
* @return used slot (2 ms slot).
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t L2_Scan_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntry)
|
||||
{
|
||||
ASSERT(instPtr != NULL);
|
||||
DBG_INFO("-------- Scan Routine --------\n");
|
||||
|
||||
if (rtneEntry->slotSeq != 0)
|
||||
{
|
||||
return SUCCESS; // skip other slots, only process in the 1st slot
|
||||
}
|
||||
|
||||
PHY_INST *phyRef = instPtr->config.phyInstPtr;
|
||||
PHY_ANT_INDEX antIndex;
|
||||
L2_TOR_TYPE torState;
|
||||
const NODE_ENTRY *commNode;
|
||||
|
||||
switch (rtneEntry->slotType)
|
||||
{
|
||||
case L2_SLOT_ADVERTISE:
|
||||
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD && rtneEntry->src == L2_GetNodeId(instPtr))
|
||||
{
|
||||
// antenna selection based on broadcast id in routing table
|
||||
antIndex = L2_AntId2AntIndex(rtneEntry->dst);
|
||||
// head node transmits messages in advertise slot
|
||||
torState = L2_TOR_TX;
|
||||
|
||||
// reset memory
|
||||
memset(instPtr->sendPktData, 0xAA, L2_PACK_LEN_MAX);
|
||||
// pack message
|
||||
if (ScanMsg_Packing(instPtr, L2_FRAME_ADV, rtneEntry->dst) != SUCCESS)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
else if (L2_GetNodeType(instPtr) == L2_NODE_MEMBER)
|
||||
{
|
||||
commNode = L2_GetNodeById(instPtr->nodeList, rtneEntry->src);
|
||||
// antenna selection based on node list
|
||||
antIndex = commNode->nodeInfo.antIndex;
|
||||
// member node receives message in advertise slot
|
||||
torState = L2_TOR_RX;
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise suspend
|
||||
antIndex = PHY_ANT_INDEX_NONE;
|
||||
torState = L2_TOR_SUSPEND;
|
||||
}
|
||||
(void)Phy_SetAntIndex(instPtr->config.phyInstPtr, antIndex);
|
||||
(void)L2_SetupNextSlot(instPtr, torState, L2_FRAME_ADV);
|
||||
break;
|
||||
case L2_SLOT_ACKNOWLEDGE:
|
||||
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD && rtneEntry->dst == L2_GetNodeId(instPtr))
|
||||
{
|
||||
// FIXME: is antenna index necessary here?
|
||||
antIndex = PHY_ANT_INDEX_NONE;
|
||||
// head node receives messages in acknowledge slot
|
||||
torState = L2_TOR_RX;
|
||||
}
|
||||
else if (L2_GetNodeType(instPtr) == L2_NODE_MEMBER && rtneEntry->src == L2_GetNodeId(instPtr))
|
||||
{
|
||||
commNode = L2_GetNodeById(instPtr->nodeList, rtneEntry->src);
|
||||
// antenna selection based on node list
|
||||
antIndex = commNode->nodeInfo.antIndex;
|
||||
// member node transmits message in acknowledge slot
|
||||
torState = L2_TOR_TX;
|
||||
|
||||
// reset memory
|
||||
memset(instPtr->sendPktData, 0xAA, L2_PACK_LEN_MAX);
|
||||
// pack message
|
||||
if (ScanMsg_Packing(instPtr, L2_FRAME_ACK, rtneEntry->dst) != SUCCESS)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise suspend
|
||||
antIndex = PHY_ANT_INDEX_NONE;
|
||||
torState = L2_TOR_SUSPEND;
|
||||
}
|
||||
(void)Phy_SetAntIndex(instPtr->config.phyInstPtr, antIndex);
|
||||
(void)L2_SetupNextSlot(instPtr, torState, L2_FRAME_ACK);
|
||||
break;
|
||||
default:
|
||||
DBG_ERROR("Cannot start a routine for slot type [%" PRId8 "] properly.\n", rtneEntry->slotType);
|
||||
return FAILURE;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/** @} LinkLayer_Scan*/
|
||||
/** @} LinkLayer*/
|
||||
Reference in New Issue
Block a user