Compare commits

...
26 Commits
Author SHA1 Message Date
Gatsby Van a2032414cc fix typo 2023-12-22 01:27:40 +08:00
Gatsby Van 16b6e18420 add w2aq rsp test. 2023-12-22 01:27:26 +08:00
Gatsby Van 6acd6e68ca adapted new node list api 2023-12-22 01:26:55 +08:00
Gatsby Van c0d347a619 fix typo and better debug print. 2023-12-22 01:26:29 +08:00
Gatsby Van b76a4cd776 miscellaneous update (and adapt to new node list api) 2023-12-22 01:25:54 +08:00
Gatsby Van c1e26fa20b miscellaneous update (enhance code coherence) 2023-12-22 01:25:00 +08:00
Gatsby Van e6d498687c bugfix: correct assert condition. 2023-12-22 01:24:13 +08:00
Gatsby Van 92cdcdc8e9 bugfix: correct return value. 2023-12-22 01:23:38 +08:00
Gatsby Van d0357cb199 adapted to new node list api. 2023-12-22 01:22:41 +08:00
Gatsby Van 9642a003e0 bugfix: rtt rx event happens two slots after. 2023-12-22 01:22:06 +08:00
Gatsby Van 57dfad7b82 add rtt event, and adapted to new schedule event pool 2023-12-22 01:20:44 +08:00
Gatsby Van f72e6fadb1 omit unused code. 2023-12-22 01:20:00 +08:00
Gatsby Van 0bec764c96 update comments. 2023-12-22 01:19:11 +08:00
Gatsby Van 218fb01193 rewrite schedule event pool. 2023-12-22 01:18:43 +08:00
Gatsby Van 595b63c8ef rewrite node list (base on util list). 2023-12-21 23:47:28 +08:00
Gatsby Van 4455e29be6 bugfix: rtt fsm won't work at none stage. 2023-12-21 23:16:47 +08:00
Gatsby Van 0a535af392 better debug print. 2023-12-21 23:15:08 +08:00
Gatsby Van 426a35b48f better print. 2023-12-21 23:12:22 +08:00
Gatsby Van 30b3afc686 miscellaneous update. 2023-12-21 23:12:01 +08:00
Gatsby Van 8b5192b3f4 rewrite schedule pool. 2023-12-21 23:11:44 +08:00
Gatsby Van 329abdfca3 enhance coherence. 2023-12-21 23:10:51 +08:00
Gatsby Van a2de2d5855 miscellaneous update. 2023-12-21 23:10:28 +08:00
Gatsby Van 62690fba15 better print. 2023-12-21 23:09:46 +08:00
Gatsby Van 9d023e2726 update makefile. 2023-12-21 23:09:22 +08:00
Gatsby Van 3a54546cbb add debug settings. 2023-12-21 23:08:58 +08:00
Gatsby Van 5f6bdf83d6 add a linked list utility. 2023-12-21 23:08:38 +08:00
30 changed files with 1329 additions and 635 deletions
+34
View File
@@ -0,0 +1,34 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch GE linklayer_emulate_unit_test",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/datalink814_ge/unit_test/linklayer_emulate_unit_test.exe",
"args": [],
"preLaunchTask": "linklayer_emulate_unit_test",
"stopAtEntry": false,
"cwd": "${workspaceFolder}/datalink814_ge/unit_test",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}
+30
View File
@@ -0,0 +1,30 @@
{
"version": "2.0.0",
"reveal": "always",
"tasks": [
{
"label": "tmc_emulate_unit_test",
"command": "bash",
"type": "shell",
"group": {
"kind": "build"
},
"options": {
"cwd": "${workspaceFolder}/datalink814_ge/unit_test"
},
"args": ["-c", "make tmc_emulate_unit_test.exe"]
},
{
"label": "linklayer_emulate_unit_test",
"command": "bash",
"type": "shell",
"group": {
"kind": "build"
},
"options": {
"cwd": "${workspaceFolder}/datalink814_ge/unit_test"
},
"args": ["-c", "make linklayer_emulate_unit_test.exe"]
}
]
}
+5 -6
View File
@@ -3,15 +3,14 @@
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../src/bit_array/bit_array.c
OBJS += \
./src/bit_array/bit_array.o
BIT_ARRAY_SRC := $(wildcard ../src/bit_array/bit_array*.c)
C_DEPS += \
./src/bit_array/bit_array.d
C_SRCS += $(BIT_ARRAY_SRC)
OBJS += $(patsubst ../src/bit_array/bit_array%.c, ./src/bit_array/bit_array%.o, $(BIT_ARRAY_SRC))
C_DEPS += $(patsubst ../src/bit_array/bit_array%.c, ./src/bit_array/bit_array%.d, $(BIT_ARRAY_SRC))
# Each subdirectory must supply rules for building sources it contributes
src/bit_array/%.o: ../src/bit_array/%.c
+6 -7
View File
@@ -2,15 +2,14 @@
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../src/config/platform.c
# Add inputs and outputs from these tool invocations to the build variables
CONFIG_SRC := $(wildcard ../src/config/*.c)
OBJS += \
./src/config/platform.o
C_SRCS += $(CONFIG_SRC)
C_DEPS += \
./src/config/platform.d
OBJS += $(patsubst ../src/config/%.c, ./src/config/%.o, $(CONFIG_SRC))
C_DEPS += $(patsubst ../src/config/%.c, ./src/config/%.d, $(CONFIG_SRC))
# Each subdirectory must supply rules for building sources it contributes
@@ -3,20 +3,13 @@
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../src/linklayer/geometry/coord.c \
../src/linklayer/geometry/eulerangles.c \
../src/linklayer/geometry/quaternion.c
GEOMETRY_SRC := $(wildcard ../src/linklayer/geometry/*.c)
OBJS += \
./src/linklayer/geometry/coord.o \
./src/linklayer/geometry/eulerangles.o \
./src/linklayer/geometry/quaternion.o
C_SRCS += $(GEOMETRY_SRC)
C_DEPS += \
./src/linklayer/geometry/coord.d \
./src/linklayer/geometry/eulerangles.d \
./src/linklayer/geometry/quaternion.d
OBJS += $(patsubst ../src/linklayer/geometry/%.c, ./src/linklayer/geometry/%.o, $(GEOMETRY_SRC))
C_DEPS += $(patsubst ../src/linklayer/geometry/%.c, ./src/linklayer/geometry/%.d, $(GEOMETRY_SRC))
# Each subdirectory must supply rules for building sources it contributes
+6 -28
View File
@@ -2,36 +2,14 @@
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../src/linklayer/framing.c \
../src/linklayer/linklayer814.c \
../src/linklayer/linklayer_routine.c \
../src/linklayer/net_mgmt.c \
../src/linklayer/net_scan.c \
../src/linklayer/net_service.c \
../src/linklayer/node_list.c \
../src/linklayer/time_sync.c
# Add inputs and outputs from these tool invocations to the build variables
LINKLAYER_SRC := $(wildcard ../src/linklayer/*.c)
OBJS += \
./src/linklayer/framing.o \
./src/linklayer/linklayer814.o \
./src/linklayer/linklayer_routine.o \
./src/linklayer/net_mgmt.o \
./src/linklayer/net_scan.o \
./src/linklayer/net_service.o \
./src/linklayer/node_list.o \
./src/linklayer/time_sync.o
C_SRCS += $(LINKLAYER_SRC)
C_DEPS += \
./src/linklayer/framing.d \
./src/linklayer/linklayer814.d \
./src/linklayer/linklayer_routine.d \
./src/linklayer/net_mgmt.d \
./src/linklayer/net_scan.d \
./src/linklayer/net_service.d \
./src/linklayer/node_list.d \
./src/linklayer/time_sync.d
OBJS += $(patsubst ../src/linklayer/%.c, ./src/linklayer/%.o, $(LINKLAYER_SRC))
C_DEPS += $(patsubst ../src/linklayer/%.c, ./src/linklayer/%.d, $(LINKLAYER_SRC))
# Each subdirectory must supply rules for building sources it contributes
+5 -6
View File
@@ -3,14 +3,13 @@
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../src/mpc/mpc_ctrl.c
MPC_SRC := $(wildcard ../src/mpc/*.c)
OBJS += \
./src/mpc/mpc_ctrl.o
C_SRCS += $(MPC_SRC)
C_DEPS += \
./src/mpc/mpc_ctrl.d
OBJS += $(patsubst ../src/mpc/%.c, ./src/mpc/%.o, $(MPC_SRC))
C_DEPS += $(patsubst ../src/mpc/%.c, ./src/mpc/%.d, $(MPC_SRC))
# Each subdirectory must supply rules for building sources it contributes
+5 -9
View File
@@ -3,17 +3,13 @@
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../src/phy_ctrl/antenna.c \
../src/phy_ctrl/phy_ctrl.c
PHY_CTRL_SRC := $(wildcard ../src/phy_ctrl/*.c)
OBJS += \
./src/phy_ctrl/antenna.o \
./src/phy_ctrl/phy_ctrl.o
C_SRCS += $(PHY_CTRL_SRC)
C_DEPS += \
./src/phy_ctrl/antenna.d \
./src/phy_ctrl/phy_ctrl.d
OBJS += $(patsubst ../src/phy_ctrl/%.c, ./src/phy_ctrl/%.o, $(PHY_CTRL_SRC))
C_DEPS += $(patsubst ../src/phy_ctrl/%.c, ./src/phy_ctrl/%.d, $(PHY_CTRL_SRC))
# Each subdirectory must supply rules for building sources it contributes
+5 -9
View File
@@ -6,17 +6,13 @@
LD_SRCS += \
../src/lscript.ld
C_SRCS += \
../src/common.c \
../src/main.c
MAIN_SRC := $(wildcard ../src/*.c)
OBJS += \
./src/common.o \
./src/main.o
C_SRCS += $(UTIL_SRC)
C_DEPS += \
./src/common.d \
./src/main.d
OBJS += $(patsubst ../src/%.c, ./src/%.o, $(MAIN_SRC))
C_DEPS += $(patsubst ../src/%.c, ./src/%.d, $(MAIN_SRC))
# Each subdirectory must supply rules for building sources it contributes
+5 -6
View File
@@ -3,14 +3,13 @@
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../src/time_ctrl/time_ctrl.c
TIME_CTRL_SRC := $(wildcard ../src/time_ctrl/*.c)
OBJS += \
./src/time_ctrl/time_ctrl.o
C_SRCS += $(TIME_CTRL_SRC)
C_DEPS += \
./src/time_ctrl/time_ctrl.d
OBJS += $(patsubst ../src/time_ctrl/%.c, ./src/time_ctrl/%.o, $(TIME_CTRL_SRC))
C_DEPS += $(patsubst ../src/time_ctrl/%.c, ./src/time_ctrl/%.d, $(TIME_CTRL_SRC))
# Each subdirectory must supply rules for building sources it contributes
+5 -9
View File
@@ -3,17 +3,13 @@
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../src/util/crc.c \
../src/util/util.c
UTIL_SRC := $(wildcard ../src/util/*.c)
OBJS += \
./src/util/crc.o \
./src/util/util.o
C_SRCS += $(UTIL_SRC)
C_DEPS += \
./src/util/crc.d \
./src/util/util.d
OBJS += $(patsubst ../src/util/%.c, ./src/util/%.o, $(UTIL_SRC))
C_DEPS += $(patsubst ../src/util/%.c, ./src/util/%.d, $(UTIL_SRC))
# Each subdirectory must supply rules for building sources it contributes
+1 -1
View File
@@ -40,6 +40,6 @@
*
******************************************************************************/
void AppAssert(const char * file, int line){
DBG_PRINT("in %s #%4d [assert] ",file, line);
DBG_PRINT("in %s #%4d [assert] .\n",file, line);
while(1);
}
+3 -3
View File
@@ -16,8 +16,8 @@
*
******************************************************************************/
/***************************** Include Files *********************************/
#ifndef DATAKINK_COMMON_H_
#define DATAKINK_COMMON_H_
#ifndef __COMMON_H_
#define __COMMON_H_
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
@@ -79,4 +79,4 @@
/************************** Function Prototypes ******************************/
void AppAssert(const char * file, int line);
#endif /* COMMON_H_ */
#endif /* __COMMON_H_ */
+32 -270
View File
@@ -41,20 +41,28 @@ static void L2_SetSlotNum(L2_INST* instPtr, uint32_t newSlotNum);
static void L2_SetFrameNum(L2_INST* instPtr, uint32_t newFrameNum);
static void L2_UpdateSlotNum(L2_INST* instPtr);
static void L2_DataAvailUpdate(L2_INST* instPtr, bool status);
static void L2_EventPoolHandler(L2_INST* instPtr);
/**
* @brief helper function to update linkelayer state
*/
static inline void UpdateMainSate(L2_INST* instPtr, L2_NODE_STATE newSate) {
ASSERT(instPtr != NULL);
DBG_INFO("MainStateUpdate: %d -> %d\n", instPtr->mainState, newSate);
instPtr->nextState = newSate;
}
/**
* @brief helper function to set slot number.
*/
static void L2_SetSlotNum(L2_INST* instPtr, uint32_t newSlotNum){
ASSERT(instPtr != NULL);
DBG_INFO("Set new slot number to %u\n", newSlotNum);
instPtr->slotNum.next = newSlotNum;
}
/**
* @brief helper function to set frame number
*/
static void L2_SetFrameNum(L2_INST* instPtr, uint32_t newFrameNum){
ASSERT(instPtr != NULL);
DBG_INFO("Set new frame number to %u\n", newFrameNum);
@@ -247,265 +255,6 @@ inline L2_RTT_FSM* L2_GetRttFsm(L2_INST* instPtr){
return instPtr->rttFSM;
}
/*****************************************************************************/
/**
* @brief Creat a new schedule envent, register event in schedule event pool.
*
* @param instPtr a pointer to linklayer instance
* @param event event type of the new schedule event.
*
* @return NULL error occurred
* Pointer to schedule event.
*
******************************************************************************/
L2_SCHD_EVENT* L2_CreatNewSchdEvent(L2_INST* instPtr, L2_EVENT_TYPE event){
L2_SCHD_EVENT* schdEventPtr = NULL;
if(instPtr->schdEventCnt >= L2_SCHD_EVENT_MAX){
DBG_ERROR("Schedule event number exceeds the max, no more schedule event can be created.\n");
return NULL;
}
schdEventPtr = (L2_SCHD_EVENT*)malloc(sizeof(L2_SCHD_EVENT));
if(schdEventPtr == NULL){
free(schdEventPtr);
return NULL;
}
if(event < L2_EV_SCAN_PROC_DONE || event > L2_ROUTINE_UPDATE){
DBG_ERROR("Unknown event type: %d.\n", event);
return NULL;
}
schdEventPtr->eventId = instPtr->schdEventCnt;
schdEventPtr->l2Event.msg = NULL;
schdEventPtr->isSchd = false;
schdEventPtr->schdSlot = L2_SLOTNO_NONE;
schdEventPtr->schdFrame = L2_FRAMENO_NONE;
instPtr->l2SchdEventPool[instPtr->schdEventCnt] = schdEventPtr;
instPtr->schdEventCnt++;
return schdEventPtr;
}
/*****************************************************************************/
/**
* @brief Delete a schedule event, remove the event from event pool,
* release memory, release event ID.
*
* @param instPtr a pointer to linklayer instance
* @param eventId ID of the event
*
* @return SUCCESS
* error code
*
******************************************************************************/
int32_t L2_DeletSchdEvent(L2_INST* instPtr, int32_t eventId){
ASSERT(instPtr != NULL);
if (eventId > instPtr->schdEventCnt) {
return EIGNORE;
}
L2_SCHD_EVENT* schdEvent = instPtr->l2SchdEventPool[eventId];
for(int32_t i = schdEvent->eventId; i < instPtr->schdEventCnt; i++){
if(i == instPtr->schdEventCnt - 1){
instPtr->l2SchdEventPool[i] = NULL;
}
else{
instPtr->l2SchdEventPool[i] = instPtr->l2SchdEventPool[i+1];
}
}
instPtr->schdEventCnt --;
if(schdEvent->l2Event.msg != NULL) {
free(schdEvent->l2Event.msg);
}
free(schdEvent);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Clear all event in the event pool.
*
* @param instPtr a pointer to linklayer instance
*
* @return NONE
*
******************************************************************************/
void L2_ClearSchdEvent(L2_INST* instPtr){
ASSERT(instPtr != NULL);
for(int32_t i = 0; i < instPtr->schdEventCnt; i++){
if(instPtr->l2SchdEventPool[i]->l2Event.msg != NULL) {
free(instPtr->l2SchdEventPool[i]->l2Event.msg);
}
free(instPtr->l2SchdEventPool[i]);
}
instPtr->schdEventCnt = 0;
}
/*****************************************************************************/
/**
* @brief Append extra message content to specific schedule event.
*
* @param schdEvent pointer to the schedule event.
* msg pointer to the append content.
*
* @return SUCCESS.
* error code.
*
******************************************************************************/
inline int32_t L2_SchdEventAppendMsg(L2_SCHD_EVENT* schdEvent, void* msg){
ASSERT(schdEvent != NULL);
schdEvent->l2Event.msg = msg;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Cancel a scheduled event.
*
* @param schdEvent pointer to the schedule event.
*
* @return SUCCESS.
*
******************************************************************************/
int32_t L2_CancelEvent(L2_SCHD_EVENT* schdEvent){
ASSERT(schdEvent != NULL);
if(schdEvent->isSchd == false){
DBG_WARNING("Event %d has not been scheduled yet.\n", schdEvent->eventId);
}
schdEvent->isSchd = false;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Check if the event was scheduled.
*
* @param schdEvent pointer to the schedule event.
*
* @return true.
* false.
*
******************************************************************************/
inline bool L2_isEventScheduled(L2_SCHD_EVENT* schdEvent){
ASSERT(schdEvent != NULL);
return schdEvent->isSchd;
}
/*****************************************************************************/
/**
* @brief Schedule a event at a specific time(indexed by frame and slot number)
*
* @param instPtr a pointer to linklayer instance
* @param schdEvent pointer to the schedule event.
* @param frameNum schedule frame number
* @param slotNum schedule slot number
*
* @return FAILURE, event has already been scheduled/schedule time not allowed.
* SUCCESS
*
******************************************************************************/
int32_t L2_ScheduleEventAt(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t frameNum, uint32_t slotNum){
ASSERT(schdEvent != NULL);
if(L2_isEventScheduled(schdEvent) == true){
DBG_ERROR("Event %d has already been scheduled.\n", schdEvent->eventId);
return FAILURE;
}
if(frameNum <= L2_GetCurrentFrameNum(instPtr) && slotNum < L2_GetCurrentSlotNum(instPtr)){
DBG_ERROR("Cannot schedule event %d to the past(current: [%u-%u], schedule: [%u-%u]).\n",
schdEvent->eventId, L2_GetCurrentFrameNum(instPtr), L2_GetCurrentSlotNum(instPtr), frameNum, slotNum);
return FAILURE;
}
schdEvent->isSchd = true;
schdEvent->schdFrame = frameNum;
schdEvent->schdSlot = slotNum;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Schedule a event after a specific time period.
*
* @param instPtr a pointer to linklayer instance
* @param schdEvent pointer to the schedule event.
* @param numSlots how many slot later the event should be scheduled
*
* @return FAILURE, event has already been scheduled/schedule time not allowed.
* SUCCESS
*
******************************************************************************/
int32_t L2_ScheduleEventAfter(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t numSlots){
ASSERT(schdEvent != NULL);
if(L2_isEventScheduled(schdEvent) == true){
DBG_ERROR("Event %d has already been scheduled.\n", schdEvent->eventId);
return FAILURE;
}
uint32_t frameNum = L2_GetCurrentFrameNum(instPtr) + (numSlots/L2_SLOTS_PER_FRAME);
uint32_t slotNum = L2_GetCurrentSlotNum(instPtr) + (numSlots%L2_SLOTS_PER_FRAME);
return L2_ScheduleEventAt(instPtr, schdEvent, frameNum, slotNum);
}
/*****************************************************************************/
/**
* @brief Reschedule a event at a specific time(indexed by frame and slot number)
*
* @param instPtr a pointer to linklayer instance
* @param schdEvent pointer to the schedule event.
* @param frameNum schedule frame number
* @param slotNum schedule slot number
*
* @return FAILURE, event has already been scheduled/schedule time not allowed.
* SUCCESS
*
******************************************************************************/
int32_t L2_RecheduleEventAt(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t frameNum, uint32_t slotNum){
ASSERT(schdEvent != NULL);
if(schdEvent->isSchd == false){
DBG_WARNING("Event %d has not been scheduled yet.\n", schdEvent->eventId);
}
schdEvent->isSchd = false;
return L2_ScheduleEventAt(instPtr, schdEvent, frameNum, slotNum);
}
/*****************************************************************************/
/**
* @brief Rechedule a event after a specific time period.
*
* @param instPtr a pointer to linklayer instance
* @param schdEvent pointer to the schedule event.
* @param numSlots how many slot later the event should be scheduled
*
* @return FAILURE, event has already been scheduled/schedule time not allowed.
* SUCCESS
*
******************************************************************************/
int32_t L2_RecheduleEventAfter(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t numSlots){
ASSERT(schdEvent != NULL);
if(schdEvent->isSchd == false){
DBG_WARNING("Event %d has not been scheduled yet.\n", schdEvent->eventId);
}
return L2_ScheduleEventAfter(instPtr, schdEvent, numSlots);
}
/*****************************************************************************/
/**
* @brief Check and excute schedule event in event pool illiterate.
*
* @param instPtr a pointer to linklayer instance
*
* @return NONE.
*
******************************************************************************/
static void L2_EventPoolHandler(L2_INST* instPtr){
ASSERT(instPtr != NULL);
for(int32_t i = 0; i < instPtr->schdEventCnt; i++){
if(instPtr->l2SchdEventPool[i]->isSchd == true){
if(instPtr->l2SchdEventPool[i]->schdFrame == instPtr->frameNum.curr
&& instPtr->l2SchdEventPool[i]->schdSlot == instPtr->slotNum.curr){
AssertL2Event(instPtr, &(instPtr->l2SchdEventPool[i]->l2Event));
}
}
}
}
/*****************************************************************************/
/**
* @brief Shift L2 status record.(newval->next->curr->last)
@@ -898,7 +647,6 @@ int32_t Linklayer_Init(L2_INST** instPtr, const L2_CONFIG *config) {
// Reset basic info
(*instPtr)->netStartTime = UINT32_MAX;
(*instPtr)->schdEventCnt = 0;
(*instPtr)->rtneConfig.last = NULL;
(*instPtr)->rtneConfig.curr = NULL;
(*instPtr)->rtneConfig.next = NULL;
@@ -939,7 +687,17 @@ int32_t Linklayer_Init(L2_INST** instPtr, const L2_CONFIG *config) {
(*instPtr)->svcMsgRecvCnt1 = 0;
(*instPtr)->buffSwitch = 0;
NodeList_Init(&((*instPtr)->nodeList));
Status = L2_CreateSchedEventPool(&((*instPtr)->schdEventPool));
if (Status != SUCCESS) {
DBG_ERROR("L2_CreateSchedEventPool runs failed, with error code: %d.\n", Status);
goto error;
}
Status = L2_NodeList_Init(&((*instPtr)->nodeList));
if (Status != SUCCESS) {
DBG_ERROR("NodeList_Init runs failed, with error code: %d.\n", Status);
goto error;
}
Status = ScanNet_Init(&((*instPtr)->scanNetFSM));
if (Status != SUCCESS) {
@@ -984,7 +742,6 @@ int32_t Linklayer_Reconfig(L2_INST* instPtr, const L2_CONFIG *config) {
// Reset basic info
instPtr->netStartTime = UINT32_MAX;
instPtr->schdEventCnt = 0;
instPtr->rtneConfig.last = NULL;
instPtr->rtneConfig.curr = NULL;
instPtr->rtneConfig.next = NULL;
@@ -1025,8 +782,8 @@ int32_t Linklayer_Reconfig(L2_INST* instPtr, const L2_CONFIG *config) {
instPtr->buffSwitch = 0;
// Reset according instance
L2_ClearSchdEvent(instPtr);
NodeList_Clear(instPtr->nodeList);
L2_ClearSchedEventPool(instPtr->schdEventPool);
L2_NodeList_Clear(instPtr->nodeList);
ScanNet_Reset(instPtr->scanNetFSM);
MgmtNet_Reset(instPtr->mgmtNetFSM);
ServiceNet_Reset(instPtr->serviceNetFSM);
@@ -1044,7 +801,8 @@ void Linklayer_Destroy(L2_INST* instPtr){
free(instPtr->mgmtMsgRecvBuff1);
free(instPtr->svcMsgRecvBuff1);
// Destroy FSMs and nodeList
NodeList_Destroy(instPtr->nodeList);
L2_DestroySchedEventPool(instPtr->schdEventPool);
L2_NodeList_Destroy(instPtr->nodeList);
ScanNet_Destroy(instPtr->scanNetFSM);
MgmtNet_Destroy(instPtr->mgmtNetFSM);
ServiceNet_Destroy(instPtr->serviceNetFSM);
@@ -1117,6 +875,10 @@ int32_t Linklayer_EventHandler(L2_INST* instPtr, const L2_EVENT* l2Event) {
DBG_INFO("Event L2_EV_TIME_SYNC asserted....\n");
break;
}
case L2_EV_RTT_RECV_UPDATE:
DBG_INFO("Event L2_EV_RTT_RECV_UPDATE asserted....\n");
RTT_FsmUpdate(instPtr, L2_TOR_RX);
break;
case L2_EV_LINK_SET_REQ: {
DBG_INFO("Event L2_EV_LINK_SET_REQ asserted....\n");
break;
@@ -1322,10 +1084,10 @@ static int32_t Linklayer_Routine (L2_INST* instPtr) {
// FIXME: Increase TTL counter
if (instPtr->mainState != INIT_STATE)
{
if ( IsNodeInList (instPtr->nodeList, rtneEntry.src0) )
{
// IncNodeTTL(usedSlots, rtneEntry.src0 );
}
// if ( L2_isNodeInList (instPtr->nodeList, rtneEntry.src0) )
// {
// IncNodeTTL(usedSlots, rtneEntry.src0 );
// }
}
return Status;
}
+6 -13
View File
@@ -22,13 +22,12 @@
#include <stdint.h>
#include "linklayer814_types.h"
#include "node_list.h"
#include "schdevent.h"
#include "rtt.h"
#include "../bit_array/bit_array.h"
#include "../phy_ctrl/phy_ctrl.h"
#include "../time_ctrl/time_ctrl.h"
/************************** Constant Definitions *****************************/
#define DATA_STORE_INTERVAL 100 // 250ms
@@ -60,8 +59,7 @@ typedef struct {
L2_CONFIG config;
L2_NODE_INFO myInfo;
NODE_LIST* nodeList;
L2_SCHD_EVENT* l2SchdEventPool[L2_SCHD_EVENT_MAX];
uint32_t schdEventCnt;
L2_SCHD_POOL* schdEventPool;
uint32_t netStartTime;
bool isEnable; // if the node is connected to the network
bool dataAvail; // if there is a valid received frame data in rx buffer
@@ -109,17 +107,12 @@ int32_t Linklayer_EventHandler(L2_INST* instPtr, const L2_EVENT* l2Event);
int32_t Linklayer_PktHandler(L2_INST* instPtr, L2_FRAME_TYPE frameType);
int32_t L2_SetupNextSlot(L2_INST* instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE frameType);
// Event
bool L2_isEventScheduled(L2_SCHD_EVENT* schdEvent);
int32_t L2_CancelEvent(L2_SCHD_EVENT* schdEvent);
int32_t L2_SchdEventAppendMsg(L2_SCHD_EVENT* schdEvent, void* msg);
L2_SCHD_EVENT* L2_CreatNewSchdEvent(L2_INST* instPtr, L2_EVENT_TYPE event);
int32_t L2_DeletSchdEvent(L2_INST* instPtr, int32_t eventId);
void L2_ClearSchdEvent(L2_INST* instPtr);
// Scheduling Event
void L2_EventPoolHandler(L2_INST* instPtr);
int32_t L2_ScheduleEventAt(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t frameNo, uint32_t slotNo);
int32_t L2_ScheduleEventAfter(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t numSlots);
int32_t L2_RecheduleEventAt(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t frameNo, uint32_t slotNo);
int32_t L2_RecheduleEventAfter(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t numSlots);
int32_t L2_RescheduleEventAt(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t frameNo, uint32_t slotNo);
int32_t L2_RescheduleEventAfter(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t numSlots);
// Framing
void L2_FrameStateUpdate(L2_INST* instPtr);
@@ -51,9 +51,6 @@
#define NUM_SLOTS_5MS 1
#define NUM_SLOTS_SKIP 0
// Common schedule event definition
#define L2_SCHD_EVENT_MAX 16
/**************************** Type Definitions *******************************/
typedef struct {
@@ -109,6 +106,7 @@ typedef enum {
L2_EV_MGMT_PROC_DONE = 2,
L2_EV_NET_SETUP_DONE = 3,
L2_EV_TIME_SYNC = 4,
L2_EV_RTT_RECV_UPDATE = 5,
L2_EV_LINK_SET_REQ = 6,
L2_EV_LOST_CXN = 7,
L2_EV_LOST_NODE = 8,
@@ -127,17 +125,6 @@ typedef struct {
void* msg;
} L2_EVENT;
/** @name L2 event
* A definition of L2 event instance.
*/
typedef struct {
uint8_t eventId;
bool isSchd;
L2_EVENT l2Event;
uint32_t schdFrame;
uint32_t schdSlot;
} L2_SCHD_EVENT;
/** @name Slot types
* A definition of different slots.
*/
+23 -12
View File
@@ -27,7 +27,9 @@
/************************** Constant Definitions *****************************/
#define SQUENCE_MGMT_SLOTS 0
#define INTER_MGMT_SLOTS 2
#define INTER_TSYNC_SLOTS 2
#define INTRA_MGMT_SLOTS 1
#define INTRA_TSYNC_SLOTS 1
#define NONE_MGMT_SLOTS -1
#define CONX_LOST_TH 10 // 10 count of mgmt msg no response to delete
#define TIME2QUIT 80 // time to send quit message
@@ -680,7 +682,7 @@ int32_t MgmtNet_PktHandler(L2_INST* instPtr) {
FrameGetChunk(mgmtMsg, NQT_MSG_CTRL_MUTE_OFFSET, NQT_MSG_CTRL_MUTE_LEN, &dataChunk);
mgmtMsgLog->quitCtrlWord = (uint8_t)(dataChunk & 0x7F);
if (mgmtMsgLog->quitCtrlWord == 0x01) {
DeletNode(instPtr->nodeList, mgmtMsgLog->quitNodeId);
L2_DeleteNodeById(instPtr->nodeList, mgmtMsgLog->quitNodeId);
}
}
else {
@@ -731,7 +733,7 @@ int32_t MgmtNet_PktHandler(L2_INST* instPtr) {
AssertL2Event(instPtr, &stateUpEvent);
}
RstNodeTTL(instPtr->nodeList, mgmtMsgLog->srcNodeId);
L2_RstNodeTTL(instPtr->nodeList, mgmtMsgLog->srcNodeId);
// TODO: Check
if(mgmtMsgLog->srcNodeId == L2_GetHeadId(instPtr)){
L2_TimeAlign(instPtr, L2_GetCurrentFrameNum(instPtr), L2_GetCurrentSlotNum(instPtr));
@@ -740,8 +742,7 @@ int32_t MgmtNet_PktHandler(L2_INST* instPtr) {
}
case L2_INTER_TSYNC_FRAME:
case L2_INTRA_TSYNC_FRAME: {
L2_RTT_SATGE rttStage = L2_GetRttFsm(instPtr)->rttStatge;
if(rttStage == RTT_REQ1 || rttStage == RTT_REQ2){
if(L2_GetNodeType(instPtr) == HEAD_NODE){
for (int i = 0; i < ARRAY_SIZE(rttReqFrameMsgs); i++) {
memcpy(mgmtMsg->words,
instPtr->recvPktData + (size_t) (i * (RTT_MSG_LEN / 8)),
@@ -793,7 +794,7 @@ int32_t MgmtNet_PktHandler(L2_INST* instPtr) {
}
}
}
else if(rttStage == RTT_RSP1 || rttStage == RTT_RSP2){
else {
for (int i = 0; i < ARRAY_SIZE(rttRspFrameMsgs); i++) {
memcpy(mgmtMsg->words,
instPtr->recvPktData + (size_t) (i * (RTT_MSG_LEN / 8)),
@@ -847,7 +848,7 @@ int32_t MgmtNet_PktHandler(L2_INST* instPtr) {
}
}
RstNodeTTL(instPtr->nodeList, rttMsgRspLog->srcAddr & 0x001F);
L2_RstNodeTTL(instPtr->nodeList, rttMsgRspLog->srcAddr & 0x001F);
// TODO: Check
if((rttMsgRspLog->srcAddr&0x001F) == L2_GetHeadId(instPtr)){
L2_TimeAlign(instPtr, L2_GetCurrentFrameNum(instPtr), L2_GetCurrentSlotNum(instPtr));
@@ -898,7 +899,7 @@ int32_t MgmtNet_Routine(L2_INST* instPtr, const L2_RTNE_TABLE_ENTRY* rtneEntry){
}
// Check if there is any node exceeds the ttl threshold.
IterDeleteNode(instPtr->nodeList, IsTTLValid);
L2_IterDeleteNode(instPtr->nodeList, IsTTLValid);
// Determine next slot TOR state.
L2_TOR_TYPE torState = L2_TOR_SUSPEND;
@@ -918,8 +919,18 @@ int32_t MgmtNet_Routine(L2_INST* instPtr, const L2_RTNE_TABLE_ENTRY* rtneEntry){
if (L2_GetLastFrameType(instPtr) == L2_INTRA_TSYNC_FRAME && L2_GetLastTor(instPtr) == L2_TOR_RX) {
RTT_FsmUpdate(instPtr, L2_TOR_RX);
}
if (rtneEntry->slotType == SLOT_INTRA_TSYNC && torState == L2_TOR_TX) {
RTT_FsmUpdate(instPtr, L2_TOR_TX);
if (rtneEntry->slotType == SLOT_INTRA_TSYNC) {
if(torState == L2_TOR_TX) {
RTT_FsmUpdate(instPtr, L2_TOR_TX);
}
else if (torState == L2_TOR_RX)
{
L2_SCHD_EVENT* rttRxEvent = L2_CreatNewSchdEvent(instPtr->schdEventPool, L2_EV_RTT_RECV_UPDATE, true);
if(rttRxEvent == NULL) {
DBG_ERROR("Failed to initialize rtt event.\n");
}
Status = L2_ScheduleEventAfter(instPtr, rttRxEvent, INTRA_TSYNC_SLOTS + 1);
}
}
switch (rtneEntry->slotType) {
@@ -973,19 +984,19 @@ int32_t MgmtNet_Routine(L2_INST* instPtr, const L2_RTNE_TABLE_ENTRY* rtneEntry){
.event = L2_EV_MAIN_STATE_UPDATE,
.msg = &newState
};
if (instPtr->nodeList->nodeNum < instPtr->config.netScale
if (L2_GetNodeListLen(instPtr->nodeList) < instPtr->config.netScale
&& L2_GetMainState(instPtr) != INTRA_SEEK_STATE) {
newState = INTRA_SEEK_STATE;
AssertL2Event(instPtr, &stateEvent);
}
else if(instPtr->nodeList->nodeNum >= instPtr->config.netScale &&
else if(L2_GetNodeListLen(instPtr->nodeList) >= instPtr->config.netScale &&
L2_GetMainState(instPtr) != NORMAL_STATE){
newState = NORMAL_STATE;
AssertL2Event(instPtr, &stateEvent);
}
}
else{ // MEMBER_NODE or BACKUP_HEAD
if(IsNodeInList(instPtr->nodeList, L2_GetHeadId(instPtr)) == false){
if(L2_isNodeInList(instPtr->nodeList, L2_GetHeadId(instPtr)) == false){
L2_NODE_STATE newState = INIT_STATE;
L2_EVENT stateEvent = {
.event = L2_EV_MAIN_STATE_UPDATE,
+17 -12
View File
@@ -632,10 +632,15 @@ int32_t ScanNet_PktHandler(L2_INST* instPtr) {
}
}
if(L2_GetNodeType(instPtr) != HEAD_NODE){
if (IsNodeInList(instPtr->nodeList, scanFsmPtr->BMrcvLog.NodeId) == false) {
AppendNode(instPtr->nodeList, scanFsmPtr->BMrcvLog.NodeId, (uint8_t) MEMBER_NODE);
NODE_ENTRY* nodeEntry = L2_GetNodeById(instPtr->nodeList, scanFsmPtr->BMrcvLog.NodeId);
if(nodeEntry == NULL) {
nodeEntry = L2_AppendNode(instPtr->nodeList, scanFsmPtr->BMrcvLog.NodeId, HEAD_NODE);
// TODO: Insert other node information.
}
else {
// TODO: Update node information.
}
// TODO: Update Node Info
if ( L2_isCxn2Net(instPtr) == false ) {
// TODO: Check
@@ -720,19 +725,19 @@ int32_t ScanNet_PktHandler(L2_INST* instPtr) {
goto failed;
}
}
// Update net start time
if(L2_GetNodeType(instPtr) != HEAD_NODE){
instPtr->netStartTime = scanFsmPtr->W2ACQrcvLog.NetScanTime;
}
if(L2_GetNodeType(instPtr) == HEAD_NODE){
if (IsNodeInList(instPtr->nodeList, scanFsmPtr->W2ACQrcvLog.NodeId) == false) {
AppendNode(instPtr->nodeList, scanFsmPtr->W2ACQrcvLog.NodeId, (uint8_t) MEMBER_NODE);
}
// TODO: Update Node Info
NODE_ENTRY* nodeEntry = L2_GetNodeById(instPtr->nodeList, scanFsmPtr->W2ACQrcvLog.NodeId);
if(nodeEntry == NULL) {
nodeEntry = L2_AppendNode(instPtr->nodeList, scanFsmPtr->W2ACQrcvLog.NodeId, MEMBER_NODE);
// TODO: Insert other node information.
}
else {
// TODO: Update node information.
}
if(L2_GetNodeType(instPtr) != HEAD_NODE && scanFsmPtr->W2ACQrcvLog.NetStage != NONE_STATE){
// Update net start time
instPtr->netStartTime = scanFsmPtr->W2ACQrcvLog.NetScanTime;
// sync state with head node
L2_NODE_STATE newState = scanFsmPtr->W2ACQrcvLog.NetStage;
L2_EVENT stateUpEvent = {
+129 -120
View File
@@ -17,22 +17,40 @@
/***************************** Include Files *********************************/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "linklayer814_types.h"
#include "node_list.h"
#include "../util/list.h"
#include "../common.h"
#include "../error.h"
/***************** Macros (Inline Functions) Definitions *********************/
inline int32_t GetNodeNum(NODE_LIST *list) {
inline uint32_t L2_GetNodeListLen(NODE_LIST *list) {
ASSERT(list != NULL);
return list->nodeNum;
return list->len;
}
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
static NODE_ENTRY util_entry;
/************************** Function Prototypes ******************************/
/**
* @brief helper function to free node entry.
*/
static void entry_free(void* val){
free(val);
}
/**
* @brief helper function to match node entries by nodeIds
*/
static bool entry_match(void* a, void* b){
ASSERT(a != NULL);
ASSERT(b != NULL);
return (((NODE_ENTRY*)a)->nodeInfo.nodeId
== ((NODE_ENTRY*)b)->nodeInfo.nodeId);
}
/*****************************************************************************/
/**
* @brief Initialize node list
@@ -43,47 +61,40 @@ inline int32_t GetNodeNum(NODE_LIST *list) {
* ENOMEM - not enough memory.
*
******************************************************************************/
int32_t NodeList_Init(NODE_LIST **list) {
NODE_ENTRY *entry;
(*list) = malloc(sizeof(NODE_LIST));
int32_t L2_NodeList_Init(NODE_LIST **list) {
(*list) = list_new();
if (*list == NULL) {
return ENOMEM;
}
entry = malloc(sizeof(NODE_ENTRY));
if(entry == NULL) {
free(*list);
return ENOMEM;
}
entry->nodeInfo.nodeId = 0;
entry->nextNode = entry;
entry->preNode = entry;
(*list)->head = entry;
(*list)->nodeNum = 0;
(*list)->free = entry_free;
(*list)->match = entry_match;
return SUCCESS;
}
void NodeList_Clear(NODE_LIST *list){
/*****************************************************************************/
/**
* @brief Clear all nodes in the node list, free allocated memory.
*
* @param list
*NONE
*
******************************************************************************/
void L2_NodeList_Clear(NODE_LIST *list){
ASSERT(list != NULL);
NODE_ENTRY *nodeEntry, *deletEntry;
nodeEntry = list->head->nextNode;
while (nodeEntry != list->head) {
deletEntry = nodeEntry;
nodeEntry = nodeEntry->nextNode;
deletEntry->preNode->nextNode = deletEntry->nextNode;
deletEntry->nextNode->preNode = deletEntry->preNode;
DBG_INFO("Deleting node [%d].\n", deletEntry->nodeInfo.nodeId);
free(deletEntry);
list->nodeNum--;
}
list_clear(list);
}
void NodeList_Destroy(NODE_LIST *list){
if(list == NULL){
return;
}
NodeList_Clear(list);
free(list->head);
free(list);
/*****************************************************************************/
/**
* @brief Completely destroy node list.
*
* @param list
*
* @return NONE
*
******************************************************************************/
void L2_NodeList_Destroy(NODE_LIST *list){
list_destroy(list);
}
/*****************************************************************************/
/**
@@ -96,40 +107,19 @@ void NodeList_Destroy(NODE_LIST *list){
* NULL if node dose not exist.
*
******************************************************************************/
NODE_ENTRY* GetNode(NODE_LIST *list, uint32_t nodeId) {
NODE_ENTRY* L2_GetNodeById(NODE_LIST *list, uint8_t nodeId) {
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = list->head->nextNode;
while (nodeEntry != list->head) {
if (nodeEntry->nodeInfo.nodeId == nodeId) {
break;
}
else {
nodeEntry = nodeEntry->nextNode;
}
}
if (nodeEntry == list->head) {
util_entry.nodeInfo.nodeId = nodeId;
list_node_t* node = list_find(list, &util_entry);
if(node == NULL) {
return NULL;
}
else {
return nodeEntry;
return ((NODE_ENTRY*) node->val);
}
}
/*****************************************************************************/
/**
* @brief Check whether the node is already in the node list.
*
* @param list
* @param nodeId
*
* @return true node in the list
* false node not in the list
*
******************************************************************************/
inline bool IsNodeInList(NODE_LIST *list, uint8_t nodeId) {
ASSERT(list != NULL);
return (GetNode(list, nodeId) != NULL);
}
/*****************************************************************************/
/**
@@ -143,20 +133,27 @@ inline bool IsNodeInList(NODE_LIST *list, uint8_t nodeId) {
* Other Error occurred.(Node already exist, memory alloc error ect.)
*
******************************************************************************/
int32_t AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType)
NODE_ENTRY* L2_AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType)
{
ASSERT(list != NULL);
if(IsNodeInList(list, nodeId)){
if(L2_isNodeInList(list, nodeId)){
DBG_WARNING("Node [%d] already exist.\n", nodeId);
return FAILURE;
return NULL;
}
DBG_INFO("Link layer appending node [%d] to node list.\n", nodeId);
NODE_ENTRY* nodeEntry = (NODE_ENTRY*) malloc(sizeof(NODE_ENTRY));
if (nodeEntry == NULL) {
return ENOMEM;
DBG_ERROR("Failed to allocated memory for nodeEntry.\n");
return NULL;
}
list_node_t* node = list_node_new(nodeEntry);
if(node == NULL) {
DBG_ERROR("Failed to allocated memory for list node.\n");
free(nodeEntry);
return NULL;
}
nodeEntry->nodeInfo.nodeId = nodeId;
nodeEntry->nodeInfo.nodeType = (uint8_t) nodeType;
nodeEntry->nodeInfo.nodeType = (uint8_t)nodeType;
nodeEntry->nodeInfo.pos.x = 0;
nodeEntry->nodeInfo.pos.y = 0;
nodeEntry->nodeInfo.pos.z = 0;
@@ -165,13 +162,8 @@ int32_t AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType)
nodeEntry->nodeInfo.speed.z = 0;
nodeEntry->nodeInfo.beamNo = 0;
nodeEntry->ttlCnt = 0;
nodeEntry->nextNode = list->head;
nodeEntry->preNode = list->head->nextNode;
list->head->nextNode = nodeEntry;
list->nodeNum++;
return SUCCESS;
list_rpush(list, node);
return nodeEntry;
}
/*****************************************************************************/
@@ -185,21 +177,34 @@ int32_t AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType)
* Other Node not exist.
*
******************************************************************************/
int32_t DeletNode(NODE_LIST *list, uint8_t nodeId) {
int32_t L2_DeleteNodeById(NODE_LIST *list, uint8_t nodeId) {
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = GetNode(list, nodeId);
if(nodeEntry == NULL){
util_entry.nodeInfo.nodeId = nodeId;
list_node_t* node = list_find(list, &util_entry);
if(node == NULL) {
DBG_WARNING("Node [%d] in not in node list, skip deleting process.\n", nodeId);
return SUCCESS;
}
nodeEntry->preNode->nextNode = nodeEntry->nextNode;
nodeEntry->nextNode->preNode = nodeEntry->preNode;
DBG_INFO("Deleting node [%d].\n", nodeId);
free(nodeEntry);
list->nodeNum--;
list_remove(list, node);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Check whether the node is already in the node list.
*
* @param list
* @param nodeId
*
* @return true node in the list
* false node not in the list
*
******************************************************************************/
bool L2_isNodeInList(NODE_LIST *list, uint8_t nodeId) {
ASSERT(list != NULL);
return (L2_GetNodeById(list, nodeId) != NULL);
}
/*****************************************************************************/
/**
@@ -214,9 +219,9 @@ int32_t DeletNode(NODE_LIST *list, uint8_t nodeId) {
*
******************************************************************************/
int32_t GetDistance(NODE_LIST *list, COORD myCoord, uint8_t nodeId, double* dst) {
int32_t L2_GetDistance(NODE_LIST *list, COORD myCoord, uint8_t nodeId, double* dst) {
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = GetNode(list, nodeId);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
return FAILURE;
}
@@ -238,9 +243,9 @@ int32_t GetDistance(NODE_LIST *list, COORD myCoord, uint8_t nodeId, double* dst)
* FAILURE node not exist.
*
******************************************************************************/
int32_t UpdateNodePos(NODE_LIST *list, uint8_t nodeId, const COORD *newPos) {
int32_t L2_UpdateNodePos(NODE_LIST *list, uint8_t nodeId, const COORD *newPos) {
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = GetNode(list, nodeId);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
return FAILURE;
}
@@ -263,9 +268,9 @@ int32_t UpdateNodePos(NODE_LIST *list, uint8_t nodeId, const COORD *newPos) {
* FAILURE node not exist.
*
******************************************************************************/
int32_t GetNodePos(NODE_LIST *list, uint8_t nodeId, COORD *pos) {
int32_t L2_GetNodePos(NODE_LIST *list, uint8_t nodeId, COORD *pos) {
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = GetNode(list, nodeId);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
return FAILURE;
}
@@ -287,9 +292,9 @@ int32_t GetNodePos(NODE_LIST *list, uint8_t nodeId, COORD *pos) {
* FAILURE node not exist.
*
******************************************************************************/
int32_t UpdateNodeSpeed(NODE_LIST *list, uint8_t nodeId, const COORD *newSpeed) {
int32_t L2_UpdateNodeSpeed(NODE_LIST *list, uint8_t nodeId, const COORD *newSpeed) {
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = GetNode(list, nodeId);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
return FAILURE;
}
@@ -312,9 +317,9 @@ int32_t UpdateNodeSpeed(NODE_LIST *list, uint8_t nodeId, const COORD *newSpeed)
* FAILURE node not exist.
*
******************************************************************************/
int32_t GetNodeSpeed(NODE_LIST *list, uint8_t nodeId, COORD *speed) {
int32_t L2_GetNodeSpeed(NODE_LIST *list, uint8_t nodeId, COORD *speed) {
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = GetNode(list, nodeId);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
return FAILURE;
}
@@ -335,9 +340,9 @@ int32_t GetNodeSpeed(NODE_LIST *list, uint8_t nodeId, COORD *speed) {
* FAILURE Node not exist.
*
******************************************************************************/
int32_t UpdateNodeTimeDeviation(NODE_LIST *list, uint8_t nodeId, int32_t devi) {
int32_t L2_UpdateNodeTimeDeviation(NODE_LIST *list, uint8_t nodeId, int32_t devi) {
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = GetNode(list, nodeId);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
return FAILURE;
}
@@ -358,9 +363,9 @@ int32_t UpdateNodeTimeDeviation(NODE_LIST *list, uint8_t nodeId, int32_t devi) {
* @return NONE
*
******************************************************************************/
int32_t IncNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t inc) {
int32_t L2_IncNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t inc) {
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = GetNode(list, nodeId);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
return FAILURE;
}
@@ -381,9 +386,9 @@ int32_t IncNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t inc) {
* FAILURE Node not exist.
*
******************************************************************************/
int32_t RstNodeTTL(NODE_LIST *list, uint8_t nodeId) {
int32_t L2_RstNodeTTL(NODE_LIST *list, uint8_t nodeId) {
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = GetNode(list, nodeId);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
return FAILURE;
}
@@ -404,9 +409,9 @@ int32_t RstNodeTTL(NODE_LIST *list, uint8_t nodeId) {
* @return NONE
*
******************************************************************************/
int32_t GetNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t *ttl) {
int32_t L2_GetNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t *ttl) {
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = GetNode(list, nodeId);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
return FAILURE;
}
@@ -429,17 +434,24 @@ int32_t GetNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t *ttl) {
* Other Error occurred.
*
******************************************************************************/
int32_t IterEditNode(NODE_LIST *list, const void *param, int32_t (*operation)(NODE_ENTRY *, const void *)) {
int32_t L2_IterEditNode(NODE_LIST *list, const void *param, int32_t (*operation)(NODE_ENTRY *, const void *)) {
ASSERT(list != NULL);
int32_t Status = SUCCESS;
NODE_ENTRY *nodeEntry = list->head->nextNode;
while (nodeEntry != list->head) {
Status = operation(nodeEntry, param);
int32_t Status;
list_node_t* node;
list_iterator_t* iter = list_iterator_new(list, LIST_HEAD);
if(iter == NULL) {
DBG_ERROR("Failed to initialize list iteration process.\n");
return EALLOC;
}
while ((node = list_iterator_next(iter)))
{
Status = operation((NODE_ENTRY*)node->val, param);
if(Status != SUCCESS){
DBG_ERROR("Error occurred when iteratively edit node entry.\n");
break;
}
nodeEntry = nodeEntry->nextNode;
}
list_iterator_destroy(iter);
return Status;
}
@@ -454,24 +466,21 @@ int32_t IterEditNode(NODE_LIST *list, const void *param, int32_t (*operation)(NO
* @return SUCCESS
*
******************************************************************************/
int32_t IterDeleteNode(NODE_LIST *list, bool (*condition)(NODE_ENTRY *)) {
int32_t L2_IterDeleteNode(NODE_LIST *list, bool (*condition)(NODE_ENTRY *)) {
ASSERT(list != NULL);
NODE_ENTRY *nodeEntry, *deletEntry;
nodeEntry = list->head->nextNode;
while (nodeEntry != list->head) {
if (condition(nodeEntry) == false) {
deletEntry = nodeEntry;
nodeEntry = nodeEntry->nextNode;
deletEntry->preNode->nextNode = deletEntry->nextNode;
deletEntry->nextNode->preNode = deletEntry->preNode;
DBG_INFO("Deleting node [%d].\n", deletEntry->nodeInfo.nodeId);
free(deletEntry);
list->nodeNum--;
}
else {
nodeEntry = nodeEntry->nextNode;
list_node_t* node;
list_iterator_t* iter = list_iterator_new(list, LIST_HEAD);
if(iter == NULL) {
DBG_ERROR("Failed to initialize list iteration process.\n");
return EALLOC;
}
while ((node = list_iterator_next(iter)))
{
if (condition((NODE_ENTRY*) node->val) == false) {
list_remove(list, node);
}
}
list_iterator_destroy(iter);
return SUCCESS;
}
+21 -25
View File
@@ -24,6 +24,7 @@
#include "linklayer814_types.h"
#include "geometry/coord.h"
#include "../util/util.h"
#include "../util/list.h"
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
@@ -32,36 +33,31 @@ typedef struct NODE_LIST_ENTRY {
L2_NODE_INFO nodeInfo;
uint32_t ttlCnt;
int32_t timeDevi;
struct NODE_LIST_ENTRY *nextNode;
struct NODE_LIST_ENTRY *preNode;
} NODE_ENTRY;
typedef struct {
uint32_t nodeNum;
NODE_ENTRY *head;
} NODE_LIST;
typedef list_t NODE_LIST;
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
int32_t NodeList_Init(NODE_LIST **list);
void NodeList_Clear(NODE_LIST *list);
void NodeList_Destroy(NODE_LIST *list);
NODE_ENTRY *GetNode(NODE_LIST *list, uint32_t nodeId);
int32_t AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType);
int32_t DeletNode(NODE_LIST *list, uint8_t nodeId);
int32_t UpdateNodePos(NODE_LIST *list, uint8_t nodeId, const COORD *newPos);
int32_t GetNodePos(NODE_LIST *list, uint8_t nodeId, COORD *newPos);
int32_t UpdateNodeSpeed(NODE_LIST *list, uint8_t nodeId, const COORD *newSpeed);
int32_t GetNodeSpeed(NODE_LIST *list, uint8_t nodeId, COORD *speed);
int32_t UpdateNodeTimeDeviation(NODE_LIST *list, uint8_t nodeId, int32_t devi);
int32_t GetDistance(NODE_LIST *list, COORD myCoord, uint8_t nodeId, double* dst);
int32_t GetNodeNum(NODE_LIST *list);
int32_t RstNodeTTL(NODE_LIST *list, uint8_t nodeId);
int32_t IncNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t inc);
int32_t GetNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t *ttl);
bool IsNodeInList(NODE_LIST *list, uint8_t nodeId);
int32_t IterEditNode(NODE_LIST *list, const void *param, int32_t (*operation)(NODE_ENTRY*, const void*));
int32_t IterDeleteNode(NODE_LIST *list, bool (*condition)(NODE_ENTRY *));
int32_t L2_NodeList_Init(NODE_LIST **list);
void L2_NodeList_Clear(NODE_LIST *list);
void L2_NodeList_Destroy(NODE_LIST *list);
uint32_t L2_GetNodeListLen(NODE_LIST *list);
NODE_ENTRY* L2_GetNodeById(NODE_LIST *list, uint8_t nodeId);
NODE_ENTRY* L2_AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType);
int32_t L2_DeleteNodeById(NODE_LIST *list, uint8_t nodeId);
int32_t L2_UpdateNodePos(NODE_LIST *list, uint8_t nodeId, const COORD *newPos);
bool L2_isNodeInList(NODE_LIST *list, uint8_t nodeId);
int32_t L2_GetNodePos(NODE_LIST *list, uint8_t nodeId, COORD *newPos);
int32_t L2_UpdateNodeSpeed(NODE_LIST *list, uint8_t nodeId, const COORD *newSpeed);
int32_t L2_GetNodeSpeed(NODE_LIST *list, uint8_t nodeId, COORD *speed);
int32_t L2_UpdateNodeTimeDeviation(NODE_LIST *list, uint8_t nodeId, int32_t devi);
int32_t L2_GetDistance(NODE_LIST *list, COORD myCoord, uint8_t nodeId, double* dst);
int32_t L2_RstNodeTTL(NODE_LIST *list, uint8_t nodeId);
int32_t L2_IncNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t inc);
int32_t L2_GetNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t *ttl);
int32_t L2_IterEditNode(NODE_LIST *list, const void *param, int32_t (*operation)(NODE_ENTRY*, const void*));
int32_t L2_IterDeleteNode(NODE_LIST *list, bool (*condition)(NODE_ENTRY *));
#endif /* NODE_LIST_H_ */
+2 -2
View File
@@ -54,10 +54,10 @@ typedef enum {
RTT_RSP1 = 2,
RTT_REQ2 = 3,
RTT_RSP2 = 4, // Rtt Stages
} L2_RTT_SATGE;
} L2_RTT_STGE;
typedef struct {
L2_RTT_SATGE rttStatge;
L2_RTT_STGE rttStage;
bool isR1Valid;
bool isR2Valid;
bool isR3Valid;
+385
View File
@@ -0,0 +1,385 @@
/*****************************************************************************/
/**
* Description: Event scheduling implementation
*
* Date: 2023-12-21 13:32
* LastEditors: Fan Hao
* LastEditTime: 2023-12-21 13:32
* Revisions: Rev 0.0
* History:
* [2023-12-21]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
/***************************** Include Files *********************************/
#include <stdlib.h>
#include "schdevent.h"
#include "linklayer814.h"
#include "linklayer814_types.h"
#include "../error.h"
#include "../util/list.h"
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
static L2_SCHD_EVENT util_schdevent;
/************************** Function Prototypes ******************************/
/**
* @brief helper function to free schedule events.
*/
static void schdevent_free(void* val){
if(val == NULL) {
return;
}
free(((L2_SCHD_EVENT*)val)->l2Event.msg);
free(val);
}
/**
* @brief helper function to match events by ids.
*/
static bool schdevent_match(void* a, void* b){
ASSERT(a == NULL);
ASSERT(b != NULL);
return (((L2_SCHD_EVENT*)a)->eventId
== ((L2_SCHD_EVENT*)b)->eventId);
}
/*****************************************************************************/
/**
* @brief Creat a schedule event pool.
*
* @param schdPool a pointer to schedule pool instance.
*
* @return SUCCESS
*
******************************************************************************/
int32_t L2_CreateSchedEventPool(L2_SCHD_POOL** schdPool) {
(*schdPool) = malloc(sizeof(L2_SCHD_POOL));
if(*schdPool == NULL) {
DBG_ERROR("Failed to allocated memory for schdPool.\n");
return EALLOC;
}
(*schdPool)->schdList = list_new();
if((*schdPool)->schdList == NULL) {
DBG_ERROR("Failed to allocated memory for schdPool->schdList.\n");
free(*schdPool);
return EALLOC;
}
(*schdPool)->schdList->free = schdevent_free;
(*schdPool)->schdList->match = schdevent_match;
(*schdPool)->envCnt = 0;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Clear schedule event pool, delete all events in pool and
* free allocated memory.
*
* @param schdPool a pointer to schedule pool instance.
*
* @return SUCCESS
*
******************************************************************************/
void L2_ClearSchedEventPool(L2_SCHD_POOL* schdPool) {
ASSERT(schdPool != NULL);
list_clear(schdPool->schdList);
schdPool->envCnt = 0;
}
/*****************************************************************************/
/**
* @brief Completely destroy schedule event pool.
*
* @param schdPool a pointer to schedule pool instance.
*
* @return SUCCESS
*
******************************************************************************/
void L2_DestroySchedEventPool(L2_SCHD_POOL* schdPool) {
if(schdPool == NULL) {
return;
}
list_destroy(schdPool->schdList);
free(schdPool);
}
/*****************************************************************************/
/**
* @brief Creat a new schedule event, register event in schedule event pool.
*
* @param schdPool a pointer to schedule pool instance.
* @param event event type of the new schedule event.
* @param isVolatile event type of the new schedule event.
*
* @return NULL error occurred
* Pointer to schedule event.
*
******************************************************************************/
L2_SCHD_EVENT* L2_CreatNewSchdEvent(L2_SCHD_POOL* schdPool, L2_EVENT_TYPE event, bool isVolatile){
ASSERT(schdPool != NULL);
if(event < L2_EV_SCAN_PROC_DONE || event > L2_ROUTINE_UPDATE){
DBG_ERROR("Unknown event type: %d.\n", event);
return NULL;
}
L2_SCHD_EVENT* schdEvent = (L2_SCHD_EVENT*)malloc(sizeof(L2_SCHD_EVENT));
if(schdEvent == NULL){
DBG_ERROR("Failed to allocate schedule event.\n");
return NULL;
}
list_node_t *node = list_node_new(schdEvent);
if(node == NULL) {
DBG_ERROR("Failed to allocate schedule event list node.\n");
free(schdEvent);
return NULL;
}
schdEvent->eventId = schdPool->envCnt++;
schdEvent->ocurrCnt = 0;
schdEvent->l2Event.event = event;
schdEvent->l2Event.msg = NULL;
schdEvent->isSchd = false;
schdEvent->isVolatile = isVolatile;
schdEvent->schdSlot = L2_SLOTNO_NONE;
schdEvent->schdFrame = L2_FRAMENO_NONE;
list_rpush(schdPool->schdList, node);
return schdEvent;
}
/*****************************************************************************/
/**
* @brief Get a schedule event by its id.
*
* @param schdPool a pointer to schedule pool instance.
* @param id ID of the event
*
* @return NULL
* Pointer to the schedule event.
*
******************************************************************************/
L2_SCHD_EVENT* L2_GetEventById(L2_SCHD_POOL* schdPool, uint32_t id) {
ASSERT(schdPool != NULL);
util_schdevent.eventId = id;
list_node_t* node = list_find(schdPool->schdList, &util_schdevent);
if(node != NULL) {
DBG_WARNING("Event with id=%d, dose not exist.\n", id);
return NULL;
}
return ((L2_SCHD_EVENT*) node->val);
}
/*****************************************************************************/
/**
* @brief Delete a schedule event, remove the event from event pool,
* release memory.
*
* @param schdPool a pointer to schedule pool instance.
* @param id ID of the event
*
* @return SUCCESS
* error code
*
******************************************************************************/
int32_t L2_DeleteSchdEventById(L2_SCHD_POOL* schdPool, uint32_t id) {
ASSERT(schdPool != NULL);
util_schdevent.eventId = id;
list_node_t* node = list_find(schdPool->schdList, &util_schdevent);
if(node != NULL) {
DBG_ERROR("Event with id=%d, dose not exist.\n", id);
return EIGNORE;
}
list_remove(schdPool->schdList, node);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Schedule a event at a specific time(indexed by frame and slot number)
*
* @param instPtr a pointer to linklayer instance
* @param schdEvent pointer to the schedule event.
* @param frameNum schedule frame number
* @param slotNum schedule slot number
*
* @return FAILURE, event has already been scheduled/schedule time not allowed.
* SUCCESS
*
******************************************************************************/
int32_t L2_ScheduleEventAt(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t frameNum, uint32_t slotNum){
ASSERT(schdEvent != NULL);
if(L2_isEventScheduled(schdEvent) == true){
DBG_ERROR("Event %d has already been scheduled.\n", schdEvent->eventId);
return FAILURE;
}
if(frameNum <= L2_GetCurrentFrameNum(instPtr) && slotNum < L2_GetCurrentSlotNum(instPtr)){
DBG_ERROR("Cannot schedule event %d to the past(current: [%u-%u], schedule: [%u-%u]).\n",
schdEvent->eventId, L2_GetCurrentFrameNum(instPtr), L2_GetCurrentSlotNum(instPtr), frameNum, slotNum);
return FAILURE;
}
DBG_INFO("Schedule event (type:%d) [%u] at %u-%u.\n",
schdEvent->l2Event.event, schdEvent->eventId,
frameNum, slotNum);
schdEvent->isSchd = true;
schdEvent->schdFrame = frameNum;
schdEvent->schdSlot = slotNum;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Schedule a event after a specific time period.
*
* @param instPtr a pointer to linklayer instance
* @param schdEvent pointer to the schedule event.
* @param numSlots how many slot later the event should be scheduled
*
* @return FAILURE, event has already been scheduled/schedule time not allowed.
* SUCCESS
*
******************************************************************************/
int32_t L2_ScheduleEventAfter(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t numSlots){
ASSERT(schdEvent != NULL);
if(L2_isEventScheduled(schdEvent) == true){
DBG_ERROR("Event %d has already been scheduled.\n", schdEvent->eventId);
return FAILURE;
}
uint32_t frameNum = L2_GetCurrentFrameNum(instPtr) + (numSlots/L2_SLOTS_PER_FRAME);
uint32_t slotNum = L2_GetCurrentSlotNum(instPtr) + (numSlots%L2_SLOTS_PER_FRAME);
return L2_ScheduleEventAt(instPtr, schdEvent, frameNum, slotNum);
}
/*****************************************************************************/
/**
* @brief Reschedule a event at a specific time(indexed by frame and slot number)
*
* @param instPtr a pointer to linklayer instance
* @param schdEvent pointer to the schedule event.
* @param frameNum schedule frame number
* @param slotNum schedule slot number
*
* @return FAILURE, event has already been scheduled/schedule time not allowed.
* SUCCESS
*
******************************************************************************/
int32_t L2_RescheduleEventAt(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t frameNum, uint32_t slotNum){
ASSERT(schdEvent != NULL);
if(schdEvent->isSchd == false){
DBG_WARNING("Event %d has not been scheduled yet.\n", schdEvent->eventId);
}
schdEvent->isSchd = false;
return L2_ScheduleEventAt(instPtr, schdEvent, frameNum, slotNum);
}
/*****************************************************************************/
/**
* @brief Reschedule a event after a specific time period.
*
* @param instPtr a pointer to linklayer instance
* @param schdEvent pointer to the schedule event.
* @param numSlots how many slot later the event should be scheduled
*
* @return FAILURE, event has already been scheduled/schedule time not allowed.
* SUCCESS
*
******************************************************************************/
int32_t L2_RescheduleEventAfter(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t numSlots){
ASSERT(schdEvent != NULL);
if(schdEvent->isSchd == false){
DBG_WARNING("Event %d has not been scheduled yet.\n", schdEvent->eventId);
}
return L2_ScheduleEventAfter(instPtr, schdEvent, numSlots);
}
/*****************************************************************************/
/**
* @brief Check and excute schedule event in event pool illiterate.
*
* @param instPtr a pointer to linklayer instance
*
* @return NONE.
*
******************************************************************************/
void L2_EventPoolHandler(L2_INST* instPtr){
ASSERT(instPtr != NULL);
list_node_t* node;
L2_SCHD_EVENT* event;
L2_SCHD_POOL *pool = instPtr->schdEventPool;
list_iterator_t* iter = list_iterator_new(pool->schdList, LIST_HEAD);
if (iter == NULL)
{
DBG_ERROR("Failed to initialize schedule event pool iteration.\n");
return;
}
while (iter->next != NULL)
{
node = list_iterator_next(iter);
event = (L2_SCHD_EVENT*)node->val;
if(L2_isEventScheduled(event)){
if(event->schdFrame == L2_GetCurrentFrameNum(instPtr)
&& event->schdSlot == L2_GetCurrentSlotNum(instPtr)){
DBG_INFO("Asserting scheduled event [%d].\n", event->eventId);
AssertL2Event(instPtr, &(event->l2Event));
if(event->isVolatile == true) {
DBG_INFO("Deleting scheduled event [%d], since it is volatile.\n", event->eventId);
list_remove(pool->schdList, node);
}
else {
event->ocurrCnt++;
}
}
}
}
list_iterator_destroy(iter);
}
/*****************************************************************************/
/**
* @brief Append extra message content to specific schedule event.
*
* @param schdEvent pointer to the schedule event.
* msg pointer to the append content.
*
* @return SUCCESS.
* error code.
*
******************************************************************************/
inline void L2_SchdEventAppendMsg(L2_SCHD_EVENT* schdEvent, void* msg){
ASSERT(schdEvent != NULL);
schdEvent->l2Event.msg = msg;
}
/*****************************************************************************/
/**
* @brief Cancel a scheduled event.
*
* @param schdEvent pointer to the schedule event.
*
* @return SUCCESS.
*
******************************************************************************/
inline int32_t L2_CancelEvent(L2_SCHD_EVENT* schdEvent){
ASSERT(schdEvent != NULL);
if(schdEvent->isSchd == false){
DBG_WARNING("Event %d has not been scheduled yet.\n", schdEvent->eventId);
}
schdEvent->isSchd = false;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Check if the event was scheduled.
*
* @param schdEvent pointer to the schedule event.
*
* @return true.
* false.
*
******************************************************************************/
inline bool L2_isEventScheduled(const L2_SCHD_EVENT* schdEvent){
ASSERT(schdEvent != NULL);
return schdEvent->isSchd;
}
+63
View File
@@ -0,0 +1,63 @@
/*****************************************************************************/
/**
* Description: Event scheduling implementation
*
* Date: 2023-12-21 13:32
* LastEditors: Fan Hao
* LastEditTime: 2023-12-21 13:32
* Revisions: Rev 0.0
* History:
* [2023-12-21]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#ifndef SCHDEVENT_H_
#define SCHDEVENT_H_
#define SCHDEVENT_ID_NONE UINT32_MAX
/***************************** Include Files *********************************/
#include <stdlib.h>
#include "linklayer814_types.h"
#include "../error.h"
#include "../util/list.h"
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/** @name L2 event
* A definition of L2 event instance.
*/
typedef struct {
bool isSchd;
bool isVolatile;
L2_EVENT l2Event;
uint32_t eventId;
uint32_t ocurrCnt;
uint32_t schdFrame;
uint32_t schdSlot;
} L2_SCHD_EVENT;
/** @name L2 event
* A definition of L2 event instance.
*/
typedef struct {
list_t* schdList;
uint32_t envCnt;
} L2_SCHD_POOL;
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
// Scheduling Event
int32_t L2_CreateSchedEventPool(L2_SCHD_POOL** schdPool);
void L2_ClearSchedEventPool(L2_SCHD_POOL* schdPool);
void L2_DestroySchedEventPool(L2_SCHD_POOL* schdPool);
L2_SCHD_EVENT* L2_CreatNewSchdEvent(L2_SCHD_POOL* schdPool, L2_EVENT_TYPE event, bool isVolatile);
L2_SCHD_EVENT* L2_GetEventById(L2_SCHD_POOL* schdPool, uint32_t id);
int32_t L2_DeleteSchdEventById(L2_SCHD_POOL* schdPool, uint32_t id);
void L2_SchdEventAppendMsg(L2_SCHD_EVENT* schdEvent, void* msg);
bool L2_isEventScheduled(const L2_SCHD_EVENT* schdEvent);
int32_t L2_CancelEvent(L2_SCHD_EVENT* schdEvent);
#endif //SCHDEVENT_H_
+55 -55
View File
@@ -39,7 +39,7 @@ const TIME_WORD RTT_TIME_NONE = {
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
static void RTT_StageUpdate(L2_RTT_FSM* rttFsmPtr, L2_RTT_SATGE newSatge);
static void RTT_StageUpdate(L2_RTT_FSM* rttFsmPtr, L2_RTT_STGE newStage);
static void RTT_GetFrameStart(L2_INST* instPtr, TIME_WORD *tmStamp, L2_TOR_TYPE torType);
void RTT_CalculateTimeGap(const TIME_WORD *tmA, const TIME_WORD *tmB, TIME_WORD *tRound);
@@ -94,10 +94,11 @@ int32_t L2_TimeAlign(L2_INST* instPtr, uint32_t frameNum, uint32_t slotNum){
* @return NONE.
*
******************************************************************************/
static void RTT_StageUpdate(L2_RTT_FSM* rttFsmPtr, L2_RTT_SATGE newSatge) {
static void RTT_StageUpdate(L2_RTT_FSM* rttFsmPtr, L2_RTT_STGE newStage) {
ASSERT(rttFsmPtr != NULL);
ASSERT(newSatge >= RTT_NONE_STAGE && newSatge <= RTT_RSP2);
DBG_INFO("RTT Stage Update: %d -> %d.\n", rttFsmPtr->rttStatge, newSatge);
ASSERT(newStage >= RTT_NONE_STAGE && newStage <= RTT_RSP2);
DBG_INFO("RTT Stage Update: %d -> %d.\n", rttFsmPtr->rttStage, newStage);
rttFsmPtr->rttStage = newStage;
}
/*****************************************************************************/
@@ -112,7 +113,7 @@ static void RTT_StageUpdate(L2_RTT_FSM* rttFsmPtr, L2_RTT_SATGE newSatge) {
void RTT_Reset(L2_RTT_FSM* rttFsmPtr){
ASSERT(rttFsmPtr != NULL);
memset(&(rttFsmPtr->rttRecord), 0x00, sizeof(RTT_RECORD));
rttFsmPtr->rttStatge = RTT_NONE_STAGE;
rttFsmPtr->rttStage = RTT_REQ1;
rttFsmPtr->isR1Valid = false;
rttFsmPtr->isR2Valid = false;
rttFsmPtr->isR3Valid = false;
@@ -248,7 +249,7 @@ int32_t RTT_FsmUpdate(L2_INST* instPtr, L2_TOR_TYPE torType) {
// Stage trans
// For Head Node: Tx->Rx->Tx->Rx
if(L2_GetNodeType(instPtr) == HEAD_NODE){
switch(rttFsmPtr->rttStatge) {
switch(rttFsmPtr->rttStage) {
case RTT_REQ1 :
if(torType == L2_TOR_TX){
DBG_INFO("Prepare data for RTT REQ-1\n");
@@ -263,7 +264,7 @@ int32_t RTT_FsmUpdate(L2_INST* instPtr, L2_TOR_TYPE torType) {
RTT_StageUpdate(rttFsmPtr, RTT_RSP1);
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStatge);
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_RSP1 :
@@ -280,22 +281,22 @@ int32_t RTT_FsmUpdate(L2_INST* instPtr, L2_TOR_TYPE torType) {
RTT_CalculateTimeGap(&(rttRecord->Tt1), &(rttRecord->Tr2), &(rttRecord->TroundA));
}
else{
DBG_WARNING("RTT RSP-1 had not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set Tr2 dopplerR2 and TroundA to dummy value.\n");
rttFsmPtr->isR2Valid = false;
rttRecord->dopplerR2 = RTT_DOPPLER_NONE;
rttRecord->Tr2 = RTT_TIME_NONE;
rttRecord->TroundA = RTT_TIME_NONE;
DBG_WARNING("RTT RSP-1 had not been received [Stage: %d].\n", rttFsmPtr->rttStatge);
DBG_WARNING("Set Tr2 dopplerR2 and TroundA to dummy value.\n");
}
DBG_INFO("dopplerR2:%08X.\n", rttRecord->dopplerR2);
DBG_INFO("dopplerR2:%d.\n", rttRecord->dopplerR2);
DBG_INFO("Tr2-timeL:%u.\n", rttRecord->Tr2.frac_part);
DBG_INFO("Tr2-timeH:%u.\n", rttRecord->Tr2.int_part);
DBG_INFO("TroundA-timeL:%08X.\n", rttRecord->TroundA.frac_part);
DBG_INFO("TroundA-timeH:%08X.\n", rttRecord->TroundA.int_part);
DBG_INFO("TroundA-timeL:%u.\n", rttRecord->TroundA.frac_part);
DBG_INFO("TroundA-timeH:%u.\n", rttRecord->TroundA.int_part);
RTT_StageUpdate(rttFsmPtr, RTT_REQ2);
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStatge);
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_REQ2 :
@@ -309,14 +310,14 @@ int32_t RTT_FsmUpdate(L2_INST* instPtr, L2_TOR_TYPE torType) {
RTT_CalculateTimeGap(&(rttRecord->Tt3), &(rttRecord->Tr2), &(rttRecord->TreplyA));
}
else {
DBG_WARNING("RTT RSP-1 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set TreplyA to dummy value.\n");
rttRecord->TreplyA = RTT_TIME_NONE;
DBG_WARNING("RTT RSP-1 have not been received [Stage: %d].\n", rttFsmPtr->rttStatge);
DBG_WARNING("Set Tt3 and TreplyA to dummy value.\n");
}
DBG_INFO("Tt3-timeL:%08X.\n", rttRecord->Tt3.frac_part);
DBG_INFO("Tt3-timeH:%08X.\n", rttRecord->Tt3.int_part);
DBG_INFO("TreplyA-timeL:%08X.\n", rttRecord->TreplyA.frac_part);
DBG_INFO("TreplyA-timeH:%08X.\n", rttRecord->TreplyA.int_part);
DBG_INFO("Tt3-timeL:%u.\n", rttRecord->Tt3.frac_part);
DBG_INFO("Tt3-timeH:%u.\n", rttRecord->Tt3.int_part);
DBG_INFO("TreplyA-timeL:%u.\n", rttRecord->TreplyA.frac_part);
DBG_INFO("TreplyA-timeH:%u.\n", rttRecord->TreplyA.int_part);
// Prepare data for sending.
rttFsmPtr->timeStamp = rttRecord->TroundA;
@@ -324,7 +325,7 @@ int32_t RTT_FsmUpdate(L2_INST* instPtr, L2_TOR_TYPE torType) {
RTT_StageUpdate(rttFsmPtr, RTT_RSP2);
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStatge);
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_RSP2 :
@@ -341,34 +342,33 @@ int32_t RTT_FsmUpdate(L2_INST* instPtr, L2_TOR_TYPE torType) {
RTT_CalculateTimeGap(&(rttRecord->Tt3), &(rttRecord->Tr4), &(rttRecord->TroundA));
}
else{
DBG_WARNING("RTT RSP-1 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set Tr4 dopplerR4 and TroundA to dummy value.\n");
rttFsmPtr->isR4Valid = false;
rttRecord->dopplerR4 = RTT_DOPPLER_NONE;
rttRecord->Tr4 = RTT_TIME_NONE;
rttRecord->TroundA = RTT_TIME_NONE;
DBG_WARNING("RTT RSP-2 have not been received [Stage: %d].\n", rttFsmPtr->rttStatge);
DBG_WARNING("Set Tr4 dopplerR4 and TroundA to dummy value.\n");
}
DBG_INFO("dopplerR4:%08X.\n", rttRecord->dopplerR4);
DBG_INFO("Tr4-timeL:%08X.\n", rttRecord->Tr4.frac_part);
DBG_INFO("Tr4-timeH:%08X.\n", rttRecord->Tr4.int_part);
DBG_INFO("TroundA-timeL:%08X.\n", rttRecord->TroundA.frac_part);
DBG_INFO("TroundA-timeH:%08X.\n", rttRecord->TroundA.int_part);
RTT_StageUpdate(rttFsmPtr, RTT_NONE_STAGE);
DBG_INFO("dopplerR4:%d.\n", rttRecord->dopplerR4);
DBG_INFO("Tr4-timeL:%u.\n", rttRecord->Tr4.frac_part);
DBG_INFO("Tr4-timeH:%u.\n", rttRecord->Tr4.int_part);
DBG_INFO("TroundA-timeL:%u.\n", rttRecord->TroundA.frac_part);
DBG_INFO("TroundA-timeH:%u.\n", rttRecord->TroundA.int_part);
RTT_StageUpdate(rttFsmPtr, RTT_REQ1);
DBG_INFO("RTT procedure end...\n");
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStatge);
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
default :
DBG_ERROR("Unexpected RTT FSM stage [%d].\n", rttFsmPtr->rttStatge);
DBG_ERROR("Unexpected RTT FSM stage [%d].\n", rttFsmPtr->rttStage);
break;
}
}
// For Member Node: Rx->Tx->Rx->Tx
else{
switch(rttFsmPtr->rttStatge) {
switch(rttFsmPtr->rttStage) {
case RTT_REQ1 :
if(torType == L2_TOR_RX){
if(L2_isDataAvail(instPtr) == true){
@@ -381,19 +381,19 @@ int32_t RTT_FsmUpdate(L2_INST* instPtr, L2_TOR_TYPE torType) {
RTT_GetFrameStart(instPtr, &(rttRecord->Tr1), torType);
}
else{
DBG_WARNING("RTT REQ-1 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set dopplerR1 and Tr1 to dummy value.\n");
rttFsmPtr->isR1Valid = false;
rttRecord->dopplerR1 = RTT_DOPPLER_NONE;
rttRecord->Tr1 = RTT_TIME_NONE;
DBG_WARNING("RTT REQ-1 have not been received [Stage: %d].\n", rttFsmPtr->rttStatge);
DBG_WARNING("Set dopplerR1 and Tr1 to dummy value.\n");
}
DBG_INFO("dopplerR1:%08X.\n", rttRecord->dopplerR1);
DBG_INFO("Tr1-timeL:%08X.\n", rttRecord->Tr1.frac_part);
DBG_INFO("Tr1-timeH:%08X.\n", rttRecord->Tr1.int_part);
DBG_INFO("dopplerR1:%d.\n", rttRecord->dopplerR1);
DBG_INFO("Tr1-timeL:%u.\n", rttRecord->Tr1.frac_part);
DBG_INFO("Tr1-timeH:%u.\n", rttRecord->Tr1.int_part);
RTT_StageUpdate(rttFsmPtr, RTT_RSP1);
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStatge);
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_RSP1 :
@@ -407,13 +407,13 @@ int32_t RTT_FsmUpdate(L2_INST* instPtr, L2_TOR_TYPE torType) {
}
else {
rttRecord->TreplyB = RTT_TIME_NONE;
DBG_WARNING("RTT REQ-1 have not been received [Stage: %d].\n", rttFsmPtr->rttStatge);
DBG_WARNING("RTT REQ-1 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set ReplayB to dummy value.\n");
}
DBG_INFO("Tt2-timeL:%u.\n", rttRecord->Tt2.frac_part);
DBG_INFO("Tt2-timeH:%u.\n", rttRecord->Tt2.int_part);
DBG_INFO("TreplyB-timeL:%08X.\n", rttRecord->TreplyB.frac_part);
DBG_INFO("TreplyB-timeH:%08X.\n", rttRecord->TreplyB.int_part);
DBG_INFO("TreplyB-timeL:%u.\n", rttRecord->TreplyB.frac_part);
DBG_INFO("TreplyB-timeH:%u.\n", rttRecord->TreplyB.int_part);
// Prepare data for sending.
rttFsmPtr->timeStamp = rttRecord->TreplyB;
@@ -421,7 +421,7 @@ int32_t RTT_FsmUpdate(L2_INST* instPtr, L2_TOR_TYPE torType) {
RTT_StageUpdate(rttFsmPtr, RTT_REQ2);
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStatge);
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_REQ2 :
@@ -438,21 +438,21 @@ int32_t RTT_FsmUpdate(L2_INST* instPtr, L2_TOR_TYPE torType) {
RTT_CalculateTimeGap(&(rttRecord->Tt2), &(rttRecord->Tr3), &(rttRecord->TroundB));
}
else{
DBG_WARNING("RTT REQ-2 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set dopplerR3 and ReplayB to dummy value.\n");
rttFsmPtr->isR3Valid = false;
rttRecord->dopplerR3 = RTT_DOPPLER_NONE;
rttRecord->TroundB = RTT_TIME_NONE;
DBG_WARNING("RTT REQ-2 have not been received [Stage: %d].\n", rttFsmPtr->rttStatge);
DBG_WARNING("Set dopplerR3 and ReplayB to dummy value.\n");
}
DBG_INFO("dopplerR3:%08X.\n", rttRecord->dopplerR3);
DBG_INFO("dopplerR3:%d.\n", rttRecord->dopplerR3);
DBG_INFO("Tr3-timeL:%u.\n", rttRecord->Tr3.frac_part);
DBG_INFO("Tr3-timeH:%u.\n", rttRecord->Tr3.int_part);
DBG_INFO("TroundB-timeL:%08X.\n", rttRecord->TroundB.frac_part);
DBG_INFO("TroundB-timeH:%08X.\n", rttRecord->TroundB.int_part);
DBG_INFO("TroundB-timeL:%u.\n", rttRecord->TroundB.frac_part);
DBG_INFO("TroundB-timeH:%u.\n", rttRecord->TroundB.int_part);
RTT_StageUpdate(rttFsmPtr, RTT_RSP2);
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStatge);
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_RSP2 :
@@ -466,27 +466,27 @@ int32_t RTT_FsmUpdate(L2_INST* instPtr, L2_TOR_TYPE torType) {
// TODO: implement a time adjustment.
}
else {
rttRecord->TreplyB = RTT_TIME_NONE;
DBG_WARNING("RTT REQ-2 have not been received [Stage: %d].\n", rttFsmPtr->rttStatge);
DBG_WARNING("RTT REQ-2 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set ReplayB to dummy value.\n");
rttRecord->TreplyB = RTT_TIME_NONE;
}
DBG_INFO("Tt4-timeL:%u.\n", rttRecord->Tt4.frac_part);
DBG_INFO("Tt4-timeH:%u.\n", rttRecord->Tt4.int_part);
DBG_INFO("TreplyB-timeL:%08X.\n", rttRecord->TreplyB.frac_part);
DBG_INFO("TreplyB-timeH:%08X.\n", rttRecord->TreplyB.int_part);
DBG_INFO("TreplyB-timeL:%u.\n", rttRecord->TreplyB.frac_part);
DBG_INFO("TreplyB-timeH:%u.\n", rttRecord->TreplyB.int_part);
// Prepare data for sending.
rttFsmPtr->timeStamp = rttRecord->TreplyB;
rttFsmPtr->doppler = rttRecord->dopplerR3;
RTT_StageUpdate(rttFsmPtr, RTT_NONE_STAGE);
RTT_StageUpdate(rttFsmPtr, RTT_REQ1);
DBG_INFO("RTT procedure end...\n");
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStatge);
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
default:
DBG_ERROR("Unexpected RTT FSM stage [%d].\n", rttFsmPtr->rttStatge);
DBG_ERROR("Unexpected RTT FSM stage [%d].\n", rttFsmPtr->rttStage);
break;
}
}
+1 -1
View File
@@ -434,7 +434,7 @@ int MPC_StateUpload(MPC_INST* instPtr , uint8_t* mgmtBuffer , uint32_t mgmtMsgC
dataChunk = BIT(L2_GetNodeId(linkInstPtr) - 1);
if (GetNodeNum(linkInstPtr->nodeList) > 1 ) {
for(int i = 1; i <= linkInstPtr->config.netScale; i++){
if (IsNodeInList(linkInstPtr->nodeList, i)) {
if (L2_isNodeInList(linkInstPtr->nodeList, i)) {
dataChunk |= BIT(i-1);
}
}
+301
View File
@@ -0,0 +1,301 @@
#ifndef LIST_MALLOC
#define LIST_MALLOC malloc
#endif
#ifndef LIST_FREE
#define LIST_FREE free
#endif
//
// list.c
//
// Copyright (c) 2010 TJ Holowaychuk <[email protected]>
//
#include "list.h"
/*
* Allocates a new list_node_t. NULL on failure.
*/
list_node_t *
list_node_new(void *val) {
list_node_t *self;
if (!(self = LIST_MALLOC(sizeof(list_node_t))))
return NULL;
self->prev = NULL;
self->next = NULL;
self->val = val;
return self;
}
/*
* Allocate a new list_t. NULL on failure.
*/
list_t *
list_new(void) {
list_t *self;
if (!(self = LIST_MALLOC(sizeof(list_t))))
return NULL;
self->head = NULL;
self->tail = NULL;
self->free = NULL;
self->match = NULL;
self->len = 0;
return self;
}
/*
* Remove all the node in list.
* @self: Pointer to the list
*/
void
list_clear(list_t *self) {
uint32_t len = self->len;
list_node_t *next;
list_node_t *curr = self->head;
while (len) {
next = curr->next;
if (self->free) self->free(curr->val);
LIST_FREE(curr);
curr = next;
len--;
}
}
/*
* Free the list.
* @self: Pointer to the list
*/
void
list_destroy(list_t *self) {
list_clear(self);
LIST_FREE(self);
}
/*
* Append the given node to the list
* and return the node, NULL on failure.
* @self: Pointer to the list for popping node
* @node: the node to push
*/
list_node_t *
list_rpush(list_t *self, list_node_t *node) {
if (!node) return NULL;
if (self->len) {
node->prev = self->tail;
node->next = NULL;
self->tail->next = node;
self->tail = node;
} else {
self->head = self->tail = node;
node->prev = node->next = NULL;
}
++self->len;
return node;
}
/*
* Return / detach the last node in the list, or NULL.
* @self: Pointer to the list for popping node
*/
list_node_t *
list_rpop(list_t *self) {
if (!self->len) return NULL;
list_node_t *node = self->tail;
if (--self->len) {
(self->tail = node->prev)->next = NULL;
} else {
self->tail = self->head = NULL;
}
node->next = node->prev = NULL;
return node;
}
/*
* Return / detach the first node in the list, or NULL.
* @self: Pointer to the list for popping node
*/
list_node_t *
list_lpop(list_t *self) {
if (!self->len) return NULL;
list_node_t *node = self->head;
if (--self->len) {
(self->head = node->next)->prev = NULL;
} else {
self->head = self->tail = NULL;
}
node->next = node->prev = NULL;
return node;
}
/*
* Prepend the given node to the list
* and return the node, NULL on failure.
* @self: Pointer to the list for pushing node
* @node: the node to push
*/
list_node_t *
list_lpush(list_t *self, list_node_t *node) {
if (!node) return NULL;
if (self->len) {
node->next = self->head;
node->prev = NULL;
self->head->prev = node;
self->head = node;
} else {
self->head = self->tail = node;
node->prev = node->next = NULL;
}
++self->len;
return node;
}
/*
* Return the node associated to val or NULL.
* @self: Pointer to the list for finding given value
* @val: Value to find
*/
list_node_t *
list_find(list_t *self, void *val) {
list_iterator_t *it = list_iterator_new(self, LIST_HEAD);
list_node_t *node;
while ((node = list_iterator_next(it))) {
if (self->match) {
if (self->match(val, node->val)) {
list_iterator_destroy(it);
return node;
}
} else {
if (val == node->val) {
list_iterator_destroy(it);
return node;
}
}
}
list_iterator_destroy(it);
return NULL;
}
/*
* Return the node at the given index or NULL.
* @self: Pointer to the list for finding given index
* @index: the index of node in the list
*/
list_node_t *
list_at(list_t *self, int index) {
list_direction_t direction = LIST_HEAD;
if (index < 0) {
direction = LIST_TAIL;
index = ~index;
}
if ((unsigned)index < self->len) {
list_iterator_t *it = list_iterator_new(self, direction);
list_node_t *node = list_iterator_next(it);
while (index--) node = list_iterator_next(it);
list_iterator_destroy(it);
return node;
}
return NULL;
}
/*
* Remove the given node from the list, freeing it and it's value.
* @self: Pointer to the list to delete a node
* @node: Pointer the node to be deleted
*/
void
list_remove(list_t *self, list_node_t *node) {
node->prev
? (node->prev->next = node->next)
: (self->head = node->next);
node->next
? (node->next->prev = node->prev)
: (self->tail = node->prev);
if (self->free) self->free(node->val);
LIST_FREE(node);
--self->len;
}
/*
* Allocate a new list_iterator_t. NULL on failure.
* Accepts a direction, which may be LIST_HEAD or LIST_TAIL.
*/
list_iterator_t *
list_iterator_new(list_t *list, list_direction_t direction) {
list_node_t *node = direction == LIST_HEAD
? list->head
: list->tail;
return list_iterator_new_from_node(node, direction);
}
/*
* Allocate a new list_iterator_t with the given start
* node. NULL on failure.
*/
list_iterator_t *
list_iterator_new_from_node(list_node_t *node, list_direction_t direction) {
list_iterator_t *self;
if (!(self = LIST_MALLOC(sizeof(list_iterator_t))))
return NULL;
self->next = node;
self->direction = direction;
return self;
}
/*
* Return the next list_node_t or NULL when no more
* nodes remain in the list.
*/
list_node_t *
list_iterator_next(list_iterator_t *self) {
list_node_t *curr = self->next;
if (curr) {
self->next = self->direction == LIST_HEAD
? curr->next
: curr->prev;
}
return curr;
}
/*
* Free the list iterator.
*/
void
list_iterator_destroy(list_iterator_t *self) {
LIST_FREE(self);
self = NULL;
}
+114
View File
@@ -0,0 +1,114 @@
//
// list.h
//
// Copyright (c) 2010 TJ Holowaychuk <[email protected]>
//
#ifndef __LIST_H__
#define __LIST_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
/*
* list_t iterator direction.
*/
typedef enum {
LIST_HEAD,
LIST_TAIL
} list_direction_t;
/*
* list_t node struct.
*/
typedef struct list_node {
struct list_node *prev;
struct list_node *next;
void *val;
} list_node_t;
/*
* list_t struct.
*/
typedef struct {
list_node_t *head;
list_node_t *tail;
uint32_t len;
void (*free)(void *val);
bool (*match)(void *a, void *b);
} list_t;
/*
* list_t iterator struct.
*/
typedef struct {
list_node_t *next;
list_direction_t direction;
} list_iterator_t;
// Node prototypes.
list_node_t *
list_node_new(void *val);
// list_t prototypes.
list_t *
list_new(void);
list_node_t *
list_rpush(list_t *self, list_node_t *node);
list_node_t *
list_lpush(list_t *self, list_node_t *node);
list_node_t *
list_find(list_t *self, void *val);
list_node_t *
list_at(list_t *self, int index);
list_node_t *
list_rpop(list_t *self);
list_node_t *
list_lpop(list_t *self);
void
list_remove(list_t *self, list_node_t *node);
void
list_clear(list_t *self);
void
list_destroy(list_t *self);
// list_t iterator prototypes.
list_iterator_t *
list_iterator_new(list_t *list, list_direction_t direction);
list_iterator_t *
list_iterator_new_from_node(list_node_t *node, list_direction_t direction);
list_node_t *
list_iterator_next(list_iterator_t *self);
void
list_iterator_destroy(list_iterator_t *self);
#ifdef __cplusplus
}
#endif
#endif /* __CLIBS_LIST_H__ */
+3 -3
View File
@@ -36,8 +36,8 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef UTIL_H_
#define UTIL_H_
#ifndef __UTIL_H_
#define __UTIL_H_
/******************************************************************************/
/***************************** Include Files **********************************/
@@ -188,5 +188,5 @@ int crc16_gen(uint8_t* buffPtr, uint32_t dataLen, uint16_t poly, uint16_t* crcVa
bool crc16_check(uint8_t* buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly);
int crc8_gen(uint8_t* buffPtr, uint32_t dataLen, uint16_t poly, uint8_t* crcVal);
bool crc8_check(uint8_t* buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly);
#endif // UTIL_H_
#endif // __UTIL_H_
@@ -1,4 +1,5 @@
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
#include "error.h"
#include "unit_test_framework.h"
@@ -193,6 +194,11 @@ TIMECTRL_CONFIG tmcConfig = {
.reset = 10
};
inline uint32_t rand_range(uint32_t a, uint32_t b){
ASSERT(b > a);
return (rand() % (b + 1 - a) + a);
}
void linklayer_setup(void){
int32_t Status;
Status = TimeCtrl_Init(&tmcInstPtr, &tmcConfig);
@@ -214,13 +220,14 @@ void linklayer_teardown(void){
TimeCtrl_Destroy(tmcInstPtr);
}
void forge_bm_frame(uint16_t nodeId, uint16_t clustId, uint16_t headId, uint64_t time) {
void forge_bm_frame(uint8_t* buff, uint8_t nodeId, uint16_t clustId, uint16_t headId, uint64_t time) {
BIT_ARRAY bitarr = {
.words = (uint64_t*)bmTemplate,
.words = (uint64_t*)buff,
.num_of_bits = INTRA_BM_FRAME_LENGTH_MAX*8,
.num_of_words = roundup_bits2words64(INTRA_BM_FRAME_LENGTH_MAX*8),
.capacity_in_words = roundup_bits2words64(INTRA_BM_FRAME_LENGTH_MAX*8),
};
memcpy(buff, bmTemplate, INTRA_BM_FRAME_LENGTH_MAX);
uint64_t dataChunk;
dataChunk = (nodeId & 0x001F) | ((clustId & 0x001F) << 5);
FrameInsertChunk(&bitarr, BM_MSG_SRC_ADDR_OFFSET, BM_MSG_SRC_ADDR_LEN, dataChunk);
@@ -242,17 +249,19 @@ void forge_bm_frame(uint16_t nodeId, uint16_t clustId, uint16_t headId, uint64_t
FrameInsertChunk(&bitarr, BM_MSG_TSLOT_NUM_OFFSET, BM_MSG_TSLOT_NUM_LEN, dataChunk);
// Append CRC
L2_CrcAppend(bmTemplate, BM_MSG_CRC_OFFSET / 8, BM_MSG_CRC_OFFSET / 8, L2_CRC8_31);
L2_CrcAppend(buff, BM_MSG_CRC_OFFSET / 8, BM_MSG_CRC_OFFSET / 8, L2_CRC8_31);
}
void forge_w2acq_frame(L2_NODE_TYPE nodeType, uint16_t srcId, uint16_t destId,
void forge_w2acq_frame(uint8_t* buff, L2_NODE_TYPE nodeType, uint16_t srcId, uint16_t destId,
uint16_t clustId, uint32_t netStartTime, L2_NODE_STATE state) {
BIT_ARRAY bitarr = {
.words = (uint64_t*)w2acqTemplate,
.words = (uint64_t*)buff,
.num_of_bits = INTRA_W2ACQ_FRAME_LENGTH_MAX*8,
.num_of_words = roundup_bits2words64(INTRA_W2ACQ_FRAME_LENGTH_MAX*8),
.capacity_in_words = roundup_bits2words64(INTRA_W2ACQ_FRAME_LENGTH_MAX*8),
};
memcpy(buff, w2acqTemplate, INTRA_W2ACQ_FRAME_LENGTH_MAX);
uint64_t dataChunk;
/* message type */
dataChunk = (nodeType == HEAD_NODE) ? 0 : 1;
@@ -287,16 +296,18 @@ void forge_w2acq_frame(L2_NODE_TYPE nodeType, uint16_t srcId, uint16_t destId,
FrameInsertChunk(&bitarr, NS_MSG_INI_SCAN_TIME_OFFSET, NS_MSG_INI_SCAN_TIME_LEN, dataChunk);
// Update CRC
L2_CrcAppend(w2acqTemplate, W2ACQ_FRAME_CRC_DLEN, W2ACQ_FRAME_CRC_POS, L2_CRC16_8005);
L2_CrcAppend(buff, W2ACQ_FRAME_CRC_DLEN, W2ACQ_FRAME_CRC_POS, L2_CRC16_8005);
}
void forge_mgmt_frame(L2_NODE_STATE state) {
void forge_mgmt_frame(uint8_t* buff, L2_NODE_STATE state) {
BIT_ARRAY bitarr = {
.words = (uint64_t*)mgmtTemplate,
.words = (uint64_t*)buff,
.num_of_bits = INTRA_MGMT_FRAME_LENGTH_MAX*8,
.num_of_words = roundup_bits2words64(INTRA_MGMT_FRAME_LENGTH_MAX*8),
.capacity_in_words = roundup_bits2words64(INTRA_MGMT_FRAME_LENGTH_MAX*8),
};
memcpy(buff, mgmtTemplate, INTRA_MGMT_FRAME_LENGTH_MAX);
uint64_t dataChunk;
switch (state) {
case INIT_STATE:
@@ -321,7 +332,14 @@ void forge_mgmt_frame(L2_NODE_STATE state) {
}
}
void forge_rtt_frame(L2_INST* instPtr) {
void forge_rtt_frame(uint8_t* buff) {
// BIT_ARRAY bitarr = {
// .words = (uint64_t*)buff,
// .num_of_bits = INTRA_BM_FRAME_LENGTH_MAX*8,
// .num_of_words = roundup_bits2words64(INTRA_BM_FRAME_LENGTH_MAX*8),
// .capacity_in_words = roundup_bits2words64(INTRA_BM_FRAME_LENGTH_MAX*8),
// };
memcpy(buff, rttReqTemplate, INTRA_BM_FRAME_LENGTH_MAX);
return;
}
@@ -332,18 +350,49 @@ TEST(linklayer_master_routine) {
for(int i = 0; i < 200*30; i++) {
tmcReg[TIME_INT_REG]++;
if(phyInstPtr->TOR.last == PHY_TOR_RX && linkInstPtr->frame.last == L2_INTRA_W2_ACQ_FRAME)
if (L2_GetLastTor(linkInstPtr) == L2_TOR_RX && rand() < (RAND_MAX*0.8))
{
if(L2_GetLastFrameType(linkInstPtr) == L2_INTRA_W2_ACQ_FRAME) {
forge_w2acq_frame((uint8_t*)phyInstPtr->recvDataAddr, MEMBER_NODE, 2, 1, 1, -1, INIT_STATE);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, INTRA_W2ACQ_FRAME_LENGTH_MAX);
}
if (L2_GetLastFrameType(linkInstPtr) == L2_INTRA_MGMT_FRAME)
{
forge_mgmt_frame((uint8_t*)phyInstPtr->recvDataAddr, NORMAL_STATE);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, INTRA_MGMT_FRAME_LENGTH_MAX);
}
if (L2_GetLastFrameType(linkInstPtr) == L2_INTRA_SVC_FRAME)
{
forge_mgmt_frame((uint8_t*)phyInstPtr->recvDataAddr, NORMAL_STATE);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, INTRA_MGMT_FRAME_LENGTH_MAX);
}
}
else {
PhyWrite(phyInstPtr, TXRX_STATE, 0x02020202);
}
Phy_UpdateState(phyInstPtr);
Status = Linklayer_Proc(linkInstPtr);
if(tmcReg[TIME_INT_REG]/200 < linkInstPtr->netStartTime) {
if((tmcReg[TIME_INT_REG]+1)/200 < linkInstPtr->netStartTime) {
ASSERT_EQUAL(EIGNORE, Status);
}
else{
ASSERT_EQUAL(SUCCESS, Status);
}
if(L2_isDataAvail(linkInstPtr)) {
if(L2_GetLastFrameType(linkInstPtr) == L2_INTRA_W2_ACQ_FRAME) {
ASSERT_EQUAL(1, L2_GetNodeListLen(linkInstPtr->nodeList));
ASSERT_TRUE(L2_isNodeInList(linkInstPtr->nodeList, 2));
}
}
}
}
+1 -1
View File
@@ -39,6 +39,6 @@
*
******************************************************************************/
void AppAssert(const char * file, int line){
DBG_PRINT("in %s #%4d [assert] ",file, line);
DBG_PRINT("in %s #%4d [assert] .\n",file, line);
while(1);
}