Skip to content
Snippets Groups Projects
Commit e1394259 authored by Grigoris Pavlakis's avatar Grigoris Pavlakis Committed by kongr45gpen
Browse files

Add a test case. More to come.

Fix a blunder with the test version of call()

Attempt to calm down clang-tidy and fix some stupid warnings in my CRC code (nothing much, just turned the counter int in a for-loop into a uint32_t to shut gcc up)

Comment out the empty constructor to mute clang-tidy's warning about trivial constructors
parent ba9a6e59
No related branches found
No related tags found
No related merge requests found
...@@ -44,6 +44,6 @@ IF (EXISTS "${PROJECT_SOURCE_DIR}/lib/Catch2/CMakeLists.txt") ...@@ -44,6 +44,6 @@ IF (EXISTS "${PROJECT_SOURCE_DIR}/lib/Catch2/CMakeLists.txt")
add_executable(tests add_executable(tests
$<TARGET_OBJECTS:common> $<TARGET_OBJECTS:common>
${test_main_SRC} ${test_main_SRC}
${test_SRC}) ${test_SRC} test/Services/FunctionManagementService.cpp)
target_link_libraries(tests Catch2::Catch2) target_link_libraries(tests Catch2::Catch2)
ENDIF () ENDIF ()
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#define MAXFUNCNAMELENGTH 32 // max length of the function name (temporary, arbitrary) #define MAXFUNCNAMELENGTH 32 // max length of the function name (temporary, arbitrary)
#define MAXARGLENGTH 32 // maximum argument byte string length (temporary, arbitrary) #define MAXARGLENGTH 32 // maximum argument byte string length (temporary, arbitrary)
#define TESTMODE // REMOVE BEFORE FLIGHT!
/** /**
* Implementation of the ST[08] function management service * Implementation of the ST[08] function management service
* *
...@@ -23,6 +25,8 @@ ...@@ -23,6 +25,8 @@
* *
* Caveats: * Caveats:
* 1) Any string handling in this class involves **non-null-terminated strings**. * 1) Any string handling in this class involves **non-null-terminated strings**.
* 2) Any remaining characters in the function name part of TC[08] shall be padded with spaces
* (0x32).
* *
* You have been warned. * You have been warned.
* *
...@@ -30,29 +34,49 @@ ...@@ -30,29 +34,49 @@
*/ */
typedef String<MAXFUNCNAMELENGTH> functionName; typedef String<MAXFUNCNAMELENGTH> functionName;
typedef etl::map<functionName, void(*)(String<MAXARGLENGTH>), (const size_t) FUNCMAPSIZE> typedef etl::map<functionName, void(*)(String<MAXARGLENGTH>), FUNCMAPSIZE>
PointerMap; PointerMap;
class FunctionManagementService { class FunctionManagementService {
/** /**
* Map of the function names to their respective pointers. Size controlled by FUNCMAPSIZE * Map of the function names to their respective pointers. Size controlled by FUNCMAPSIZE
*/ */
PointerMap funcPtrIndex; #ifdef TESTMODE
public: PointerMap funcPtrIndex;
#else
PointerMap funcPtrIndex;
#endif
public: public:
/** /**
* Constructs the function pointer index with all the necessary functions at initialization time * Constructs the function pointer index with all the necessary functions at initialization time
* These functions need to be in scope. * These functions need to be in scope. Uncomment when needed.
*
* @param None * @param None
*/ */
FunctionManagementService(); //FunctionManagementService();
/** /**
* Calls the function described in the TC[8,1] message *msg*, passing the arguments contained * Calls the function described in the TC[8,1] message *msg*, passing the arguments contained
* WARNING: Do not include any spaces in the arguments, they are ignored and replaced with NULL * WARNING: Do not include any spaces in the arguments, they are ignored and replaced with NULL
*
* @param msg A TC[8,1] message * @param msg A TC[8,1] message
*/ */
#ifdef TESTMODE
int call(Message msg);
#else
void call(Message msg); void call(Message msg);
#endif
/**
* Includes a new function in the pointer map. This enables it to be called by way of a valid
* TC [8,1] message.
*
* @param funcName the function's name. Max. length is MAXFUNCNAMELENGTH bytes.
* @param ptr pointer to a function of void return type and a MAXARGLENGTH-lengthed byte
* string as argument (which contains the actual arguments of the function)
*/
void include(String<MAXFUNCNAMELENGTH> funcName, void(*ptr)(String<MAXARGLENGTH>));
}; };
#endif //ECSS_SERVICES_FUNCTIONMANAGEMENTSERVICE_HPP #endif //ECSS_SERVICES_FUNCTIONMANAGEMENTSERVICE_HPP
...@@ -9,7 +9,7 @@ uint16_t CRCHelper::calculateCRC(const uint8_t* message, uint32_t length) { ...@@ -9,7 +9,7 @@ uint16_t CRCHelper::calculateCRC(const uint8_t* message, uint32_t length) {
// CRC16-CCITT generator polynomial (as specified in standard) // CRC16-CCITT generator polynomial (as specified in standard)
uint16_t polynomial = 0x1021u; uint16_t polynomial = 0x1021u;
for (int i = 0; i < length; i++) { for (uint32_t i = 0; i < length; i++) {
// "copy" (XOR w/ existing contents) the current msg bits into the MSB of the shift register // "copy" (XOR w/ existing contents) the current msg bits into the MSB of the shift register
shiftReg ^= (message[i] << 8u); shiftReg ^= (message[i] << 8u);
......
#include "Services/FunctionManagementService.hpp" #include "Services/FunctionManagementService.hpp"
// Dummy functions which will populate the map. //void dummy1(const String<MAXARGLENGTH> a) {
// This one prints whatever bytes are contained in the argument. // std::cout << a.c_str() << std::endl;
void dummy1(const String<MAXARGLENGTH> a) { //}
std::cout << a.c_str() << std::endl;
}
/*
FunctionManagementService::FunctionManagementService() { FunctionManagementService::FunctionManagementService() {
String<MAXFUNCNAMELENGTH> str(""); // Sample inclusion of a function in the pointer map.
str.append("dummy1"); // include(String<MAXFUNCNAMELENGTH>("dummy1"), &dummy1);
str.append(MAXFUNCNAMELENGTH - 6, '\0');
void(*dummyPtr)(String<MAXARGLENGTH>) = &dummy1; // All the functions that should be included in the pointer map at initialization shall be here.
funcPtrIndex.insert(std::make_pair(str, dummyPtr));
} }
*/
void FunctionManagementService::call(Message msg){ #ifdef TESTMODE
int FunctionManagementService::call(Message msg){
assert(msg.messageType == 1); assert(msg.messageType == 1);
assert(msg.serviceType == 8); assert(msg.serviceType == 8);
...@@ -49,14 +49,64 @@ void FunctionManagementService::call(Message msg){ ...@@ -49,14 +49,64 @@ void FunctionManagementService::call(Message msg){
// locate the appropriate function pointer // locate the appropriate function pointer
String<MAXFUNCNAMELENGTH> name(funcName); String<MAXFUNCNAMELENGTH> name(funcName);
PointerMap::iterator iter = funcPtrIndex.find(name); PointerMap::iterator iter = funcPtrIndex.find(name);
void(*selected)(String<MAXARGLENGTH>) = nullptr; void(*selected)(String<MAXARGLENGTH>);
if (iter != funcPtrIndex.end()) { if (iter != funcPtrIndex.end()) {
selected = *iter->second; selected = *iter->second;
} }
else {
/**
* @todo Send failed start of execution
*/
return 1;
}
// execute the function if there are no obvious flaws (defined in the standard, pg.158)
selected(funcArgs);
return 0;
}
#else
void FunctionManagementService::call(Message msg){
assert(msg.messageType == 1);
assert(msg.serviceType == 8);
// send proper exec failure notification and terminate if name is incorrect uint8_t funcName[MAXFUNCNAMELENGTH]; // the function's name
if (selected == nullptr) { uint8_t funcArgs[MAXARGLENGTH]; // arguments for the function
// initialize the function name and the argument arrays
for (int i = 0; i < MAXFUNCNAMELENGTH; i++) {
funcName[i] = '\0';
funcArgs[i] = '\0';
}
// isolate the function's name from the incoming message
for (int i = 0; i < MAXFUNCNAMELENGTH; i++) {
uint8_t currByte = msg.readByte();
if (currByte == 0x20) {
continue;
}
funcName[i] = currByte;
}
// isolate the string containing the args (if string length exceeds max, the remaining bytes
// are silently ignored)
for (int i = 0; i < MAXARGLENGTH; i++) {
uint8_t currByte = msg.readByte();
if (currByte == 0x20) {
continue;
}
funcArgs[i] = currByte;
}
// locate the appropriate function pointer
String<MAXFUNCNAMELENGTH> name(funcName);
PointerMap::iterator iter = funcPtrIndex.find(name);
void(*selected)(String<MAXARGLENGTH>);
if (iter != funcPtrIndex.end()) {
selected = *iter->second;
}
else {
/** /**
* @todo Send failed start of execution * @todo Send failed start of execution
*/ */
...@@ -66,3 +116,27 @@ void FunctionManagementService::call(Message msg){ ...@@ -66,3 +116,27 @@ void FunctionManagementService::call(Message msg){
// execute the function if there are no obvious flaws (defined in the standard, pg.158) // execute the function if there are no obvious flaws (defined in the standard, pg.158)
selected(funcArgs); selected(funcArgs);
} }
void FunctionManagementService::include(String<MAXFUNCNAMELENGTH> funcName,
void (*ptr)(String<MAXARGLENGTH>)) {
if (funcName.length() <= MAXFUNCNAMELENGTH) {
funcName.append(MAXFUNCNAMELENGTH - funcName.length(), '\0');
}
else {
return;
}
funcPtrIndex.insert(std::make_pair(funcName, ptr));
}
#endif
void FunctionManagementService::include(String<MAXFUNCNAMELENGTH> funcName, void(*ptr)
(String<MAXARGLENGTH>)) {
if (funcName.length() <= MAXFUNCNAMELENGTH) {
funcName.append(MAXFUNCNAMELENGTH - funcName.length(), '\0');
}
funcPtrIndex.insert(std::make_pair(funcName, ptr));
}
#include "catch2/catch.hpp"
#include "Services/FunctionManagementService.hpp"
#define CATCH_CONFIG_MAIN
void test(String<MAXARGLENGTH> a) {
std::cout << a.c_str() << std::endl;
}
TEST_CASE("FMS - Call Tests") {
FunctionManagementService fms;
SECTION("Malformed name") {
fms.include(String<MAXFUNCNAMELENGTH>("test"), &test);
Message msg(8, 1, Message::TC, 1);
msg.appendString(String<MAXFUNCNAMELENGTH>("t3st"));
CHECK(fms.call(msg) == 1);
}
/**
* @todo Add more tests
*/
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment