Initial version.

This commit is contained in:
Gatsby Van
2023-12-20 00:11:03 +08:00
commit 416bd53733
1043 changed files with 293547 additions and 0 deletions
+295
View File
@@ -0,0 +1,295 @@
/*****************************************************************************/
/**
* Description: Implementations for 814 datalink service net.
* Date: 2021-11-16 00:08
* LastEditors: Fan Hao
* LastEditTime: 2022-07-16 17:04
* Revisions: Rev 0.1
* History:
* [2022-07-16]: New branch for DiJian.
* [2021-11-16]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
/***************************** Include Files *********************************/
#include <string.h>
#include "linklayer814.h"
#include "linklayer814_types.h"
#include "msg_def.h"
#include "../error.h"
#include "../common.h"
#ifdef _MPC_CTRL
#endif
/************************** Constant Definitions *****************************/
#define SQUENCE_SVC_SLOTS 0
#define INER_SVC_SLOTS 2
#define INRA_SVC_SLOTS 1
#define NONE_SVC_SLOTS 0
#define TEST_UDU_PDLEN 16
#define TEST_UDU_LEN (UDUH_LEN/8 + TEST_UDU_PDLEN + PDU_CRC_LEN/8 )
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
#ifdef _MPC_CTRL
#endif
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
#ifdef _MPC_CTRL
#endif
/*****************************************************************************/
/**
* @brief Packing UDU Header to a bit array.
*
* @param bitarr pointer to bit array buffer.
* dst Destination node address.
* dataLen Length of UDU data.
*
* @return EPARAM
* SUCCESS
*
******************************************************************************/
static int UduHeader_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, uint8_t dst, uint32_t dataLen){
ASSERT(bitarr != NULL);
if(bitarr->num_of_bits < UDUH_LEN){
return EPARAM;
}
uint64_t dataChunk = 0;
memset(bitarr->words, 0xF0, (size_t)(UDUH_LEN/8));
// priority
dataChunk = 1;
FrameInsertChunk(bitarr, UDUH_PRI_OFFSET, UDUH_PRI_LEN, dataChunk);
// message type
dataChunk = 2;
FrameInsertChunk(bitarr, UDUH_MSG_TYPE_OFFSET, UDUH_MSG_TYPE_LEN, dataChunk);
// data length
dataChunk = dataLen;
FrameInsertChunk(bitarr, UDUH_LENGTH_OFFSET, UDUH_LENGTH_LEN, dataChunk);
// source node id
dataChunk = (instPtr->myInfo.nodeId & 0x1F)|((instPtr->myInfo.clustId & 0x1F) << 5);
FrameInsertChunk(bitarr, UDUH_SRC_ADDR_OFFSET, UDUH_SRC_ADDR_LEN, dataChunk);
// destination node id
dataChunk = (dst & 0x1F)|((instPtr->myInfo.clustId & 0x1F) << 5);
FrameInsertChunk(bitarr, UDUH_DST_ADDR_OFFSET, UDUH_DST_ADDR_LEN, dataChunk);
// UDU Sequence number
dataChunk = 0;
FrameInsertChunk(bitarr, UDUH_UDU_SEQ_NUM_OFFSET, UDUH_UDU_SEQ_NUM_LEN, dataChunk);
// retransmission times
dataChunk = 0;
FrameInsertChunk(bitarr, UDUH_RETRANS_NUM_OFFSET, UDUH_RETRANS_NUM_LEN, dataChunk);
// number of slice
dataChunk = 1;
FrameInsertChunk(bitarr, UDUH_NUM_SLICE_OFFSET, UDUH_NUM_SLICE_LEN, dataChunk);
// slice id
dataChunk = 1;
FrameInsertChunk(bitarr, UDUH_SLICE_ID_OFFSET, UDUH_SLICE_ID_LEN, dataChunk);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Packing PDU Header to a bit array.
*
* @param bitarr pointer to bit array buffer.
* headerType PDU header type.
* dst Destination node address.
*
* @return EPARAM
* SUCCESS
*
******************************************************************************/
static int PduHeader_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_PDU_HEADER_TYPE headerType, uint8_t dst){
ASSERT(bitarr != NULL);
if(headerType < L2_PDU_HEADER_0 || headerType > L2_PDU_HEADER_1){
return EPARAM;
}
uint64_t dataChunk = 0;
if(headerType == L2_PDU_HEADER_0){
if(bitarr->num_of_bits < PDUH0_LEN){
return EPARAM;
}
memset(bitarr->words, 0xF0, (size_t)(PDUH0_LEN/8));
// PDU type
dataChunk = 0;
FrameInsertChunk(bitarr, PDUH0_TYPE_OFFSET, PDUH0_TYPE_LEN, dataChunk);
// frame length
dataChunk = INTRA_SVC_FRAME_LENGTH_MAX;
FrameInsertChunk(bitarr, PDUH0_LENGTH_OFFSET, PDUH0_LENGTH_LEN, dataChunk);
// source node id
dataChunk = (instPtr->myInfo.nodeId & 0x1F)|((instPtr->myInfo.clustId & 0x1F) << 5);
FrameInsertChunk(bitarr, PDUH0_SRC_ADDR_OFFSET, PDUH0_SRC_ADDR_LEN, dataChunk);
// destination node id
dataChunk = (dst & 0x1F)|((instPtr->myInfo.clustId & 0x1F) << 5);
FrameInsertChunk(bitarr, PDUH0_DST_ADDR_OFFSET, PDUH0_DST_ADDR_LEN, dataChunk);
// Sequence number
dataChunk = 0;
FrameInsertChunk(bitarr, PDUH0_SEQ_NUM_OFFSET, PDUH0_SEQ_NUM_LEN, dataChunk);
// Append CRC
L2_CrcAppend((uint8_t*)bitarr->words, PDUH0_HEADER_CRC_OFFSET/8, PDUH0_HEADER_CRC_OFFSET/8, L2_CRC8_31);
}
else if(headerType == L2_PDU_HEADER_1){
if(bitarr->num_of_bits < PDUH1_LEN){
return EPARAM;
}
memset(bitarr->words, 0xF0, (size_t)(PDUH1_LEN/8));
// PDU type
dataChunk = 1;
FrameInsertChunk(bitarr, PDUH1_TYPE_OFFSET, PDUH1_TYPE_LEN, dataChunk);
// frame length
dataChunk = INTRA_SVC_FRAME_LENGTH_MAX;
FrameInsertChunk(bitarr, PDUH1_LENGTH_OFFSET, PDUH1_LENGTH_LEN, dataChunk);
// source node id
dataChunk = (instPtr->myInfo.nodeId & 0x1F)|((instPtr->myInfo.clustId & 0x1F) << 5);
FrameInsertChunk(bitarr, PDUH1_SRC_ADDR_OFFSET, PDUH1_SRC_ADDR_LEN, dataChunk);
// destination node id
dataChunk = (dst & 0x1F)|((instPtr->myInfo.clustId & 0x1F) << 5);
FrameInsertChunk(bitarr, PDUH1_DST_ADDR_OFFSET, PDUH1_DST_ADDR_LEN, dataChunk);
// Slice tage...
// Append CRC
L2_CrcAppend((uint8_t*)bitarr->words, PDUH1_HEADER_CRC_OFFSET/8, PDUH1_HEADER_CRC_OFFSET/8, L2_CRC8_31);
}
else{
return FAILURE;
}
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Initialize service net FSM
*
* @param serviceFSM A pointer to service FSM instance.
*
* @return SUCCESS Initialize successfully.
* Other Initialize failed.
*
******************************************************************************/
int32_t ServiceNet_Init(L2_SVC_FSM** serviceFSM) {
(*serviceFSM) = (L2_SVC_FSM*) malloc(sizeof(L2_SVC_FSM));
if (*serviceFSM == NULL) {
return EALLOC;
}
ServiceNet_Reset(*serviceFSM);
return SUCCESS;
}
void ServiceNet_Reset(L2_SVC_FSM* serviceFSM) {
serviceFSM->isBisar = false;
serviceFSM->isBisarEven = false;
serviceFSM->bisarDst = NONE_ID;
}
void ServiceNet_Destroy(L2_SVC_FSM* serviceFSM){
free(serviceFSM);
}
/*****************************************************************************/
/**
* @brief Handle service received packet. Send data up to MPC
*
* @param instPtr a pointer to linklayer layer instance
*
* @return SUCCESS message has been successfully handled.
* other error occurred.
*
******************************************************************************/
int32_t ServiceNet_PktHandler(L2_INST* instPtr) {
// TODO:
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Service net FSM procedure.
*
* @param instPtr a pointer to linklayer layer instance
* @param rtneEntry
*
* @return Slot has been used.
*
******************************************************************************/
int32_t ServiceNet_Routine(L2_INST* instPtr, const L2_RTNE_TABLE_ENTRY* rtneEntry) {
ASSERT(instPtr != NULL);
int32_t Status;
L2_TOR_TYPE torState;
DBG_INFO("-------- ServiceNet Routine --------\n");
if(rtneEntry->slotSeq != 0){
return SQUENCE_SVC_SLOTS;
}
// Determine TOR State.
if(rtneEntry->src0 == instPtr->myInfo.nodeId){
torState = L2_TOR_TX;
}
else if(rtneEntry->dst0 == instPtr->myInfo.nodeId){
torState = L2_TOR_RX;
}
else{
torState = L2_TOR_SUSPEND;
}
BIT_ARRAY* svcMsg = bit_array_create(L2_MSG_MAX);
if(svcMsg == NULL){
DBG_ERROR("Failed to allocate memory for svcMsg.\n");
return NUM_SLOTS_NONE;
}
memset(instPtr->sendPktData, 0xCC, (size_t)(INTRA_SVC_FRAME_LENGTH_MAX));
switch(rtneEntry->slotType){
case SLOT_INTER_SVC:
L2_SetupNextSlot(instPtr, torState, L2_INTER_SVC_FRAME);
break;
case SLOT_INTRA_SVC:
if(torState == L2_TOR_TX){
//TODO:
memset(instPtr->sendPktData, 0xAA, INTRA_SVC_FRAME_LENGTH_MAX);
// Pack PDU header
if(PduHeader_Packing(instPtr, svcMsg, L2_PDU_HEADER_0, rtneEntry->dst0) != SUCCESS){
DBG_ERROR("Failed to packing PduHeader.\n");
Status = FAILURE;
goto routine_err;
}
memcpy(instPtr->sendPktData, svcMsg->words, (size_t)(PDUH0_LEN/8));
// Pack UDU Header
if(UduHeader_Packing(instPtr, svcMsg, rtneEntry->dst0,
INTRA_SVC_FRAME_LENGTH_MAX-(PDUH0_LEN+MSG_KEY_LENGTH_LEN)/8)
!= SUCCESS){
DBG_ERROR("Failed to packing UduHeader.\n");
Status = FAILURE;
goto routine_err;
}
memcpy(instPtr->sendPktData + ((PDUH0_LEN+MSG_KEY_LENGTH_LEN)/8), svcMsg->words, (size_t)(UDUH_LEN/8));
// For ZhiQiang
// Payload Byte3, bit0~2: message class, bit3~7 message subclass
// FIXME: message class tag 0x01, only for test.
memset(instPtr->sendPktData+((PDUH0_LEN+MSG_KEY_LENGTH_LEN+UDUH_LEN)/8) + 3, 0x01, 1);
L2_CrcAppend(instPtr->sendPktData + ((PDUH0_LEN+MSG_KEY_LENGTH_LEN)/8),
INTRA_SVC_FRAME_LENGTH_MAX-(PDUH0_LEN+MSG_KEY_LENGTH_LEN+PDU_CRC_LEN)/8,
INTRA_SVC_FRAME_LENGTH_MAX-(PDUH0_LEN+MSG_KEY_LENGTH_LEN+PDU_CRC_LEN)/8,
L2_CRC16_8005
);
}
L2_SetupNextSlot(instPtr, torState, L2_INTRA_SVC_FRAME);
break;
default:
DBG_ERROR("UNKNOWN slot type [%d].\n", rtneEntry->slotType);
DBG_ERROR("Failed to packing PduHeader.\n");
Status = FAILURE;
goto routine_err;
}
bit_array_free(svcMsg);// free memory
return SUCCESS;
routine_err:
bit_array_free(svcMsg);// free memory
return Status;
}