Compare commits
26
Commits
6c1b2b929e
...
a2032414cc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2032414cc | ||
|
|
16b6e18420 | ||
|
|
6acd6e68ca | ||
|
|
c0d347a619 | ||
|
|
b76a4cd776 | ||
|
|
c1e26fa20b | ||
|
|
e6d498687c | ||
|
|
92cdcdc8e9 | ||
|
|
d0357cb199 | ||
|
|
9642a003e0 | ||
|
|
57dfad7b82 | ||
|
|
f72e6fadb1 | ||
|
|
0bec764c96 | ||
|
|
218fb01193 | ||
|
|
595b63c8ef | ||
|
|
4455e29be6 | ||
|
|
0a535af392 | ||
|
|
426a35b48f | ||
|
|
30b3afc686 | ||
|
|
8b5192b3f4 | ||
|
|
329abdfca3 | ||
|
|
a2de2d5855 | ||
|
|
62690fba15 | ||
|
|
9d023e2726 | ||
|
|
3a54546cbb | ||
|
|
5f6bdf83d6 |
Vendored
+34
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
Vendored
+30
@@ -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"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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_
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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__ */
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user