This commit is contained in:
Robin Müller 2022-08-30 23:49:09 +02:00
commit 9319d58137
No known key found for this signature in database
GPG Key ID: 71B58F8A3CDFA9AC
183 changed files with 920 additions and 16161 deletions

3
.gitmodules vendored
View File

@ -22,3 +22,6 @@
[submodule "thirdparty/rapidcsv"]
path = thirdparty/rapidcsv
url = https://github.com/d99kris/rapidcsv.git
[submodule "thirdparty/gomspace-sw"]
path = thirdparty/gomspace-sw
url = https://egit.irs.uni-stuttgart.de/eive/gomspace-sw.git

View File

@ -13,6 +13,10 @@ list yields a list of all related PRs for each release.
# [v1.14.0]
- Update for FSFW: `HasReturnvaluesIF` class replaced by namespace `returnvalue`
- Add some GomSpace clients as a submodule dependency. Use this dependency to deserialize the
GomSpace TM tables
- Add API to retrieve GomSpace device parameter tables
PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/287
# [v1.13.0] 24.08.2022

View File

@ -170,6 +170,9 @@ set(LIB_ETL_TARGET etl::etl)
set(LIB_CSP_NAME libcsp)
set(LIB_LWGPS_NAME lwgps)
set(LIB_ARCSEC wire)
set(LIB_GOMSPACE_CLIENTS gs_clients)
set(LIB_GOMSPACE_CSP gs_csp)
set(THIRD_PARTY_FOLDER thirdparty)
set(LIB_CXX_FS -lstdc++fs)
set(LIB_CATCH2 Catch2)
@ -182,6 +185,7 @@ set(FSFW_PATH fsfw)
set(TEST_PATH test)
set(UNITTEST_PATH unittest)
set(LINUX_PATH linux)
set(LIB_GOMSPACE_PATH ${THIRD_PARTY_FOLDER}/gomspace-sw)
set(COMMON_PATH common)
set(DUMMY_PATH dummies)
set(WATCHDOG_PATH watchdog)
@ -189,7 +193,6 @@ set(COMMON_CONFIG_PATH ${COMMON_PATH}/config)
set(UNITTEST_CFG_PATH ${UNITTEST_PATH}/testcfg)
set(LIB_EIVE_MISSION_PATH mission)
set(LIB_CSP_PATH ${THIRD_PARTY_FOLDER}/libcsp)
set(LIB_ETL_PATH ${THIRD_PARTY_FOLDER}/etl)
set(LIB_CATCH2_PATH ${THIRD_PARTY_FOLDER}/Catch2)
set(LIB_LWGPS_PATH ${THIRD_PARTY_FOLDER}/lwgps)
@ -217,7 +220,8 @@ if(TGT_BSP)
set(FSFW_CONFIG_PATH "linux/fsfwconfig")
if(NOT BUILD_Q7S_SIMPLE_MODE)
set(EIVE_ADD_LINUX_FILES TRUE)
set(ADD_CSP_LIB TRUE)
set(ADD_GOMSPACE_CSP TRUE)
set(ADD_GOMSPACE_CLIENTS TRUE)
set(FSFW_HAL_ADD_LINUX ON)
set(FSFW_HAL_LINUX_ADD_LIBGPIOD ON)
set(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS ON)
@ -280,7 +284,25 @@ set(FSFW_ADDITIONAL_INC_PATHS "${COMMON_PATH}/config"
# global compiler options need to be set before adding executables
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(
# Remove unused sections.
add_compile_options("-ffunction-sections" "-fdata-sections")
# Removed unused sections.
add_link_options("-Wl,--gc-sections")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(COMPILER_FLAGS "/permissive-")
endif()
add_library(${LIB_EIVE_MISSION})
add_library(${LIB_DUMMIES})
# Add main executable
add_executable(${OBSW_NAME})
set(OBSW_BIN_NAME ${CMAKE_PROJECT_NAME})
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(WARNING_FLAGS
"-Wall"
"-Wextra"
"-Wimplicit-fallthrough=1"
@ -301,27 +323,15 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
"-Wcast-qual" # Warn if the constness is cast away
"-Wstringop-overflow=4"
# -Wstack-protector # Emits a few false positives for low level access
# -Wconversion # Creates many false positives -Warith-conversion # Use with
# Wconversion to find more implicit conversions -fanalyzer # Should be used
# to look through problems
# -Wconversion # Creates many false positives -Warith-conversion # Use
# with Wconversion to find more implicit conversions -fanalyzer # Should
# be used to look through problems
)
# Remove unused sections.
add_compile_options("-ffunction-sections" "-fdata-sections")
# Removed unused sections.
add_link_options("-Wl,--gc-sections")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(COMPILER_FLAGS "/permissive-")
target_compile_options(${OBSW_NAME} PRIVATE ${WARNING_FLAGS})
target_compile_options(${LIB_EIVE_MISSION} PRIVATE ${WARNING_FLAGS})
target_compile_options(${LIB_DUMMIES} PRIVATE ${WARNING_FLAGS})
endif()
add_library(${LIB_EIVE_MISSION})
add_library(${LIB_DUMMIES})
# Add main executable
add_executable(${OBSW_NAME})
set(OBSW_BIN_NAME ${CMAKE_PROJECT_NAME})
set_target_properties(${OBSW_NAME} PROPERTIES OUTPUT_NAME ${OBSW_BIN_NAME})
# Watchdog
@ -357,10 +367,7 @@ if(EIVE_ADD_LINUX_FILES)
add_subdirectory(${LINUX_PATH})
endif()
add_subdirectory(${BSP_PATH})
if(ADD_CSP_LIB)
add_subdirectory(${LIB_CSP_PATH})
endif()
add_subdirectory(${LIB_GOMSPACE_PATH})
add_subdirectory(${COMMON_PATH})
add_subdirectory(${DUMMY_PATH})
@ -444,16 +451,17 @@ if(TGT_BSP MATCHES "arm/q7s")
target_link_libraries(${LIB_EIVE_MISSION} PUBLIC ${LIB_GPS} ${LIB_ARCSEC})
endif()
target_link_libraries(${UNITTEST_NAME} PRIVATE Catch2 ${LIB_EIVE_MISSION}
rapidcsv ${LIB_DUMMIES})
target_link_libraries(
${UNITTEST_NAME} PRIVATE Catch2 ${LIB_EIVE_MISSION} rapidcsv ${LIB_DUMMIES}
${LIB_GOMSPACE_CLIENTS})
if(TGT_BSP MATCHES "arm/egse")
target_link_libraries(${OBSW_NAME} PRIVATE ${LIB_ARCSEC})
endif()
if(ADD_CSP_LIB)
target_link_libraries(${OBSW_NAME} PRIVATE ${LIB_CSP_NAME})
endif()
target_link_libraries(${OBSW_NAME} PRIVATE ${LIB_GOMSPACE_CLIENTS})
target_link_libraries(${LIB_EIVE_MISSION} PRIVATE ${LIB_GOMSPACE_CLIENTS})
target_link_libraries(${LIB_DUMMIES} PRIVATE ${LIB_GOMSPACE_CLIENTS})
if(EIVE_ADD_ETL_LIB)
target_link_libraries(${LIB_EIVE_MISSION} PUBLIC ${LIB_ETL_TARGET})

View File

@ -129,9 +129,7 @@ ArduinoComIF::~ArduinoComIF() {
CloseHandle(hCom);
#endif
}
ReturnValue_t ArduinoComIF::initializeInterface(CookieIF *cookie) {
return returnvalue::OK;
}
ReturnValue_t ArduinoComIF::initializeInterface(CookieIF *cookie) { return returnvalue::OK; }
ReturnValue_t ArduinoComIF::sendMessage(CookieIF *cookie, const uint8_t *data, size_t len) {
ArduinoCookie *arduinoCookie = dynamic_cast<ArduinoCookie *>(cookie);

View File

@ -115,7 +115,6 @@
#cmakedefine LIBGPS_VERSION_MAJOR @LIBGPS_VERSION_MAJOR@
#cmakedefine LIBGPS_VERSION_MINOR @LIBGPS_VERSION_MINOR@
#ifdef __cplusplus
#include "objects/systemObjectList.h"

View File

@ -3,9 +3,12 @@
#include <bsp_q7s/core/CoreController.h>
#include <bsp_q7s/memory/FileSystemHandler.h>
#include <bsp_q7s/xadc/Xadc.h>
#include <fsfw/globalfunctions/arrayprinter.h>
#include <fsfw/objectmanager/ObjectManager.h>
#include <gps.h>
#include <libgpsmm.h>
#include <param/param_string.h>
#include <param/rparam_client.h>
#include <cstdio>
#include <ctime>
@ -18,6 +21,7 @@
#include "bsp_q7s/memory/scratchApi.h"
#include "fsfw/tasks/TaskFactory.h"
#include "fsfw/timemanager/Stopwatch.h"
#include "p60pdu.h"
#include "test/DummyParameter.h"
Q7STestTask::Q7STestTask(object_id_t objectId) : TestTask(objectId) {
@ -35,6 +39,33 @@ ReturnValue_t Q7STestTask::performOneShotAction() {
if (doTestScratchApi) {
testScratchApi();
}
if (DO_TEST_GOMSPACE_API) {
uint8_t p60pdu_node = 3;
uint8_t hk_mem[P60PDU_HK_SIZE];
param_index_t p60pdu_hk{};
p60pdu_hk.physaddr = hk_mem;
if (!p60pdu_get_hk(&p60pdu_hk, p60pdu_node, 1000)) {
printf("Error getting p60pdu hk\n");
} else {
param_list(&p60pdu_hk, 1);
}
}
if (DO_TEST_GOMSPACE_GET_CONFIG) {
uint8_t p60pdu_node = 3;
param_index_t requestStruct{};
requestStruct.table = p60pdu_config;
requestStruct.mem_id = P60PDU_PARAM;
uint8_t hk_mem[P60PDU_PARAM_SIZE];
requestStruct.count = p60pdu_config_count;
requestStruct.size = P60PDU_PARAM_SIZE;
requestStruct.physaddr = hk_mem;
int result = rparam_get_full_table(&requestStruct, p60pdu_node, P60_PORT_RPARAM,
requestStruct.mem_id, 1000);
param_list(&requestStruct, 1);
return (result == 0);
}
// testJsonLibDirect();
// testDummyParams();
if (doTestProtHandler) {

View File

@ -16,6 +16,8 @@ class Q7STestTask : public TestTask {
private:
bool doTestSdCard = false;
bool doTestScratchApi = false;
static constexpr bool DO_TEST_GOMSPACE_API = false;
static constexpr bool DO_TEST_GOMSPACE_GET_CONFIG = false;
bool doTestGpsShm = false;
bool doTestGpsSocket = false;
bool doTestProtHandler = false;

View File

@ -20,7 +20,6 @@
#include "linux/boardtest/UartTestClass.h"
#include "linux/callbacks/gpioCallbacks.h"
#include "linux/csp/CspComIF.h"
#include "linux/csp/CspCookie.h"
#include "linux/devices/GPSHyperionLinuxController.h"
#include "linux/devices/devicedefinitions/PlocMPSoCDefinitions.h"
#include "linux/devices/devicedefinitions/StarTrackerDefinitions.h"
@ -35,6 +34,7 @@
#include "linux/obc/PdecHandler.h"
#include "linux/obc/Ptme.h"
#include "linux/obc/PtmeConfig.h"
#include "mission/csp/CspCookie.h"
#include "mission/system/RwAssembly.h"
#include "mission/system/fdir/AcsBoardFdir.h"
#include "mission/system/fdir/GomspacePowerFdir.h"
@ -158,10 +158,10 @@ void ObjectFactory::createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, Ua
}
void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF** pwrSwitcher) {
CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH, addresses::P60DOCK);
CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU1);
CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU2);
CspCookie* acuCspCookie = new CspCookie(ACU::MAX_REPLY_LENGTH, addresses::ACU);
CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_SIZE, addresses::P60DOCK, 500);
CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_SIZE, addresses::PDU1, 500);
CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_SIZE, addresses::PDU2, 500);
CspCookie* acuCspCookie = new CspCookie(ACU::MAX_REPLY_SIZE, addresses::ACU, 500);
auto p60Fdir = new GomspacePowerFdir(objects::P60DOCK_HANDLER);
P60DockHandler* p60dockhandler =

View File

@ -46,20 +46,15 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
static constexpr ReturnValue_t OP_ONGOING = returnvalue::makeCode(INTERFACE_ID, 0);
static constexpr ReturnValue_t ALREADY_ON = returnvalue::makeCode(INTERFACE_ID, 1);
static constexpr ReturnValue_t ALREADY_MOUNTED =
returnvalue::makeCode(INTERFACE_ID, 2);
static constexpr ReturnValue_t ALREADY_MOUNTED = returnvalue::makeCode(INTERFACE_ID, 2);
static constexpr ReturnValue_t ALREADY_OFF = returnvalue::makeCode(INTERFACE_ID, 3);
static constexpr ReturnValue_t STATUS_FILE_NEXISTS =
returnvalue::makeCode(INTERFACE_ID, 10);
static constexpr ReturnValue_t STATUS_FILE_NEXISTS = returnvalue::makeCode(INTERFACE_ID, 10);
static constexpr ReturnValue_t STATUS_FILE_FORMAT_INVALID =
returnvalue::makeCode(INTERFACE_ID, 11);
static constexpr ReturnValue_t MOUNT_ERROR = returnvalue::makeCode(INTERFACE_ID, 12);
static constexpr ReturnValue_t UNMOUNT_ERROR =
returnvalue::makeCode(INTERFACE_ID, 13);
static constexpr ReturnValue_t SYSTEM_CALL_ERROR =
returnvalue::makeCode(INTERFACE_ID, 14);
static constexpr ReturnValue_t POPEN_CALL_ERROR =
returnvalue::makeCode(INTERFACE_ID, 15);
static constexpr ReturnValue_t UNMOUNT_ERROR = returnvalue::makeCode(INTERFACE_ID, 13);
static constexpr ReturnValue_t SYSTEM_CALL_ERROR = returnvalue::makeCode(INTERFACE_ID, 14);
static constexpr ReturnValue_t POPEN_CALL_ERROR = returnvalue::makeCode(INTERFACE_ID, 15);
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FILE_SYSTEM;

View File

@ -37,6 +37,6 @@ uint32_t AcuDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return
ReturnValue_t AcuDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(P60System::pool::ACU_TEMPERATURES, new PoolEntry<float>(3));
localDataPoolMap.emplace(ACU::pool::ACU_TEMPERATURES, new PoolEntry<float>(3));
return returnvalue::OK;
}

View File

@ -40,7 +40,7 @@ uint32_t P60DockDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { re
ReturnValue_t P60DockDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(P60System::pool::P60DOCK_TEMPERATURE_1, new PoolEntry<float>({0}));
localDataPoolMap.emplace(P60System::pool::P60DOCK_TEMPERATURE_2, new PoolEntry<float>({0}));
localDataPoolMap.emplace(P60Dock::pool::P60DOCK_TEMPERATURE_1, new PoolEntry<float>({0}));
localDataPoolMap.emplace(P60Dock::pool::P60DOCK_TEMPERATURE_2, new PoolEntry<float>({0}));
return returnvalue::OK;
}

View File

@ -37,6 +37,6 @@ uint32_t PduDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return
ReturnValue_t PduDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(P60System::pool::PDU_TEMPERATURE, new PoolEntry<float>({0}));
localDataPoolMap.emplace(PDU::pool::PDU_TEMPERATURE, new PoolEntry<float>({0}));
return returnvalue::OK;
}

View File

@ -33,7 +33,9 @@ ReturnValue_t SusDummy::initialize() {
return returnvalue::OK;
}
ReturnValue_t SusDummy::handleCommandMessage(CommandMessage* message) { return returnvalue::FAILED; }
ReturnValue_t SusDummy::handleCommandMessage(CommandMessage* message) {
return returnvalue::FAILED;
}
void SusDummy::performControlOperation() {
iteration++;

2
fsfw

@ -1 +1 @@
Subproject commit f5866ddacee6cd0f381fb1a69f1d0cf22b5b310a
Subproject commit 141dcb1f149b824b5bd6e5d3339ecb712835751e

View File

@ -1 +1 @@
target_sources(${OBSW_NAME} PUBLIC CspComIF.cpp CspCookie.cpp)
target_sources(${OBSW_NAME} PUBLIC CspComIF.cpp)

View File

@ -3,8 +3,16 @@
#include <csp/drivers/can_socketcan.h>
#include <fsfw/serialize/SerializeAdapter.h>
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
#include <p60acu.h>
#include <p60dock.h>
#include <p60pdu.h>
#include <param/param_string.h>
#include <param/rparam_client.h>
#include "CspCookie.h"
#include "mission/csp/CspCookie.h"
using namespace GOMSPACE;
CspComIF::CspComIF(object_id_t objectId) : SystemObject(objectId) {}
@ -63,48 +71,111 @@ ReturnValue_t CspComIF::initializeInterface(CookieIF* cookie) {
uint16_t maxReplyLength = cspCookie->getMaxReplyLength();
if (cspDeviceMap.find(cspAddress) == cspDeviceMap.end()) {
/* Insert device information in CSP map */
cspDeviceMap.emplace(cspAddress, vectorBuffer(maxReplyLength));
cspDeviceMap.emplace(cspAddress, ReplyInfo(maxReplyLength));
}
return returnvalue::OK;
}
ReturnValue_t CspComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) {
int result;
if (cookie == NULL) {
if (cookie == nullptr) {
return returnvalue::FAILED;
}
CspCookie* cspCookie = dynamic_cast<CspCookie*>(cookie);
if (cspCookie == NULL) {
if (cspCookie == nullptr) {
return returnvalue::FAILED;
}
/* Extract csp port and bytes to query from command buffer */
uint8_t cspPort;
uint16_t querySize = 0;
if (cspCookie->getRequest() == GOMSPACE::SpecialRequestTypes::DEFAULT_COM_IF) {
/* Extract csp port and bytes to query from command buffer */
result = getPortAndQuerySize(&sendData, &sendLen, &cspPort, &querySize);
if (result != returnvalue::OK) {
return result;
}
} else {
cspPort = cspCookie->getCspPort();
querySize = cspCookie->getReplyLen();
}
if (querySize > cspCookie->getMaxReplyLength()) {
sif::error << "Query size " << querySize << " is larger than maximum allowed "
<< cspCookie->getMaxReplyLength() << std::endl;
return returnvalue::FAILED;
}
uint8_t cspAddress = cspCookie->getCspAddress();
auto iter = cspDeviceMap.find(cspAddress);
if (iter == cspDeviceMap.end()) {
return returnvalue::FAILED;
}
switch (cspPort) {
case (Ports::CSP_PING): {
case (CspPorts::CSP_PING): {
initiatePingRequest(cspAddress, querySize);
break;
}
case (Ports::CSP_REBOOT): {
case (CspPorts::CSP_REBOOT): {
csp_reboot(cspAddress);
break;
}
case (Ports::P60_PORT_GNDWDT_RESET):
case (Ports::P60_PORT_RPARAM): {
case (CspPorts::P60_PORT_GNDWDT_RESET_ENUM):
case (CspPorts::P60_PORT_RPARAM_ENUM): {
if (cspCookie->getRequest() != SpecialRequestTypes::DEFAULT_COM_IF) {
param_index_t requestStruct{};
requestStruct.physaddr = iter->second.replyBuf.data();
auto req = cspCookie->getRequest();
if (req == GOMSPACE::SpecialRequestTypes::GET_PDU_HK) {
if (!p60pdu_get_hk(&requestStruct, cspAddress, cspCookie->getTimeout())) {
return returnvalue::FAILED;
}
} else if (req == GOMSPACE::SpecialRequestTypes::GET_ACU_HK) {
if (!p60acu_get_hk(&requestStruct, cspAddress, cspCookie->getTimeout())) {
return returnvalue::FAILED;
}
} else if (req == GOMSPACE::SpecialRequestTypes::GET_P60DOCK_HK) {
if (!p60dock_get_hk(&requestStruct, cspAddress, cspCookie->getTimeout())) {
return returnvalue::FAILED;
}
} else if (req == GOMSPACE::SpecialRequestTypes::GET_PDU_CONFIG) {
requestStruct.table = p60pdu_config;
requestStruct.mem_id = P60PDU_PARAM;
requestStruct.count = p60pdu_config_count;
requestStruct.size = P60PDU_PARAM_SIZE;
int result = rparam_get_full_table(&requestStruct, cspAddress, P60_PORT_RPARAM,
requestStruct.mem_id, cspCookie->getTimeout());
if (result != 0) {
return returnvalue::FAILED;
}
} else if (req == GOMSPACE::SpecialRequestTypes::GET_ACU_CONFIG) {
requestStruct.table = p60acu_config;
requestStruct.mem_id = P60ACU_PARAM;
requestStruct.count = p60acu_config_count;
requestStruct.size = P60ACU_PARAM_SIZE;
int result = rparam_get_full_table(&requestStruct, cspAddress, P60_PORT_RPARAM,
requestStruct.mem_id, cspCookie->getTimeout());
if (result != 0) {
return returnvalue::FAILED;
}
} else if (req == GOMSPACE::SpecialRequestTypes::GET_P60DOCK_CONFIG) {
requestStruct.table = p60dock_config;
requestStruct.mem_id = P60DOCK_PARAM;
requestStruct.count = p60dock_config_count;
requestStruct.size = P60DOCK_PARAM_SIZE;
int result = rparam_get_full_table(&requestStruct, cspAddress, P60_PORT_RPARAM,
requestStruct.mem_id, cspCookie->getTimeout());
if (result != 0) {
return returnvalue::FAILED;
}
}
} else {
/* No CSP fixed port was selected. Send data to the specified port and
* wait for querySize number of bytes */
result = cspTransfer(cspAddress, cspPort, sendData, sendLen, querySize);
if (result != returnvalue::OK) {
return returnvalue::FAILED;
}
replySize = querySize;
}
iter->second.replyLen = querySize;
break;
}
default:
@ -130,9 +201,12 @@ ReturnValue_t CspComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
}
uint8_t cspAddress = cspCookie->getCspAddress();
*buffer = cspDeviceMap[cspAddress].data();
*size = replySize;
auto iter = cspDeviceMap.find(cspAddress);
if (iter == cspDeviceMap.end()) {
return returnvalue::FAILED;
}
*buffer = iter->second.replyBuf.data();
*size = iter->second.replyLen;
return returnvalue::OK;
}
@ -142,13 +216,13 @@ ReturnValue_t CspComIF::cspTransfer(uint8_t cspAddress, uint8_t cspPort, const u
uint32_t timeout_ms = 1000;
uint16_t bytesRead = 0;
int32_t expectedSize = static_cast<int32_t>(querySize);
vectorBufferIter iter = cspDeviceMap.find(cspAddress);
auto iter = cspDeviceMap.find(cspAddress);
if (iter == cspDeviceMap.end()) {
sif::error << "CSP device with address " << cspAddress << " no found in"
<< " device map" << std::endl;
return returnvalue::FAILED;
}
uint8_t* replyBuffer = iter->second.data();
uint8_t* replyBuffer = iter->second.replyBuf.data();
csp_conn_t* conn = csp_connect(CSP_PRIO_HIGH, cspAddress, cspPort, 0, CSP_O_NONE);
@ -193,7 +267,7 @@ ReturnValue_t CspComIF::cspTransfer(uint8_t cspAddress, uint8_t cspPort, const u
csp_close(conn);
return returnvalue::FAILED;
}
if ((reply->length + bytesRead) > iter->second.size()) {
if ((reply->length + bytesRead) > iter->second.replyBuf.size()) {
sif::error << "CspComIF::cspTransfer: Reply buffer to short" << std::endl;
csp_buffer_free(reply);
csp_close(conn);
@ -240,8 +314,12 @@ void CspComIF::initiatePingRequest(uint8_t cspAddress, uint16_t querySize) {
uint32_t replyTime = csp_ping(cspAddress, timeout_ms, querySize, CSP_O_NONE);
sif::info << "Ping address: " << cspAddress << ", reply after " << replyTime << " ms"
<< std::endl;
/* Store reply time in reply buffer * */
uint8_t* replyBuffer = cspDeviceMap[cspAddress].data();
memcpy(replyBuffer, &replyTime, sizeof(replyTime));
replySize = sizeof(replyTime);
auto iter = cspDeviceMap.find(cspAddress);
if (iter == cspDeviceMap.end()) {
return;
}
/* Store reply time in reply buffer * */
uint8_t* replyBuffer = iter->second.replyBuf.data();
memcpy(replyBuffer, &replyTime, sizeof(replyTime));
iter->second.replyLen = sizeof(replyTime);
}

View File

@ -42,24 +42,22 @@ class CspComIF : public DeviceCommunicationIF, public SystemObject {
ReturnValue_t cspTransfer(uint8_t cspAddress, uint8_t cspPort, const uint8_t *cmdBuffer,
int cmdLen, uint16_t querySize);
enum Ports { CSP_PING = 1, CSP_REBOOT = 4, P60_PORT_RPARAM = 7, P60_PORT_GNDWDT_RESET = 9 };
typedef uint8_t node_t;
using vectorBuffer = std::vector<uint8_t>;
using VectorBufferMap = std::unordered_map<node_t, vectorBuffer>;
using vectorBufferIter = VectorBufferMap::iterator;
struct ReplyInfo {
ReplyInfo(size_t maxLen) : replyBuf(maxLen){};
std::vector<uint8_t> replyBuf;
size_t replyLen = 0;
};
using VectorBufferMap = std::unordered_map<node_t, ReplyInfo>;
/* In this map assigns reply buffers to a CSP device */
VectorBufferMap cspDeviceMap;
uint16_t replySize = 0;
/* This is the CSP address of the OBC. */
node_t cspOwnAddress = 1;
/* Interface struct for csp protocol stack */
csp_iface_t csp_if;
char canInterface[5] = "can0";
int bitrate = 1000;

View File

@ -1,10 +0,0 @@
#include "CspCookie.h"
CspCookie::CspCookie(uint16_t maxReplyLength_, uint8_t cspAddress_)
: maxReplyLength(maxReplyLength_), cspAddress(cspAddress_) {}
CspCookie::~CspCookie() {}
uint16_t CspCookie::getMaxReplyLength() { return maxReplyLength; }
uint8_t CspCookie::getCspAddress() { return cspAddress; }

View File

@ -1,26 +0,0 @@
#ifndef LINUX_CSP_CSPCOOKIE_H_
#define LINUX_CSP_CSPCOOKIE_H_
#include <fsfw/devicehandlers/CookieIF.h>
#include <cstdint>
/**
* @brief This is the cookie for devices supporting the CSP (CubeSat Space
* Protocol).
* @author J. Meier
*/
class CspCookie : public CookieIF {
public:
CspCookie(uint16_t maxReplyLength_, uint8_t cspAddress_);
virtual ~CspCookie();
uint16_t getMaxReplyLength();
uint8_t getCspAddress();
private:
uint16_t maxReplyLength;
uint8_t cspAddress;
};
#endif /* LINUX_CSP_CSPCOOKIE_H_ */

View File

@ -87,7 +87,7 @@ ReturnValue_t GPSHyperionLinuxController::initializeLocalDataPool(
localDataPoolMap.emplace(GpsHyperion::SATS_IN_USE, new PoolEntry<uint8_t>());
localDataPoolMap.emplace(GpsHyperion::SATS_IN_VIEW, new PoolEntry<uint8_t>());
localDataPoolMap.emplace(GpsHyperion::FIX_MODE, new PoolEntry<uint8_t>());
poolManager.subscribeForRegularPeriodicPacket({gpsSet.getSid(), 30.0});
poolManager.subscribeForRegularPeriodicPacket({gpsSet.getSid(), false, 30.0});
return returnvalue::OK;
}

View File

@ -311,6 +311,9 @@ ReturnValue_t Max31865RtdReader::readReceivedMessage(CookieIF* cookie, uint8_t**
return returnvalue::FAILED;
}
auto* rtdCookie = dynamic_cast<Max31865ReaderCookie*>(cookie);
if (rtdCookie == nullptr) {
return returnvalue::FAILED;
}
uint8_t* exchangePtr = rtdCookie->exchangeBuf.data();
size_t serLen = 0;
auto result = rtdCookie->db.serialize(&exchangePtr, &serLen, rtdCookie->exchangeBuf.size(),

View File

@ -458,8 +458,7 @@ class TcReplayStart : public TcBase {
static const uint8_t ONCE = 1;
ReturnValue_t lengthCheck(size_t commandDataLen) {
if (commandDataLen != COMMAND_DATA_LENGTH or
checkPayloadLen() != returnvalue::OK) {
if (commandDataLen != COMMAND_DATA_LENGTH or checkPayloadLen() != returnvalue::OK) {
sif::warning << "TcReplayStart: Command has invalid length " << commandDataLen << std::endl;
return INVALID_LENGTH;
}

View File

@ -417,6 +417,9 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(DeviceCommandId_t d
break;
}
case LOGGING_SET_TOPIC: {
if (commandData == nullptr or commandDataLen == 0) {
return HasActionsIF::INVALID_PARAMETERS;
}
uint8_t tpc = *(commandData);
RequestLoggingData packet(spParams);
result = packet.buildPacket(RequestLoggingData::Sa::SET_LOGGING_TOPIC, tpc);

View File

@ -1830,7 +1830,7 @@ ReturnValue_t StarTrackerHandler::handleChecksumReply() {
}
PoolReadGuard rg(&checksumSet);
checksumSet.checksum = checksumReply.getChecksum();
handleDeviceTM(&checksumSet, startracker::CHECKSUM);
handleDeviceTm(util::DataWrapper(checksumSet), startracker::CHECKSUM);
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1
checksumReply.printChecksum();
#endif /* OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_STARTRACKER == 1 */

View File

@ -323,7 +323,8 @@ class StrHelper : public SystemObject, public ExecutableObjectIF {
*
* @param expectedPosition Value of expected position
*
* @return returnvalue::OK if received position matches expected position, otherwise returnvalue::FAILED
* @return returnvalue::OK if received position matches expected position, otherwise
* returnvalue::FAILED
*/
ReturnValue_t checkReplyPosition(uint32_t expectedPosition);

View File

@ -31,9 +31,7 @@
*
* @author J. Meier
*/
class PdecHandler : public SystemObject,
public ExecutableObjectIF,
public HasActionsIF {
class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasActionsIF {
public:
/**
* @brief Constructor

View File

@ -5,3 +5,4 @@ add_subdirectory(utility)
add_subdirectory(memory)
add_subdirectory(tmtc)
add_subdirectory(system)
add_subdirectory(csp)

View File

@ -45,7 +45,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_3_RM3100_UT, &mgm3PoolVec);
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_NT, &imtqMgmPoolVec);
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_ACT_STATUS, &imtqCalActStatus);
poolManager.subscribeForRegularPeriodicPacket({mgmData.getSid(), 5.0});
poolManager.subscribeForRegularPeriodicPacket({mgmData.getSid(), false, 5.0});
return returnvalue::OK;
}

View File

@ -699,7 +699,7 @@ void ThermalController::copyDevices() {
sif::warning << "ThermalController: Failed to commit" << std::endl;
}
lp_vec_t<float, 3> tempAcu =
lp_vec_t<float, 3>(objects::ACU_HANDLER, P60System::pool::ACU_TEMPERATURES);
lp_vec_t<float, 3>(objects::ACU_HANDLER, ACU::pool::ACU_TEMPERATURES);
result = tempAcu.read();
if (result != returnvalue::OK) {
sif::warning << "ThermalController: Failed to read ACU temperatures" << std::endl;
@ -715,8 +715,7 @@ void ThermalController::copyDevices() {
if (result != returnvalue::OK) {
sif::warning << "ThermalController: Failed to commit" << std::endl;
}
lp_var_t<float> tempPdu1 =
lp_var_t<float>(objects::PDU1_HANDLER, P60System::pool::PDU_TEMPERATURE);
lp_var_t<float> tempPdu1 = lp_var_t<float>(objects::PDU1_HANDLER, PDU::pool::PDU_TEMPERATURE);
result = tempPdu1.read();
if (result != returnvalue::OK) {
sif::warning << "ThermalController: Failed to read PDU1 temperature" << std::endl;
@ -730,8 +729,7 @@ void ThermalController::copyDevices() {
if (result != returnvalue::OK) {
sif::warning << "ThermalController: Failed to commit" << std::endl;
}
lp_var_t<float> tempPdu2 =
lp_var_t<float>(objects::PDU2_HANDLER, P60System::pool::PDU_TEMPERATURE);
lp_var_t<float> tempPdu2 = lp_var_t<float>(objects::PDU2_HANDLER, PDU::pool::PDU_TEMPERATURE);
result = tempPdu2.read();
if (result != returnvalue::OK) {
sif::warning << "ThermalController: Failed to read PDU2 temperature" << std::endl;
@ -746,7 +744,7 @@ void ThermalController::copyDevices() {
sif::warning << "ThermalController: Failed to commit" << std::endl;
}
lp_var_t<float> temp1P60dock =
lp_var_t<float>(objects::P60DOCK_HANDLER, P60System::pool::P60DOCK_TEMPERATURE_1);
lp_var_t<float>(objects::P60DOCK_HANDLER, P60Dock::pool::P60DOCK_TEMPERATURE_1);
result = temp1P60dock.read();
if (result != returnvalue::OK) {
sif::warning << "ThermalController: Failed to read P60 dock temperature 1" << std::endl;
@ -761,7 +759,7 @@ void ThermalController::copyDevices() {
sif::warning << "ThermalController: Failed to commit" << std::endl;
}
lp_var_t<float> temp2P60dock =
lp_var_t<float>(objects::P60DOCK_HANDLER, P60System::pool::P60DOCK_TEMPERATURE_2);
lp_var_t<float>(objects::P60DOCK_HANDLER, P60Dock::pool::P60DOCK_TEMPERATURE_2);
result = temp2P60dock.read();
if (result != returnvalue::OK) {
sif::warning << "ThermalController: Failed to read P60 dock temperature 2" << std::endl;

View File

@ -0,0 +1 @@
target_sources(${LIB_EIVE_MISSION} PRIVATE CspCookie.cpp)

28
mission/csp/CspCookie.cpp Normal file
View File

@ -0,0 +1,28 @@
#include "CspCookie.h"
CspCookie::CspCookie(uint16_t maxReplyLength_, uint8_t cspAddress_, uint32_t timeoutMs)
: maxReplyLength(maxReplyLength_),
cspAddress(cspAddress_),
timeoutMs(timeoutMs),
reqType(GOMSPACE::DEFAULT_COM_IF) {}
CspCookie::~CspCookie() {}
uint16_t CspCookie::getMaxReplyLength() { return maxReplyLength; }
uint8_t CspCookie::getCspAddress() { return cspAddress; }
GOMSPACE::SpecialRequestTypes CspCookie::getRequest() const { return reqType; }
void CspCookie::setRequest(GOMSPACE::SpecialRequestTypes request, size_t replyLen_) {
reqType = request;
replyLen = replyLen_;
}
uint8_t CspCookie::getCspPort() const { return cspPort; }
uint32_t CspCookie::getTimeout() const { return timeoutMs; }
void CspCookie::setCspPort(uint8_t port) { cspPort = port; }
size_t CspCookie::getReplyLen() const { return replyLen; }

39
mission/csp/CspCookie.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef LINUX_CSP_CSPCOOKIE_H_
#define LINUX_CSP_CSPCOOKIE_H_
#include <fsfw/devicehandlers/CookieIF.h>
#include <cstddef>
#include <cstdint>
#include "mission/devices/devicedefinitions/GomspaceDefinitions.h"
/**
* @brief This is the cookie for devices supporting the CSP (CubeSat Space
* Protocol).
* @author J. Meier
*/
class CspCookie : public CookieIF {
public:
CspCookie(uint16_t maxReplyLength_, uint8_t cspAddress_, uint32_t timeoutMs);
virtual ~CspCookie();
void setCspPort(uint8_t port);
uint8_t getCspPort() const;
uint16_t getMaxReplyLength();
GOMSPACE::SpecialRequestTypes getRequest() const;
void setRequest(GOMSPACE::SpecialRequestTypes request, size_t replyLen);
size_t getReplyLen() const;
uint8_t getCspAddress();
uint32_t getTimeout() const;
private:
uint8_t cspPort;
uint16_t maxReplyLength;
uint8_t cspAddress;
size_t replyLen = 0;
uint32_t timeoutMs;
GOMSPACE::SpecialRequestTypes reqType;
};
#endif /* LINUX_CSP_CSPCOOKIE_H_ */

View File

@ -4,16 +4,20 @@
ACUHandler::ACUHandler(object_id_t objectId, object_id_t comIF, CookieIF *comCookie,
FailureIsolationBase *customFdir)
: GomspaceDeviceHandler(objectId, comIF, comCookie, customFdir, ACU::MAX_CONFIGTABLE_ADDRESS,
ACU::MAX_HKTABLE_ADDRESS, ACU::HK_TABLE_REPLY_SIZE),
: GomspaceDeviceHandler(objectId, comIF, comCookie, cfg, customFdir),
coreHk(this),
auxHk(this) {}
auxHk(this) {
cfg.maxConfigTableAddress = ACU::MAX_CONFIGTABLE_ADDRESS;
cfg.maxHkTableAddress = ACU::MAX_HKTABLE_ADDRESS;
cfg.hkTableSize = ACU::HK_TABLE_SIZE;
cfg.cfgTableSize = ACU::CONFIG_TABLE_SIZE;
}
ACUHandler::~ACUHandler() {}
ReturnValue_t ACUHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
*id = GOMSPACE::REQUEST_HK_TABLE;
return buildCommandFromCommand(*id, NULL, 0);
return buildCommandFromCommand(*id, nullptr, 0);
}
void ACUHandler::fillCommandAndReplyMap() { GomspaceDeviceHandler::fillCommandAndReplyMap(); }
@ -38,6 +42,10 @@ void ACUHandler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *pack
}
}
void ACUHandler::letChildHandleConfigReply(DeviceCommandId_t id, const uint8_t *packet) {
handleDeviceTm(util::DataWrapper(packet, ACU::CONFIG_TABLE_SIZE), id);
}
LocalPoolDataSetBase *ACUHandler::getDataSetHandle(sid_t sid) {
if (sid == coreHk.getSid()) {
return &coreHk;
@ -48,7 +56,6 @@ LocalPoolDataSetBase *ACUHandler::getDataSetHandle(sid_t sid) {
}
ReturnValue_t ACUHandler::parseHkTableReply(const uint8_t *packet) {
uint16_t dataOffset = 0;
PoolReadGuard pg0(&coreHk);
PoolReadGuard pg1(&auxHk);
auto res0 = pg0.getReadResult();
@ -59,80 +66,51 @@ ReturnValue_t ACUHandler::parseHkTableReply(const uint8_t *packet) {
if (res1 != returnvalue::OK) {
return res1;
}
dataOffset += 12;
for (size_t idx = 0; idx < 6; idx++) {
coreHk.currentInChannels[idx] = (packet[dataOffset] << 8) | packet[dataOffset + 1];
dataOffset += 4;
coreHk.currentInChannels[idx] = as<int16_t>(packet + (idx * 2));
}
for (size_t idx = 0; idx < 6; idx++) {
coreHk.voltageInChannels[idx] = (packet[dataOffset] << 8) | packet[dataOffset + 1];
dataOffset += 4;
coreHk.voltageInChannels[idx] = as<uint16_t>(packet + 0xc + (idx * 2));
}
coreHk.vcc = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
coreHk.vbat = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
coreHk.vcc = as<uint16_t>(packet + 0x1a);
coreHk.vbat = as<uint16_t>(packet + 0x18);
for (size_t idx = 0; idx < 3; idx++) {
coreHk.temperatures[idx] =
static_cast<int16_t>((packet[dataOffset] << 8) | packet[dataOffset + 1]) * 0.1;
dataOffset += 4;
coreHk.temperatures[idx] = as<int16_t>(packet + 0x1c + (idx * 2)) * 0.1;
}
coreHk.mpptMode = packet[dataOffset];
dataOffset += 3;
coreHk.mpptMode = packet[0x22];
for (size_t idx = 0; idx < 6; idx++) {
coreHk.vboostInChannels[idx] = (packet[dataOffset] << 8) | packet[dataOffset + 1];
dataOffset += 4;
coreHk.vboostInChannels[idx] = as<uint16_t>(packet + 0x24 + (idx * 2));
}
for (size_t idx = 0; idx < 6; idx++) {
coreHk.powerInChannels[idx] = (packet[dataOffset] << 8) | packet[dataOffset + 1];
dataOffset += 4;
coreHk.powerInChannels[idx] = as<uint16_t>(packet + 0x30 + (idx * 2));
}
for (size_t idx = 0; idx < 3; idx++) {
auxHk.dacEnables[idx] = packet[dataOffset];
dataOffset += 3;
auxHk.dacEnables[idx] = *(packet + 0x3c + idx);
}
for (size_t idx = 0; idx < 6; idx++) {
auxHk.dacRawChannelVals[idx] = (packet[dataOffset] << 8) | packet[dataOffset + 1];
dataOffset += 4;
auxHk.dacRawChannelVals[idx] = as<uint16_t>(packet + 0x40 + (idx * 2));
}
auxHk.bootCause = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
coreHk.bootcnt = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
coreHk.uptime = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.resetCause = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
coreHk.mpptTime = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
/* +12 because here starts the second csp packet */
dataOffset += 2 + 12;
coreHk.mpptPeriod = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
auxHk.bootCause = as<uint32_t>(packet + 0x50);
coreHk.bootcnt = as<uint32_t>(packet + 0x54);
coreHk.uptime = as<uint32_t>(packet + 0x58);
auxHk.resetCause = as<uint16_t>(packet + 0x5c);
coreHk.mpptTime = as<uint16_t>(packet + 0x5e);
coreHk.mpptPeriod = as<uint16_t>(packet + 0x60);
for (size_t idx = 0; idx < 8; idx++) {
auxHk.deviceTypes[idx] = packet[dataOffset];
dataOffset += 3;
auxHk.deviceTypes[idx] = *(packet + 0x64 + idx);
}
for (size_t idx = 0; idx < 8; idx++) {
auxHk.devicesStatus[idx] = packet[dataOffset];
dataOffset += 3;
auxHk.devicesStatus[idx] = *(packet + 0x6c + idx);
}
auxHk.wdtCntGnd = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.wdtGndLeft = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.wdtCntGnd = as<uint32_t>(packet + 0x74);
auxHk.wdtGndLeft = as<uint32_t>(packet + 0x78);
coreHk.setValidity(true, true);
auxHk.setValidity(true, true);
return returnvalue::OK;
@ -140,7 +118,7 @@ ReturnValue_t ACUHandler::parseHkTableReply(const uint8_t *packet) {
ReturnValue_t ACUHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
using namespace P60System;
using namespace ACU;
localDataPoolMap.emplace(pool::ACU_CURRENT_IN_CHANNELS, new PoolEntry<int16_t>(6));
localDataPoolMap.emplace(pool::ACU_VOLTAGE_IN_CHANNELS, new PoolEntry<uint16_t>(6));

View File

@ -22,8 +22,8 @@ class ACUHandler : public GomspaceDeviceHandler {
LocalDataPoolManager& poolManager) override;
protected:
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override;
void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override;
void letChildHandleConfigReply(DeviceCommandId_t id, const uint8_t* packet) override;
/**
* @brief As soon as the device is in MODE_NORMAL, this function is executed periodically.
*/
@ -38,6 +38,7 @@ class ACUHandler : public GomspaceDeviceHandler {
private:
ACU::CoreHk coreHk;
ACU::AuxHk auxHk;
TableConfig cfg;
bool debugMode = false;
/**

View File

@ -2,23 +2,31 @@
#include <common/config/commonObjects.h>
#include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/globalfunctions/arrayprinter.h>
#include <cassert>
#include "devicedefinitions/GomSpacePackets.h"
#include "devicedefinitions/powerDefinitions.h"
using namespace GOMSPACE;
GomspaceDeviceHandler::GomspaceDeviceHandler(object_id_t objectId, object_id_t comIF,
CookieIF* comCookie, FailureIsolationBase* customFdir,
uint16_t maxConfigTableAddress,
uint16_t maxHkTableAddress, uint16_t hkTableReplySize)
: DeviceHandlerBase(objectId, comIF, comCookie, customFdir),
maxConfigTableAddress(maxConfigTableAddress),
maxHkTableAddress(maxHkTableAddress),
hkTableReplySize(hkTableReplySize) {
CookieIF* comCookie, TableConfig& tableConfig,
FailureIsolationBase* customFdir)
: DeviceHandlerBase(objectId, comIF, comCookie, customFdir), tableCfg(tableConfig) {
if (comCookie == nullptr) {
sif::error << "GomspaceDeviceHandler::GomspaceDeviceHandler: Invalid com cookie" << std::endl;
}
}
void GomspaceDeviceHandler::initPduConfigTable() {
tableCfg.maxConfigTableAddress = PDU::MAX_CONFIGTABLE_ADDRESS;
tableCfg.maxHkTableAddress = PDU::MAX_HKTABLE_ADDRESS;
tableCfg.hkTableSize = PDU::HK_TABLE_SIZE;
tableCfg.cfgTableSize = PDU::CONFIG_TABLE_SIZE;
}
GomspaceDeviceHandler::~GomspaceDeviceHandler() {}
void GomspaceDeviceHandler::doStartUp() {}
@ -76,7 +84,32 @@ ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand(DeviceCommandId_t d
break;
}
case (GOMSPACE::REQUEST_HK_TABLE): {
result = generateRequestFullHkTableCmd(hkTableReplySize);
auto reqType = SpecialRequestTypes::DEFAULT_COM_IF;
if (getObjectId() == objects::PDU1_HANDLER or getObjectId() == objects::PDU2_HANDLER) {
reqType = SpecialRequestTypes::GET_PDU_HK;
} else if (getObjectId() == objects::ACU_HANDLER) {
reqType = SpecialRequestTypes::GET_ACU_HK;
} else if (getObjectId() == objects::P60DOCK_HANDLER) {
reqType = SpecialRequestTypes::GET_P60DOCK_HK;
}
result = generateRequestFullTableCmd(reqType, GOMSPACE::TableIds::HK, tableCfg.hkTableSize,
deviceCommand);
if (result != returnvalue::OK) {
return result;
}
break;
}
case (GOMSPACE::REQUEST_CONFIG_TABLE): {
auto reqType = SpecialRequestTypes::DEFAULT_COM_IF;
if (getObjectId() == objects::PDU1_HANDLER or getObjectId() == objects::PDU2_HANDLER) {
reqType = SpecialRequestTypes::GET_PDU_CONFIG;
} else if (getObjectId() == objects::ACU_HANDLER) {
reqType = SpecialRequestTypes::GET_ACU_CONFIG;
} else if (getObjectId() == objects::P60DOCK_HANDLER) {
reqType = SpecialRequestTypes::GET_P60DOCK_CONFIG;
}
result = generateRequestFullTableCmd(reqType, GOMSPACE::TableIds::CONFIG,
tableCfg.cfgTableSize, deviceCommand);
if (result != returnvalue::OK) {
return result;
}
@ -94,6 +127,7 @@ void GomspaceDeviceHandler::fillCommandAndReplyMap() {
this->insertInCommandAndReplyMap(GOMSPACE::PARAM_SET, 3);
this->insertInCommandAndReplyMap(GOMSPACE::PARAM_GET, 3);
this->insertInCommandAndReplyMap(GOMSPACE::REQUEST_HK_TABLE, 3);
this->insertInCommandAndReplyMap(GOMSPACE::REQUEST_CONFIG_TABLE, 3);
this->insertInCommandMap(GOMSPACE::GNDWDT_RESET);
this->insertInCommandMap(GOMSPACE::PRINT_SWITCH_V_I);
this->insertInCommandMap(GOMSPACE::PRINT_LATCHUPS);
@ -119,9 +153,16 @@ ReturnValue_t GomspaceDeviceHandler::scanForReply(const uint8_t* start, size_t r
rememberCommandId = GOMSPACE::NONE;
break;
}
case (GOMSPACE::REQUEST_HK_TABLE): {
*foundId = GOMSPACE::REQUEST_HK_TABLE;
*foundLen = rememberRequestedSize + GOMSPACE::GS_HDR_LENGTH;
case (GOMSPACE::REQUEST_HK_TABLE):
case (GOMSPACE::REQUEST_CONFIG_TABLE): {
if (remainingSize < rememberRequestedSize) {
sif::error << "GomspaceDeviceHandler::scanForReply: Table reply, received data smaller "
"than expected "
<< rememberRequestedSize << std::endl;
return returnvalue::FAILED;
}
*foundId = rememberCommandId;
*foundLen = rememberRequestedSize;
rememberCommandId = GOMSPACE::NONE;
break;
}
@ -136,7 +177,9 @@ ReturnValue_t GomspaceDeviceHandler::interpretDeviceReply(DeviceCommandId_t id,
switch (id) {
case (GOMSPACE::PING): {
SerializeElement<uint32_t> replyTime = *packet;
handleDeviceTM(&replyTime, id, true);
util::DataWrapper wrapper;
wrapper.setSerializable(replyTime);
handleDeviceTm(wrapper, id, true);
break;
}
case (GOMSPACE::PARAM_GET): {
@ -163,7 +206,7 @@ ReturnValue_t GomspaceDeviceHandler::interpretDeviceReply(DeviceCommandId_t id,
uint16_t address = cspGetParamReply.getAddress();
/* Pack relevant information into a tm packet */
ParamReply paramReply(action, tableId, address, payloadLength, tempPayloadBuffer);
handleDeviceTM(&paramReply, id, true);
handleDeviceTm(util::DataWrapper(paramReply), id, true);
break;
}
case (GOMSPACE::PARAM_SET): {
@ -179,6 +222,10 @@ ReturnValue_t GomspaceDeviceHandler::interpretDeviceReply(DeviceCommandId_t id,
letChildHandleHkReply(id, packet);
break;
}
case (GOMSPACE::REQUEST_CONFIG_TABLE): {
letChildHandleConfigReply(id, packet);
break;
}
default:
break;
}
@ -209,14 +256,11 @@ ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* comm
}
/* Get and check address */
uint16_t address = setParamCacher.getAddress();
if (address > maxConfigTableAddress) {
if (address > tableCfg.maxConfigTableAddress) {
sif::error << "GomspaceDeviceHandler: Invalid address for set parameter "
<< "action" << std::endl;
return INVALID_ADDRESS;
}
uint16_t checksum = GOMSPACE::IGNORE_CHECKSUM;
uint16_t seq = 0;
uint16_t total = 0;
/* CSP reply only contains the transaction state */
uint16_t querySize = 1;
const uint8_t* parameterPtr = setParamCacher.getParameter();
@ -224,8 +268,7 @@ ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* comm
uint16_t payloadlength = sizeof(address) + parameterSize;
/* Generate command for CspComIF */
CspSetParamCommand setParamCmd(querySize, payloadlength, checksum, seq, total, address,
parameterPtr, parameterSize);
CspSetParamCommand setParamCmd(querySize, payloadlength, address, parameterPtr, parameterSize);
size_t cspPacketLen = 0;
uint8_t* buffer = cspPacket;
result = setParamCmd.serialize(&buffer, &cspPacketLen, sizeof(cspPacket),
@ -263,7 +306,7 @@ ReturnValue_t GomspaceDeviceHandler::generateGetParamCommand(const uint8_t* comm
}
/* Get an check table id to read from */
uint8_t tableId = getParamMessage.getTableId();
if (tableId != CONFIG_TABLE_ID && tableId != HK_TABLE_ID) {
if (not validTableId(tableId)) {
sif::error << "GomspaceDeviceHandler: Invalid table id in get parameter"
" message"
<< std::endl;
@ -271,20 +314,17 @@ ReturnValue_t GomspaceDeviceHandler::generateGetParamCommand(const uint8_t* comm
}
/* Get and check address */
uint16_t address = getParamMessage.getAddress();
if (address > maxHkTableAddress && tableId == HK_TABLE_ID) {
if (address > tableCfg.maxHkTableAddress and tableId == TableIds::HK) {
sif::error << "GomspaceDeviceHandler: Invalid address to get parameter from "
<< "housekeeping table" << std::endl;
return INVALID_ADDRESS;
}
if (address > maxConfigTableAddress && tableId == CONFIG_TABLE_ID) {
if (address > tableCfg.maxConfigTableAddress and tableId == TableIds::CONFIG) {
sif::error << "GomspaceDeviceHandler: Invalid address to get parameter from "
<< "configuration table" << std::endl;
return INVALID_ADDRESS;
}
uint16_t length = sizeof(address);
uint16_t checksum = GOMSPACE::IGNORE_CHECKSUM;
uint16_t seq = 0;
uint16_t total = 0;
uint8_t parameterSize = getParamMessage.getParameterSize();
if (parameterSize > sizeof(uint32_t)) {
sif::error << "GomspaceDeviceHandler: GET_PARAM: Invalid parameter "
@ -294,7 +334,7 @@ ReturnValue_t GomspaceDeviceHandler::generateGetParamCommand(const uint8_t* comm
uint16_t querySize = parameterSize + GOMSPACE::GS_HDR_LENGTH;
/* Generate the CSP command to send to the P60 Dock */
CspGetParamCommand getParamCmd(querySize, tableId, length, checksum, seq, total, address);
CspGetParamCommand getParamCmd(querySize, tableId, length, address);
size_t cspPacketLen = 0;
uint8_t* buffer = cspPacket;
result = getParamCmd.serialize(&buffer, &cspPacketLen, sizeof(cspPacket),
@ -361,41 +401,50 @@ ReturnValue_t GomspaceDeviceHandler::setParamCallback(SetParamMessageUnpacker& u
ReturnValue_t GomspaceDeviceHandler::initializePduPool(
localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager,
std::array<uint8_t, PDU::CHANNELS_LEN> initOutEnb) {
localDataPoolMap.emplace(P60System::pool::PDU_CURRENTS, new PoolEntry<int16_t>(9));
localDataPoolMap.emplace(P60System::pool::PDU_VOLTAGES, new PoolEntry<int16_t>(9));
using namespace PDU;
localDataPoolMap.emplace(pool::PDU_CURRENTS, new PoolEntry<int16_t>(9));
localDataPoolMap.emplace(pool::PDU_VOLTAGES, new PoolEntry<int16_t>(9));
localDataPoolMap.emplace(P60System::pool::PDU_VCC, new PoolEntry<int16_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_VBAT, new PoolEntry<int16_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_TEMPERATURE, new PoolEntry<float>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_CONV_EN, new PoolEntry<uint8_t>(3));
localDataPoolMap.emplace(pool::PDU_VCC, new PoolEntry<int16_t>({0}));
localDataPoolMap.emplace(pool::PDU_VBAT, new PoolEntry<int16_t>({0}));
localDataPoolMap.emplace(pool::PDU_TEMPERATURE, new PoolEntry<float>({0}));
localDataPoolMap.emplace(pool::PDU_CONV_EN, new PoolEntry<uint8_t>(3));
localDataPoolMap.emplace(P60System::pool::PDU_OUT_ENABLE,
localDataPoolMap.emplace(pool::PDU_OUT_ENABLE,
new PoolEntry<uint8_t>(initOutEnb.data(), initOutEnb.size()));
localDataPoolMap.emplace(P60System::pool::PDU_BOOTCAUSE, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_BOOTCNT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_UPTIME, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_RESETCAUSE, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_BATT_MODE, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(pool::PDU_BOOTCAUSE, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_BOOTCNT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_UPTIME, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_RESETCAUSE, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(pool::PDU_BATT_MODE, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_LATCHUPS, new PoolEntry<uint16_t>(9));
localDataPoolMap.emplace(pool::PDU_LATCHUPS, new PoolEntry<uint16_t>(9));
localDataPoolMap.emplace(P60System::pool::PDU_DEVICES, new PoolEntry<uint8_t>(8));
localDataPoolMap.emplace(P60System::pool::PDU_STATUSES, new PoolEntry<uint8_t>(8));
localDataPoolMap.emplace(pool::PDU_DEVICES, new PoolEntry<uint8_t>(8));
localDataPoolMap.emplace(pool::PDU_STATUSES, new PoolEntry<uint8_t>(8));
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CNT_GND, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CNT_I2C, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CNT_CAN, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CNT_CSP1, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CNT_CSP2, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_WDT_GND_LEFT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_WDT_I2C_LEFT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CAN_LEFT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CSP_LEFT1, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(P60System::pool::PDU_WDT_CSP_LEFT2, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_CNT_GND, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_CNT_I2C, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_CNT_CAN, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_CNT_CSP1, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_CNT_CSP2, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_GND_LEFT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_I2C_LEFT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_CAN_LEFT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_CSP_LEFT1, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(pool::PDU_WDT_CSP_LEFT2, new PoolEntry<uint8_t>({0}));
return returnvalue::OK;
}
bool GomspaceDeviceHandler::validTableId(uint8_t id) {
if (id == TableIds::CONFIG or id == TableIds::BOARD_PARAMS or id == TableIds::CALIBRATION or
id == TableIds::HK) {
return true;
}
return false;
}
ReturnValue_t GomspaceDeviceHandler::generateResetWatchdogCmd() {
WatchdogResetCommand watchdogResetCommand;
size_t cspPacketLen = 0;
@ -415,25 +464,20 @@ ReturnValue_t GomspaceDeviceHandler::generateResetWatchdogCmd() {
return returnvalue::OK;
}
ReturnValue_t GomspaceDeviceHandler::generateRequestFullHkTableCmd(uint16_t hkTableReplySize) {
uint16_t querySize = hkTableReplySize;
uint8_t tableId = HK_TABLE_ID;
RequestFullTableCommand requestFullTableCommand(querySize, tableId);
size_t cspPacketLen = 0;
uint8_t* buffer = cspPacket;
ReturnValue_t result = requestFullTableCommand.serialize(
&buffer, &cspPacketLen, sizeof(cspPacket), SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) {
sif::error << "GomspaceDeviceHandler::generateRequestFullHkTableCmd Failed to serialize "
"full table request command "
<< std::endl;
return result;
ReturnValue_t GomspaceDeviceHandler::generateRequestFullTableCmd(SpecialRequestTypes reqType,
uint8_t tableId,
uint16_t tableReplySize,
DeviceCommandId_t id) {
uint16_t querySize = tableReplySize;
if (reqType == SpecialRequestTypes::DEFAULT_COM_IF) {
sif::warning << "Default communication for table requests not implemented anymore" << std::endl;
return returnvalue::FAILED;
}
rawPacket = cspPacket;
rawPacketLen = cspPacketLen;
auto* cspCookie = dynamic_cast<CspCookie*>(comCookie);
cspCookie->setRequest(reqType, tableReplySize);
cspCookie->setCspPort(CspPorts::P60_PORT_RPARAM_ENUM);
rememberRequestedSize = querySize;
rememberCommandId = GOMSPACE::REQUEST_HK_TABLE;
rememberCommandId = id;
return returnvalue::OK;
}
@ -448,102 +492,59 @@ ReturnValue_t GomspaceDeviceHandler::printStatus(DeviceCommandId_t cmd) {
ReturnValue_t GomspaceDeviceHandler::parsePduHkTable(PDU::PduCoreHk& coreHk, PDU::PduAuxHk& auxHk,
const uint8_t* packet) {
uint16_t dataOffset = 0;
PoolReadGuard pg0(&coreHk);
PoolReadGuard pg1(&auxHk);
if (pg0.getReadResult() != returnvalue::OK or
pg1.getReadResult() != returnvalue::OK) {
if (pg0.getReadResult() != returnvalue::OK or pg1.getReadResult() != returnvalue::OK) {
sif::warning << "Reading PDU1 datasets failed!" << std::endl;
return returnvalue::FAILED;
}
/* Fist 10 bytes contain the gomspace header. Each variable is preceded by the 16-bit table
* address. */
dataOffset += 12;
// dataOffset += 12;
for (uint8_t idx = 0; idx < PDU::CHANNELS_LEN; idx++) {
coreHk.currents[idx] = (packet[dataOffset] << 8) | packet[dataOffset + 1];
dataOffset += 4;
coreHk.currents[idx] = as<int16_t>(packet + (idx * 2));
}
for (uint8_t idx = 0; idx < PDU::CHANNELS_LEN; idx++) {
coreHk.voltages[idx] = (packet[dataOffset] << 8) | packet[dataOffset + 1];
dataOffset += 4;
coreHk.voltages[idx] = as<uint16_t>(packet + 0x12 + (idx * 2));
}
auxHk.vcc = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
auxHk.vbat = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
coreHk.temperature =
static_cast<int16_t>(*(packet + dataOffset) << 8 | *(packet + dataOffset + 1)) * 0.1;
dataOffset += 4;
auxHk.vcc.value = as<int16_t>(packet + 0x24);
auxHk.vbat.value = as<int16_t>(packet + 0x26);
coreHk.temperature = as<int16_t>(packet + 0x28) * 0.1;
for (uint8_t idx = 0; idx < 3; idx++) {
auxHk.converterEnable[idx] = packet[dataOffset];
dataOffset += 3;
auxHk.converterEnable[idx] = packet[0x2a + idx];
}
for (uint8_t idx = 0; idx < PDU::CHANNELS_LEN; idx++) {
coreHk.outputEnables[idx] = packet[dataOffset];
dataOffset += 3;
coreHk.outputEnables[idx] = packet[0x2e + idx];
}
auxHk.bootcause = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
coreHk.bootcount = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.uptime = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.resetcause = *(packet + dataOffset + 1) << 8 | *(packet + dataOffset);
dataOffset += 4;
coreHk.battMode = *(packet + dataOffset);
/* +10 because here begins the second gomspace csp packet */
dataOffset += 3 + 10;
auxHk.bootcause = as<uint32_t>(packet + 0x38);
coreHk.bootcount = as<uint32_t>(packet + 0x3c);
auxHk.uptime = as<uint32_t>(packet + 0x40);
auxHk.resetcause = as<uint16_t>(packet + 0x44);
coreHk.battMode = *(packet + 0x46);
for (uint8_t idx = 0; idx < PDU::CHANNELS_LEN; idx++) {
auxHk.latchups[idx] = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
auxHk.latchups[idx] = as<uint16_t>(packet + 0x48 + (idx * 2));
}
for (uint8_t idx = 0; idx < PDU::DEVICES_NUM; idx++) {
auxHk.deviceTypes[idx] = *(packet + dataOffset);
dataOffset += 3;
auxHk.deviceTypes[idx] = *(packet + 0x5a + idx);
}
for (uint8_t idx = 0; idx < PDU::DEVICES_NUM; idx++) {
auxHk.devicesStatus[idx] = *(packet + dataOffset);
dataOffset += 3;
auxHk.devicesStatus[idx] = *(packet + 0x62 + idx);
}
auxHk.gndWdtReboots = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.i2cWdtReboots = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.canWdtReboots = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.csp1WdtReboots = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.csp2WdtReboots = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.groundWatchdogSecondsLeft = *(packet + dataOffset) << 24 |
*(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.i2cWatchdogSecondsLeft = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.canWatchdogSecondsLeft = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.csp1WatchdogPingsLeft = *(packet + dataOffset);
dataOffset += 3;
auxHk.csp2WatchdogPingsLeft = *(packet + dataOffset);
auxHk.gndWdtReboots = as<uint32_t>(packet + 0x6c);
auxHk.i2cWdtReboots = as<uint32_t>(packet + 0x70);
auxHk.canWdtReboots = as<uint32_t>(packet + 0x74);
auxHk.csp1WdtReboots = as<uint32_t>(packet + 0x78);
auxHk.csp2WdtReboots = as<uint32_t>(packet + 0x78 + 4);
auxHk.groundWatchdogSecondsLeft = as<uint32_t>(packet + 0x80);
auxHk.i2cWatchdogSecondsLeft = as<uint32_t>(packet + 0x84);
auxHk.canWatchdogSecondsLeft = as<uint32_t>(packet + 0x88);
auxHk.csp1WatchdogPingsLeft = *(packet + 0x8c);
auxHk.csp2WatchdogPingsLeft = *(packet + 0x8c + 1);
coreHk.setChanged(true);
if (not coreHk.isValid()) {
coreHk.setValidity(true, true);

View File

@ -1,12 +1,19 @@
#ifndef MISSION_DEVICES_GOMSPACEDEVICEHANDLER_H_
#define MISSION_DEVICES_GOMSPACEDEVICEHANDLER_H_
#include <mission/csp/CspCookie.h>
#include <mission/devices/devicedefinitions/GomSpacePackets.h>
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "mission/devices/devicedefinitions/GomspaceDefinitions.h"
#include "returnvalues/classIds.h"
struct TableConfig {
uint16_t maxConfigTableAddress;
uint16_t maxHkTableAddress;
uint16_t hkTableSize;
uint16_t cfgTableSize;
};
/**
* @brief This is the device handler class for all gomspace devices.
*
@ -38,8 +45,7 @@ class GomspaceDeviceHandler : public DeviceHandlerBase {
* device.
*/
GomspaceDeviceHandler(object_id_t objectId, object_id_t comIF, CookieIF *comCookie,
FailureIsolationBase *customFdir, uint16_t maxConfigTableAddress,
uint16_t maxHkTableAddress, uint16_t hkTableReplySize);
TableConfig &tableConfig, FailureIsolationBase *customFdir);
virtual ~GomspaceDeviceHandler();
/**
@ -52,21 +58,14 @@ class GomspaceDeviceHandler : public DeviceHandlerBase {
static const uint8_t MAX_PACKET_LEN = 36;
static const uint8_t PARAM_SET_OK = 1;
static const uint8_t PING_REPLY_SIZE = 2;
static const uint8_t CONFIG_TABLE_ID = 1;
static const uint8_t HK_TABLE_ID = 4;
uint8_t rememberRequestedSize = 0;
uint8_t rememberCommandId = GOMSPACE::NONE;
uint8_t cspPacket[MAX_PACKET_LEN];
uint16_t maxConfigTableAddress;
uint16_t maxHkTableAddress;
/** The size of the reply following a full hk table request.*/
uint16_t hkTableReplySize;
LocalPoolDataSetBase *hkTableDataset = nullptr;
void initPduConfigTable();
void doStartUp() override;
void doShutDown() override;
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
@ -83,7 +82,9 @@ class GomspaceDeviceHandler : public DeviceHandlerBase {
* @brief The command to generate a request to receive the full housekeeping table is device
* specific. Thus the child has to build this command.
*/
virtual ReturnValue_t generateRequestFullHkTableCmd(uint16_t hkTableSize);
virtual ReturnValue_t generateRequestFullTableCmd(GOMSPACE::SpecialRequestTypes reqType,
uint8_t tableId, uint16_t tableSize,
DeviceCommandId_t id);
/**
* This command handles printing the HK table to the console. This is useful for debugging
@ -99,7 +100,7 @@ class GomspaceDeviceHandler : public DeviceHandlerBase {
* @param packet Pointer to the reply containing the hk table.
*/
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) = 0;
virtual void letChildHandleConfigReply(DeviceCommandId_t id, const uint8_t *packet) = 0;
virtual LocalPoolDataSetBase *getDataSetHandle(sid_t sid) = 0;
/**
@ -116,8 +117,13 @@ class GomspaceDeviceHandler : public DeviceHandlerBase {
LocalDataPoolManager &poolManager,
std::array<uint8_t, PDU::CHANNELS_LEN> initOutEnb);
template <typename T>
T as(const uint8_t *);
static bool validTableId(uint8_t id);
private:
SetParamMessageUnpacker setParamCacher;
TableConfig &tableCfg;
/**
* @brief Function to generate the command to set a parameter. Command
* will be sent to the ComIF over the rawPacket buffer.
@ -159,4 +165,9 @@ class GomspaceDeviceHandler : public DeviceHandlerBase {
ReturnValue_t generateResetWatchdogCmd();
};
template <typename T>
inline T GomspaceDeviceHandler::as(const uint8_t *ptr) {
return *(reinterpret_cast<const T *>(ptr));
}
#endif /* MISSION_DEVICES_GOMSPACEDEVICEHANDLER_H_ */

View File

@ -6,11 +6,14 @@
P60DockHandler::P60DockHandler(object_id_t objectId, object_id_t comIF, CookieIF *comCookie,
FailureIsolationBase *customFdir)
: GomspaceDeviceHandler(objectId, comIF, comCookie, customFdir,
P60Dock::MAX_CONFIGTABLE_ADDRESS, P60Dock::MAX_HKTABLE_ADDRESS,
P60Dock::HK_TABLE_REPLY_SIZE),
: GomspaceDeviceHandler(objectId, comIF, comCookie, cfg, customFdir),
coreHk(this),
auxHk(this) {}
auxHk(this) {
cfg.maxConfigTableAddress = P60Dock::MAX_CONFIGTABLE_ADDRESS;
cfg.maxHkTableAddress = P60Dock::MAX_HKTABLE_ADDRESS;
cfg.hkTableSize = P60Dock::HK_TABLE_SIZE;
cfg.cfgTableSize = P60Dock::CONFIG_TABLE_SIZE;
}
P60DockHandler::~P60DockHandler() {}
@ -21,20 +24,13 @@ ReturnValue_t P60DockHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
void P60DockHandler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) {
parseHkTableReply(packet);
/**
* Hk table will be sent to the commander if hk table request was not triggered by the
* P60DockHandler itself.
*/
handleDeviceTM(&coreHk, id, true);
}
void P60DockHandler::parseHkTableReply(const uint8_t *packet) {
using namespace P60Dock;
uint16_t dataOffset = 0;
PoolReadGuard pg0(&coreHk);
PoolReadGuard pg1(&auxHk);
if (pg0.getReadResult() != returnvalue::OK or
pg1.getReadResult() != returnvalue::OK) {
if (pg0.getReadResult() != returnvalue::OK or pg1.getReadResult() != returnvalue::OK) {
coreHk.setValidity(false, true);
auxHk.setValidity(false, true);
return;
@ -43,45 +39,27 @@ void P60DockHandler::parseHkTableReply(const uint8_t *packet) {
* Fist 10 bytes contain the gomspace header. Each variable is preceded by the 16-bit table
* address.
*/
dataOffset += 12;
for (uint8_t idx = 0; idx < hk::CHNLS_LEN; idx++) {
coreHk.currents[idx] = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
coreHk.currents[idx] = as<int16_t>(packet + (idx * 2));
}
for (uint8_t idx = 0; idx < hk::CHNLS_LEN; idx++) {
coreHk.voltages[idx] = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
coreHk.voltages[idx] = as<uint16_t>(packet + 0x1a + (idx * 2));
}
for (uint8_t idx = 0; idx < hk::CHNLS_LEN; idx++) {
coreHk.outputEnables[idx] = *(packet + dataOffset);
dataOffset += 3;
coreHk.outputEnables[idx] = *(packet + 0x34 + idx);
}
coreHk.temperature1 =
static_cast<int16_t>(*(packet + dataOffset) << 8 | *(packet + dataOffset + 1)) * 0.1;
dataOffset += 4;
coreHk.temperature2 =
static_cast<int16_t>(*(packet + dataOffset) << 8 | *(packet + dataOffset + 1)) * 0.1;
dataOffset += 4;
coreHk.temperature1 = as<int16_t>(packet + 0x44) * 0.1;
coreHk.temperature2 = as<int16_t>(packet + 0x44 + 2) * 0.1;
auxHk.bootcause = *(packet + dataOffset) << 24 |
*(packet + dataOffset + 1) << 16 | *(packet + dataOffset + 2) << 8 |
*(packet + dataOffset + 3);
dataOffset += 6;
coreHk.bootCount = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
auxHk.bootcause = as<uint32_t>(packet + 0x48);
coreHk.bootCount = as<uint32_t>(packet + 0x4c);
if (firstHk) {
triggerEvent(P60_BOOT_COUNT, coreHk.bootCount.value);
}
dataOffset += 6;
auxHk.uptime = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.resetcause = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
uint8_t newBattMode = packet[dataOffset];
auxHk.uptime = as<uint32_t>(packet + 0x50);
auxHk.resetcause = as<uint16_t>(packet + 0x54);
uint8_t newBattMode = packet[0x56];
if (firstHk) {
triggerEvent(BATT_MODE, newBattMode);
} else if (newBattMode != coreHk.battMode.value) {
@ -89,83 +67,46 @@ void P60DockHandler::parseHkTableReply(const uint8_t *packet) {
}
coreHk.battMode = newBattMode;
dataOffset += 3;
auxHk.heaterOn = *(packet + dataOffset);
/* + 13 because here begins a new gomspace csp data field */
dataOffset += 13;
auxHk.converter5VStatus = *(packet + dataOffset);
dataOffset += 3;
auxHk.heaterOn = *(packet + 0x57);
auxHk.converter5VStatus = *(packet + 0x58);
for (uint8_t idx = 0; idx < hk::CHNLS_LEN; idx++) {
auxHk.latchups[idx] = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
auxHk.latchups[idx] = as<uint16_t>(packet + 0x5a + (idx * 2));
}
auxHk.dockVbatVoltageValue = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
auxHk.dockVccCurrent = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
coreHk.batteryCurrent = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
coreHk.batteryVoltage = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
auxHk.dockVbatVoltageValue = as<uint16_t>(packet + 0x74);
auxHk.dockVccCurrent = as<int16_t>(packet + 0x76);
coreHk.batteryCurrent = as<int16_t>(packet + 0x78);
coreHk.batteryVoltage = as<uint16_t>(packet + 0x7a);
auxHk.batteryTemperature1 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
auxHk.batteryTemperature2 = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
auxHk.batteryTemperature1 = as<int16_t>(packet + 0x7c);
auxHk.batteryTemperature2 = as<int16_t>(packet + 0x7c + 2);
for (uint8_t idx = 0; idx < NUM_DEVS; idx++) {
auxHk.devicesType[idx] = *(packet + dataOffset);
dataOffset += 3;
auxHk.devicesType[idx] = *(packet + 0x80 + idx);
}
for (uint8_t idx = 0; idx < NUM_DEVS; idx++) {
auxHk.devicesStatus[idx] = *(packet + dataOffset);
dataOffset += 3;
auxHk.devicesStatus[idx] = *(packet + 0x88 + idx);
}
auxHk.dearmStatus = *(packet + dataOffset);
dataOffset += 3;
auxHk.dearmStatus = *(packet + 0x90);
auxHk.wdtCntGnd = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.wdtCntI2c = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.wdtCntCan = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.wdtCntCsp1 = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.wdtCntCsp2 = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.wdtCntGnd = as<uint32_t>(packet + 0x94);
auxHk.wdtCntI2c = as<uint32_t>(packet + 0x98);
auxHk.wdtCntCan = as<uint32_t>(packet + 0x9c);
auxHk.wdtCntCsp1 = as<uint32_t>(packet + 0xa0);
auxHk.wdtCntCsp2 = as<uint32_t>(packet + 0xa0 + 4);
auxHk.wdtGndLeft = as<uint32_t>(packet + 0xa8);
auxHk.wdtI2cLeft = as<uint32_t>(packet + 0xac);
auxHk.wdtCanLeft = as<uint32_t>(packet + 0xb0);
auxHk.wdtGndLeft = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.wdtI2cLeft = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
dataOffset += 6;
auxHk.wdtCanLeft = *(packet + dataOffset) << 24 | *(packet + dataOffset + 1) << 16 |
*(packet + dataOffset + 2) << 8 | *(packet + dataOffset + 3);
/* +16 because here begins a new gomspace csp packet */
dataOffset += 16;
auxHk.wdtCspLeft1 = *(packet + 0xb4);
auxHk.wdtCspLeft2 = *(packet + 0xb4 + 1);
auxHk.wdtCspLeft1 = *(packet + dataOffset);
dataOffset += 3;
auxHk.wdtCspLeft2 = *(packet + dataOffset);
dataOffset += 3;
auxHk.batteryChargeCurrent = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
auxHk.batteryDischargeCurrent = *(packet + dataOffset) << 8 | *(packet + dataOffset + 1);
dataOffset += 4;
auxHk.ant6Depl = *(packet + dataOffset);
dataOffset += 3;
auxHk.ar6Depl = *(packet + dataOffset);
auxHk.batteryChargeCurrent = as<int16_t>(packet + 0xb6);
auxHk.batteryDischargeCurrent = as<int16_t>(packet + 0xb8);
auxHk.ant6Depl = *(packet + 0xba);
auxHk.ar6Depl = *(packet + 0xbb);
if (firstHk) {
firstHk = false;
}
@ -175,7 +116,7 @@ void P60DockHandler::parseHkTableReply(const uint8_t *packet) {
ReturnValue_t P60DockHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
using namespace P60System;
using namespace P60Dock;
localDataPoolMap.emplace(pool::P60_CURRENTS, &hkCurrents);
localDataPoolMap.emplace(pool::P60_VOLTAGES, &hkVoltages);
@ -238,8 +179,7 @@ ReturnValue_t P60DockHandler::printStatus(DeviceCommandId_t cmd) {
case (GOMSPACE::PRINT_SWITCH_V_I): {
PoolReadGuard pg0(&coreHk);
PoolReadGuard pg1(&auxHk);
if (pg0.getReadResult() != returnvalue::OK or
pg1.getReadResult() != returnvalue::OK) {
if (pg0.getReadResult() != returnvalue::OK or pg1.getReadResult() != returnvalue::OK) {
break;
}
printHkTableSwitchIV();
@ -326,3 +266,7 @@ void P60DockHandler::printHkTableLatchups() {
}
void P60DockHandler::setDebugMode(bool enable) { this->debugMode = enable; }
void P60DockHandler::letChildHandleConfigReply(DeviceCommandId_t id, const uint8_t *packet) {
handleDeviceTm(util::DataWrapper(packet, P60Dock::CONFIG_TABLE_SIZE), id);
}

View File

@ -36,8 +36,8 @@ class P60DockHandler : public GomspaceDeviceHandler {
*/
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override;
void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override;
void letChildHandleConfigReply(DeviceCommandId_t id, const uint8_t* packet) override;
/**
* This command handles printing the HK table to the console. This is useful for debugging
* purposes
@ -52,6 +52,7 @@ class P60DockHandler : public GomspaceDeviceHandler {
private:
P60Dock::CoreHkSet coreHk;
P60Dock::HkTableDataset auxHk;
TableConfig cfg;
bool firstHk = true;
bool debugMode = false;
static constexpr uint8_t MAX_CHANNEL_STR_WIDTH = 16;

View File

@ -7,10 +7,11 @@
PDU1Handler::PDU1Handler(object_id_t objectId, object_id_t comIF, CookieIF *comCookie,
FailureIsolationBase *customFdir)
: GomspaceDeviceHandler(objectId, comIF, comCookie, customFdir, PDU::MAX_CONFIGTABLE_ADDRESS,
PDU::MAX_HKTABLE_ADDRESS, PDU::HK_TABLE_REPLY_SIZE),
: GomspaceDeviceHandler(objectId, comIF, comCookie, cfg, customFdir),
coreHk(this),
auxHk(this) {}
auxHk(this) {
initPduConfigTable();
}
PDU1Handler::~PDU1Handler() {}
@ -21,7 +22,6 @@ ReturnValue_t PDU1Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
void PDU1Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) {
parseHkTableReply(packet);
handleDeviceTM(&coreHk, id, true);
}
void PDU1Handler::assignChannelHookFunction(GOMSPACE::ChannelSwitchHook hook, void *args) {
@ -79,6 +79,12 @@ ReturnValue_t PDU1Handler::setParamCallback(SetParamMessageUnpacker &unpacker,
return returnvalue::OK;
}
void PDU1Handler::letChildHandleConfigReply(DeviceCommandId_t id, const uint8_t *packet) {
util::DataWrapper wrapper;
wrapper.setRawData({packet, PDU::CONFIG_TABLE_SIZE});
handleDeviceTm(wrapper, id);
}
void PDU1Handler::parseHkTableReply(const uint8_t *packet) {
GomspaceDeviceHandler::parsePduHkTable(coreHk, auxHk, packet);
}

View File

@ -35,7 +35,8 @@ class PDU1Handler : public GomspaceDeviceHandler {
* @brief In MODE_NORMAL, a command will be built periodically by this function.
*/
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override;
void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override;
void letChildHandleConfigReply(DeviceCommandId_t id, const uint8_t* packet) override;
ReturnValue_t printStatus(DeviceCommandId_t cmd) override;
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
ReturnValue_t setParamCallback(SetParamMessageUnpacker& unpacker, bool afterExectuion) override;
@ -46,6 +47,7 @@ class PDU1Handler : public GomspaceDeviceHandler {
/** Dataset for the housekeeping table of the PDU1 */
PDU1::Pdu1CoreHk coreHk;
PDU1::Pdu1AuxHk auxHk;
TableConfig cfg;
GOMSPACE::ChannelSwitchHook channelSwitchHook = nullptr;
void* hookArgs = nullptr;

View File

@ -7,10 +7,11 @@
PDU2Handler::PDU2Handler(object_id_t objectId, object_id_t comIF, CookieIF *comCookie,
FailureIsolationBase *customFdir)
: GomspaceDeviceHandler(objectId, comIF, comCookie, customFdir, PDU::MAX_CONFIGTABLE_ADDRESS,
PDU::MAX_HKTABLE_ADDRESS, PDU::HK_TABLE_REPLY_SIZE),
: GomspaceDeviceHandler(objectId, comIF, comCookie, cfg, customFdir),
coreHk(this),
auxHk(this) {}
auxHk(this) {
initPduConfigTable();
}
PDU2Handler::~PDU2Handler() {}
@ -21,11 +22,12 @@ ReturnValue_t PDU2Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
void PDU2Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) {
parseHkTableReply(packet);
/**
* Hk table will be sent to the commander if hk table request was not triggered by the
* PDU2Handler itself.
*/
handleDeviceTM(&coreHk, id, true);
}
void PDU2Handler::letChildHandleConfigReply(DeviceCommandId_t id, const uint8_t *packet) {
util::DataWrapper wrapper;
wrapper.setRawData({packet, PDU::CONFIG_TABLE_SIZE});
handleDeviceTm(wrapper, id);
}
void PDU2Handler::assignChannelHookFunction(GOMSPACE::ChannelSwitchHook hook, void *args) {

View File

@ -34,7 +34,8 @@ class PDU2Handler : public GomspaceDeviceHandler {
* @brief As soon as the device is in MODE_NORMAL, this function is executed periodically.
*/
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override;
void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override;
void letChildHandleConfigReply(DeviceCommandId_t id, const uint8_t* packet) override;
ReturnValue_t printStatus(DeviceCommandId_t cmd) override;
ReturnValue_t setParamCallback(SetParamMessageUnpacker& unpacker, bool afterExecution) override;
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
@ -45,6 +46,7 @@ class PDU2Handler : public GomspaceDeviceHandler {
/** Dataset for the housekeeping table of the PDU2 */
PDU2::Pdu2CoreHk coreHk;
PDU2::Pdu2AuxHk auxHk;
TableConfig cfg;
GOMSPACE::ChannelSwitchHook channelSwitchHook = nullptr;
void* hookArgs = nullptr;

View File

@ -7,6 +7,35 @@
#include <fsfw/serialize/SerializeElement.h>
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
class CspParamRequestBase : public SerialLinkedListAdapter<SerializeIF> {
public:
CspParamRequestBase(uint16_t querySize, uint8_t tableId)
: querySize(querySize), tableId(tableId) {
setLinks();
}
protected:
void setLinks() {
setStart(&cspPort);
cspPort.setNext(&querySize);
querySize.setNext(&action);
action.setNext(&tableId);
tableId.setNext(&payloadlength);
payloadlength.setNext(&checksum);
checksum.setNext(&seq);
seq.setNext(&total);
}
SerializeElement<uint8_t> cspPort = GOMSPACE::PARAM_PORT;
SerializeElement<uint16_t> querySize;
SerializeElement<uint8_t> action = GOMSPACE::ParamRequestIds::GET;
SerializeElement<uint8_t> tableId;
// Default value 0: Fetch whole table.
SerializeElement<uint16_t> payloadlength = 0;
SerializeElement<uint16_t> checksum = GOMSPACE::IGNORE_CHECKSUM;
SerializeElement<uint16_t> seq = 0;
SerializeElement<uint16_t> total = 0;
};
/**
* @brief This class can be used to generated the command for the CspComIF
* to reset the watchdog in a gomspace device.
@ -74,46 +103,21 @@ class CspPingCommand : public SerialLinkedListAdapter<SerializeIF> {
* gomspace device but are required for the CspComIF to get the port
* and the size to query.
*/
class CspSetParamCommand : public SerialLinkedListAdapter<SerializeIF> {
class CspSetParamCommand : public CspParamRequestBase {
public:
CspSetParamCommand(uint16_t querySize_, uint16_t payloadlength_, uint16_t checksum_,
uint16_t seq_, uint16_t total_, uint16_t addr_, const uint8_t *parameter_,
uint8_t parameterCount_)
: querySize(querySize_),
payloadlength(payloadlength_),
checksum(checksum_),
seq(seq_),
total(total_),
CspSetParamCommand(uint16_t querySize_, uint16_t payloadlength_, uint16_t addr_,
const uint8_t *parameter_, uint8_t parameterCount_, uint8_t tableId = 1)
: CspParamRequestBase(querySize_, tableId),
addr(addr_),
parameter(parameter_, parameterCount_) {
setLinks();
}
private:
CspSetParamCommand(const CspSetParamCommand &command);
void setLinks() {
setStart(&cspPort);
cspPort.setNext(&querySize);
querySize.setNext(&action);
action.setNext(&tableId);
tableId.setNext(&payloadlength);
payloadlength.setNext(&checksum);
checksum.setNext(&seq);
seq.setNext(&total);
total.setNext(&addr);
addr.setNext(&parameter);
CspParamRequestBase::payloadlength = payloadlength_;
CspParamRequestBase::action = GOMSPACE::ParamRequestIds::SET;
}
SerializeElement<uint8_t> cspPort = GOMSPACE::PARAM_PORT;
/* Only a parameter will be set. No data will be queried with this command */
SerializeElement<uint16_t> querySize;
SerializeElement<uint8_t> action = 0xFF; // param set
/* We will never set a parameter in a table other than the configuration
* table */
SerializeElement<uint8_t> tableId = 1;
SerializeElement<uint16_t> payloadlength;
SerializeElement<uint16_t> checksum;
SerializeElement<uint16_t> seq;
SerializeElement<uint16_t> total;
CspSetParamCommand(const CspSetParamCommand &command) = delete;
private:
SerializeElement<uint16_t> addr;
SerializeElement<SerialBufferAdapter<uint8_t>> parameter;
};
@ -126,48 +130,20 @@ class CspSetParamCommand : public SerialLinkedListAdapter<SerializeIF> {
* @note cspPort and querySize only serve as information for the CspComIF
* and will not be transmitted physically to the target device.
*/
class CspGetParamCommand : public SerialLinkedListAdapter<SerializeIF> {
class CspGetParamCommand : public CspParamRequestBase {
public:
/* The size of the header of a gomspace CSP packet. */
static const uint8_t GS_HDR_LENGTH = 12;
CspGetParamCommand(uint16_t querySize_, uint8_t tableId_, uint16_t addresslength_,
uint16_t checksum_, uint16_t seq_, uint16_t total_, uint16_t addr_)
: querySize(querySize_),
tableId(tableId_),
addresslength(addresslength_),
checksum(checksum_),
seq(seq_),
total(total_),
addr(addr_) {
fixedValuesInit();
setLinks();
CspGetParamCommand(uint16_t querySize_, uint8_t tableId_, uint16_t addresslength_, uint16_t addr_)
: CspParamRequestBase(querySize_, tableId_), addr(addr_) {
total.setNext(&addr);
CspParamRequestBase::tableId = tableId_;
CspParamRequestBase::payloadlength = addresslength_;
}
CspGetParamCommand(const CspGetParamCommand &command) = delete;
private:
CspGetParamCommand(const CspGetParamCommand &command);
void setLinks() {
setStart(&cspPort);
cspPort.setNext(&querySize);
querySize.setNext(&action);
action.setNext(&tableId);
tableId.setNext(&addresslength);
addresslength.setNext(&checksum);
checksum.setNext(&seq);
seq.setNext(&total);
total.setNext(&addr);
}
void fixedValuesInit() { cspPort.entry = GOMSPACE::PARAM_PORT; }
SerializeElement<uint8_t> cspPort;
SerializeElement<uint16_t> querySize; // size of bytes to query
/* Following information will also be physically transmitted to the target
* device*/
SerializeElement<uint8_t> action = 0x00; // get param
SerializeElement<uint8_t> tableId;
SerializeElement<uint16_t> addresslength;
SerializeElement<uint16_t> checksum;
SerializeElement<uint16_t> seq;
SerializeElement<uint16_t> total;
SerializeElement<uint16_t> addr;
};
@ -179,37 +155,14 @@ class CspGetParamCommand : public SerialLinkedListAdapter<SerializeIF> {
* @note cspPort and querySize only serve as information for the CspComIF
* and will not be transmitted physically to the target device.
*/
class RequestFullTableCommand : public SerialLinkedListAdapter<SerializeIF> {
class RequestFullTableCommand : public CspParamRequestBase {
public:
RequestFullTableCommand(uint16_t querySize_, uint8_t tableId_)
: querySize(querySize_), tableId(tableId_) {
setLinks();
}
: CspParamRequestBase(querySize_, tableId_) {}
RequestFullTableCommand(const RequestFullTableCommand &command) = delete;
private:
RequestFullTableCommand(const RequestFullTableCommand &command);
void setLinks() {
setStart(&cspPort);
cspPort.setNext(&querySize);
querySize.setNext(&action);
action.setNext(&tableId);
tableId.setNext(&addresslength);
addresslength.setNext(&checksum);
checksum.setNext(&seq);
seq.setNext(&total);
}
SerializeElement<uint8_t> cspPort = GOMSPACE::PARAM_PORT;
/** Size of bytes to query (size of csp header + size of table) */
SerializeElement<uint16_t> querySize;
/* Following information will also be physically transmitted to the target
* device*/
SerializeElement<uint8_t> action = 0x00; // get param
SerializeElement<uint8_t> tableId;
/* Size of address. Set to 0 to get full table */
SerializeElement<uint16_t> addresslength = 0;
SerializeElement<uint16_t> checksum = GOMSPACE::IGNORE_CHECKSUM;
SerializeElement<uint16_t> seq = 0;
SerializeElement<uint16_t> total = 0;
};
/**

View File

@ -9,9 +9,32 @@
#include <cstdint>
#include "devices/powerSwitcherList.h"
#include "p60acu_hk.h"
#include "p60acu_param.h"
#include "p60dock_hk.h"
#include "p60dock_param.h"
#include "p60pdu_hk.h"
#include "p60pdu_param.h"
namespace GOMSPACE {
enum SpecialRequestTypes {
DEFAULT_COM_IF,
GET_PDU_HK,
GET_PDU_CONFIG,
GET_ACU_HK,
GET_ACU_CONFIG,
GET_P60DOCK_HK,
GET_P60DOCK_CONFIG
};
enum CspPorts : uint8_t {
CSP_PING = 1,
CSP_REBOOT = 4,
P60_PORT_RPARAM_ENUM = 7,
P60_PORT_GNDWDT_RESET_ENUM = 9
};
enum class Pdu { PDU1, PDU2 };
using ChannelSwitchHook = void (*)(Pdu pdu, uint8_t channel, bool on, void* args);
@ -37,12 +60,33 @@ static const DeviceCommandId_t GNDWDT_RESET = 9; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t PARAM_GET = 0; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t PARAM_SET = 255; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t REQUEST_HK_TABLE = 16; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t REQUEST_CONFIG_TABLE = 17; //!< [EXPORT] : [COMMAND]
// Not implemented yet
// static const DeviceCommandId_t REQUEST_CALIB_TABLE = 18; //!< [EXPORT] : [COMMAND]
//! [EXPORT] : [COMMAND] Print switch states, voltages and currents to the console
//! For the ACU device, only print voltages and currents of the 6 ACU channels
static const DeviceCommandId_t PRINT_SWITCH_V_I = 32;
static const DeviceCommandId_t PRINT_LATCHUPS = 33;
enum ParamRequestIds : uint8_t {
GET = 0x00,
REPLY = 0x55,
SET = 0xFF,
TABLE_SPEC = 0x44,
// Copy memory slot to memory slot
COPY = 0x77,
// Load from file to slot. Load from primary slot
LOAD = 0x88,
// Load by name(s)
LOAD_FROM_STORE = 0x89,
// Save to primary slot
SAVE = 0x99,
// Save by name(s)
SAVE_TO_STORE = 0x9a
};
enum TableIds : uint8_t { BOARD_PARAMS = 0, CONFIG = 1, CALIBRATION = 2, HK = 4 };
} // namespace GOMSPACE
namespace P60System {
@ -57,9 +101,16 @@ enum class SetIds : uint32_t {
P60_CORE = 5,
P60_AUX = 6,
ACU_CORE = 7,
ACU_AUX = 8
ACU_AUX = 8,
PDU_1_CONFIG = 9,
PDU_2_CONFIG = 10
};
} // namespace P60System
namespace P60Dock {
namespace pool {
enum Ids : lp_id_t {
@ -102,60 +153,8 @@ enum Ids : lp_id_t {
P60DOCK_BATT_DISCHARGE_CURRENT,
P60DOCK_ANT6_DEPL,
P60DOCK_AR6_DEPL,
// IDs for both PDUs
PDU_CURRENTS,
PDU_VOLTAGES,
PDU_VCC,
PDU_VBAT,
PDU_TEMPERATURE,
PDU_CONV_EN,
PDU_OUT_ENABLE,
PDU_BOOTCAUSE,
PDU_BOOTCNT,
PDU_UPTIME,
PDU_RESETCAUSE,
PDU_BATT_MODE,
PDU_LATCHUPS,
PDU_DEVICES,
PDU_STATUSES,
PDU_WDT_CNT_GND,
PDU_WDT_CNT_I2C,
PDU_WDT_CNT_CAN,
PDU_WDT_CNT_CSP1,
PDU_WDT_CNT_CSP2,
PDU_WDT_GND_LEFT,
PDU_WDT_I2C_LEFT,
PDU_WDT_CAN_LEFT,
PDU_WDT_CSP_LEFT1,
PDU_WDT_CSP_LEFT2,
/** ACU Ids */
ACU_CURRENT_IN_CHANNELS,
ACU_VOLTAGE_IN_CHANNELS,
ACU_VCC,
ACU_VBAT,
ACU_TEMPERATURES,
ACU_MPPT_MODE,
ACU_VBOOST_IN_CHANNELS,
ACU_POWER_IN_CHANNELS,
ACU_DAC_ENABLES,
ACU_DAC_RAW_CHANNELS,
ACU_BOOTCAUSE,
ACU_BOOTCNT,
ACU_UPTIME,
ACU_RESET_CAUSE,
ACU_MPPT_TIME,
ACU_MPPT_PERIOD,
ACU_DEVICES,
ACU_DEVICES_STATUS,
ACU_WDT_CNT_GND,
ACU_WDT_GND_LEFT,
};
}
} // namespace P60System
namespace P60Dock {
static constexpr uint8_t NUM_DEVS = 8;
@ -196,21 +195,16 @@ enum SwitchChannels : uint8_t {
GS5V = 12
};
/** Max reply size reached when requesting full hk table */
static const uint16_t MAX_REPLY_LENGTH = 407;
static const uint16_t MAX_CONFIGTABLE_ADDRESS = 408;
static const uint16_t MAX_HKTABLE_ADDRESS = 187;
static const uint16_t HK_TABLE_SIZE = 188;
// Sources:
// GomSpace library lib/p60-dock_client/include/gs/p60-dock/param
static const uint16_t HK_TABLE_SIZE = P60DOCK_HK_SIZE;
static const uint16_t CONFIG_TABLE_SIZE = P60DOCK_PARAM_SIZE;
static const size_t MAX_REPLY_SIZE = CONFIG_TABLE_SIZE;
static const uint16_t CAL_TABLE = 0xAE;
static const uint8_t HK_TABLE_ENTRIES = 100;
/**
* Requesting the full housekeeping table from the P60 dock will generate a reply comprising
* 402 bytes of data.
*/
static const uint16_t HK_TABLE_REPLY_SIZE = 407;
class CoreHkSet : public StaticLocalDataSet<16> {
public:
CoreHkSet(HasLocalDataPoolIF* owner)
@ -221,33 +215,26 @@ class CoreHkSet : public StaticLocalDataSet<16> {
/** Measured output currents */
lp_vec_t<int16_t, P60Dock::hk::Index::CHNLS_LEN> currents =
lp_vec_t<int16_t, P60Dock::hk::Index::CHNLS_LEN>(sid.objectId, P60System::pool::P60_CURRENTS,
this);
lp_vec_t<int16_t, P60Dock::hk::Index::CHNLS_LEN>(sid.objectId, pool::P60_CURRENTS, this);
/** Measured output voltages */
lp_vec_t<uint16_t, P60Dock::hk::Index::CHNLS_LEN> voltages =
lp_vec_t<uint16_t, P60Dock::hk::Index::CHNLS_LEN>(sid.objectId, P60System::pool::P60_VOLTAGES,
this);
lp_vec_t<uint16_t, P60Dock::hk::Index::CHNLS_LEN>(sid.objectId, pool::P60_VOLTAGES, this);
/** Output enable states */
lp_vec_t<uint8_t, P60Dock::hk::Index::CHNLS_LEN> outputEnables =
lp_vec_t<uint8_t, P60Dock::hk::Index::CHNLS_LEN>(sid.objectId,
P60System::pool::P60_OUTPUT_ENABLE, this);
lp_var_t<uint32_t> bootCount =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::P60DOCK_BOOT_CNT, this);
lp_var_t<uint8_t> battMode =
lp_var_t<uint8_t>(sid.objectId, P60System::pool::P60DOCK_BATT_MODE, this);
lp_vec_t<uint8_t, P60Dock::hk::Index::CHNLS_LEN>(sid.objectId, pool::P60_OUTPUT_ENABLE, this);
lp_var_t<uint32_t> bootCount = lp_var_t<uint32_t>(sid.objectId, pool::P60DOCK_BOOT_CNT, this);
lp_var_t<uint8_t> battMode = lp_var_t<uint8_t>(sid.objectId, pool::P60DOCK_BATT_MODE, this);
// Difference between charge and discharge current
lp_var_t<int16_t> batteryCurrent =
lp_var_t<int16_t>(sid.objectId, P60System::pool::P60DOCK_BATTERY_CURRENT, this);
lp_var_t<int16_t>(sid.objectId, pool::P60DOCK_BATTERY_CURRENT, this);
lp_var_t<uint16_t> batteryVoltage =
lp_var_t<uint16_t>(sid.objectId, P60System::pool::P60DOCK_BATTERY_VOLTAGE, this);
lp_var_t<uint16_t>(sid.objectId, pool::P60DOCK_BATTERY_VOLTAGE, this);
lp_var_t<float> temperature1 =
lp_var_t<float>(sid.objectId, P60System::pool::P60DOCK_TEMPERATURE_1, this);
lp_var_t<float> temperature2 =
lp_var_t<float>(sid.objectId, P60System::pool::P60DOCK_TEMPERATURE_2, this);
lp_var_t<float> temperature1 = lp_var_t<float>(sid.objectId, pool::P60DOCK_TEMPERATURE_1, this);
lp_var_t<float> temperature2 = lp_var_t<float>(sid.objectId, pool::P60DOCK_TEMPERATURE_2, this);
};
/**
* @brief This class defines a dataset for the hk table of the P60 Dock.
@ -265,70 +252,59 @@ class HkTableDataset : public StaticLocalDataSet<32> {
/** Number of detected latchups on each output channel */
lp_vec_t<uint16_t, P60Dock::hk::Index::CHNLS_LEN> latchups =
lp_vec_t<uint16_t, P60Dock::hk::Index::CHNLS_LEN>(sid.objectId, P60System::pool::LATCHUPS,
this);
lp_vec_t<uint16_t, P60Dock::hk::Index::CHNLS_LEN>(sid.objectId, pool::LATCHUPS, this);
lp_var_t<uint32_t> bootcause =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::P60DOCK_BOOT_CAUSE, this);
lp_var_t<uint32_t> uptime =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::P60DOCK_UPTIME, this);
lp_var_t<uint16_t> resetcause =
lp_var_t<uint16_t>(sid.objectId, P60System::pool::P60DOCK_RESETCAUSE, this);
lp_var_t<uint32_t> bootcause = lp_var_t<uint32_t>(sid.objectId, pool::P60DOCK_BOOT_CAUSE, this);
lp_var_t<uint32_t> uptime = lp_var_t<uint32_t>(sid.objectId, pool::P60DOCK_UPTIME, this);
lp_var_t<uint16_t> resetcause = lp_var_t<uint16_t>(sid.objectId, pool::P60DOCK_RESETCAUSE, this);
/** Battery heater control only possible on BP4 packs */
lp_var_t<uint8_t> heaterOn =
lp_var_t<uint8_t>(sid.objectId, P60System::pool::P60DOCK_HEATER_ON, this);
lp_var_t<uint8_t> heaterOn = lp_var_t<uint8_t>(sid.objectId, pool::P60DOCK_HEATER_ON, this);
lp_var_t<uint8_t> converter5VStatus =
lp_var_t<uint8_t>(sid.objectId, P60System::pool::P60DOCK_CONV_5V_ENABLE_STATUS, this);
lp_var_t<uint8_t>(sid.objectId, pool::P60DOCK_CONV_5V_ENABLE_STATUS, this);
lp_var_t<uint16_t> dockVbatVoltageValue =
lp_var_t<uint16_t>(sid.objectId, P60System::pool::P60DOCK_DOCK_VBAT, this);
lp_var_t<uint16_t>(sid.objectId, pool::P60DOCK_DOCK_VBAT, this);
lp_var_t<int16_t> dockVccCurrent =
lp_var_t<int16_t>(sid.objectId, P60System::pool::P60DOCK_DOCK_VCC_CURRENT, this);
lp_var_t<int16_t>(sid.objectId, pool::P60DOCK_DOCK_VCC_CURRENT, this);
lp_var_t<int16_t> batteryTemperature1 =
lp_var_t<int16_t>(sid.objectId, P60System::pool::P60DOCK_BATTERY_TEMPERATURE_1, this);
lp_var_t<int16_t>(sid.objectId, pool::P60DOCK_BATTERY_TEMPERATURE_1, this);
lp_var_t<int16_t> batteryTemperature2 =
lp_var_t<int16_t>(sid.objectId, P60System::pool::P60DOCK_BATTERY_TEMPERATURE_2, this);
lp_var_t<int16_t>(sid.objectId, pool::P60DOCK_BATTERY_TEMPERATURE_2, this);
lp_var_t<uint8_t> dearmStatus =
lp_var_t<uint8_t>(sid.objectId, P60System::pool::P60DOCK_DEARM_STATUS, this);
lp_var_t<uint8_t> dearmStatus = lp_var_t<uint8_t>(sid.objectId, pool::P60DOCK_DEARM_STATUS, this);
/** Number of reboots due to gnd, i2c, csp watchdog timeout */
lp_var_t<uint32_t> wdtCntGnd =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::P60DOCK_WDT_CNT_GND, this);
lp_var_t<uint32_t> wdtCntI2c =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::P60DOCK_WDT_CNT_I2C, this);
lp_var_t<uint32_t> wdtCntCan =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::P60DOCK_WDT_CNT_CAN, this);
lp_var_t<uint32_t> wdtCntGnd = lp_var_t<uint32_t>(sid.objectId, pool::P60DOCK_WDT_CNT_GND, this);
lp_var_t<uint32_t> wdtCntI2c = lp_var_t<uint32_t>(sid.objectId, pool::P60DOCK_WDT_CNT_I2C, this);
lp_var_t<uint32_t> wdtCntCan = lp_var_t<uint32_t>(sid.objectId, pool::P60DOCK_WDT_CNT_CAN, this);
lp_var_t<uint32_t> wdtCntCsp1 =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::P60DOCK_WDT_CNT_CSP_1, this);
lp_var_t<uint32_t>(sid.objectId, pool::P60DOCK_WDT_CNT_CSP_1, this);
lp_var_t<uint32_t> wdtCntCsp2 =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::P60DOCK_WDT_CNT_CSP_2, this);
lp_var_t<uint32_t>(sid.objectId, pool::P60DOCK_WDT_CNT_CSP_2, this);
lp_var_t<uint32_t> wdtGndLeft =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::P60DOCK_WDT_GND_LEFT, this);
lp_var_t<uint32_t>(sid.objectId, pool::P60DOCK_WDT_GND_LEFT, this);
lp_var_t<uint32_t> wdtI2cLeft =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::P60DOCK_WDT_I2C_LEFT, this);
lp_var_t<uint32_t>(sid.objectId, pool::P60DOCK_WDT_I2C_LEFT, this);
lp_var_t<uint32_t> wdtCanLeft =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::P60DOCK_WDT_CAN_LEFT, this);
lp_var_t<uint32_t>(sid.objectId, pool::P60DOCK_WDT_CAN_LEFT, this);
lp_var_t<uint8_t> wdtCspLeft1 =
lp_var_t<uint8_t>(sid.objectId, P60System::pool::P60DOCK_WDT_CSP_LEFT_1, this);
lp_var_t<uint8_t>(sid.objectId, pool::P60DOCK_WDT_CSP_LEFT_1, this);
lp_var_t<uint8_t> wdtCspLeft2 =
lp_var_t<uint8_t>(sid.objectId, P60System::pool::P60DOCK_WDT_CSP_LEFT_2, this);
lp_var_t<uint8_t>(sid.objectId, pool::P60DOCK_WDT_CSP_LEFT_2, this);
lp_var_t<int16_t> batteryChargeCurrent =
lp_var_t<int16_t>(sid.objectId, P60System::pool::P60DOCK_BATT_CHARGE_CURRENT, this);
lp_var_t<int16_t>(sid.objectId, pool::P60DOCK_BATT_CHARGE_CURRENT, this);
lp_var_t<int16_t> batteryDischargeCurrent =
lp_var_t<int16_t>(sid.objectId, P60System::pool::P60DOCK_BATT_DISCHARGE_CURRENT, this);
lp_var_t<int8_t> ant6Depl =
lp_var_t<int8_t>(sid.objectId, P60System::pool::P60DOCK_ANT6_DEPL, this);
lp_var_t<int8_t> ar6Depl =
lp_var_t<int8_t>(sid.objectId, P60System::pool::P60DOCK_AR6_DEPL, this);
lp_var_t<int16_t>(sid.objectId, pool::P60DOCK_BATT_DISCHARGE_CURRENT, this);
lp_var_t<int8_t> ant6Depl = lp_var_t<int8_t>(sid.objectId, pool::P60DOCK_ANT6_DEPL, this);
lp_var_t<int8_t> ar6Depl = lp_var_t<int8_t>(sid.objectId, pool::P60DOCK_AR6_DEPL, this);
lp_vec_t<uint8_t, P60Dock::NUM_DEVS> devicesType =
lp_vec_t<uint8_t, P60Dock::NUM_DEVS>(sid.objectId, P60System::pool::DEVICES_TYPE, this);
lp_vec_t<uint8_t, P60Dock::NUM_DEVS>(sid.objectId, pool::DEVICES_TYPE, this);
lp_vec_t<uint8_t, P60Dock::NUM_DEVS> devicesStatus =
lp_vec_t<uint8_t, P60Dock::NUM_DEVS>(sid.objectId, P60System::pool::DEVICES_STATUS, this);
lp_vec_t<uint8_t, P60Dock::NUM_DEVS>(sid.objectId, pool::DEVICES_STATUS, this);
};
} // namespace P60Dock
@ -336,12 +312,74 @@ class HkTableDataset : public StaticLocalDataSet<32> {
* @brief Constants common for both PDU1 and PDU2.
*/
namespace PDU {
/** When retrieving full configuration parameter table */
static const uint16_t MAX_REPLY_LENGTH = 318;
namespace pool {
enum Ids {
// IDs for both PDUs
PDU_CURRENTS,
PDU_VOLTAGES,
PDU_VCC,
PDU_VBAT,
PDU_TEMPERATURE,
PDU_CONV_EN,
PDU_OUT_ENABLE,
PDU_BOOTCAUSE,
PDU_BOOTCNT,
PDU_UPTIME,
PDU_RESETCAUSE,
PDU_BATT_MODE,
PDU_LATCHUPS,
PDU_DEVICES,
PDU_STATUSES,
PDU_WDT_CNT_GND,
PDU_WDT_CNT_I2C,
PDU_WDT_CNT_CAN,
PDU_WDT_CNT_CSP1,
PDU_WDT_CNT_CSP2,
PDU_WDT_GND_LEFT,
PDU_WDT_I2C_LEFT,
PDU_WDT_CAN_LEFT,
PDU_WDT_CSP_LEFT1,
PDU_WDT_CSP_LEFT2,
OUT_ON_CNT,
OUT_OFF_CNT,
INIT_OUT_NORM,
INIT_OUT_SAFE,
INIT_ON_DLY,
INIT_OFF_DLY,
SAFE_OFF_DLY,
CUR_LU_LIM,
CUR_LIM,
CUR_EMA,
OUT_LINK,
OUT_CONV,
OUT_VOLTAGE,
CONV_EN,
CUR_EMA_GAIN,
BATT_HWMAX,
BATT_MAX,
BATT_NORM,
BATT_SAFE,
BATT_CRIT,
WDT_I2C_RST,
WDT_CAN_RST,
WDT_I2C,
WDT_CAN,
WDT_CSP,
WDT_CSP_PING,
WDT_CSP_CHAN,
WDT_CSP_ADDR
};
}
static const uint16_t MAX_CONFIGTABLE_ADDRESS = 316;
static const uint16_t MAX_HKTABLE_ADDRESS = 141;
/** The size of the csp reply containing the housekeeping table data */
static const uint16_t HK_TABLE_REPLY_SIZE = 303;
static const uint16_t HK_TABLE_SIZE = P60PDU_HK_SIZE;
static const uint16_t CONFIG_TABLE_SIZE = P60PDU_PARAM_SIZE;
/** When retrieving full configuration parameter table */
static const uint16_t MAX_REPLY_SIZE = CONFIG_TABLE_SIZE;
static const uint8_t HK_TABLE_ENTRIES = 73;
static constexpr uint8_t CHANNELS_LEN = 9;
@ -354,22 +392,53 @@ class PduCoreHk : public StaticLocalDataSet<9> {
PduCoreHk(object_id_t objectId, uint32_t setId) : StaticLocalDataSet(sid_t(objectId, setId)) {}
/** Measured output currents */
lp_vec_t<int16_t, 9> currents =
lp_vec_t<int16_t, 9>(sid.objectId, P60System::pool::PDU_CURRENTS, this);
lp_vec_t<int16_t, 9> currents = lp_vec_t<int16_t, 9>(sid.objectId, pool::PDU_CURRENTS, this);
/** Measured output currents */
lp_vec_t<int16_t, 9> voltages =
lp_vec_t<int16_t, 9>(sid.objectId, P60System::pool::PDU_VOLTAGES, this);
lp_vec_t<int16_t, 9> voltages = lp_vec_t<int16_t, 9>(sid.objectId, pool::PDU_VOLTAGES, this);
/** Output switch states */
lp_vec_t<uint8_t, 9> outputEnables =
lp_vec_t<uint8_t, 9>(sid.objectId, P60System::pool::PDU_OUT_ENABLE, this);
lp_vec_t<uint8_t, 9>(sid.objectId, pool::PDU_OUT_ENABLE, this);
/** Number of reboots */
lp_var_t<uint32_t> bootcount =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::PDU_BOOTCNT, this);
lp_var_t<uint32_t> bootcount = lp_var_t<uint32_t>(sid.objectId, pool::PDU_BOOTCNT, this);
/** Battery mode: 1 = Critical, 2 = Safe, 3 = Normal, 4 = Full */
lp_var_t<uint8_t> battMode =
lp_var_t<uint8_t>(sid.objectId, P60System::pool::PDU_BATT_MODE, this);
lp_var_t<float> temperature =
lp_var_t<float>(sid.objectId, P60System::pool::PDU_TEMPERATURE, this);
lp_var_t<uint8_t> battMode = lp_var_t<uint8_t>(sid.objectId, pool::PDU_BATT_MODE, this);
lp_var_t<float> temperature = lp_var_t<float>(sid.objectId, pool::PDU_TEMPERATURE, this);
};
class PduConfig : public StaticLocalDataSet<32> {
public:
PduConfig(HasLocalDataPoolIF* owner, uint32_t setId) : StaticLocalDataSet(owner, setId) {}
lp_vec_t<uint16_t, 9> outOnDelaySecs =
lp_vec_t<uint16_t, 9>(sid.objectId, pool::OUT_ON_CNT, this);
lp_vec_t<uint16_t, 9> outOffDelaySecs =
lp_vec_t<uint16_t, 9>(sid.objectId, pool::OUT_OFF_CNT, this);
lp_vec_t<uint8_t, 9> initOutNorm = lp_vec_t<uint8_t, 9>(sid.objectId, pool::INIT_OUT_NORM, this);
lp_vec_t<uint8_t, 9> initOutSafe = lp_vec_t<uint8_t, 9>(sid.objectId, pool::INIT_OUT_SAFE, this);
lp_vec_t<uint16_t, 9> initOnDly = lp_vec_t<uint16_t, 9>(sid.objectId, pool::INIT_ON_DLY, this);
lp_vec_t<uint16_t, 9> initOffDly = lp_vec_t<uint16_t, 9>(sid.objectId, pool::INIT_OFF_DLY, this);
lp_vec_t<uint8_t, 9> safeOffDly = lp_vec_t<uint8_t, 9>(sid.objectId, pool::SAFE_OFF_DLY, this);
lp_vec_t<uint16_t, 9> curLuLim = lp_vec_t<uint16_t, 9>(sid.objectId, pool::CUR_LU_LIM, this);
lp_vec_t<uint16_t, 9> curLim = lp_vec_t<uint16_t, 9>(sid.objectId, pool::CUR_LIM, this);
lp_vec_t<uint16_t, 9> curEma = lp_vec_t<uint16_t, 9>(sid.objectId, pool::CUR_EMA, this);
lp_vec_t<uint8_t, 9> outLink = lp_vec_t<uint8_t, 9>(sid.objectId, pool::OUT_LINK, this);
lp_vec_t<uint8_t, 9> outConv = lp_vec_t<uint8_t, 9>(sid.objectId, pool::OUT_CONV, this);
lp_vec_t<uint16_t, 9> outVoltage = lp_vec_t<uint16_t, 9>(sid.objectId, pool::OUT_VOLTAGE, this);
lp_vec_t<uint8_t, 9> convEnable = lp_vec_t<uint8_t, 9>(sid.objectId, pool::CONV_EN, this);
lp_var_t<float> curEmaGain = lp_var_t<float>(sid.objectId, pool::CUR_EMA_GAIN, this);
lp_var_t<uint16_t> battHwMax = lp_var_t<uint16_t>(sid.objectId, pool::BATT_HWMAX, this);
lp_var_t<uint16_t> battMax = lp_var_t<uint16_t>(sid.objectId, pool::BATT_MAX, this);
lp_var_t<uint16_t> battNorm = lp_var_t<uint16_t>(sid.objectId, pool::BATT_NORM, this);
lp_var_t<uint16_t> battSafe = lp_var_t<uint16_t>(sid.objectId, pool::BATT_SAFE, this);
lp_var_t<uint16_t> battCrit = lp_var_t<uint16_t>(sid.objectId, pool::BATT_CRIT, this);
lp_var_t<uint16_t> wdtI2cRst = lp_var_t<uint16_t>(sid.objectId, pool::WDT_I2C_RST, this);
lp_var_t<uint16_t> wdtCanRst = lp_var_t<uint16_t>(sid.objectId, pool::WDT_CAN_RST, this);
lp_var_t<uint32_t> wdtI2c = lp_var_t<uint32_t>(sid.objectId, pool::WDT_I2C, this);
lp_var_t<uint32_t> wdtCan = lp_var_t<uint32_t>(sid.objectId, pool::WDT_CAN, this);
lp_vec_t<uint32_t, 2> wdtCsp = lp_vec_t<uint32_t, 2>(sid.objectId, pool::WDT_CSP, this);
lp_vec_t<uint8_t, 2> wdtCspPing = lp_vec_t<uint8_t, 2>(sid.objectId, pool::WDT_CSP_PING, this);
lp_vec_t<uint8_t, 2> wdtCspChannel = lp_vec_t<uint8_t, 2>(sid.objectId, pool::WDT_CSP_CHAN, this);
lp_vec_t<uint8_t, 2> wdtCspAddr = lp_vec_t<uint8_t, 2>(sid.objectId, pool::WDT_CSP_ADDR, this);
};
/**
@ -382,66 +451,57 @@ class PduAuxHk : public StaticLocalDataSet<36> {
PduAuxHk(object_id_t objectId, uint32_t setId) : StaticLocalDataSet(sid_t(objectId, setId)) {}
/** Measured VCC */
lp_var_t<int16_t> vcc = lp_var_t<int16_t>(sid.objectId, P60System::pool::PDU_VCC, this);
lp_var_t<int16_t> vcc = lp_var_t<int16_t>(sid.objectId, pool::PDU_VCC, this);
/** Measured VBAT */
lp_var_t<int16_t> vbat = lp_var_t<int16_t>(sid.objectId, P60System::pool::PDU_VBAT, this);
lp_var_t<int16_t> vbat = lp_var_t<int16_t>(sid.objectId, pool::PDU_VBAT, this);
/** Output converter enable status */
lp_vec_t<uint8_t, 3> converterEnable =
lp_vec_t<uint8_t, 3>(sid.objectId, P60System::pool::PDU_CONV_EN, this);
lp_vec_t<uint8_t, 3>(sid.objectId, pool::PDU_CONV_EN, this);
lp_var_t<uint32_t> bootcause =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::PDU_BOOTCAUSE, this);
lp_var_t<uint32_t> bootcause = lp_var_t<uint32_t>(sid.objectId, pool::PDU_BOOTCAUSE, this);
/** Uptime in seconds */
lp_var_t<uint32_t> uptime = lp_var_t<uint32_t>(sid.objectId, P60System::pool::PDU_UPTIME, this);
lp_var_t<uint16_t> resetcause =
lp_var_t<uint16_t>(sid.objectId, P60System::pool::PDU_RESETCAUSE, this);
lp_var_t<uint32_t> uptime = lp_var_t<uint32_t>(sid.objectId, pool::PDU_UPTIME, this);
lp_var_t<uint16_t> resetcause = lp_var_t<uint16_t>(sid.objectId, pool::PDU_RESETCAUSE, this);
/** Number of detected latchups on each output channel */
lp_vec_t<uint16_t, 9> latchups =
lp_vec_t<uint16_t, 9>(sid.objectId, P60System::pool::PDU_LATCHUPS, this);
lp_vec_t<uint16_t, 9> latchups = lp_vec_t<uint16_t, 9>(sid.objectId, pool::PDU_LATCHUPS, this);
/**
* There are 8 devices on the PDU. FRAM, ADCs, temperature sensor etc. Each device is
* identified by an ID. Refer also to gs-man-nanopower-p60-pdu-200-1.pdf on pages 17 and 18.
*/
lp_vec_t<uint8_t, 8> deviceTypes =
lp_vec_t<uint8_t, 8>(sid.objectId, P60System::pool::PDU_DEVICES, this);
lp_vec_t<uint8_t, 8> deviceTypes = lp_vec_t<uint8_t, 8>(sid.objectId, pool::PDU_DEVICES, this);
/** The status of each device. 0 = None, 1 = Ok, 2 = Error, 3 = Not found */
lp_vec_t<uint8_t, 8> devicesStatus =
lp_vec_t<uint8_t, 8>(sid.objectId, P60System::pool::PDU_STATUSES, this);
lp_vec_t<uint8_t, 8> devicesStatus = lp_vec_t<uint8_t, 8>(sid.objectId, pool::PDU_STATUSES, this);
/** Number of reboots triggered by the ground watchdog */
lp_var_t<uint32_t> gndWdtReboots =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::PDU_WDT_CNT_GND, this);
lp_var_t<uint32_t> gndWdtReboots = lp_var_t<uint32_t>(sid.objectId, pool::PDU_WDT_CNT_GND, this);
/** Number of reboots triggered through the I2C watchdog. Not relevant for EIVE. */
lp_var_t<uint32_t> i2cWdtReboots =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::PDU_WDT_CNT_I2C, this);
lp_var_t<uint32_t> i2cWdtReboots = lp_var_t<uint32_t>(sid.objectId, pool::PDU_WDT_CNT_I2C, this);
/** Number of reboots triggered through the CAN watchdog */
lp_var_t<uint32_t> canWdtReboots =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::PDU_WDT_CNT_CAN, this);
lp_var_t<uint32_t> canWdtReboots = lp_var_t<uint32_t>(sid.objectId, pool::PDU_WDT_CNT_CAN, this);
/** Number of reboots triggered through the CSP watchdog */
lp_var_t<uint32_t> csp1WdtReboots =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::PDU_WDT_CNT_CSP1, this);
lp_var_t<uint32_t>(sid.objectId, pool::PDU_WDT_CNT_CSP1, this);
lp_var_t<uint32_t> csp2WdtReboots =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::PDU_WDT_CNT_CSP2, this);
lp_var_t<uint32_t>(sid.objectId, pool::PDU_WDT_CNT_CSP2, this);
/** Ground watchdog remaining seconds before rebooting */
lp_var_t<uint32_t> groundWatchdogSecondsLeft =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::PDU_WDT_GND_LEFT, this);
lp_var_t<uint32_t>(sid.objectId, pool::PDU_WDT_GND_LEFT, this);
/** I2C watchdog remaining seconds before rebooting. Not relevant for EIVE. */
lp_var_t<uint32_t> i2cWatchdogSecondsLeft =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::PDU_WDT_I2C_LEFT, this);
lp_var_t<uint32_t>(sid.objectId, pool::PDU_WDT_I2C_LEFT, this);
/** CAN watchdog remaining seconds before rebooting. */
lp_var_t<uint32_t> canWatchdogSecondsLeft =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::PDU_WDT_CAN_LEFT, this);
lp_var_t<uint32_t>(sid.objectId, pool::PDU_WDT_CAN_LEFT, this);
/** CSP watchdogs remaining pings before rebooting. */
lp_var_t<uint8_t> csp2WatchdogPingsLeft =
lp_var_t<uint8_t>(sid.objectId, P60System::pool::PDU_WDT_CSP_LEFT1, this);
lp_var_t<uint8_t>(sid.objectId, pool::PDU_WDT_CSP_LEFT1, this);
lp_var_t<uint8_t> csp1WatchdogPingsLeft =
lp_var_t<uint8_t>(sid.objectId, P60System::pool::PDU_WDT_CSP_LEFT2, this);
lp_var_t<uint8_t>(sid.objectId, pool::PDU_WDT_CSP_LEFT2, this);
};
} // namespace PDU
namespace PDU1 {
@ -491,6 +551,12 @@ class Pdu1AuxHk : public ::PDU::PduAuxHk {
: PduAuxHk(objectId, static_cast<uint32_t>(::P60System::SetIds::PDU_1_AUX)) {}
};
class Pdu1Config : public ::PDU::PduConfig {
public:
Pdu1Config(HasLocalDataPoolIF* owner)
: PduConfig(owner, static_cast<uint32_t>(::P60System::SetIds::PDU_1_CONFIG)) {}
};
} // namespace PDU1
namespace PDU2 {
@ -540,16 +606,48 @@ class Pdu2AuxHk : public ::PDU::PduAuxHk {
: PduAuxHk(objectId, static_cast<uint32_t>(::P60System::SetIds::PDU_2_AUX)) {}
};
class Pdu2Config : public ::PDU::PduConfig {
public:
Pdu2Config(HasLocalDataPoolIF* owner)
: PduConfig(owner, static_cast<uint32_t>(::P60System::SetIds::PDU_2_CONFIG)) {}
};
} // namespace PDU2
namespace ACU {
/* When receiving full housekeeping (telemetry) table */
static const uint16_t MAX_REPLY_LENGTH = 262;
namespace pool {
enum Ids : lp_id_t {
/** ACU Ids */
ACU_CURRENT_IN_CHANNELS,
ACU_VOLTAGE_IN_CHANNELS,
ACU_VCC,
ACU_VBAT,
ACU_TEMPERATURES,
ACU_MPPT_MODE,
ACU_VBOOST_IN_CHANNELS,
ACU_POWER_IN_CHANNELS,
ACU_DAC_ENABLES,
ACU_DAC_RAW_CHANNELS,
ACU_BOOTCAUSE,
ACU_BOOTCNT,
ACU_UPTIME,
ACU_RESET_CAUSE,
ACU_MPPT_TIME,
ACU_MPPT_PERIOD,
ACU_DEVICES,
ACU_DEVICES_STATUS,
ACU_WDT_CNT_GND,
ACU_WDT_GND_LEFT
};
}
static const uint16_t MAX_CONFIGTABLE_ADDRESS = 26;
static const uint16_t MAX_HKTABLE_ADDRESS = 120;
static const uint8_t HK_TABLE_ENTRIES = 64;
static const uint16_t HK_TABLE_REPLY_SIZE = 262;
static const uint16_t HK_TABLE_SIZE = P60ACU_HK_SIZE;
static const uint16_t CONFIG_TABLE_SIZE = P60ACU_PARAM_SIZE;
static const size_t MAX_REPLY_SIZE = HK_TABLE_SIZE;
class CoreHk : public StaticLocalDataSet<14> {
public:
@ -559,31 +657,27 @@ class CoreHk : public StaticLocalDataSet<14> {
CoreHk(object_id_t objectId)
: StaticLocalDataSet(sid_t(objectId, static_cast<uint32_t>(::P60System::SetIds::ACU_CORE))) {}
lp_var_t<uint8_t> mpptMode =
lp_var_t<uint8_t>(sid.objectId, P60System::pool::ACU_MPPT_MODE, this);
lp_var_t<uint8_t> mpptMode = lp_var_t<uint8_t>(sid.objectId, pool::ACU_MPPT_MODE, this);
lp_vec_t<int16_t, 6> currentInChannels =
lp_vec_t<int16_t, 6>(sid.objectId, P60System::pool::ACU_CURRENT_IN_CHANNELS, this);
lp_vec_t<int16_t, 6>(sid.objectId, pool::ACU_CURRENT_IN_CHANNELS, this);
lp_vec_t<uint16_t, 6> voltageInChannels =
lp_vec_t<uint16_t, 6>(sid.objectId, P60System::pool::ACU_VOLTAGE_IN_CHANNELS, this);
lp_vec_t<uint16_t, 6>(sid.objectId, pool::ACU_VOLTAGE_IN_CHANNELS, this);
lp_var_t<uint16_t> vcc = lp_var_t<uint16_t>(sid.objectId, P60System::pool::ACU_VCC, this);
lp_var_t<uint16_t> vbat = lp_var_t<uint16_t>(sid.objectId, P60System::pool::ACU_VBAT, this);
lp_var_t<uint16_t> vcc = lp_var_t<uint16_t>(sid.objectId, pool::ACU_VCC, this);
lp_var_t<uint16_t> vbat = lp_var_t<uint16_t>(sid.objectId, pool::ACU_VBAT, this);
lp_vec_t<uint16_t, 6> vboostInChannels =
lp_vec_t<uint16_t, 6>(sid.objectId, P60System::pool::ACU_VBOOST_IN_CHANNELS, this);
lp_vec_t<uint16_t, 6>(sid.objectId, pool::ACU_VBOOST_IN_CHANNELS, this);
lp_vec_t<uint16_t, 6> powerInChannels =
lp_vec_t<uint16_t, 6>(sid.objectId, P60System::pool::ACU_POWER_IN_CHANNELS, this);
lp_vec_t<uint16_t, 6>(sid.objectId, pool::ACU_POWER_IN_CHANNELS, this);
lp_vec_t<float, 3> temperatures =
lp_vec_t<float, 3>(sid.objectId, P60System::pool::ACU_TEMPERATURES, this);
lp_vec_t<float, 3> temperatures = lp_vec_t<float, 3>(sid.objectId, pool::ACU_TEMPERATURES, this);
lp_var_t<uint32_t> bootcnt = lp_var_t<uint32_t>(sid.objectId, P60System::pool::ACU_BOOTCNT, this);
lp_var_t<uint32_t> uptime = lp_var_t<uint32_t>(sid.objectId, P60System::pool::ACU_UPTIME, this);
lp_var_t<uint16_t> mpptTime =
lp_var_t<uint16_t>(sid.objectId, P60System::pool::ACU_MPPT_TIME, this);
lp_var_t<uint16_t> mpptPeriod =
lp_var_t<uint16_t>(sid.objectId, P60System::pool::ACU_MPPT_PERIOD, this);
lp_var_t<uint32_t> bootcnt = lp_var_t<uint32_t>(sid.objectId, pool::ACU_BOOTCNT, this);
lp_var_t<uint32_t> uptime = lp_var_t<uint32_t>(sid.objectId, pool::ACU_UPTIME, this);
lp_var_t<uint16_t> mpptTime = lp_var_t<uint16_t>(sid.objectId, pool::ACU_MPPT_TIME, this);
lp_var_t<uint16_t> mpptPeriod = lp_var_t<uint16_t>(sid.objectId, pool::ACU_MPPT_PERIOD, this);
};
/**
* @brief This class defines a dataset for the hk table of the ACU.
@ -596,31 +690,25 @@ class AuxHk : public StaticLocalDataSet<12> {
AuxHk(object_id_t objectId)
: StaticLocalDataSet(sid_t(objectId, static_cast<uint32_t>(::P60System::SetIds::ACU_AUX))) {}
lp_vec_t<uint8_t, 3> dacEnables =
lp_vec_t<uint8_t, 3>(sid.objectId, P60System::pool::ACU_DAC_ENABLES, this);
lp_vec_t<uint8_t, 3> dacEnables = lp_vec_t<uint8_t, 3>(sid.objectId, pool::ACU_DAC_ENABLES, this);
lp_vec_t<uint16_t, 6> dacRawChannelVals =
lp_vec_t<uint16_t, 6>(sid.objectId, P60System::pool::ACU_DAC_RAW_CHANNELS, this);
lp_vec_t<uint16_t, 6>(sid.objectId, pool::ACU_DAC_RAW_CHANNELS, this);
lp_var_t<uint32_t> bootCause =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::ACU_BOOTCAUSE, this);
lp_var_t<uint16_t> resetCause =
lp_var_t<uint16_t>(sid.objectId, P60System::pool::ACU_RESET_CAUSE, this);
lp_var_t<uint32_t> bootCause = lp_var_t<uint32_t>(sid.objectId, pool::ACU_BOOTCAUSE, this);
lp_var_t<uint16_t> resetCause = lp_var_t<uint16_t>(sid.objectId, pool::ACU_RESET_CAUSE, this);
lp_var_t<uint32_t> wdtCntGnd =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::ACU_WDT_CNT_GND, this);
lp_var_t<uint32_t> wdtGndLeft =
lp_var_t<uint32_t>(sid.objectId, P60System::pool::ACU_WDT_GND_LEFT, this);
lp_var_t<uint32_t> wdtCntGnd = lp_var_t<uint32_t>(sid.objectId, pool::ACU_WDT_CNT_GND, this);
lp_var_t<uint32_t> wdtGndLeft = lp_var_t<uint32_t>(sid.objectId, pool::ACU_WDT_GND_LEFT, this);
/**
* There are 8 devices on the PDU. FRAM, ADCs, temperature sensor etc. Each device is
* identified by an ID. Refer also to gs-man-nanopower-p60-pdu-200-1.pdf on pages 17 and 18.
*/
lp_vec_t<uint8_t, 8> deviceTypes =
lp_vec_t<uint8_t, 8>(sid.objectId, P60System::pool::ACU_DEVICES, this);
lp_vec_t<uint8_t, 8> deviceTypes = lp_vec_t<uint8_t, 8>(sid.objectId, pool::ACU_DEVICES, this);
/** The status of each device. 0 = None, 1 = Ok, 2 = Error, 3 = Not found */
lp_vec_t<uint8_t, 8> devicesStatus =
lp_vec_t<uint8_t, 8>(sid.objectId, P60System::pool::ACU_DEVICES_STATUS, this);
lp_vec_t<uint8_t, 8>(sid.objectId, pool::ACU_DEVICES_STATUS, this);
};
} // namespace ACU

View File

@ -23,6 +23,7 @@ if command -v ${cmake_fmt} &> /dev/null; then
for dir in ${folder_list[@]}; do
find ${dir} ${file_selectors} | xargs ${cmake_fmt} -i
done
${cmake_fmt} -i ./thirdparty/gomspace-sw/CMakeLists.txt
else
echo "No ${cmake_fmt} tool found, not formatting CMake files"
fi

1
thirdparty/gomspace-sw vendored Submodule

@ -0,0 +1 @@
Subproject commit 15d489b884f46d232ec7d8879e7355d83873f06f

View File

@ -1,12 +0,0 @@
cmake_minimum_required(VERSION 3.13)
set(LIB_CSP_NAME libcsp)
add_library(${LIB_CSP_NAME})
add_subdirectory(src)
add_subdirectory(include)
target_include_directories(${LIB_CSP_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)

View File

@ -1,6 +0,0 @@
import sys
if sys.version_info >= (3, 0):
from libcsp_py3 import *
else:
from libcsp_py2 import *

View File

@ -1,123 +0,0 @@
Client and server example
=========================
The following examples show the initialization of the protocol stack and examples of client/server code.
Initialization Sequence
-----------------------
This code initializes the CSP buffer system, device drivers and router core. The example uses the CAN interface function csp_can_tx but the initialization is similar for other interfaces. The loopback interface does not require any explicit initialization.
.. code-block:: c
#include <csp/csp.h>
#include <csp/interfaces/csp_if_can.h>
/* CAN configuration struct for SocketCAN interface "can0" */
struct csp_can_config can_conf = {.ifc = "can0"};
/* Init buffer system with 10 packets of maximum 320 bytes each */
csp_buffer_init(10, 320);
/* Init CSP with address 1 */
csp_init(1);
/* Init the CAN interface with hardware filtering */
csp_can_init(CSP_CAN_MASKED, &can_conf)
/* Setup default route to CAN interface */
csp_route_set(CSP_DEFAULT_ROUTE, &csp_can_tx, CSP_HOST_MAC);
/* Start router task with 500 word stack, OS task priority 1 */
csp_route_start_task(500, 1);
Server
------
This example shows how to create a server task that listens for incoming connections. CSP should be initialized before starting this task. Note the use of `csp_service_handler()` as the default branch in the port switch case. The service handler will automatically reply to ICMP-like requests, such as pings and buffer status requests.
.. code-block:: c
void csp_task(void *parameters) {
/* Create socket without any socket options */
csp_socket_t *sock = csp_socket(CSP_SO_NONE);
/* Bind all ports to socket */
csp_bind(sock, CSP_ANY);
/* Create 10 connections backlog queue */
csp_listen(sock, 10);
/* Pointer to current connection and packet */
csp_conn_t *conn;
csp_packet_t *packet;
/* Process incoming connections */
while (1) {
/* Wait for connection, 10000 ms timeout */
if ((conn = csp_accept(sock, 10000)) == NULL)
continue;
/* Read packets. Timout is 1000 ms */
while ((packet = csp_read(conn, 1000)) != NULL) {
switch (csp_conn_dport(conn)) {
case MY_PORT:
/* Process packet here */
default:
/* Let the service handler reply pings, buffer use, etc. */
csp_service_handler(conn, packet);
break;
}
}
/* Close current connection, and handle next */
csp_close(conn);
}
}
Client
------
This example shows how to allocate a packet buffer, connect to another host and send the packet. CSP should be initialized before calling this function. RDP, XTEA, HMAC and CRC checksums can be enabled per connection, by setting the connection option to a bitwise OR of any combination of `CSP_O_RDP`, `CSP_O_XTEA`, `CSP_O_HMAC` and `CSP_O_CRC`.
.. code-block:: c
int send_packet(void) {
/* Get packet buffer for data */
csp_packet_t *packet = csp_buffer_get(data_size);
if (packet == NULL) {
/* Could not get buffer element */
printf("Failed to get buffer element\\n");
return -1;
}
/* Connect to host HOST, port PORT with regular UDP-like protocol and 1000 ms timeout */
csp_conn_t *conn = csp_connect(CSP_PRIO_NORM, HOST, PORT, 1000, CSP_O_NONE);
if (conn == NULL) {
/* Connect failed */
printf("Connection failed\\n");
/* Remember to free packet buffer */
csp_buffer_free(packet);
return -1;
}
/* Copy message to packet */
char *msg = "HELLO";
strcpy(packet->data, msg);
/* Set packet length */
packet->length = strlen(msg);
/* Send packet */
if (!csp_send(conn, packet, 1000)) {
/* Send failed */
printf("Send failed\\n");
csp_buffer_free(packet);
}
/* Close connection */
csp_close(conn);
return 0
}

View File

@ -1,17 +0,0 @@
History
=======
The idea was developed by a group of students from Aalborg University in 2008. In 2009 the main developer started working for GomSpace, and CSP became integrated into the GomSpace products. The protocol is based on a 32-bit header containing both transport, network and MAC-layer information. It's implementation is designed for, but not limited to, embedded systems such as the 8-bit AVR microprocessor and the 32-bit ARM and AVR from Atmel. The implementation is written in C and is currently ported to run on FreeRTOS and POSIX and pthreads based operating systems like Linux and BSD. The three letter acronym CSP was originally an abbreviation for CAN Space Protocol because the first MAC-layer driver was written for CAN-bus. Now the physical layer has extended to include spacelink, I2C and RS232, the name was therefore extended to the more general CubeSat Space Protocol without changing the abbreviation.
Satellites using CSP
--------------------
This is the known list of satellites or organisations that uses CSP.
* GomSpace GATOSS GOMX-1
* AAUSAT-3
* EgyCubeSat
* EuroLuna
* NUTS
* Hawaiian Space Flight Laboratory
* GomSpace GOMX-3

View File

@ -1,95 +0,0 @@
CSP Interfaces
==============
This is an example of how to implement a new layer-2 interface in CSP. The example is going to show how to create a `csp_if_fifo`, using a set of [named pipes](http://en.wikipedia.org/wiki/Named_pipe). The complete interface example code can be found in `examples/fifo.c`. For an example of a fragmenting interface, see the CAN interface in `src/interfaces/csp_if_can.c`.
CSP interfaces are declared in a `csp_iface_t` structure, which sets the interface nexthop function and name. A maximum transmission unit can also be set, which forces CSP to drop outgoing packets above a certain size. The fifo interface is defined as:
.. code-block:: c
#include <csp/csp.h>
#include <csp/csp_interface.h>
csp_iface_t csp_if_fifo = {
.name = "fifo",
.nexthop = csp_fifo_tx,
.mtu = BUF_SIZE,
};
Outgoing traffic
----------------
The nexthop function takes a pointer to a CSP packet and a timeout as parameters. All outgoing packets that are routed to the interface are passed to this function:
.. code-block:: c
int csp_fifo_tx(csp_packet_t *packet, uint32_t timeout) {
write(tx_channel, &packet->length, packet->length + sizeof(uint32_t) + sizeof(uint16_t));
csp_buffer_free(packet);
return 1;
}
In the fifo interface, we simply transmit the header, length field and data using a write to the fifo. CSP does not dictate the wire format, so other interfaces may decide to e.g. ignore the length field if the physical layer provides start/stop flags.
_Important notice: If the transmission succeeds, the interface must free the packet and return 1. If transmission fails, the nexthop function should return 0 and not free the packet, to allow retransmissions by the caller._
Incoming traffic
----------------
The interface also needs to receive incoming packets and pass it to the CSP protocol stack. In the fifo interface, this is handled by a thread that blocks on the incoming fifo and waits for packets:
.. code-block:: c
void * fifo_rx(void * parameters) {
csp_packet_t *buf = csp_buffer_get(BUF_SIZE);
/* Wait for packet on fifo */
while (read(rx_channel, &buf->length, BUF_SIZE) > 0) {
csp_qfifo_write(buf, &csp_if_fifo, NULL);
buf = csp_buffer_get(BUF_SIZE);
}
}
A new CSP buffer is preallocated with csp_buffer_get(). When data is received, the packet is passed to CSP using `csp_qfifo_write()` and a new buffer is allocated for the next packet. In addition to the received packet, `csp_qfifo_write()` takes two additional arguments:
.. code-block:: c
void csp_qfifo_write(csp_packet_t *packet, csp_iface_t *interface, CSP_BASE_TYPE *pxTaskWoken);
The calling interface must be passed in `interface` to avoid routing loops. Furthermore, `pxTaskWoken` must be set to a non-NULL value if the packet is received in an interrupt service routine. If the packet is received in task context, NULL must be passed. 'pxTaskWoken' only applies to FreeRTOS systems, and POSIX system should always set the value to NULL.
`csp_qfifo_write` will either accept the packet or free the packet buffer, so the interface must never free the packet after passing it to CSP.
Initialization
--------------
In order to initialize the interface, and make it available to the router, use the following function found in `csp/csp_interface.h`:
.. code-block:: c
csp_route_add_if(&csp_if_fifo);
This actually happens automatically if you try to call `csp_route_add()` with an interface that is unknown to the router. This may however be removed in the future, in order to ensure that all interfaces are initialised before configuring the routing table. The reason is, that some products released in the future may ship with an empty routing table, which is then configured by a routing protocol rather than a static configuration.
In order to setup a manual static route, use the following example where the default route is set to the fifo interface:
.. code-block:: c
csp_route_set(CSP_DEFAULT_ROUTE, &csp_if_fifo, CSP_NODE_MAC);
All outgoing traffic except loopback, is now passed to the fifo interface's nexthop function.
Building the example
--------------------
The fifo examples can be compiled with:
.. code-block:: bash
% gcc csp_if_fifo.c -o csp_if_fifo -I<CSP PATH>/include -L<CSP PATH>/build -lcsp -lpthread -lrt
The two named pipes are created with:
.. code-block:: bash
% mkfifo server_to_client client_to_server

View File

@ -1,21 +0,0 @@
.. CSP Documentation master file.
.. _libcsp:
**********************
CubeSat Space Protocol
**********************
.. toctree::
:maxdepth: 3
../README
history
structure
interfaces
memory
protocolstack
topology
mtu
example

View File

@ -1,28 +0,0 @@
How CSP uses memory
===================
CSP has been written for small microprocessor systems. The way memory is handled is therefore a tradeoff between the amount used and the code efficiency. This section tries to give some answers to what the memory is used for and how it it used. The primary memory blocks in use by CSP is:
* Routing table
* Ports table
* Connection table
* Buffer pool
* Interface list
Tables
------
The reason for using tables for the routes, ports and connections is speed. When a new packet arrives the core of CSP needs to do a quick lookup in the connection so see if it can find an existing connection to which the packet matches. If this is not found, it will take a lookup in the ports table to see if there are any applications listening on the incoming port number. Another argument of using tables are pre-allocation. The linker will reserve an area of the memory for which the routes and connections can be stored. This avoid an expensive `malloc()` call during initialization of CSP, and practically costs zero CPU instructions. The downside of using tables are the wasted memory used by unallocated ports and connections. For the routing table the argumentation is the same, pre-allocation is better than calling `malloc()`.
Buffer Pool
-----------
The buffer handling system can be compiled for either static allocation or a one-time dynamic allocation of the main memory block. After this, the buffer system is entirely self-contained. All allocated elements are of the same size, so the buffer size must be chosen to be able to handle the maximum possible packet length. The buffer pool uses a queue to store pointers to free buffer elements. First of all, this gives a very quick method to get the next free element since the dequeue is an O(1) operation. Furthermore, since the queue is a protected operating system primitive, it can be accessed from both task-context and interrupt-context. The `csp_buffer_get` version is for task-context and `csp_buffer_get_isr` is for interrupt-context. Using fixed size buffer elements that are preallocated is again a question of speed and safety.
A basic concept of the buffer system is called Zero-Copy. This means that from userspace to the kernel-driver, the buffer is never copied from one buffer to another. This is a big deal for a small microprocessor, where a call to `memcpy()` can be very expensive. In practice when data is inserted into a packet, it is shifted a certain number of bytes in order to allow for a packet header to be prepended at the lower layers. This also means that there is a strict contract between the layers, which data can be modified and where. The buffer object is normally casted to a `csp_packet_t`, but when its given to an interface on the MAC layer it's casted to a `csp_i2c_frame_t` for example.
Interface list
--------------
The interface list is a simple single-ended linked list of references to the interface specification structures. These structures are static const and allocated by the linker. The pointer to this data is inserted into the list one time during setup of the interface. Each entry in the routing table has a direct pointer to the interface element, thereby avoiding list lookup, but the list is needed in order for the dynamic route configuration to know which interfaces are available.

View File

@ -1,19 +0,0 @@
Maximum Transfer Unit
=====================
There are two things limiting the MTU of CSP.
1. The pre-allocated buffer pools allocation size
2. The link layer protocol.
So lets assume that you have made a protocol called KISS with a MTU of 256. The 256 is the total amount of data that you can put into the CSP-packet. However, you need to take the overhead of the link layer into account. Typically this could consist of a length field and/or a start/stop flag. So the actual frame size on the link layer would for example be 256 bytes of data + 2 bytes sync flag + 2 bytes length field.
This requires a buffer allocation of at lest 256 + 2 + 2. However, the CSP packet itself has some reserved bytes in the beginning of the packet (which you can see in csp.h) - so the recommended buffer allocation size is MAX MTU + 16 bytes. In this case the max MTU would be 256.
If you try to pass data which is longer than the MTU, the chance is that you will also make a buffer overflow in the CSP buffer pool. However, lets assume that you have two interfaces one with an MTU of 200 bytes and another with an MTU of 100 bytes. In this case you might successfully transfer 150 bytes over the first interface, but the packet will be rejected once it comes to the second interface.
If you want to increase your MTU of a specific link layer, it is up to the link layer protocol to implement its own fragmentation protocol. A good example is CAN-bus which only allows a frame size of 8 bytes. libcsp have a small protocol for this called the “CAN fragmentation protocol" or CFP for short. This allows data of much larger size to be transferred over the CAN bus.
Okay, but what if you want to transfer 1000 bytes, and the network maximum MTU is 256? Well, since CSP does not include streaming sockets, only packets. Somebody will have to split that data up into chunks. It might be that you application have special knowledge about the datatype you are transmitting, and that it makes sense to split the 1000 byte content into 10 chunks of 100 byte status messages. This, application layer delimitation might be good if you have a situation with packet loss, because your receiver could still make good usage of the partially delivered chunks.
But, what if you just want 1000 bytes transmitted, and you dont care about the fragmentation unit, and also dont want the hassle of writing the fragmentation code yourself? - In this case, libcsp now features a new (still experimental) feature called SFP (small fragmentation protocol) designed to work on the application layer. For this purpose you will not use csp_send and csp_recv, but csp_sfp_send and csp_sfp_recv. This will split your data into chunks of a certain size, enumerate them and transfer over a given connection. If a chunk is missing the SFP client will abort the reception, because SFP does not provide retransmission. If you wish to also have retransmission and orderly delivery you will have to open an RDP connection and send your SFP message to that connection.

View File

@ -1,54 +0,0 @@
The Protocol Stack
==================
The CSP protocol stack includes functionality on all layers of the TCP/IP model:
Layer 1: Drivers
----------------
Lib CSP is not designed for any specific processor or hardware peripheral, but yet these drivers are required in order to work. The intention of LibCSP is not to provide CAN, I2C or UART drivers for all platforms, however some drivers has been included for some platforms. If you do not find your platform supported, it is quite simple to add a driver that conforms to the CSP interfaces. For example the I2C driver just requires three functions: `init`, `send` and `recv`. For good stability and performance interrupt driven drivers are preferred in favor of polled drivers. Where applicable also DMA usage is recommended.
Layer 2: MAC interfaces
-----------------------
CSP has interfaces for I2C, CAN, RS232 (KISS) and Loopback. The layer 2 protocol software defines a frame-format that is suitable for the media. CSP can be easily extended with implementations for even more links. For example a radio-link and IP-networks. The file `csp_interface.h` declares the rx and tx functions needed in order to define a network interface in CSP. During initialisation of CSP each interface will be inserted into a linked list of interfaces that is available to the router. In cases where link-layer addresses are required, such as I2C, the routing table supports specifying next-hop link-layer address directly. This avoids the need to implement an address resolution protocol to translate CSP addresses to I2C addresses.
Layer 3: Network Router
-----------------------
The router core is the backbone of the CSP implementation. The router works by looking at a 32-bit CSP header which contains the delivery and source address together with port numbers for the connection. Each router supports both local delivery and forwarding of frames to another destination. Frames will never exit the router on the same interface that they arrives at, this concept is called split horizon, and helps prevent routing loops.
The main purpose of the router is to accept incoming packets and deliver them to the right message queue. Therefore, in order to listen on a port-number on the network, a task must create a socket and call the accept() call. This will make the task block and wait for incoming traffic, just like a web-server or similar. When an incoming connection is opened, the task is woken. Depending on the task-priority, the task can even preempt another task and start execution immediately.
There is no routing protocol for automatic route discovery, all routing tables are pre-programmed into the subsystems. The table itself contains a separate route to each of the possible 32 nodes in the network and the additional default route. This means that the overall topology must be decided before putting sub-systems together, as explained in the `topology.md` file. However CSP has an extension on port zero CMP (CSP management protocol), which allows for over-the-network routing table configuration. This has the advantage that default routes could be changed if for example the primary radio fails, and the secondary should be used instead.
Layer 4: Transport Layer
------------------------
LibCSP implements two different Transport Layer protocols, they are called UDP (unreliable datagram protocol) and RDP (reliable datagram protocol). The name UDP has not been chosen to be an exact replica of the UDP (user datagram protocol) known from the TCP/IP model, but they have certain similarities.
The most important thing to notice is that CSP is entirely a datagram service. There is no stream based service like TCP. A datagram is defined a block of data with a specified size and structure. This block enters the transport layer as a single datagram and exits the transport layer in the other end as a single datagram. CSP preserves this structure all the way to the physical layer for I2C, KISS and Loopback interfaces are used. The CAN-bus interface has to fragment the datagram into CAN-frames of 8 bytes, however only a fully completed datagram will arrive at the receiver.
UDP
^^^
UDP uses a simple transmission model without implicit hand-shaking dialogues for guaranteeing reliability, ordering, or data integrity. Thus, UDP provides an unreliable service and datagrams may arrive out of order, appear duplicated, or go missing without notice. UDP assumes that error checking and correction is either not necessary or performed in the application, avoiding the overhead of such processing at the network interface level. Time-sensitive applications often use UDP because dropping packets is preferable to waiting for delayed packets, which may not be an option in a real-time system.
UDP is very practical to implement request/reply based communication where a single packet forms the request and a single packet forms the reply. In this case a typical request and wait protocol is used between the client and server, which will simply return an error if a reply is not received within a specified time limit. An error would normally lead to a retransmission of the request from the user or operator which sent the request.
While UDP is very simple, it also has some limitations. Normally a human in the loop is a good thing when operating the satellite over UDP. But when it comes to larger file transfers, the human becomes the bottleneck. When a high-speed file transfer is initiated data acknowledgment should be done automatically in order to speed up the transfer. This is where the RDP protocol can help.
RDP
^^^
CSP provides a transport layer extension called RDP (reliable datagram protocol) which is an implementation of RFC908 and RFC1151. RDP provides a few additional features:
* Three-way handshake
* Flow Control
* Data-buffering
* Packet re-ordering
* Retransmission
* Windowing
* Extended Acknowledgment
For more information on this, please refer to RFC908.

View File

@ -1,27 +0,0 @@
Structure
=========
The Cubesat Space Protocol library is structured as shown in the following table:
============================= =========================================================================
**Folder** **Description**
============================= =========================================================================
libcsp/include/csp Main include files
libcsp/include/csp/arch Architecture include files
libcsp/include/csp/interfaces Interface include files
libcsp/include/csp/drivers Drivers include files
libcsp/src Main modules for CSP: io, router, connections, services
libcsp/src/interfaces Interface modules for CAN, I2C, KISS, LOOP and ZMQHUB
libcsp/src/drivers/can Driver for CAN
libcsp/src/drivers/usart Driver for USART
libcsp/src/arch/freertos FreeRTOS architecture module
libcsp/src/arch/macosx Mac OS X architecture module
libcsp/src/arch/posix Posix architecture module
libcsp/src/arch/windows Windows architecture module
libcsp/src/rtable Routing table module
libcsp/transport Transport module, UDP and RDP
libcsp/crypto Crypto module
libcsp/utils Utilities
libcsp/bindings/python Python wrapper for libcsp
libcsp/examples CSP examples (source code)
libasf/doc The doc folder contains the source code for this documentation
============================= =========================================================================

View File

@ -1,26 +0,0 @@
Network Topology
================
CSP uses a network oriented terminology similar to what is known from the Internet and the TCP/IP model. A CSP network can be configured for several different topologies. The most common topology is to create two segments, one for the Satellite and one for the Ground-Station.
.. code-block:: none
I2C BUS
_______________________________
/ | | | \
+---+ +---+ +---+ +---+ +---+
|OBC| |COM| |EPS| |PL1| |PL2| Nodes 0 - 7 (Space segment)
+---+ +---+ +---+ +---+ +---+
^
| Radio
v
+---+ +----+
|TNC| ------- | PC | Nodes 8 - 15 (Ground segment)
+---+ USB +----+
Node 9 Node 10
The address range, from 0 to 15, has been segmented into two equal size segments. This allows for easy routing in the network. All addresses starting with binary 1 is on the ground-segment, and all addresses starting with 0 is on the space segment. From CSP v1.0 the address space has been increased to 32 addresses, 0 to 31. But for legacy purposes, the old 0 to 15 is still used in most products.
The network is configured using static routes initialised at boot-up of each sub-system. This means that the basic routing table must be assigned compile-time of each subsystem. However each node supports assigning an individual route to every single node in the network and can be changed run-time. This means that the network topology can be easily reconfigured after startup.

View File

@ -1,165 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdint.h>
#include <csp/csp.h>
#include <csp/csp_interface.h>
#define TYPE_SERVER 1
#define TYPE_CLIENT 2
#define PORT 10
#define BUF_SIZE 250
pthread_t rx_thread;
int rx_channel, tx_channel;
int csp_fifo_tx(csp_iface_t *ifc, csp_packet_t *packet, uint32_t timeout);
csp_iface_t csp_if_fifo = {
.name = "fifo",
.nexthop = csp_fifo_tx,
.mtu = BUF_SIZE,
};
int csp_fifo_tx(csp_iface_t *ifc, csp_packet_t *packet, uint32_t timeout) {
/* Write packet to fifo */
if (write(tx_channel, &packet->length, packet->length + sizeof(uint32_t) + sizeof(uint16_t)) < 0)
printf("Failed to write frame\r\n");
csp_buffer_free(packet);
return CSP_ERR_NONE;
}
void * fifo_rx(void * parameters) {
csp_packet_t *buf = csp_buffer_get(BUF_SIZE);
/* Wait for packet on fifo */
while (read(rx_channel, &buf->length, BUF_SIZE) > 0) {
csp_qfifo_write(buf, &csp_if_fifo, NULL);
buf = csp_buffer_get(BUF_SIZE);
}
return NULL;
}
int main(int argc, char **argv) {
int me, other, type;
const char *message = "Testing CSP";
const char *rx_channel_name;
const char *tx_channel_name;
csp_socket_t *sock;
csp_conn_t *conn;
csp_packet_t *packet;
/* Run as either server or client */
if (argc != 2) {
printf("usage: %s <server/client>\r\n", argv[0]);
return -1;
}
/* Set type */
if (strcmp(argv[1], "server") == 0) {
me = 1;
other = 2;
tx_channel_name = "server_to_client";
rx_channel_name = "client_to_server";
type = TYPE_SERVER;
} else if (strcmp(argv[1], "client") == 0) {
me = 2;
other = 1;
tx_channel_name = "client_to_server";
rx_channel_name = "server_to_client";
type = TYPE_CLIENT;
} else {
printf("Invalid type. Must be either 'server' or 'client'\r\n");
return -1;
}
/* Init CSP and CSP buffer system */
if (csp_init(me) != CSP_ERR_NONE || csp_buffer_init(10, 300) != CSP_ERR_NONE) {
printf("Failed to init CSP\r\n");
return -1;
}
tx_channel = open(tx_channel_name, O_RDWR);
if (tx_channel < 0) {
printf("Failed to open TX channel\r\n");
return -1;
}
rx_channel = open(rx_channel_name, O_RDWR);
if (rx_channel < 0) {
printf("Failed to open RX channel\r\n");
return -1;
}
/* Start fifo RX task */
pthread_create(&rx_thread, NULL, fifo_rx, NULL);
/* Set default route and start router */
csp_route_set(CSP_DEFAULT_ROUTE, &csp_if_fifo, CSP_NODE_MAC);
csp_route_start_task(0, 0);
/* Create socket and listen for incoming connections */
if (type == TYPE_SERVER) {
sock = csp_socket(CSP_SO_NONE);
csp_bind(sock, PORT);
csp_listen(sock, 5);
}
/* Super loop */
while (1) {
if (type == TYPE_SERVER) {
/* Process incoming packet */
conn = csp_accept(sock, 1000);
if (conn) {
packet = csp_read(conn, 0);
if (packet)
printf("Received: %s\r\n", packet->data);
csp_buffer_free(packet);
csp_close(conn);
}
} else {
/* Send a new packet */
packet = csp_buffer_get(strlen(message));
if (packet) {
strcpy((char *) packet->data, message);
packet->length = strlen(message);
conn = csp_connect(CSP_PRIO_NORM, other, PORT, 1000, CSP_O_NONE);
printf("Sending: %s\r\n", message);
if (!conn || !csp_send(conn, packet, 1000))
return -1;
csp_close(conn);
}
sleep(1);
}
}
close(rx_channel);
close(tx_channel);
return 0;
}

View File

@ -1,225 +0,0 @@
#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <ctype.h>
#include <stddef.h>
#undef interface
#include <csp/csp.h>
#include <csp/csp_interface.h>
#define PIPE_BUFSIZE 1024
#define TYPE_SERVER 1
#define TYPE_CLIENT 2
#define PORT 10
#define BUF_SIZE 250
static LPCTSTR pipeName = TEXT("\\\\.\\pipe\\CSP_Pipe");
static HANDLE pipe = INVALID_HANDLE_VALUE;
unsigned WINAPI fifo_rx(void *);
unsigned WINAPI pipe_listener(void *);
void printError(void);
int csp_fifo_tx(csp_packet_t *packet, uint32_t timeout);
csp_iface_t csp_if_fifo = {
.name = "fifo",
.nexthop = csp_fifo_tx,
.mtu = BUF_SIZE,
};
int csp_fifo_tx(csp_packet_t *packet, uint32_t timeout) {
printf("csp_fifo_tx tid: %lu\n", GetCurrentThreadId());
DWORD expectedSent = packet->length + sizeof(uint32_t) + sizeof(uint16_t);
DWORD actualSent;
/* Write packet to fifo */
if( !WriteFile(pipe, &packet->length, expectedSent, &actualSent, NULL)
|| actualSent != expectedSent ) {
printError();
}
csp_buffer_free(packet);
return CSP_ERR_NONE;
}
int main(int argc, char *argv[]) {
int me, other, type;
char *message = "Testing CSP";
csp_socket_t *sock = NULL;
csp_conn_t *conn = NULL;
csp_packet_t *packet = NULL;
/* Run as either server or client */
if (argc != 2) {
printf("usage: server <server/client>\r\n");
return -1;
}
/* Set type */
if (strcmp(argv[1], "server") == 0) {
me = 1;
other = 2;
type = TYPE_SERVER;
} else if (strcmp(argv[1], "client") == 0) {
me = 2;
other = 1;
type = TYPE_CLIENT;
} else {
printf("Invalid type. Must be either 'server' or 'client'\r\n");
return -1;
}
/* Init CSP and CSP buffer system */
if (csp_init(me) != CSP_ERR_NONE || csp_buffer_init(10, 300) != CSP_ERR_NONE) {
printf("Failed to init CSP\r\n");
return -1;
}
if( type == TYPE_SERVER ) {
_beginthreadex(NULL, 0, pipe_listener, NULL, 0, 0);
} else {
pipe = CreateFile(
pipeName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if( pipe == INVALID_HANDLE_VALUE ) {
printError();
return -1;
}
}
/* Set default route and start router */
csp_route_set(CSP_DEFAULT_ROUTE, &csp_if_fifo, CSP_NODE_MAC);
csp_route_start_task(0, 0);
/* Create socket and listen for incoming connections */
if (type == TYPE_SERVER) {
sock = csp_socket(CSP_SO_NONE);
csp_bind(sock, PORT);
csp_listen(sock, 5);
}
/* Super loop */
while (1) {
if (type == TYPE_SERVER) {
/* Process incoming packet */
conn = csp_accept(sock, 1000);
if (conn) {
packet = csp_read(conn, 0);
if (packet)
printf("Received: %s\r\n", packet->data);
csp_buffer_free(packet);
csp_close(conn);
}
} else {
/* Send a new packet */
packet = csp_buffer_get(strlen(message));
if (packet) {
strcpy((char *) packet->data, message);
packet->length = strlen(message);
conn = csp_connect(CSP_PRIO_NORM, other, PORT, 1000, CSP_O_NONE);
printf("Sending: %s\r\n", message);
if (!conn || !csp_send(conn, packet, 1000))
return -1;
csp_close(conn);
Sleep(1000);
}
}
}
return 0;
}
void printError(void) {
LPTSTR messageBuffer = NULL;
DWORD errorCode = GetLastError();
DWORD formatMessageRet;
formatMessageRet = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
errorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&messageBuffer,
0,
NULL);
if( !formatMessageRet ) {
wprintf(L"FormatMessage error, code: %lu\n", GetLastError());
return;
}
printf("%s\n", messageBuffer);
LocalFree(messageBuffer);
}
unsigned WINAPI pipe_listener(void *parameters) {
while(1) {
HANDLE pipe = CreateNamedPipe(
pipeName,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
PIPE_BUFSIZE,
PIPE_BUFSIZE,
0,
NULL);
BOOL clientConnected;
if( pipe == INVALID_HANDLE_VALUE ) {
printf("Error creating named pipe. Code %lu\n", GetLastError());
return -1;
}
// True if client connects *after* server called ConnectNamedPipe
// or *between* CreateNamedPipe and ConnectNamedPipe
clientConnected =
ConnectNamedPipe(pipe, NULL) ? TRUE : GetLastError()==ERROR_PIPE_CONNECTED;
printf("Client connected!\n");
if( !clientConnected ) {
printf("Failure while listening for clients. Code %lu\n", GetLastError());
CloseHandle(pipe);
return -1;
}
printf("Create client thread\n");
_beginthreadex(NULL, 0, fifo_rx, (PVOID)pipe, 0, 0);
}
return 0;
}
unsigned WINAPI fifo_rx(void *handle) {
printf("fifo_rx tid: %lu\n", GetCurrentThreadId());
HANDLE pipe = (HANDLE) handle;
csp_packet_t *buf = csp_buffer_get(BUF_SIZE);
DWORD bytesRead;
BOOL readSuccess;
while(1) {
readSuccess =
ReadFile(pipe, &buf->length, BUF_SIZE, &bytesRead, NULL);
if( !readSuccess || bytesRead == 0 ) {
csp_buffer_free(buf);
printError();
break;
}
csp_qfifo_write(buf, &csp_if_fifo, NULL);
buf = csp_buffer_get(BUF_SIZE);
}
printf("Closing pipe to client\n");
CloseHandle(pipe);
return 0;
}

View File

@ -1,151 +0,0 @@
/**
* Build this example on linux with:
* ./waf configure --enable-examples --enable-if-kiss --with-driver-usart=linux --enable-crc32 clean build
*/
#include <stdio.h>
#include <csp/csp.h>
#include <csp/interfaces/csp_if_kiss.h>
#include <csp/drivers/usart.h>
#include <csp/arch/csp_thread.h>
#define PORT 10
#define MY_ADDRESS 1
#define SERVER_TIDX 0
#define CLIENT_TIDX 1
#define USART_HANDLE 0
CSP_DEFINE_TASK(task_server) {
int running = 1;
csp_socket_t *socket = csp_socket(CSP_SO_NONE);
csp_conn_t *conn;
csp_packet_t *packet;
csp_packet_t *response;
response = csp_buffer_get(sizeof(csp_packet_t) + 2);
if( response == NULL ) {
fprintf(stderr, "Could not allocate memory for response packet!\n");
return CSP_TASK_RETURN;
}
response->data[0] = 'O';
response->data[1] = 'K';
response->length = 2;
csp_bind(socket, CSP_ANY);
csp_listen(socket, 5);
printf("Server task started\r\n");
while(running) {
if( (conn = csp_accept(socket, 10000)) == NULL ) {
continue;
}
while( (packet = csp_read(conn, 100)) != NULL ) {
switch( csp_conn_dport(conn) ) {
case PORT:
if( packet->data[0] == 'q' )
running = 0;
csp_buffer_free(packet);
csp_send(conn, response, 1000);
break;
default:
csp_service_handler(conn, packet);
break;
}
}
csp_close(conn);
}
csp_buffer_free(response);
return CSP_TASK_RETURN;
}
CSP_DEFINE_TASK(task_client) {
char outbuf = 'q';
char inbuf[3] = {0};
int pingResult;
for(int i = 50; i <= 200; i+= 50) {
pingResult = csp_ping(MY_ADDRESS, 1000, 100, CSP_O_NONE);
printf("Ping with payload of %d bytes, took %d ms\n", i, pingResult);
csp_sleep_ms(1000);
}
csp_ps(MY_ADDRESS, 1000);
csp_sleep_ms(1000);
csp_memfree(MY_ADDRESS, 1000);
csp_sleep_ms(1000);
csp_buf_free(MY_ADDRESS, 1000);
csp_sleep_ms(1000);
csp_uptime(MY_ADDRESS, 1000);
csp_sleep_ms(1000);
csp_transaction(0, MY_ADDRESS, PORT, 1000, &outbuf, 1, inbuf, 2);
printf("Quit response from server: %s\n", inbuf);
return CSP_TASK_RETURN;
}
int main(int argc, char **argv) {
csp_debug_toggle_level(CSP_PACKET);
csp_debug_toggle_level(CSP_INFO);
csp_buffer_init(10, 300);
csp_init(MY_ADDRESS);
struct usart_conf conf;
#if defined(CSP_WINDOWS)
conf.device = argc != 2 ? "COM4" : argv[1];
conf.baudrate = CBR_9600;
conf.databits = 8;
conf.paritysetting = NOPARITY;
conf.stopbits = ONESTOPBIT;
conf.checkparity = FALSE;
#elif defined(CSP_POSIX)
conf.device = argc != 2 ? "/dev/ttyUSB0" : argv[1];
conf.baudrate = 500000;
#elif defined(CSP_MACOSX)
conf.device = argc != 2 ? "/dev/tty.usbserial-FTSM9EGE" : argv[1];
conf.baudrate = 115200;
#endif
/* Run USART init */
usart_init(&conf);
/* Setup CSP interface */
static csp_iface_t csp_if_kiss;
static csp_kiss_handle_t csp_kiss_driver;
csp_kiss_init(&csp_if_kiss, &csp_kiss_driver, usart_putc, usart_insert, "KISS");
/* Setup callback from USART RX to KISS RS */
void my_usart_rx(uint8_t * buf, int len, void * pxTaskWoken) {
csp_kiss_rx(&csp_if_kiss, buf, len, pxTaskWoken);
}
usart_set_callback(my_usart_rx);
csp_route_set(MY_ADDRESS, &csp_if_kiss, CSP_NODE_MAC);
csp_route_start_task(0, 0);
csp_conn_print_table();
csp_route_print_table();
csp_route_print_interfaces();
csp_thread_handle_t handle_server;
csp_thread_create(task_server, "SERVER", 1000, NULL, 0, &handle_server);
csp_thread_handle_t handle_client;
csp_thread_create(task_client, "CLIENT", 1000, NULL, 0, &handle_client);
/* Wait for program to terminate (ctrl + c) */
while(1) {
csp_sleep_ms(1000000);
}
return 0;
}

View File

@ -1,42 +0,0 @@
#!/usr/bin/python
# libcsp must be build with at least these options to run this example client:
# ./waf distclean configure build --enable-bindings --enable-crc32 --enable-rdp --enable-if-zmq --with-driver-usart=linux --enable-if-kiss --enable-xtea --enable-if-can --enable-can-socketcan --enable-hmac --enable-examples
# Can be run from root of libcsp like this:
# LD_LIBRARY_PATH=build PYTHONPATH=bindings/python:build python examples/python_bindings_example_client.py
#
import os
import time
import libcsp as csp
if __name__ == "__main__":
csp.buffer_init(10, 300)
csp.init(28)
csp.zmqhub_init(28, "localhost")
csp.rtable_set(27, 5, "ZMQHUB")
csp.route_start_task()
## allow router task startup
time.sleep(1)
## cmp_ident
(rc, host, model, rev, date, time) = csp.cmp_ident(27)
if rc == csp.CSP_ERR_NONE:
print (host, model, rev, date, time)
else:
print ("error in cmp_ident, rc=%i" % (rc))
## transaction
outbuf = bytearray().fromhex('01')
inbuf = bytearray(1)
print ("using csp_transaction to send a single byte")
if csp.transaction(0, 27, 10, 1000, outbuf, inbuf) < 1:
print ("csp_transaction failed")
else:
print ("got reply, data=" + ''.join('{:02x}'.format(x) for x in inbuf))

View File

@ -1,30 +0,0 @@
#!/usr/bin/python
# libcsp must be build with at least these options to run this example client:
# ./waf distclean configure build --enable-bindings --enable-crc32 --enable-rdp --enable-if-zmq --with-driver-usart=linux --enable-if-kiss --enable-xtea --enable-if-can --enable-can-socketcan --enable-hmac --enable-examples
# Can be run from root of libcsp like this:
# LD_LIBRARY_PATH=build PYTHONPATH=bindings/python:build python examples/python_bindings_example_client.py
#
import os
import time
import libcsp as csp
if __name__ == "__main__":
csp.buffer_init(10, 300)
csp.init(28)
csp.can_socketcan_init("can0")
csp.rtable_set(4, 5, "CAN")
csp.route_start_task()
## allow router task startup
time.sleep(1)
node = 4
if csp.ping(node) < 0:
print ("Unable to ping node %d"%(node))

View File

@ -1,72 +0,0 @@
#!/usr/bin/python
# libcsp must be build with at least these options to run this example server:
# ./waf distclean configure build --enable-bindings --enable-crc32 --enable-rdp --enable-if-zmq --with-driver-usart=linux --enable-if-kiss --enable-xtea --enable-if-can --enable-can-socketcan --enable-hmac --enable-examples
# Can be run from root of libcsp like this:
# LD_LIBRARY_PATH=build PYTHONPATH=bindings/python:build python examples/python_bindings_example_server.py
#
import os
import time
import sys
import libcsp as csp
import subprocess
if __name__ == "__main__":
# start a zmqproxy to transport messages to and from the client
zmqp = subprocess.Popen('build/zmqproxy')
# init csp
csp.buffer_init(10, 300)
csp.init(27)
csp.zmqhub_init(27, "localhost")
csp.rtable_set(28, 5, "ZMQHUB")
csp.route_start_task()
# set identity
csp.set_hostname("test_service")
csp.set_model("bindings")
csp.set_revision("1.2.3")
# and read it back
print (csp.get_hostname())
print (csp.get_model())
print (csp.get_revision())
# start listening for packets...
sock = csp.socket()
csp.bind(sock, csp.CSP_ANY)
csp.listen(sock)
while True:
conn = csp.accept(sock)
if not conn:
continue
print ("connection: source=%i:%i, dest=%i:%i" % (csp.conn_src(conn),
csp.conn_sport(conn),
csp.conn_dst(conn),
csp.conn_dport(conn)))
while True:
packet = csp.read(conn)
if not packet:
break
if csp.conn_dport(conn) == 10:
data = bytearray(csp.packet_get_data(packet))
length = csp.packet_get_length(packet)
print ("got packet, len=" + str(length) + ", data=" + ''.join('{:02x}'.format(x) for x in data))
data[0] = data[0] + 1
reply_packet = csp.buffer_get(1)
if reply_packet:
csp.packet_set_data(reply_packet, data)
csp.sendto_reply(packet, reply_packet, csp.CSP_O_NONE)
csp.buffer_free(packet)
else:
csp.service_handler(conn, packet)
csp.close(conn)

View File

@ -1,200 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <csp/csp.h>
/* Using un-exported header file.
* This is allowed since we are still in libcsp */
#include <csp/arch/csp_thread.h>
/** Example defines */
#define MY_ADDRESS 1 // Address of local CSP node
#define MY_PORT 10 // Port to send test traffic to
CSP_DEFINE_TASK(task_server) {
/* Create socket without any socket options */
csp_socket_t *sock = csp_socket(CSP_SO_NONE);
/* Bind all ports to socket */
csp_bind(sock, CSP_ANY);
/* Create 10 connections backlog queue */
csp_listen(sock, 10);
/* Pointer to current connection and packet */
csp_conn_t *conn;
csp_packet_t *packet;
/* Process incoming connections */
while (1) {
/* Wait for connection, 10000 ms timeout */
if ((conn = csp_accept(sock, 10000)) == NULL)
continue;
/* Read packets. Timout is 100 ms */
while ((packet = csp_read(conn, 100)) != NULL) {
switch (csp_conn_dport(conn)) {
case MY_PORT:
/* Process packet here */
printf("Packet received on MY_PORT: %s\r\n", (char *) packet->data);
csp_buffer_free(packet);
break;
default:
/* Let the service handler reply pings, buffer use, etc. */
csp_service_handler(conn, packet);
break;
}
}
/* Close current connection, and handle next */
csp_close(conn);
}
return CSP_TASK_RETURN;
}
CSP_DEFINE_TASK(task_client) {
csp_packet_t * packet;
csp_conn_t * conn;
while (1) {
/**
* Try ping
*/
csp_sleep_ms(1000);
int result = csp_ping(MY_ADDRESS, 100, 100, CSP_O_NONE);
printf("Ping result %d [ms]\r\n", result);
csp_sleep_ms(1000);
/**
* Try data packet to server
*/
/* Get packet buffer for data */
packet = csp_buffer_get(100);
if (packet == NULL) {
/* Could not get buffer element */
printf("Failed to get buffer element\n");
return CSP_TASK_RETURN;
}
/* Connect to host HOST, port PORT with regular UDP-like protocol and 1000 ms timeout */
conn = csp_connect(CSP_PRIO_NORM, MY_ADDRESS, MY_PORT, 1000, CSP_O_NONE);
if (conn == NULL) {
/* Connect failed */
printf("Connection failed\n");
/* Remember to free packet buffer */
csp_buffer_free(packet);
return CSP_TASK_RETURN;
}
/* Copy dummy data to packet */
const char *msg = "Hello World";
strcpy((char *) packet->data, msg);
/* Set packet length */
packet->length = strlen(msg);
/* Send packet */
if (!csp_send(conn, packet, 1000)) {
/* Send failed */
printf("Send failed\n");
csp_buffer_free(packet);
}
/* Close connection */
csp_close(conn);
}
return CSP_TASK_RETURN;
}
int main(int argc, char * argv[]) {
/**
* Initialise CSP,
* No physical interfaces are initialised in this example,
* so only the loopback interface is registered.
*/
/* Init buffer system with 10 packets of maximum 300 bytes each */
printf("Initialising CSP\r\n");
csp_buffer_init(5, 300);
/* Init CSP with address MY_ADDRESS */
csp_init(MY_ADDRESS);
/* Start router task with 500 word stack, OS task priority 1 */
csp_route_start_task(500, 1);
/* Enable debug output from CSP */
if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) {
printf("Debug enabed\r\n");
csp_debug_toggle_level(3);
csp_debug_toggle_level(4);
printf("Conn table\r\n");
csp_conn_print_table();
printf("Route table\r\n");
csp_route_print_table();
printf("Interfaces\r\n");
csp_route_print_interfaces();
}
/**
* Initialise example threads, using pthreads.
*/
/* Server */
printf("Starting Server task\r\n");
csp_thread_handle_t handle_server;
csp_thread_create(task_server, "SERVER", 1000, NULL, 0, &handle_server);
/* Client */
printf("Starting Client task\r\n");
csp_thread_handle_t handle_client;
csp_thread_create(task_client, "SERVER", 1000, NULL, 0, &handle_client);
/* Wait for execution to end (ctrl+c) */
while(1) {
csp_sleep_ms(100000);
}
return 0;
}

View File

@ -1,82 +0,0 @@
#include <zmq.h>
#include <assert.h>
#include <stdio.h>
#include <pthread.h>
#include <malloc.h>
#include <unistd.h>
#include <csp/csp.h>
static void * task_capture(void *ctx) {
/* Subscriber (RX) */
void *subscriber = zmq_socket(ctx, ZMQ_SUB);
assert(zmq_connect(subscriber, "tcp://localhost:7000") == 0);
assert(zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0) == 0);
while (1) {
zmq_msg_t msg;
zmq_msg_init_size(&msg, 1024);
/* Receive data */
if (zmq_msg_recv(&msg, subscriber, 0) < 0) {
zmq_msg_close(&msg);
csp_log_error("ZMQ: %s\r\n", zmq_strerror(zmq_errno()));
continue;
}
int datalen = zmq_msg_size(&msg);
if (datalen < 5) {
csp_log_warn("ZMQ: Too short datalen: %u\r\n", datalen);
while(zmq_msg_recv(&msg, subscriber, ZMQ_NOBLOCK) > 0)
zmq_msg_close(&msg);
continue;
}
/* Create new csp packet */
csp_packet_t * packet = malloc(1024);
if (packet == NULL) {
zmq_msg_close(&msg);
continue;
}
/* Copy the data from zmq to csp */
char * satidptr = ((char *) &packet->id) - 1;
memcpy(satidptr, zmq_msg_data(&msg), datalen);
packet->length = datalen - 4 - 1;
printf("Input: Src %u, Dst %u, Dport %u, Sport %u, Pri %u, Flags 0x%02X, Size %"PRIu16"\r\n",
packet->id.src, packet->id.dst, packet->id.dport,
packet->id.sport, packet->id.pri, packet->id.flags, packet->length);
free(packet);
zmq_msg_close(&msg);
}
}
int main(int argc, char ** argv) {
/**
* ZMQ PROXY
*/
void * ctx = zmq_ctx_new();
assert(ctx);
void *frontend = zmq_socket(ctx, ZMQ_XSUB);
assert(frontend);
assert(zmq_bind (frontend, "tcp://*:6000") == 0);
void *backend = zmq_socket(ctx, ZMQ_XPUB);
assert(backend);
assert(zmq_bind(backend, "tcp://*:7000") == 0);
pthread_t capworker;
pthread_create(&capworker, NULL, task_capture, ctx);
printf("Starting ZMQproxy\r\n");
zmq_proxy(frontend, backend, NULL);
printf("Closing ZMQproxy\r\n");
zmq_ctx_destroy(ctx);
return 0;
}

View File

@ -1,9 +0,0 @@
target_include_directories(${LIB_CSP_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
target_include_directories(${LIB_CSP_NAME} INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}
)

View File

@ -1,60 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_CLOCK_H_
#define _CSP_CLOCK_H_
/**
@file
Clock API.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
Cross-platform timestamp.
*/
typedef struct {
//! Seconds
uint32_t tv_sec;
//! Nano-seconds.
uint32_t tv_nsec;
} csp_timestamp_t;
/**
Get time - must be implemented by the user.
*/
__attribute__((weak)) extern void clock_get_time(csp_timestamp_t * time);
/**
Set time - must be implemented by the user.
*/
__attribute__((weak)) extern void clock_set_time(csp_timestamp_t * time);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_CLOCK_H_

View File

@ -1,39 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_MALLOC_H_
#define _CSP_MALLOC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
void * csp_malloc(size_t size);
void csp_free(void * ptr);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_MALLOC_H_

View File

@ -1,49 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_QUEUE_H_
#define _CSP_QUEUE_H_
#ifdef __cplusplus
extern "C" {
#endif
#define CSP_QUEUE_FULL 0
#define CSP_QUEUE_ERROR 0
#define CSP_QUEUE_OK 1
typedef void * csp_queue_handle_t;
#include <stdint.h>
#include <csp/csp.h>
csp_queue_handle_t csp_queue_create(int length, size_t item_size);
void csp_queue_remove(csp_queue_handle_t queue);
int csp_queue_enqueue(csp_queue_handle_t handle, void *value, uint32_t timeout);
int csp_queue_enqueue_isr(csp_queue_handle_t handle, void * value, CSP_BASE_TYPE * task_woken);
int csp_queue_dequeue(csp_queue_handle_t handle, void *buf, uint32_t timeout);
int csp_queue_dequeue_isr(csp_queue_handle_t handle, void * buf, CSP_BASE_TYPE * task_woken);
int csp_queue_size(csp_queue_handle_t handle);
int csp_queue_size_isr(csp_queue_handle_t handle);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_QUEUE_H_

View File

@ -1,109 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_SEMAPHORE_H_
#define _CSP_SEMAPHORE_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <csp/csp.h>
/* POSIX interface */
#if defined(CSP_POSIX)
#include <pthread.h>
#include <semaphore.h>
#define CSP_SEMAPHORE_OK 1
#define CSP_SEMAPHORE_ERROR 2
#define CSP_MUTEX_OK CSP_SEMAPHORE_OK
#define CSP_MUTEX_ERROR CSP_SEMAPHORE_ERROR
typedef sem_t csp_bin_sem_handle_t;
typedef pthread_mutex_t csp_mutex_t;
#endif // CSP_POSIX
/* MAC OS X interface */
#if defined(CSP_MACOSX)
#include <pthread.h>
#include "posix/pthread_queue.h"
#define CSP_SEMAPHORE_OK PTHREAD_QUEUE_OK
#define CSP_SEMAPHORE_ERROR PTHREAD_QUEUE_EMPTY
#define CSP_MUTEX_OK CSP_SEMAPHORE_OK
#define CSP_MUTEX_ERROR CSP_SEMAPHORE_ERROR
typedef pthread_queue_t * csp_bin_sem_handle_t;
typedef pthread_queue_t * csp_mutex_t;
#endif // CSP_MACOSX
#if defined(CSP_WINDOWS)
#include <Windows.h>
#undef interface
#define CSP_SEMAPHORE_OK 1
#define CSP_SEMAPHORE_ERROR 2
#define CSP_MUTEX_OK CSP_SEMAPHORE_OK
#define CSP_MUTEX_ERROR CSP_SEMAPHORE_ERROR
typedef HANDLE csp_bin_sem_handle_t;
typedef HANDLE csp_mutex_t;
#endif
/* FreeRTOS interface */
#if defined(CSP_FREERTOS)
#include <FreeRTOS.h>
#include <semphr.h>
#define CSP_SEMAPHORE_OK pdPASS
#define CSP_SEMAPHORE_ERROR pdFAIL
#define CSP_MUTEX_OK CSP_SEMAPHORE_OK
#define CSP_MUTEX_ERROR CSP_SEMAPHORE_ERROR
typedef xSemaphoreHandle csp_bin_sem_handle_t;
typedef xSemaphoreHandle csp_mutex_t;
#endif // CSP_FREERTOS
int csp_mutex_create(csp_mutex_t * mutex);
int csp_mutex_remove(csp_mutex_t * mutex);
int csp_mutex_lock(csp_mutex_t * mutex, uint32_t timeout);
int csp_mutex_unlock(csp_mutex_t * mutex);
int csp_bin_sem_create(csp_bin_sem_handle_t * sem);
int csp_bin_sem_remove(csp_bin_sem_handle_t * sem);
int csp_bin_sem_wait(csp_bin_sem_handle_t * sem, uint32_t timeout);
int csp_bin_sem_post(csp_bin_sem_handle_t * sem);
int csp_bin_sem_post_isr(csp_bin_sem_handle_t * sem, CSP_BASE_TYPE * task_woken);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_SEMAPHORE_H_

View File

@ -1,74 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_SYSTEM_H_
#define _CSP_SYSTEM_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#define COLOR_MASK_COLOR 0x0F
#define COLOR_MASK_MODIFIER 0xF0
typedef enum {
/* Colors */
COLOR_RESET = 0xF0,
COLOR_BLACK = 0x01,
COLOR_RED = 0x02,
COLOR_GREEN = 0x03,
COLOR_YELLOW = 0x04,
COLOR_BLUE = 0x05,
COLOR_MAGENTA = 0x06,
COLOR_CYAN = 0x07,
COLOR_WHITE = 0x08,
/* Modifiers */
COLOR_NORMAL = 0x0F,
COLOR_BOLD = 0x10,
COLOR_UNDERLINE = 0x20,
COLOR_BLINK = 0x30,
COLOR_HIDE = 0x40,
} csp_color_t;
/**
* Writes out a task list into a pre-allocate buffer,
* use csp_sys_tasklist_size to get sizeof buffer to allocate
* @param out pointer to output buffer
* @return
*/
int csp_sys_tasklist(char * out);
/**
* @return Size of tasklist buffer to allocate for the csp_sys_tasklist call
*/
int csp_sys_tasklist_size(void);
uint32_t csp_sys_memfree(void);
int csp_sys_reboot(void);
int csp_sys_shutdown(void);
void csp_sys_set_color(csp_color_t color);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_SYSTEM_H_

View File

@ -1,100 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_THREAD_H_
#define _CSP_THREAD_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <csp/csp.h>
/* POSIX interface */
#if defined(CSP_POSIX) || defined(CSP_MACOSX)
#include <pthread.h>
#include <unistd.h>
#define csp_thread_exit() pthread_exit(NULL)
typedef pthread_t csp_thread_handle_t;
typedef void * csp_thread_return_t;
#define CSP_DEFINE_TASK(task_name) csp_thread_return_t task_name(void * param)
#define CSP_TASK_RETURN NULL
#define csp_sleep_ms(time_ms) usleep(time_ms * 1000);
#endif // CSP_POSIX
/* Windows interface */
#if defined(CSP_WINDOWS)
#include <Windows.h>
#undef interface
#include <process.h>
#define csp_thread_exit() _endthreadex(0)
typedef HANDLE csp_thread_handle_t;
typedef unsigned int csp_thread_return_t;
#define CSP_DEFINE_TASK(task_name) csp_thread_return_t __attribute__((stdcall)) task_name(void * param)
#define CSP_TASK_RETURN 0
#define csp_sleep_ms(time_ms) Sleep(time_ms);
#endif // CSP_WINDOWS
/* FreeRTOS interface */
#if defined(CSP_FREERTOS)
#include <FreeRTOS.h>
#include <task.h>
#if INCLUDE_vTaskDelete
#define csp_thread_exit() vTaskDelete(NULL)
#else
#define csp_thread_exit()
#endif
typedef xTaskHandle csp_thread_handle_t;
typedef void csp_thread_return_t;
#define CSP_DEFINE_TASK(task_name) csp_thread_return_t task_name(void * param)
#define CSP_TASK_RETURN
#define csp_sleep_ms(time_ms) vTaskDelay(time_ms / portTICK_RATE_MS);
#endif // CSP_FREERTOS
#ifndef CSP_WINDOWS
int csp_thread_create(csp_thread_return_t (* routine)(void *), const char * const thread_name, unsigned short stack_depth, void * parameters, unsigned int priority, csp_thread_handle_t * handle);
#else
int csp_thread_create(csp_thread_return_t (* routine)(void *)__attribute__((stdcall)), const char * const thread_name, unsigned short stack_depth, void * parameters, unsigned int priority, csp_thread_handle_t * handle);
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_THREAD_H_

View File

@ -1,57 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_TIME_H_
#define _CSP_TIME_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <csp/csp.h>
/* Blackfin/x86 on Linux */
#if defined(CSP_POSIX)
#include <time.h>
#include <sys/time.h>
#include <limits.h>
#endif // CSP_POSIX
/* AVR/ARM on FreeRTOS */
#if defined(CSP_FREERTOS)
#include <FreeRTOS.h>
#include <task.h>
#endif // CSP_FREERTOS
uint32_t csp_get_ms(void);
uint32_t csp_get_ms_isr(void);
uint32_t csp_get_s(void);
uint32_t csp_get_s_isr(void);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_TIME_H_

View File

@ -1,118 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _PTHREAD_QUEUE_H_
#define _PTHREAD_QUEUE_H_
/**
@file
Queue implemented using pthread locks and conds.
Inspired by c-pthread-queue by Matthew Dickinson: http://code.google.com/p/c-pthread-queue/
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdint.h>
#include <sys/time.h>
#include <csp/arch/csp_queue.h>
/**
Queue error codes.
@{
*/
/**
General error code - something went wrong.
*/
#define PTHREAD_QUEUE_ERROR CSP_QUEUE_ERROR
/**
Queue is empty - cannot extract element.
*/
#define PTHREAD_QUEUE_EMPTY CSP_QUEUE_ERROR
/**
Queue is full - cannot insert element.
*/
#define PTHREAD_QUEUE_FULL CSP_QUEUE_ERROR
/**
Ok - no error.
*/
#define PTHREAD_QUEUE_OK CSP_QUEUE_OK
/** @{ */
/**
Queue handle.
*/
typedef struct pthread_queue_s {
//! Memory area.
void * buffer;
//! Memory size.
int size;
//! Item/element size.
int item_size;
//! Items/elements in queue.
int items;
//! Insert point.
int in;
//! Extract point.
int out;
//! Lock.
pthread_mutex_t mutex;
//! Wait because queue is full (insert).
pthread_cond_t cond_full;
//! Wait because queue is empty (extract).
pthread_cond_t cond_empty;
} pthread_queue_t;
/**
Create queue.
*/
pthread_queue_t * pthread_queue_create(int length, size_t item_size);
/**
Delete queue.
*/
void pthread_queue_delete(pthread_queue_t * q);
/**
Enqueue/insert element.
*/
int pthread_queue_enqueue(pthread_queue_t * queue, void * value, uint32_t timeout);
/**
Dequeue/extract element.
*/
int pthread_queue_dequeue(pthread_queue_t * queue, void * buf, uint32_t timeout);
/**
Return number of elements in the queue.
*/
int pthread_queue_items(pthread_queue_t * queue);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _PTHREAD_QUEUE_H_

View File

@ -1,73 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_HMAC_H_
#define _CSP_HMAC_H_
#include <csp/csp_types.h>
#ifdef __cplusplus
extern "C" {
#endif
#define CSP_HMAC_LENGTH 4
/**
* Append HMAC to packet
* @param packet Pointer to packet
* @param include_header use header in hmac calculation (this will not modify the flags field)
* @return 0 on success, negative on failure
*/
int csp_hmac_append(csp_packet_t * packet, bool include_header);
/**
* Verify HMAC of packet
* @param packet Pointer to packet
* @param include_header use header in hmac calculation (this will not modify the flags field)
* @return 0 on success, negative on failure
*/
int csp_hmac_verify(csp_packet_t * packet, bool include_header);
/**
* Calculate HMAC on buffer
*
* This function is used by append/verify but cal also be called separately.
* @param key HMAC key
* @param keylen HMAC key length
* @param data pointer to data
* @param datalen lehgth of data
* @param hmac output HMAC calculation (CSP_HMAC_LENGTH)
* @return 0 on success, negative on failure
*/
int csp_hmac_memory(const uint8_t * key, uint32_t keylen, const uint8_t * data, uint32_t datalen, uint8_t * hmac);
/**
* Save a copy of the key string for use by the append/verify functions
* @param key HMAC key
* @param keylen HMAC key length
* @return Always returns 0
*/
int csp_hmac_set_key(char * key, uint32_t keylen);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_HMAC_H_

View File

@ -1,81 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_SHA1_H_
#define _CSP_SHA1_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* The SHA1 block and message digest size in bytes */
#define SHA1_BLOCKSIZE 64
#define SHA1_DIGESTSIZE 20
/**
SHA1 state structure
*/
typedef struct {
//! Internal SHA1 state.
uint64_t length;
//! Internal SHA1 state.
uint32_t state[5];
//! Internal SHA1 state.
uint32_t curlen;
//! Internal SHA1 state.
uint8_t buf[SHA1_BLOCKSIZE];
} csp_sha1_state;
/**
* Initialize the hash state
* @param sha1 The hash state you wish to initialize
*/
void csp_sha1_init(csp_sha1_state * sha1);
/**
* Process a block of memory though the hash
* @param sha1 The hash state
* @param in The data to hash
* @param inlen The length of the data (octets)
*/
void csp_sha1_process(csp_sha1_state * sha1, const uint8_t * in, uint32_t inlen);
/**
* Terminate the hash to get the digest
* @param sha1 The hash state
* @param out [out] The destination of the hash (20 bytes)
*/
void csp_sha1_done(csp_sha1_state * sha1, uint8_t * out);
/**
* Calculate SHA1 hash of block of memory.
* @param msg Pointer to message buffer
* @param len Length of message
* @param sha1 Pointer to SHA1 output buffer. Must be 20 bytes or more!
*/
void csp_sha1_memory(const uint8_t * msg, uint32_t len, uint8_t * hash);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_SHA1_H_

View File

@ -1,52 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_XTEA_H_
#define _CSP_XTEA_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define CSP_XTEA_IV_LENGTH 8
/**
* XTEA encrypt byte array
* @param plain Pointer to plain text
* @param len Length of plain text
* @param iv Initialization vector
*/
int csp_xtea_encrypt(uint8_t * plain, const uint32_t len, uint32_t iv[2]);
/**
* Decrypt XTEA encrypted byte array
* @param cipher Pointer to cipher text
* @param len Length of plain text
* @param iv Initialization vector
*/
int csp_xtea_decrypt(uint8_t * cipher, const uint32_t len, uint32_t iv[2]);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_XTEA_H_

View File

@ -1,545 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_H_
#define _CSP_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Includes */
#include <stdint.h>
#include <csp/csp_autoconfig.h>
/* CSP includes */
#include "csp_types.h"
#include "csp_platform.h"
#include "csp_error.h"
#include "csp_debug.h"
#include "csp_buffer.h"
#include "csp_rtable.h"
#include "csp_iflist.h"
/** csp_init
* Start up the can-space protocol
* @param my_node_address The CSP node address
*/
int csp_init(uint8_t my_node_address);
/** csp_set_address
* Set the systems own address
* @param addr The new address of the system
*/
void csp_set_address(uint8_t addr);
/** csp_get_address
* Get the systems own address
* @return The current address of the system
*/
uint8_t csp_get_address(void);
/** csp_set_hostname
* Set subsystem hostname.
* This function takes a pointer to a string, which should remain static
* @param hostname Hostname to set
*/
void csp_set_hostname(const char *hostname);
/** csp_get_hostname
* Get current subsystem hostname.
* @return Pointer to char array with current hostname.
*/
const char *csp_get_hostname(void);
/** csp_set_model
* Set subsystem model name.
* This function takes a pointer to a string, which should remain static
* @param model Model name to set
*/
void csp_set_model(const char *model);
/** csp_get_model
* Get current model name.
* @return Pointer to char array with current model name.
*/
const char *csp_get_model(void);
/** csp_set_revision
* Set subsystem revision. This can be used to override the CMP revision field.
* This function takes a pointer to a string, which should remain static
* @param revision Revision name to set
*/
void csp_set_revision(const char *revision);
/** csp_get_revision
* Get subsystem revision.
* @return Pointer to char array with software revision.
*/
const char *csp_get_revision(void);
/** csp_socket
* Create CSP socket endpoint
* @param opts Socket options
* @return Pointer to socket on success, NULL on failure
*/
csp_socket_t *csp_socket(uint32_t opts);
/**
* Wait for a new connection on a socket created by csp_socket
* @param socket Socket to accept connections on
* @param timeout use CSP_MAX_DELAY for infinite timeout
* @return Return pointer to csp_conn_t or NULL if timeout was reached
*/
csp_conn_t *csp_accept(csp_socket_t *socket, uint32_t timeout);
/**
* Read data from a connection
* This fuction uses the RX queue of a connection to receive a packet
* If no packet is available and a timeout has been specified
* The call will block.
* Do NOT call this from ISR
* @param conn pointer to connection
* @param timeout timeout in ms, use CSP_MAX_DELAY for infinite blocking time
* @return Returns pointer to csp_packet_t, which you MUST free yourself, either by calling csp_buffer_free() or reusing the buffer for a new csp_send.
*/
csp_packet_t *csp_read(csp_conn_t *conn, uint32_t timeout);
/**
* Send a packet on an already established connection
* @param conn pointer to connection
* @param packet pointer to packet,
* @param timeout a timeout to wait for TX to complete. NOTE: not all underlying drivers supports flow-control.
* @return returns 1 if successful and 0 otherwise. you MUST free the frame yourself if the transmission was not successful.
*/
int csp_send(csp_conn_t *conn, csp_packet_t *packet, uint32_t timeout);
/**
* Send a packet on an already established connection, and change the default priority of the connection
*
* @note When using this function, the priority of the connection will change. If you need to change it back
* use another call to csp_send_prio, or ensure that all packets sent on a given connection is using send_prio call.
*
* @param prio csp priority
* @param conn pointer to connection
* @param packet pointer to packet,
* @param timeout a timeout to wait for TX to complete. NOTE: not all underlying drivers supports flow-control.
* @return returns 1 if successful and 0 otherwise. you MUST free the frame yourself if the transmission was not successful.
*/
int csp_send_prio(uint8_t prio, csp_conn_t *conn, csp_packet_t *packet, uint32_t timeout);
/**
* Perform an entire request/reply transaction
* Copies both input buffer and reply to output buffeer.
* Also makes the connection and closes it again
* @param prio CSP Prio
* @param dest CSP Dest
* @param port CSP Port
* @param timeout timeout in ms
* @param outbuf pointer to outgoing data buffer
* @param outlen length of request to send
* @param inbuf pointer to incoming data buffer
* @param inlen length of expected reply, -1 for unknown size (note inbuf MUST be large enough)
* @return Return 1 or reply size if successful, 0 if error or incoming length does not match or -1 if timeout was reached
*/
int csp_transaction(uint8_t prio, uint8_t dest, uint8_t port, uint32_t timeout, void *outbuf, int outlen, void *inbuf, int inlen);
/**
* Perform an entire request/reply transaction
* Copies both input buffer and reply to output buffeer.
* Also makes the connection and closes it again
* @param prio CSP Prio
* @param dest CSP Dest
* @param port CSP Port
* @param timeout timeout in ms
* @param outbuf pointer to outgoing data buffer
* @param outlen length of request to send
* @param inbuf pointer to incoming data buffer
* @param inlen length of expected reply, -1 for unknown size (note inbuf MUST be large enough)
* @param opts Connection options.
* @return Return 1 or reply size if successful, 0 if error or incoming length does not match or -1 if timeout was reached
*/
int csp_transaction2(uint8_t prio, uint8_t dest, uint8_t port, uint32_t timeout, void *outbuf, int outlen, void *inbuf, int inlen, uint32_t opts);
/**
* Use an existing connection to perform a transaction,
* This is only possible if the next packet is on the same port and destination!
* @param conn pointer to connection structure
* @param timeout timeout in ms
* @param outbuf pointer to outgoing data buffer
* @param outlen length of request to send
* @param inbuf pointer to incoming data buffer
* @param inlen length of expected reply, -1 for unknown size (note inbuf MUST be large enough)
* @return
*/
int csp_transaction_persistent(csp_conn_t *conn, uint32_t timeout, void *outbuf, int outlen, void *inbuf, int inlen);
/**
* Read data from a connection-less server socket
* This fuction uses the socket directly to receive a frame
* If no packet is available and a timeout has been specified the call will block.
* Do NOT call this from ISR
* @return Returns pointer to csp_packet_t, which you MUST free yourself, either by calling csp_buffer_free() or reusing the buffer for a new csp_send.
*/
csp_packet_t *csp_recvfrom(csp_socket_t *socket, uint32_t timeout);
/**
* Send a packet without previously opening a connection
* @param prio CSP_PRIO_x
* @param dest destination node
* @param dport destination port
* @param src_port source port
* @param opts CSP_O_x
* @param packet pointer to packet
* @param timeout timeout used by interfaces with blocking send
* @return -1 if error (you must free packet), 0 if OK (you must discard pointer)
*/
int csp_sendto(uint8_t prio, uint8_t dest, uint8_t dport, uint8_t src_port, uint32_t opts, csp_packet_t *packet, uint32_t timeout);
/**
* Send a packet as a direct reply to the source of an incoming packet,
* but still without holding an entire connection
* @param request_packet pointer to packet to reply to
* @param reply_packet actual reply data
* @param opts CSP_O_x
* @param timeout timeout used by interfaces with blocking send
* @return -1 if error (you must free packet), 0 if OK (you must discard pointer)
*/
int csp_sendto_reply(csp_packet_t * request_packet, csp_packet_t * reply_packet, uint32_t opts, uint32_t timeout);
/** csp_connect
* Used to establish outgoing connections
* This function searches the port table for free slots and finds an unused
* connection from the connection pool
* There is no handshake in the CSP protocol
* @param prio Connection priority.
* @param dest Destination address.
* @param dport Destination port.
* @param timeout Timeout in ms.
* @param opts Connection options.
* @return a pointer to a new connection or NULL
*/
csp_conn_t *csp_connect(uint8_t prio, uint8_t dest, uint8_t dport, uint32_t timeout, uint32_t opts);
/** csp_close
* Closes a given connection and frees buffers used.
* @param conn pointer to connection structure
* @return CSP_ERR_NONE if connection was closed. Otherwise, an err code is returned.
*/
int csp_close(csp_conn_t *conn);
/**
* @param conn pointer to connection structure
* @return destination port of an incoming connection
*/
int csp_conn_dport(csp_conn_t *conn);
/**
* @param conn pointer to connection structure
* @return source port of an incoming connection
*/
int csp_conn_sport(csp_conn_t *conn);
/**
* @param conn pointer to connection structure
* @return destination address of an incoming connection
*/
int csp_conn_dst(csp_conn_t *conn);
/**
* @param conn pointer to connection structure
* @return source address of an incoming connection
*/
int csp_conn_src(csp_conn_t *conn);
/**
* @param conn pointer to connection structure
* @return flags field of an incoming connection
*/
int csp_conn_flags(csp_conn_t *conn);
/**
* Set socket to listen for incoming connections
* @param socket Socket to enable listening on
* @param conn_queue_length Lenght of backlog connection queue
* @return 0 on success, -1 on error.
*/
int csp_listen(csp_socket_t *socket, size_t conn_queue_length);
/**
* Bind port to socket
* @param socket Socket to bind port to
* @param port Port number to bind
* @return 0 on success, -1 on error.
*/
int csp_bind(csp_socket_t *socket, uint8_t port);
/**
* Start the router task.
* @param task_stack_size The number of portStackType to allocate. This only affects FreeRTOS systems.
* @param priority The OS task priority of the router
*/
int csp_route_start_task(unsigned int task_stack_size, unsigned int priority);
/**
* Call the router worker function manually (without the router task)
* This must be run inside a loop or called periodically for the csp router to work.
* Use this function instead of calling and starting the router task.
* @param timeout max blocking time
* @return -1 if no packet was processed, 0 otherwise
*/
int csp_route_work(uint32_t timeout);
/**
* Start the bridge task.
* @param task_stack_size The number of portStackType to allocate. This only affects FreeRTOS systems.
* @param priority The OS task priority of the router
* @param _if_a pointer to first side
* @param _if_b pointer to second side
* @return CSP_ERR type
*/
int csp_bridge_start(unsigned int task_stack_size, unsigned int task_priority, csp_iface_t * _if_a, csp_iface_t * _if_b);
/**
* Enable promiscuous mode packet queue
* This function is used to enable promiscuous mode for the router.
* If enabled, a copy of all incoming packets are placed in a queue
* that can be read with csp_promisc_get(). Not all interface drivers
* support promiscuous mode.
*
* @param buf_size Size of buffer for incoming packets
*/
int csp_promisc_enable(unsigned int buf_size);
/**
* Disable promiscuous mode.
* If the queue was initialised prior to this, it can be re-enabled
* by calling promisc_enable(0)
*/
void csp_promisc_disable(void);
/**
* Get packet from promiscuous mode packet queue
* Returns the first packet from the promiscuous mode packet queue.
* The queue is FIFO, so the returned packet is the oldest one
* in the queue.
*
* @param timeout Timeout in ms to wait for a new packet
*/
csp_packet_t *csp_promisc_read(uint32_t timeout);
/**
* Send multiple packets using the simple fragmentation protocol
* CSP will add total size and offset to all packets
* This can be read by the client using the csp_sfp_recv, if the CSP_FFRAG flag is set
* @param conn pointer to connection
* @param data pointer to data to send
* @param totalsize size of data to send
* @param mtu maximum transfer unit
* @param timeout timeout in ms to wait for csp_send()
* @return 0 if OK, -1 if ERR
*/
int csp_sfp_send(csp_conn_t * conn, const void * data, int totalsize, int mtu, uint32_t timeout);
/**
* Same as csp_sfp_send but with option to supply your own memcpy function.
* This is usefull if you wish to send data stored in flash memory or another location
* @param conn pointer to connection
* @param data pointer to data to send
* @param totalsize size of data to send
* @param mtu maximum transfer unit
* @param timeout timeout in ms to wait for csp_send()
* @param memcpyfcn, pointer to memcpy function
* @return 0 if OK, -1 if ERR
*/
int csp_sfp_send_own_memcpy(csp_conn_t * conn, const void * data, int totalsize, int mtu, uint32_t timeout, void * (*memcpyfcn)(void *, const void *, size_t));
/**
* This is the counterpart to the csp_sfp_send function
* @param conn pointer to active conn, on which you expect to receive sfp packed data
* @param dataout pointer to NULL pointer, whill be overwritten with malloc pointer
* @param datasize actual size of received data
* @param timeout timeout in ms to wait for csp_recv()
* @return 0 if OK, -1 if ERR
*/
int csp_sfp_recv(csp_conn_t * conn, void ** dataout, int * datasize, uint32_t timeout);
/**
* This is the counterpart to the csp_sfp_send function
* @param conn pointer to active conn, on which you expect to receive sfp packed data
* @param dataout pointer to NULL pointer, whill be overwritten with malloc pointer
* @param datasize actual size of received data
* @param timeout timeout in ms to wait for csp_recv()
* @param first_packet This is a pointer to the first SFP packet (previously received with csp_read)
* @return 0 if OK, -1 if ERR
*/
int csp_sfp_recv_fp(csp_conn_t * conn, void ** dataout, int * datasize, uint32_t timeout, csp_packet_t * first_packet);
/**
* If the given packet is a service-request (that is uses one of the csp service ports)
* it will be handled according to the CSP service handler.
* This function will either use the packet buffer or delete it,
* so this function is typically called in the last "default" clause of
* a switch/case statement in a csp_listener task.
* In order to listen to csp service ports, bind your listener to the CSP_ANY port.
* This function may only be called from task context.
* @param conn Pointer to the new connection
* @param packet Pointer to the first packet, obtained by using csp_read()
*/
void csp_service_handler(csp_conn_t *conn, csp_packet_t *packet);
/**
* Send a single ping/echo packet
* @param node node id
* @param timeout timeout in ms
* @param size size of packet to transmit
* @param conn_options csp connection options
* @return >0 = Echo time in ms, -1 = ERR
*/
int csp_ping(uint8_t node, uint32_t timeout, unsigned int size, uint8_t conn_options);
/**
* Send a single ping/echo packet without waiting for reply
* @param node node id
*/
void csp_ping_noreply(uint8_t node);
/**
* Request process list.
* @note This is only available for FreeRTOS systems
* @param node node id
* @param timeout timeout in ms
*/
void csp_ps(uint8_t node, uint32_t timeout);
/**
* Request amount of free memory
* @param node node id
* @param timeout timeout in ms
*/
void csp_memfree(uint8_t node, uint32_t timeout);
/**
* Request number of free buffer elements
* @param node node id
* @param timeout timeout in ms
*/
void csp_buf_free(uint8_t node, uint32_t timeout);
/**
* Reboot subsystem
* @param node node id
*/
void csp_reboot(uint8_t node);
/**
* Shutdown subsystem
* @param node node id
*/
void csp_shutdown(uint8_t node);
/**
* Request subsystem uptime
* @param node node id
* @param timeout timeout in ms
*/
void csp_uptime(uint8_t node, uint32_t timeout);
/**
* Set RDP options
* @param window_size Window size
* @param conn_timeout_ms Connection timeout in ms
* @param packet_timeout_ms Packet timeout in ms
* @param delayed_acks Enable/disable delayed acknowledgements
* @param ack_timeout Acknowledgement timeout when delayed ACKs is enabled
* @param ack_delay_count Send acknowledgement for every ack_delay_count packets
*/
void csp_rdp_set_opt(unsigned int window_size, unsigned int conn_timeout_ms,
unsigned int packet_timeout_ms, unsigned int delayed_acks,
unsigned int ack_timeout, unsigned int ack_delay_count);
/**
* Get RDP options
* @param window_size Window size
* @param conn_timeout_ms Connection timeout in ms
* @param packet_timeout_ms Packet timeout in ms
* @param delayed_acks Enable/disable delayed acknowledgements
* @param ack_timeout Acknowledgement timeout when delayed ACKs is enabled
* @param ack_delay_count Send acknowledgement for every ack_delay_count packets
*/
void csp_rdp_get_opt(unsigned int *window_size, unsigned int *conn_timeout_ms,
unsigned int *packet_timeout_ms, unsigned int *delayed_acks,
unsigned int *ack_timeout, unsigned int *ack_delay_count);
/**
* Set XTEA key
* @param key Pointer to key array
* @param keylen Length of key
* @return 0 if key was successfully set, -1 otherwise
*/
int csp_xtea_set_key(char *key, uint32_t keylen);
/**
* Set HMAC key
* @param key Pointer to key array
* @param keylen Length of key
* @return 0 if key was successfully set, -1 otherwise
*/
int csp_hmac_set_key(char *key, uint32_t keylen);
/**
* Print connection table
*/
void csp_conn_print_table(void);
int csp_conn_print_table_str(char * str_buf, int str_size);
/**
* Print buffer usage table
*/
void csp_buffer_print_table(void);
/**
* Hex dump to stdout
*/
void csp_hex_dump(const char *desc, void *addr, int len);
#ifdef __AVR__
typedef uint32_t csp_memptr_t;
#else
typedef void * csp_memptr_t;
#endif
typedef csp_memptr_t (*csp_memcpy_fnc_t)(csp_memptr_t, const csp_memptr_t, size_t);
void csp_cmp_set_memcpy(csp_memcpy_fnc_t fnc);
/**
* Set csp_debug hook function
* @param f Hook function
*/
#include <stdarg.h>
typedef void (*csp_debug_hook_func_t)(csp_debug_level_t level, const char *format, va_list args);
void csp_debug_hook_set(csp_debug_hook_func_t f);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_H_

View File

@ -1,48 +0,0 @@
/*
* csp_autoconfig.h
*
* Created on: 20.11.2020
* Author: jakob
*/
#ifndef GOMSPACE_LIBCSP_INCLUDE_CSP_CSP_AUTOCONFIG_H_
#define GOMSPACE_LIBCSP_INCLUDE_CSP_CSP_AUTOCONFIG_H_
#define ENABLE_NANOPOWER2_CLIENT 1
#define GIT_REV "unknown"
/* #undef CSP_FREERTOS */
#define CSP_POSIX 1
/* #undef CSP_WINDOWS */
/* #undef CSP_MACOSX */
#define HAVE_LIBZMQ 1
#define CSP_DEBUG 1
#define CSP_USE_RDP 1
#define CSP_USE_CRC32 1
#define CSP_USE_HMAC 1
#define CSP_USE_XTEA 1
#define CSP_USE_PROMISC 1
#define CSP_USE_QOS 1
/* #undef CSP_USE_DEDUP */
/* #undef CSP_USE_INIT_SHUTDOWN */
#define CSP_USE_CAN 1
/* #define CSP_USE_I2C 1 */
/* #define CSP_USE_KISS 1 */
/* #define CSP_USE_ZMQHUB 1 */
#define CSP_CONN_MAX 10
#define CSP_CONN_QUEUE_LENGTH 100
#define CSP_FIFO_INPUT 100
#define CSP_MAX_BIND_PORT 31
#define CSP_RDP_MAX_WINDOW 20
#define CSP_PADDING_BYTES 8
#define CSP_CONNECTION_SO 64
#define CSP_LOG_LEVEL_DEBUG 1
#define CSP_LOG_LEVEL_INFO 1
#define CSP_LOG_LEVEL_WARN 1
#define CSP_LOG_LEVEL_ERROR 1
#define CSP_LITTLE_ENDIAN 1
/* #undef CSP_BIG_ENDIAN */
#define CSP_HAVE_STDBOOL_H 1
/* #define CSP_HAVE_LIBSOCKETCAN 1 */
#define LIBCSP_VERSION "1.5"
#endif /* GOMSPACE_LIBCSP_INCLUDE_CSP_CSP_AUTOCONFIG_H_ */

View File

@ -1,92 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_BUFFER_H_
#define _CSP_BUFFER_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* Start the buffer handling system
* You must specify the number for buffers and the size. All buffers are fixed
* size so you must specify the size of your largest buffer.
*
* @param count Number of buffers to allocate
* @param size Buffer size in bytes.
*
* @return CSP_ERR_NONE if malloc() succeeded, CSP_ERR message otherwise.
*/
int csp_buffer_init(int count, int size);
/**
* Get a reference to a free buffer. This function can only be called
* from task context.
*
* @param size Specify what data-size you will put in the buffer
* @return pointer to a free csp_packet_t or NULL if out of memory
*/
void * csp_buffer_get(size_t size);
/**
* Get a reference to a free buffer. This function can only be called
* from interrupt context.
*
* @param buf_size Specify what data-size you will put in the buffer
* @return pointer to a free csp_packet_t or NULL if out of memory
*/
void * csp_buffer_get_isr(size_t buf_size);
/**
* Free a buffer after use.
* @param packet pointer to memory area, must be acquired by csp_buffer_get().
*/
void csp_buffer_free(void *packet);
/**
* Free a buffer after use in ISR context.
* @param packet pointer to memory area, must be acquired by csp_buffer_get().
*/
void csp_buffer_free_isr(void *packet);
/**
* Clone an existing packet and increase/decrease cloned packet size.
* @param buffer Existing buffer to clone.
*/
void * csp_buffer_clone(void *buffer);
/**
* Return how many buffers that are currently free.
* @return number of free buffers
*/
int csp_buffer_remaining(void);
/**
* Return the size of the CSP buffers
* @return size of CSP buffers
*/
int csp_buffer_size(void);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _CSP_BUFFER_H_ */

View File

@ -1,189 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_CMP_H_
#define _CSP_CMP_H_
/**
@file
CSP management protocol (CMP).
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <csp/csp.h>
#include <csp/arch/csp_clock.h>
/**
CMP type.
@{
*/
/**
CMP request.
*/
#define CSP_CMP_REQUEST 0x00
/**
CMP reply.
*/
#define CSP_CMP_REPLY 0xff
/**@}*/
/**
CMP requests.
@{
*/
/**
CMP request codes.
*/
/**
Request identification, compile time, revision, name.
*/
#define CSP_CMP_IDENT 1
/**
Set/configure routing.
*/
#define CSP_CMP_ROUTE_SET 2
/**
Request interface statistics.
*/
#define CSP_CMP_IF_STATS 3
/**
Peek/read data from memory.
*/
#define CSP_CMP_PEEK 4
/**
Poke/write data from memory.
*/
#define CSP_CMP_POKE 5
/**
Get/set clock.
*/
#define CSP_CMP_CLOCK 6
/**@}*/
/**
CMP identification - max revision length.
*/
#define CSP_CMP_IDENT_REV_LEN 20
/**
CMP identification - max date length.
*/
#define CSP_CMP_IDENT_DATE_LEN 12
/**
CMP identification - max time length.
*/
#define CSP_CMP_IDENT_TIME_LEN 9
/**
CMP interface statistics - max interface name length.
*/
#define CSP_CMP_ROUTE_IFACE_LEN 11
/**
CMP peek/read memeory - max read length.
*/
#define CSP_CMP_PEEK_MAX_LEN 200
/**
CMP poke/write memeory - max write length.
*/
#define CSP_CMP_POKE_MAX_LEN 200
/**
CSP management protocol description.
*/
struct csp_cmp_message {
//! CMP request type.
uint8_t type;
//! CMP request code.
uint8_t code;
union {
struct {
char hostname[CSP_HOSTNAME_LEN];
char model[CSP_MODEL_LEN];
char revision[CSP_CMP_IDENT_REV_LEN];
char date[CSP_CMP_IDENT_DATE_LEN];
char time[CSP_CMP_IDENT_TIME_LEN];
} ident;
struct {
uint8_t dest_node;
uint8_t next_hop_mac;
char interface[CSP_CMP_ROUTE_IFACE_LEN];
} route_set;
struct __attribute__((__packed__)) {
char interface[CSP_CMP_ROUTE_IFACE_LEN];
uint32_t tx;
uint32_t rx;
uint32_t tx_error;
uint32_t rx_error;
uint32_t drop;
uint32_t autherr;
uint32_t frame;
uint32_t txbytes;
uint32_t rxbytes;
uint32_t irq;
} if_stats;
struct {
uint32_t addr;
uint8_t len;
char data[CSP_CMP_PEEK_MAX_LEN];
} peek;
struct {
uint32_t addr;
uint8_t len;
char data[CSP_CMP_POKE_MAX_LEN];
} poke;
csp_timestamp_t clock;
};
} __attribute__ ((packed));
/**
Macro for calculating size of management message.
*/
#define CMP_SIZE(_memb) (sizeof(((struct csp_cmp_message *)0)->_memb) + sizeof(uint8_t) + sizeof(uint8_t))
/**
Generic send management message request.
*/
int csp_cmp(uint8_t node, uint32_t timeout, uint8_t code, int membsize, struct csp_cmp_message *msg);
/**
Macro for defining management handling function.
*/
#define CMP_MESSAGE(_code, _memb) \
static inline int csp_cmp_##_memb(uint8_t node, uint32_t timeout, struct csp_cmp_message *msg) { \
return csp_cmp(node, timeout, _code, CMP_SIZE(_memb), msg); \
}
CMP_MESSAGE(CSP_CMP_IDENT, ident)
CMP_MESSAGE(CSP_CMP_ROUTE_SET, route_set)
CMP_MESSAGE(CSP_CMP_IF_STATS, if_stats)
CMP_MESSAGE(CSP_CMP_PEEK, peek)
CMP_MESSAGE(CSP_CMP_POKE, poke)
CMP_MESSAGE(CSP_CMP_CLOCK, clock)
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_CMP_H_

View File

@ -1,63 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_CRC32_H_
#define _CSP_CRC32_H_
#include <csp/csp.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Generate precomputed CRC32 table
*/
void csp_crc32_gentab(void);
/**
* Append CRC32 checksum to packet
* @param packet Packet to append checksum
* @param include_header use header in calculation (this will not modify the flags field)
* @return 0 on success, -1 on error
*/
int csp_crc32_append(csp_packet_t * packet, bool include_header);
/**
* Verify CRC32 checksum on packet
* @param packet Packet to verify
* @param include_header use header in calculation (this will not modify the flags field)
* @return 0 if checksum is valid, -1 otherwise
*/
int csp_crc32_verify(csp_packet_t * packet, bool include_header);
/**
* Calculate checksum for a given memory area
* @param data pointer to memory
* @param length length of memory to do checksum on
* @return return uint32_t checksum
*/
uint32_t csp_crc32_memory(const uint8_t * data, uint32_t length);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _CSP_CRC32_H_ */

View File

@ -1,150 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_DEBUG_H_
#define _CSP_DEBUG_H_
#include <inttypes.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Debug levels */
typedef enum {
CSP_ERROR = 0,
CSP_WARN = 1,
CSP_INFO = 2,
CSP_BUFFER = 3,
CSP_PACKET = 4,
CSP_PROTOCOL = 5,
CSP_LOCK = 6,
} csp_debug_level_t;
/* Extract filename component from path */
#define BASENAME(_file) ((strrchr(_file, '/') ? : (strrchr(_file, '\\') ? : _file)) + 1)
/* Implement csp_assert_fail_action to override default failure action */
extern void __attribute__((weak)) csp_assert_fail_action(const char *assertion, const char *file, int line);
#ifndef NDEBUG
#define csp_assert(exp) \
do { \
if (!(exp)) { \
const char *assertion = #exp; \
const char *file = BASENAME(__FILE__); \
int line = __LINE__; \
printf("\E[1;31m[%02" PRIu8 "] Assertion \'%s\' failed in %s:%d\E[0m\r\n", \
csp_get_address(), assertion, file, line); \
if (csp_assert_fail_action) \
csp_assert_fail_action(assertion, file, line); \
} \
} while (0)
#else
#define csp_assert(...) do {} while (0)
#endif
#ifdef __AVR__
#include <stdio.h>
#include <avr/pgmspace.h>
#define CONSTSTR(data) PSTR(data)
#undef printf
#undef sscanf
#undef scanf
#undef sprintf
#undef snprintf
#define printf(s, ...) printf_P(PSTR(s), ## __VA_ARGS__)
#define sscanf(buf, s, ...) sscanf_P(buf, PSTR(s), ## __VA_ARGS__)
#define scanf(s, ...) scanf_P(PSTR(s), ## __VA_ARGS__)
#define sprintf(buf, s, ...) sprintf_P(buf, PSTR(s), ## __VA_ARGS__)
#define snprintf(buf, size, s, ...) snprintf_P(buf, size, PSTR(s), ## __VA_ARGS__)
#else
#define CONSTSTR(data) data
#endif
#ifdef CSP_DEBUG
#define csp_debug(level, format, ...) do { do_csp_debug(level, CONSTSTR(format), ##__VA_ARGS__); } while(0)
#else
#define csp_debug(...) do {} while (0)
#endif
#ifdef CSP_LOG_LEVEL_ERROR
#define csp_log_error(format, ...) csp_debug(CSP_ERROR, format, ##__VA_ARGS__)
#else
#define csp_log_error(...) do {} while (0)
#endif
#ifdef CSP_LOG_LEVEL_WARN
#define csp_log_warn(format, ...) csp_debug(CSP_WARN, format, ##__VA_ARGS__)
#else
#define csp_log_warn(...) do {} while (0)
#endif
#ifdef CSP_LOG_LEVEL_INFO
#define csp_log_info(format, ...) csp_debug(CSP_INFO, format, ##__VA_ARGS__)
#else
#define csp_log_info(...) do {} while (0)
#endif
#ifdef CSP_LOG_LEVEL_DEBUG
#define csp_log_buffer(format, ...) csp_debug(CSP_BUFFER, format, ##__VA_ARGS__)
#define csp_log_packet(format, ...) csp_debug(CSP_PACKET, format, ##__VA_ARGS__)
#define csp_log_protocol(format, ...) csp_debug(CSP_PROTOCOL, format, ##__VA_ARGS__)
#define csp_log_lock(format, ...) csp_debug(CSP_LOCK, format, ##__VA_ARGS__)
#else
#define csp_log_buffer(...) do {} while (0)
#define csp_log_packet(...) do {} while (0)
#define csp_log_protocol(...) do {} while (0)
#define csp_log_lock(...) do {} while (0)
#endif
/**
* This function should not be used directly, use csp_log_<level>() macro instead
* @param level
* @param format
*/
void do_csp_debug(csp_debug_level_t level, const char *format, ...);
/**
* Toggle debug level on/off
* @param level Level to toggle
*/
void csp_debug_toggle_level(csp_debug_level_t level);
/**
* Set debug level
* @param level Level to set
* @param value New level value
*/
void csp_debug_set_level(csp_debug_level_t level, bool value);
/**
* Get current debug level value
* @param level Level value to get
* @return Level value
*/
int csp_debug_get_level(csp_debug_level_t level);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_DEBUG_H_

View File

@ -1,170 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_ENDIAN_H_
#define _CSP_ENDIAN_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* Convert 16-bit integer from host byte order to network byte order
* @param h16 Host byte order 16-bit integer
*/
uint16_t csp_hton16(uint16_t h16);
/**
* Convert 16-bit integer from host byte order to host byte order
* @param n16 Network byte order 16-bit integer
*/
uint16_t csp_ntoh16(uint16_t n16);
/**
* Convert 32-bit integer from host byte order to network byte order
* @param h32 Host byte order 32-bit integer
*/
uint32_t csp_hton32(uint32_t h32);
/**
* Convert 32-bit integer from host byte order to host byte order
* @param n32 Network byte order 32-bit integer
*/
uint32_t csp_ntoh32(uint32_t n32);
/**
* Convert 64-bit integer from host byte order to network byte order
* @param h64 Host byte order 64-bit integer
*/
uint64_t csp_hton64(uint64_t h64);
/**
* Convert 64-bit integer from host byte order to host byte order
* @param n64 Network byte order 64-bit integer
*/
uint64_t csp_ntoh64(uint64_t n64);
/**
* Convert 16-bit integer from host byte order to big endian byte order
* @param h16 Host byte order 16-bit integer
*/
uint16_t csp_htobe16(uint16_t h16);
/**
* Convert 16-bit integer from host byte order to little endian byte order
* @param h16 Host byte order 16-bit integer
*/
uint16_t csp_htole16(uint16_t h16);
/**
* Convert 16-bit integer from big endian byte order to little endian byte order
* @param be16 Big endian byte order 16-bit integer
*/
uint16_t csp_betoh16(uint16_t be16);
/**
* Convert 16-bit integer from little endian byte order to host byte order
* @param le16 Little endian byte order 16-bit integer
*/
uint16_t csp_letoh16(uint16_t le16);
/**
* Convert 32-bit integer from host byte order to big endian byte order
* @param h32 Host byte order 32-bit integer
*/
uint32_t csp_htobe32(uint32_t h32);
/**
* Convert 32-bit integer from little endian byte order to host byte order
* @param h32 Host byte order 32-bit integer
*/
uint32_t csp_htole32(uint32_t h32);
/**
* Convert 32-bit integer from big endian byte order to host byte order
* @param be32 Big endian byte order 32-bit integer
*/
uint32_t csp_betoh32(uint32_t be32);
/**
* Convert 32-bit integer from little endian byte order to host byte order
* @param le32 Little endian byte order 32-bit integer
*/
uint32_t csp_letoh32(uint32_t le32);
/**
* Convert 64-bit integer from host byte order to big endian byte order
* @param h64 Host byte order 64-bit integer
*/
uint64_t csp_htobe64(uint64_t h64);
/**
* Convert 64-bit integer from host byte order to little endian byte order
* @param h64 Host byte order 64-bit integer
*/
uint64_t csp_htole64(uint64_t h64);
/**
* Convert 64-bit integer from big endian byte order to host byte order
* @param be64 Big endian byte order 64-bit integer
*/
uint64_t csp_betoh64(uint64_t be64);
/**
* Convert 64-bit integer from little endian byte order to host byte order
* @param le64 Little endian byte order 64-bit integer
*/
uint64_t csp_letoh64(uint64_t le64);
/**
* Convert float from host to network byte order
* @param f Float in host order
* @return Float in network order
*/
float csp_htonflt(float f);
/**
* Convert float from network to host byte order
* @param f Float in network order
* @return Float in host order
*/
float csp_ntohflt(float f);
/**
* Convert double from host to network byte order
* @param d Double in host order
* @return Double in network order
*/
double csp_htondbl(double d);
/**
* Convert double from network to host order
* @param d Double in network order
* @return Double in host order
*/
double csp_ntohdbl(double d);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_ENDIAN_H_

View File

@ -1,50 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_ERROR_H_
#define _CSP_ERROR_H_
#ifdef __cplusplus
extern "C" {
#endif
#define CSP_ERR_NONE 0 /* No error */
#define CSP_ERR_NOMEM -1 /* Not enough memory */
#define CSP_ERR_INVAL -2 /* Invalid argument */
#define CSP_ERR_TIMEDOUT -3 /* Operation timed out */
#define CSP_ERR_USED -4 /* Resource already in use */
#define CSP_ERR_NOTSUP -5 /* Operation not supported */
#define CSP_ERR_BUSY -6 /* Device or resource busy */
#define CSP_ERR_ALREADY -7 /* Connection already in progress */
#define CSP_ERR_RESET -8 /* Connection reset */
#define CSP_ERR_NOBUFS -9 /* No more buffer space available */
#define CSP_ERR_TX -10 /* Transmission failed */
#define CSP_ERR_DRIVER -11 /* Error in driver layer */
#define CSP_ERR_AGAIN -12 /* Resource temporarily unavailable */
#define CSP_ERR_HMAC -100 /* HMAC failed */
#define CSP_ERR_XTEA -101 /* XTEA failed */
#define CSP_ERR_CRC32 -102 /* CRC32 failed */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_ERROR_H_

View File

@ -1,56 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef CSP_IFLIST_H_
#define CSP_IFLIST_H_
#include <csp/csp_types.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Add interface to list
* @param ifc Pointer to interface to add
*/
void csp_iflist_add(csp_iface_t *ifc);
/**
* Lookup interface by name
* @param name String with interface name
* @return Pointer to interface or NULL if not found
*/
csp_iface_t * csp_iflist_get_by_name(const char *name);
/**
* Print list of interfaces to stdout
*/
void csp_iflist_print(void);
/**
* Return list of registered interfaces.
*/
csp_iface_t * csp_iflist_get(void);
#ifdef __cplusplus
}
#endif
#endif /* CSP_IFLIST_H_ */

View File

@ -1,54 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_INTERFACE_H_
#define _CSP_INTERFACE_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <csp/csp.h>
/**
* Inputs a new packet into the system
* This function is called from interface drivers ISR to route and accept packets.
* But it can also be called from a task, provided that the pxTaskWoken parameter is NULL!
*
* EXTREMELY IMPORTANT:
* pxTaskWoken arg must ALWAYS be NULL if called from task,
* and ALWAYS be NON NULL if called from ISR!
* If this condition is met, this call is completely thread-safe
*
* This function is fire and forget, it returns void, meaning
* that a packet will always be either accepted or dropped
* so the memory will always be freed.
*
* @param packet A pointer to the incoming packet
* @param interface A pointer to the incoming interface TX function.
* @param pxTaskWoken This must be a pointer a valid variable if called from ISR or NULL otherwise!
*/
void csp_qfifo_write(csp_packet_t *packet, csp_iface_t *interface, CSP_BASE_TYPE *pxTaskWoken);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_INTERFACE_H_

View File

@ -1,56 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_PLATFORM_H_
#define _CSP_PLATFORM_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/* Set OS */
#if defined(CSP_POSIX) || defined(CSP_WINDOWS) || defined(CSP_MACOSX)
#define CSP_BASE_TYPE int
#define CSP_MAX_DELAY (UINT32_MAX)
#define CSP_INFINITY (UINT32_MAX)
#define CSP_DEFINE_CRITICAL(lock) static csp_bin_sem_handle_t lock
#define CSP_INIT_CRITICAL(lock) ({(csp_bin_sem_create(&lock) == CSP_SEMAPHORE_OK) ? CSP_ERR_NONE : CSP_ERR_NOMEM;})
#define CSP_ENTER_CRITICAL(lock) do { csp_bin_sem_wait(&lock, CSP_MAX_DELAY); } while(0)
#define CSP_EXIT_CRITICAL(lock) do { csp_bin_sem_post(&lock); } while(0)
#elif defined(CSP_FREERTOS)
#include "FreeRTOS.h"
#define CSP_BASE_TYPE portBASE_TYPE
#define CSP_MAX_DELAY portMAX_DELAY
#define CSP_INFINITY portMAX_DELAY
#define CSP_DEFINE_CRITICAL(lock)
#define CSP_INIT_CRITICAL(lock) ({CSP_ERR_NONE;})
#define CSP_ENTER_CRITICAL(lock) do { portENTER_CRITICAL(); } while (0)
#define CSP_EXIT_CRITICAL(lock) do { portEXIT_CRITICAL(); } while (0)
#else
#error "OS must be either CSP_POSIX, CSP_MACOSX, CSP_FREERTOS OR CSP_WINDOWS"
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_PLATFORM_H_

View File

@ -1,149 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef CSP_RTABLE_H_
#define CSP_RTABLE_H_
#include <csp/csp_iflist.h>
#ifdef __cplusplus
extern "C" {
#endif
#define CSP_NODE_MAC 0xFF
#define CSP_ROUTE_COUNT (CSP_ID_HOST_MAX + 2)
#define CSP_ROUTE_TABLE_SIZE 5 * CSP_ROUTE_COUNT
/**
* Find outgoing interface in routing table
* @param id Destination node
* @return pointer to outgoing interface or NULL
*/
csp_iface_t * csp_rtable_find_iface(uint8_t id);
/**
* Find MAC address associated with node
* @param id Destination node
* @return MAC address
*/
uint8_t csp_rtable_find_mac(uint8_t id);
/**
* Setup routing entry
* @param node Host
* @param mask Number of bits in netmask
* @param ifc Interface
* @param mac MAC address
* @return CSP error type
*/
int csp_rtable_set(uint8_t node, uint8_t mask, csp_iface_t *ifc, uint8_t mac);
/**
* Print routing table to stdout
*/
void csp_rtable_print(void);
/**
* Load the routing table from a buffer
* (deprecated, please use new csp_rtable_load)
*
* Warning:
* The table will be RAW from memory and contains direct pointers, not interface names.
* Therefore it's very important that a saved routing table is deleted after a firmware update
*
* @param route_table_in pointer to routing table buffer
*/
void csp_route_table_load(uint8_t route_table_in[CSP_ROUTE_TABLE_SIZE]);
/**
* Save the routing table to a buffer
* (deprecated, please use new csp_rtable_save)
*
* Warning:
* The table will be RAW from memory and contains direct pointers, not interface names.
* Therefore it's very important that a saved routing table is deleted after a firmware update
*
* @param route_table_out pointer to routing table buffer
*/
void csp_route_table_save(uint8_t route_table_out[CSP_ROUTE_TABLE_SIZE]);
/**
* Save routing table as a string to a buffer, which can be parsed
* again by csp_rtable_load.
* @param buffer pointer to buffer
* @param maxlen length of buffer
* @return length of saved string
*/
int csp_rtable_save(char * buffer, int maxlen);
/**
* Load routing table from a string in the format
* %u/%u %s %u
* - Address
* - Netmask
* - Ifname
* - Mac Address (this field is optional)
* An example routing string is "0/0 I2C, 8/2 KISS"
* The string must be \0 null terminated
* @param buffer Pointer to string
*/
void csp_rtable_load(const char * buffer);
/**
* Check string for valid routing table
* @param buffer Pointer to string
* @return number of valid entries found
*/
int csp_rtable_check(const char * buffer);
/**
* Clear routing table:
* This could be done before load to ensure an entire clean table is loaded.
*/
void csp_rtable_clear(void);
/**
* Setup routing entry to single node
* (deprecated, please use csp_rtable_set)
*
* @param node Host
* @param ifc Interface
* @param mac MAC address
* @return CSP error type
*/
#define csp_route_set(node, ifc, mac) csp_rtable_set(node, CSP_ID_HOST_SIZE, ifc, mac)
/**
* Print routing table
* (deprecated, please use csp_rtable_print)
*/
#define csp_route_print_table() csp_rtable_print();
/**
* Print list of interfaces
* (deprecated, please use csp_iflist_print)
*/
#define csp_route_print_interfaces() csp_iflist_print();
#ifdef __cplusplus
}
#endif
#endif /* CSP_RTABLE_H_ */

View File

@ -1,235 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef CSP_TYPES_H_
#define CSP_TYPES_H_
#include <stdint.h>
#include <csp/csp_autoconfig.h> // -> CSP_HAVE_X defines
#ifdef CSP_HAVE_STDBOOL_H
#include <stdbool.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Make bool for compilers without stdbool.h */
#ifndef CSP_HAVE_STDBOOL_H
#define bool int
#define false 0
#define true !false
#endif
/**
* RESERVED PORTS (SERVICES)
*/
enum csp_reserved_ports_e {
CSP_CMP = 0,
CSP_PING = 1,
CSP_PS = 2,
CSP_MEMFREE = 3,
CSP_REBOOT = 4,
CSP_BUF_FREE = 5,
CSP_UPTIME = 6,
CSP_ANY = (CSP_MAX_BIND_PORT + 1),
CSP_PROMISC = (CSP_MAX_BIND_PORT + 2)
};
typedef enum {
CSP_PRIO_CRITICAL = 0,
CSP_PRIO_HIGH = 1,
CSP_PRIO_NORM = 2,
CSP_PRIO_LOW = 3,
} csp_prio_t;
#define CSP_PRIORITIES (1 << CSP_ID_PRIO_SIZE)
#ifdef CSP_USE_QOS
#define CSP_RX_QUEUE_LENGTH (CSP_CONN_QUEUE_LENGTH / CSP_PRIORITIES)
#define CSP_ROUTE_FIFOS CSP_PRIORITIES
#define CSP_RX_QUEUES CSP_PRIORITIES
#else
#define CSP_RX_QUEUE_LENGTH CSP_CONN_QUEUE_LENGTH
#define CSP_ROUTE_FIFOS 1
#define CSP_RX_QUEUES 1
#endif
/** Size of bit-fields in CSP header */
#define CSP_ID_PRIO_SIZE 2
#define CSP_ID_HOST_SIZE 5
#define CSP_ID_PORT_SIZE 6
#define CSP_ID_FLAGS_SIZE 8
#define CSP_HEADER_BITS (CSP_ID_PRIO_SIZE + 2 * CSP_ID_HOST_SIZE + 2 * CSP_ID_PORT_SIZE + CSP_ID_FLAGS_SIZE)
#define CSP_HEADER_LENGTH (CSP_HEADER_BITS / 8)
#if CSP_HEADER_BITS != 32 && __GNUC__
#error "Header length must be 32 bits"
#endif
/** Highest number to be entered in field */
#define CSP_ID_PRIO_MAX ((1 << (CSP_ID_PRIO_SIZE)) - 1)
#define CSP_ID_HOST_MAX ((1 << (CSP_ID_HOST_SIZE)) - 1)
#define CSP_ID_PORT_MAX ((1 << (CSP_ID_PORT_SIZE)) - 1)
#define CSP_ID_FLAGS_MAX ((1 << (CSP_ID_FLAGS_SIZE)) - 1)
/** Identifier field masks */
#define CSP_ID_PRIO_MASK ((uint32_t) CSP_ID_PRIO_MAX << (CSP_ID_FLAGS_SIZE + 2 * CSP_ID_PORT_SIZE + 2 * CSP_ID_HOST_SIZE))
#define CSP_ID_SRC_MASK ((uint32_t) CSP_ID_HOST_MAX << (CSP_ID_FLAGS_SIZE + 2 * CSP_ID_PORT_SIZE + 1 * CSP_ID_HOST_SIZE))
#define CSP_ID_DST_MASK ((uint32_t) CSP_ID_HOST_MAX << (CSP_ID_FLAGS_SIZE + 2 * CSP_ID_PORT_SIZE))
#define CSP_ID_DPORT_MASK ((uint32_t) CSP_ID_PORT_MAX << (CSP_ID_FLAGS_SIZE + 1 * CSP_ID_PORT_SIZE))
#define CSP_ID_SPORT_MASK ((uint32_t) CSP_ID_PORT_MAX << (CSP_ID_FLAGS_SIZE))
#define CSP_ID_FLAGS_MASK ((uint32_t) CSP_ID_FLAGS_MAX << (0))
#define CSP_ID_CONN_MASK (CSP_ID_SRC_MASK | CSP_ID_DST_MASK | CSP_ID_DPORT_MASK | CSP_ID_SPORT_MASK)
/**
CSP identifier.
*/
typedef union {
//! Entire identifier.
uint32_t ext;
//! Individual fields.
struct __attribute__((__packed__)) {
#if defined(CSP_BIG_ENDIAN) && !defined(CSP_LITTLE_ENDIAN)
unsigned int pri : CSP_ID_PRIO_SIZE;
unsigned int src : CSP_ID_HOST_SIZE;
unsigned int dst : CSP_ID_HOST_SIZE;
unsigned int dport : CSP_ID_PORT_SIZE;
unsigned int sport : CSP_ID_PORT_SIZE;
unsigned int flags : CSP_ID_FLAGS_SIZE;
#elif defined(CSP_LITTLE_ENDIAN) && !defined(CSP_BIG_ENDIAN)
unsigned int flags : CSP_ID_FLAGS_SIZE;
unsigned int sport : CSP_ID_PORT_SIZE;
unsigned int dport : CSP_ID_PORT_SIZE;
unsigned int dst : CSP_ID_HOST_SIZE;
unsigned int src : CSP_ID_HOST_SIZE;
unsigned int pri : CSP_ID_PRIO_SIZE;
#else
#error "Must define one of CSP_BIG_ENDIAN or CSP_LITTLE_ENDIAN in csp_platform.h"
#endif
};
} csp_id_t;
/** Broadcast address */
#define CSP_BROADCAST_ADDR CSP_ID_HOST_MAX
/** Default routing address */
#define CSP_DEFAULT_ROUTE (CSP_ID_HOST_MAX + 1)
/** CSP Flags */
#define CSP_FRES1 0x80 // Reserved for future use
#define CSP_FRES2 0x40 // Reserved for future use
#define CSP_FRES3 0x20 // Reserved for future use
#define CSP_FFRAG 0x10 // Use fragmentation
#define CSP_FHMAC 0x08 // Use HMAC verification
#define CSP_FXTEA 0x04 // Use XTEA encryption
#define CSP_FRDP 0x02 // Use RDP protocol
#define CSP_FCRC32 0x01 // Use CRC32 checksum
/** CSP Socket options */
#define CSP_SO_NONE 0x0000 // No socket options
#define CSP_SO_RDPREQ 0x0001 // Require RDP
#define CSP_SO_RDPPROHIB 0x0002 // Prohibit RDP
#define CSP_SO_HMACREQ 0x0004 // Require HMAC
#define CSP_SO_HMACPROHIB 0x0008 // Prohibit HMAC
#define CSP_SO_XTEAREQ 0x0010 // Require XTEA
#define CSP_SO_XTEAPROHIB 0x0020 // Prohibit HMAC
#define CSP_SO_CRC32REQ 0x0040 // Require CRC32
#define CSP_SO_CRC32PROHIB 0x0080 // Prohibit CRC32
#define CSP_SO_CONN_LESS 0x0100 // Enable Connection Less mode
#define CSP_SO_INTERNAL_LISTEN 0x1000 // Internal flag: listen called on socket
/** CSP Connect options */
#define CSP_O_NONE CSP_SO_NONE // No connection options
#define CSP_O_RDP CSP_SO_RDPREQ // Enable RDP
#define CSP_O_NORDP CSP_SO_RDPPROHIB // Disable RDP
#define CSP_O_HMAC CSP_SO_HMACREQ // Enable HMAC
#define CSP_O_NOHMAC CSP_SO_HMACPROHIB // Disable HMAC
#define CSP_O_XTEA CSP_SO_XTEAREQ // Enable XTEA
#define CSP_O_NOXTEA CSP_SO_XTEAPROHIB // Disable XTEA
#define CSP_O_CRC32 CSP_SO_CRC32REQ // Enable CRC32
#define CSP_O_NOCRC32 CSP_SO_CRC32PROHIB // Disable CRC32
/**
* CSP PACKET STRUCTURE
* Note: This structure is constructed to fit
* with all interface frame types in order to
* have buffer reuse
*/
typedef struct __attribute__((__packed__)) {
uint8_t padding[CSP_PADDING_BYTES]; /**< Interface dependent padding */
uint16_t length; /**< Length field must be just before CSP ID */
csp_id_t id; /**< CSP id must be just before data */
union {
uint8_t data[0]; /**< This just points to the rest of the buffer, without a size indication. */
uint16_t data16[0]; /**< The data 16 and 32 types makes it easy to reference an integer (properly aligned) */
uint32_t data32[0]; /**< without the compiler warning about strict aliasing rules. */
};
} csp_packet_t;
/** Interface TX function */
struct csp_iface_s;
typedef int (*nexthop_t)(struct csp_iface_s * interface, csp_packet_t *packet, uint32_t timeout);
/** Interface struct */
typedef struct csp_iface_s {
const char *name; /**< Interface name (keep below 10 bytes) */
void * driver; /**< Pointer to interface handler structure */
nexthop_t nexthop; /**< Next hop function */
uint16_t mtu; /**< Maximum Transmission Unit of interface */
uint8_t split_horizon_off; /**< Disable the route-loop prevention on if */
uint32_t tx; /**< Successfully transmitted packets */
uint32_t rx; /**< Successfully received packets */
uint32_t tx_error; /**< Transmit errors */
uint32_t rx_error; /**< Receive errors */
uint32_t drop; /**< Dropped packets */
uint32_t autherr; /**< Authentication errors */
uint32_t frame; /**< Frame format errors */
uint32_t txbytes; /**< Transmitted bytes */
uint32_t rxbytes; /**< Received bytes */
uint32_t irq; /**< Interrupts */
struct csp_iface_s *next; /**< Next interface */
} csp_iface_t;
/**
* This define must be equal to the size of the packet overhead in csp_packet_t.
* It is used in csp_buffer_get() to check the allocated buffer size against
* the required buffer size.
*/
#define CSP_BUFFER_PACKET_OVERHEAD (sizeof(csp_packet_t) - sizeof(((csp_packet_t *)0)->data))
/** Forward declaration of socket and connection structures */
typedef struct csp_conn_s csp_socket_t;
typedef struct csp_conn_s csp_conn_t;
#define CSP_HOSTNAME_LEN 20
#define CSP_MODEL_LEN 30
/* CSP_REBOOT magic values */
#define CSP_REBOOT_MAGIC 0x80078007
#define CSP_REBOOT_SHUTDOWN_MAGIC 0xD1E5529A
#ifdef __cplusplus
}
#endif
#endif /* CSP_TYPES_H_ */

View File

@ -1,22 +0,0 @@
/*
* can_socketcan.h
*
* Created on: Feb 6, 2017
* Author: johan
*/
#ifndef LIB_CSP_INCLUDE_CSP_DRIVERS_CAN_SOCKETCAN_H_
#define LIB_CSP_INCLUDE_CSP_DRIVERS_CAN_SOCKETCAN_H_
#include <csp/csp_types.h>
#ifdef __cplusplus
extern "C" {
#endif
csp_iface_t * csp_can_socketcan_init(const char * ifc, int bitrate, int promisc);
#ifdef __cplusplus
}
#endif
#endif /* LIB_CSP_INCLUDE_CSP_DRIVERS_CAN_SOCKETCAN_H_ */

View File

@ -1,120 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Common I2C interface,
* This file is derived from the Gomspace I2C driver,
*
*/
#ifndef I2C_H_
#define I2C_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* The return value of the driver is a bit strange,
* It should return E_NO_ERR if successfull and the value is -1
*/
#define E_NO_ERR -1
/**
* Maximum transfer length on I2C
*/
#define I2C_MTU 256
/**
I2C device modes
@{
*/
/**
I2C Master mode.
*/
#define I2C_MASTER 0
/**
I2C Slave mode.
*/
#define I2C_SLAVE 1
/**@}*/
/**
Data structure for I2C frames.
This structs fits on top of #csp_packet_t, removing the need for copying data.
*/
typedef struct __attribute__((packed)) i2c_frame_s {
//! Not used by CSP
uint8_t padding;
//! Not used by CSP - cleared before Tx
uint8_t retries;
//! Not used by CSP
uint32_t reserved;
//! Destination address
uint8_t dest;
//! Not used by CSP - cleared before Tx
uint8_t len_rx;
//! Length of \a data part
uint16_t len;
//! CSP data
uint8_t data[I2C_MTU];
} i2c_frame_t;
/**
Callback for receiving data.
@param[in] frame received I2C frame
@param[out] pxTaskWoken can be set, if context switch is required due to received data.
*/
typedef void (*i2c_callback_t) (i2c_frame_t * frame, void * pxTaskWoken);
/**
Initialise the I2C driver
Functions is called by csp_i2c_init().
@param handle Which I2C bus (if more than one exists)
@param mode I2C device mode. Must be either I2C_MASTER or I2C_SLAVE
@param addr Own slave address
@param speed Bus speed in kbps
@param queue_len_tx Length of transmit queue
@param queue_len_rx Length of receive queue
@param callback If this value is set, the driver will call this function instead of using an RX queue
@return Error code
*/
int i2c_init(int handle, int mode, uint8_t addr, uint16_t speed, int queue_len_tx, int queue_len_rx, i2c_callback_t callback);
/**
User I2C transmit function.
Called by CSP, when sending message over I2C.
@param handle Handle to the device
@param frame Pointer to I2C frame
@param timeout Ticks to wait
@return Error code
*/
int i2c_send(int handle, i2c_frame_t * frame, uint16_t timeout);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,107 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Common USART interface,
* This file is derived from the Gomspace USART driver,
* the main difference is the assumption that only one USART will be present on a PC
*/
#ifndef USART_H_
#define USART_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
Usart configuration, to be used with the usart_init call.
*/
struct usart_conf {
//! USART device.
const char *device;
//! bits per second.
uint32_t baudrate;
//! Number of data bits.
uint8_t databits;
//! Number of stop bits.
uint8_t stopbits;
//! Parity setting.
uint8_t paritysetting;
//! Enable parity checking (Windows only).
uint8_t checkparity;
};
/**
Initialise UART with the usart_conf data structure
@param[in] conf full configuration structure
*/
void usart_init(struct usart_conf *conf);
/**
In order to catch incoming chars use the callback.
Only one callback per interface.
@param[in] handle usart[0,1,2,3]
@param[in] callback function pointer
*/
typedef void (*usart_callback_t) (uint8_t *buf, int len, void *pxTaskWoken);
/**
Set callback for receiving data.
*/
void usart_set_callback(usart_callback_t callback);
/**
Insert a character to the RX buffer of a usart
@param[in] c character to insert
@param[out] pxTaskWoken can be set, if context switch is required due to received data.
*/
void usart_insert(char c, void *pxTaskWoken);
/**
Polling putchar (stdin).
@param[in] c Character to transmit
*/
void usart_putc(char c);
/**
Send char buffer on UART (stdout).
@param[in] buf Pointer to data
@param[in] len Length of data
*/
void usart_putstr(char *buf, int len);
/**
Buffered getchar (stdin).
@return Character received
*/
char usart_getc(void);
#ifdef __cplusplus
}
#endif
#endif /* USART_H_ */

View File

@ -1,76 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_IF_CAN_H_
#define _CSP_IF_CAN_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <csp/csp.h>
#include <csp/csp_interface.h>
/* CAN header macros */
#define CFP_HOST_SIZE 5
#define CFP_TYPE_SIZE 1
#define CFP_REMAIN_SIZE 8
#define CFP_ID_SIZE 10
/* Macros for extracting header fields */
#define CFP_FIELD(id,rsiz,fsiz) ((uint32_t)((uint32_t)((id) >> (rsiz)) & (uint32_t)((1 << (fsiz)) - 1)))
#define CFP_SRC(id) CFP_FIELD(id, CFP_HOST_SIZE + CFP_TYPE_SIZE + CFP_REMAIN_SIZE + CFP_ID_SIZE, CFP_HOST_SIZE)
#define CFP_DST(id) CFP_FIELD(id, CFP_TYPE_SIZE + CFP_REMAIN_SIZE + CFP_ID_SIZE, CFP_HOST_SIZE)
#define CFP_TYPE(id) CFP_FIELD(id, CFP_REMAIN_SIZE + CFP_ID_SIZE, CFP_TYPE_SIZE)
#define CFP_REMAIN(id) CFP_FIELD(id, CFP_ID_SIZE, CFP_REMAIN_SIZE)
#define CFP_ID(id) CFP_FIELD(id, 0, CFP_ID_SIZE)
/* Macros for building CFP headers */
#define CFP_MAKE_FIELD(id,fsiz,rsiz) ((uint32_t)(((id) & (uint32_t)((uint32_t)(1 << (fsiz)) - 1)) << (rsiz)))
#define CFP_MAKE_SRC(id) CFP_MAKE_FIELD(id, CFP_HOST_SIZE, CFP_HOST_SIZE + CFP_TYPE_SIZE + CFP_REMAIN_SIZE + CFP_ID_SIZE)
#define CFP_MAKE_DST(id) CFP_MAKE_FIELD(id, CFP_HOST_SIZE, CFP_TYPE_SIZE + CFP_REMAIN_SIZE + CFP_ID_SIZE)
#define CFP_MAKE_TYPE(id) CFP_MAKE_FIELD(id, CFP_TYPE_SIZE, CFP_REMAIN_SIZE + CFP_ID_SIZE)
#define CFP_MAKE_REMAIN(id) CFP_MAKE_FIELD(id, CFP_REMAIN_SIZE, CFP_ID_SIZE)
#define CFP_MAKE_ID(id) CFP_MAKE_FIELD(id, CFP_ID_SIZE, 0)
/* Mask to uniquely separate connections */
#define CFP_ID_CONN_MASK (CFP_MAKE_SRC((uint32_t)(1 << CFP_HOST_SIZE) - 1) | \
CFP_MAKE_DST((uint32_t)(1 << CFP_HOST_SIZE) - 1) | \
CFP_MAKE_ID((uint32_t)(1 << CFP_ID_SIZE) - 1))
/**
Default Maximum Transmission Unit (MTU) for CSP over CAN.
Maximum value is 2042 bytes.
*/
#define CSP_CAN_MTU 256
int csp_can_rx(csp_iface_t *interface, uint32_t id, const uint8_t * data, uint8_t dlc, CSP_BASE_TYPE *task_woken);
int csp_can_tx(csp_iface_t *interface, csp_packet_t *packet, uint32_t timeout);
/* Must be implemented by the driver */
int csp_can_tx_frame(csp_iface_t *interface, uint32_t id, const uint8_t * data, uint8_t dlc);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _CSP_IF_CAN_H_ */

View File

@ -1,51 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_IF_I2C_H_
#define _CSP_IF_I2C_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <csp/csp.h>
#include <csp/csp_interface.h>
#include <csp/drivers/i2c.h>
extern csp_iface_t csp_if_i2c;
/**
* Capture I2C RX events for CSP
* @param opt_addr local i2c address
* @param handle which i2c device to use
* @param speed interface speed in kHz (normally 100 or 400)
* @return csp_error.h code
*/
int csp_i2c_init(uint8_t opt_addr, int handle, int speed);
void csp_i2c_rx(i2c_frame_t * frame, void * pxTaskWoken);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _CSP_IF_I2C_H_ */

View File

@ -1,110 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_IF_KISS_H_
#define _CSP_IF_KISS_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <csp/csp.h>
#include <csp/csp_interface.h>
/**
* The KISS interface relies on the USART callback in order to parse incoming
* messaged from the serial interface. The USART callback however does not
* support passing the handle number of the responding USART, so you need to implement
* a USART callback for each handle and then call kiss_rx subsequently.
*
* In order to initialize the KISS interface. Fist call kiss_init() and then
* setup your usart to call csp_kiss_rx when new data is available.
*
* When a byte is not a part of a kiss packet, it will be returned to your
* usart driver using the usart_insert funtion that you provide.
*
* @param csp_iface pointer to interface
* @param buf pointer to incoming data
* @param len length of incoming data
* @param pxTaskWoken NULL if task context, pointer to variable if ISR
*/
void csp_kiss_rx(csp_iface_t * interface, uint8_t *buf, int len, void *pxTaskWoken);
/**
* The putc function is used by the kiss interface to send
* a string of data to the serial port. This function must
* be implemented by the user, and passed to the kiss
* interface through the kiss_init function.
* @param buf byte to push
*/
typedef void (*csp_kiss_putc_f)(char buf);
/**
* The characters not accepted by the kiss interface, are discarded
* using this function, which must be implemented by the user
* and passed through the kiss_init function.
*
* This reject function is typically used to display ASCII strings
* sent over the serial port, which are not in KISS format. Such as
* debugging information.
*
* @param c rejected character
* @param pxTaskWoken NULL if task context, pointer to variable if ISR
*/
typedef void (*csp_kiss_discard_f)(char c, void *pxTaskWoken);
typedef enum {
KISS_MODE_NOT_STARTED,
KISS_MODE_STARTED,
KISS_MODE_ESCAPED,
KISS_MODE_SKIP_FRAME,
} kiss_mode_e;
/**
* This structure should be statically allocated by the user
* and passed to the kiss interface during the init function
* no member information should be changed
*/
typedef struct csp_kiss_handle_s {
//! Put character on usart (tx).
csp_kiss_putc_f kiss_putc;
//! Discard - not KISS data (rx).
csp_kiss_discard_f kiss_discard;
//! Internal KISS state.
unsigned int rx_length;
//! Internal KISS state.
kiss_mode_e rx_mode;
//! Internal KISS state.
unsigned int rx_first;
//! Not used.
volatile unsigned char *rx_cbuf;
//! Internal KISS state.
csp_packet_t * rx_packet;
} csp_kiss_handle_t;
void csp_kiss_init(csp_iface_t * csp_iface, csp_kiss_handle_t * csp_kiss_handle, csp_kiss_putc_f kiss_putc_f, csp_kiss_discard_f kiss_discard_f, const char * name);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _CSP_IF_KISS_H_ */

View File

@ -1,38 +0,0 @@
/*
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _CSP_IF_LO_H_
#define _CSP_IF_LO_H_
#ifdef __cplusplus
extern "C" {
#endif
/* CSP includes */
#include <csp/csp.h>
#include <csp/csp_interface.h>
extern csp_iface_t csp_if_lo;
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _CSP_IF_LO_H_

View File

@ -1,26 +0,0 @@
#ifndef CSP_IF_ZMQHUB_H_
#define CSP_IF_ZMQHUB_H_
#include <csp/csp.h>
extern csp_iface_t csp_if_zmqhub;
/**
* Setup ZMQ interface
* @param addr only receive messages matching this address (255 means all)
* @param host Pointer to string containing zmqproxy host
* @return CSP_ERR
*/
int csp_zmqhub_init(uint8_t addr, const char * host);
/**
* Setup ZMQ interface
* @param addr only receive messages matching this address (255 means all)
* @param publisher_endpoint Pointer to string containing zmqproxy publisher endpoint
* @param subscriber_endpoint Pointer to string containing zmqproxy subscriber endpoint
* @return CSP_ERR
*/
int csp_zmqhub_init_w_endpoints(uint8_t addr, const char * publisher_url,
const char * subscriber_url);
#endif /* CSP_IF_ZMQHUB_H_ */

View File

@ -1,12 +0,0 @@
CSRC += $(wildcard $(CURRENTPATH)/src/drivers/can/*.c)
CSRC += $(wildcard $(CURRENTPATH)/src/*.c)
CSRC += $(wildcard $(CURRENTPATH)/src/interfaces/*.c)
CSRC += $(wildcard $(CURRENTPATH)/src/rtable/csp_rtable_cidr.c)
CSRC += $(wildcard $(CURRENTPATH)/src/crypto/*.c)
CSRC += $(wildcard $(CURRENTPATH)/src/arch/posix/*.c)
CSRC += $(wildcard $(CURRENTPATH)/src/transport/*.c)
INCLUDES += $(CURRENTPATH)/include
INCLUDES += $(CURRENTPATH)/include/csp
INCLUDES += $(CURRENTPATH)/include/csp/crypto
INCLUDES += $(CURRENTPATH)

View File

@ -1,27 +0,0 @@
target_sources(${LIB_CSP_NAME} PRIVATE
csp_bridge.c
csp_buffer.c
csp_conn.c
csp_crc32.c
csp_debug.c
csp_dedup.c
csp_endian.c
csp_hex_dump.c
csp_iflist.c
csp_io.c
csp_port.c
csp_promisc.c
csp_qfifo.c
csp_route.c
csp_service_handler.c
csp_services.c
csp_sfp.c
)
add_subdirectory(drivers)
add_subdirectory(crypto)
add_subdirectory(interfaces)
add_subdirectory(rtable)
add_subdirectory(transport)
add_subdirectory(arch)

Some files were not shown because too many files have changed in this diff Show More