From 640087c7d35297418ccbdc28af12dd3ca4aec4de Mon Sep 17 00:00:00 2001 From: xtof Date: Sat, 26 Feb 2022 11:17:51 +0100 Subject: [PATCH 01/12] Update Short_message_mailbox_messages_description.md --- .../Short_message_mailbox_messages_description.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/SPECIFICATIONS/Short_message_mailbox_messages_description.md b/SPECIFICATIONS/Short_message_mailbox_messages_description.md index 400299a..8f39309 100644 --- a/SPECIFICATIONS/Short_message_mailbox_messages_description.md +++ b/SPECIFICATIONS/Short_message_mailbox_messages_description.md @@ -20,11 +20,14 @@ |:-----------------------------:|:--------------:|:--------------------------------------------------------:|:-------:| | Add Message | 0 | Message contents [0-242] bytes | | | Delette message | 1 | Mailbox Name : (Callsign) 6 byte | | -| | | Message ID : 1 byte | | +| | | Message ID : 1 byte | | | Delette mailbox | 2 | Mailbox Name : (Callsign) 6 byte | | | List all mailbox | 3 | | | | List all message in a mailbox | 4 | Mailbox Name : (Callsign) 6 byte | | -| Flush all mailbox | 5 | secure word : 4 bytes | | -| | | | | +| Flush all mailbox | 5 | Secure word : 4 bytes | | +| Read message | 6 | Mailbox Name : (Callsign) 6 byte | | +| | | Message ID : 1 byte | | + +#### Acknolegment Message -- GitLab From 3111f8cf1f03ff53f0ae6864b6fa823d51787083 Mon Sep 17 00:00:00 2001 From: xtof Date: Sat, 26 Feb 2022 11:40:53 +0100 Subject: [PATCH 02/12] Update Short_message_mailbox_messages_description.md Acknolegment Message --- ...rt_message_mailbox_messages_description.md | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/SPECIFICATIONS/Short_message_mailbox_messages_description.md b/SPECIFICATIONS/Short_message_mailbox_messages_description.md index 8f39309..a2aa78f 100644 --- a/SPECIFICATIONS/Short_message_mailbox_messages_description.md +++ b/SPECIFICATIONS/Short_message_mailbox_messages_description.md @@ -7,12 +7,12 @@ ## Command message -### AX25 UI Frame +### AX25 UI Frame Command | Flag | Destination Calssign | Destination SSID | Source Address | Source SSID | Control Bits | Protocol | Mailbox commandes | Mailbox Parameters | Frame Check Sequence | Flag | |------|----------------------|-------------------|----------------|--------------|-------------|----------|-------------------|-------------------|-----------------------------|------| | 8 | 48 | 8 | 48 | 8 | 8 | 8 | 8 | 0-242 | 16 | 8 | -#### Commands +### Commands @@ -28,6 +28,29 @@ | Read message | 6 | Mailbox Name : (Callsign) 6 byte | | | | | Message ID : 1 byte | | -#### Acknolegment Message +## Acknolegment Message +### AX25 UI Frame Acknolegment + +| Flag | Destination Calssign | Destination SSID | Source Address | Source SSID | Control Bits | Protocol | Mailbox Acknolegment| Parameters | Frame Check Sequence | Flag | +|------|----------------------|-------------------|----------------|--------------|-------------|----------|---------------------|-------------------|-----------------------------|------| +| 8 | 48 | 8 | 48 | 8 | 8 | 8 | 8 | 0-1 | 16 | 8 | + + + +The call sign of the station that sent the message will be put in the destination field of the AX25 frame header. + +### Acknolegment Value + +| Return | Value | parameter | Comments | +|----------------------------------------|:-----:|-----------------------------|-----------------------------------------------| +| Message added | 0 | Message identifier : 1 byte | | +| Mailbox created and message added | 1 | Message identifier : 1 byte | | +| Commande accepted | 2 | Command identifier : 1 byte | | +| Error - Message too long | -1 | | | +| Error - Message empty | -2 | | | +| Error - Mailbox not available | -3 | | Maximum mailbox number reached | +| Error - Mailbox full | -4 | | Maximum message number reached in the mailbox | +| Error - Commande not executed | -5 | Command identifier : 1 byte | | +| Error - Message box mode not available | -127 | | | -- GitLab From 052630d03148e87a1ce35fee8989e71ff52ac010 Mon Sep 17 00:00:00 2001 From: xtof Date: Wed, 2 Mar 2022 22:13:39 +0100 Subject: [PATCH 03/12] Update MailboxMode.md --- SPECIFICATIONS/MailboxMode.md | 60 ++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/SPECIFICATIONS/MailboxMode.md b/SPECIFICATIONS/MailboxMode.md index 3b69cfb..b919f53 100644 --- a/SPECIFICATIONS/MailboxMode.md +++ b/SPECIFICATIONS/MailboxMode.md @@ -1,6 +1,6 @@ | Last modification | Status | |-------------------- |--------- | -| 21/02/2022 | Draft | +| 02/03/2022 | Draft | # Short message mailbox mode @@ -33,47 +33,57 @@ The "ARSxyz" station sends a message to the "ARSuvw" station ### viewing the list of messages of a box -- (list of 16 messages identified by sender and number) +User send request *List all message in a mailbox* to Satellite with Mailbox Callsign +If the mailbox exist, the satellite send following information : +- number of message in the mailbox +- list of message information : Message id & time +If the mailbox does not exist, the satellite send a acknolegment with the error message : Mailbox not available -### viewing a message +### read a message -(identified by its number) +User send request *Read message* to Satellite with Mailbox Callsign and Message ID +If the message in the mailbox exist, the satellite send following information : +- time, +- message id, +- message information + +If the message in the mailbox does not exist, the satellite send a acknolegment with the error message : Message not available +If the mailbox does not exist, the satellite send a acknolegment with the error message : Mailbox not available + + ### delete a message -(identified by its number) +User send request *Delette message* to Satellite with Mailbox Callsign and Message ID +If the message in the mailbox exist, the satellite send a acknolegment with the information : message deleted +If the message in the mailbox does not exist, the satellite send a acknolegment with the error message : Message not available +If the mailbox does not exist, the satellite send a acknolegment with the error message : Mailbox not available ### viewing the list of active mailboxes -- viewing the list of active mailboxes (list of max 64 active mailboxes at a given time) +User send request *List all mailbox* to Satellite +The satellite send following information : +- number of mailbox +- list of mailbox callsign +### delete a mailbox -### flush of mailboxes (Service Message) +User send request *Delete mailbox* to Satellite with Mailbox Callsign +If the message in the mailbox exist, the satellite send a acknolegment with the information : mailbox deleted +If the mailbox does not exist, the satellite send a acknolegment with the error message : Mailbox not available +### flush of mailboxes (Service Message) + +User send request *Flush all mailbox* to Satellite +the satellite delette all mailbox and message +the satellite send a acknolegment with the information : mailboxes deleted + ## Activation - - based on AX25 protocol - Service message (protected by a private key as head of the payload) are read/write of configuration registers allowing : - - - - - - - - - - - - - - - - - - -- GitLab From f0aa89fe38f4f3ef26cea8084b9bdb2e2551026e Mon Sep 17 00:00:00 2001 From: chris Date: Mon, 22 Aug 2022 07:19:56 +0200 Subject: [PATCH 04/12] feat : add 1st Source version --- EmbededSw/src/Makefile | 19 + EmbededSw/src/ax25/ax25.c | 84 +++ EmbededSw/src/ax25/ax25.h | 27 + EmbededSw/src/core/command.c | 397 ++++++++++++ EmbededSw/src/core/command.h | 181 ++++++ EmbededSw/src/core/configuration.h | 54 ++ EmbededSw/src/core/control.c | 98 +++ EmbededSw/src/core/control.h | 16 + EmbededSw/src/core/informationMessage.c | 138 +++++ EmbededSw/src/core/informationMessage.h | 31 + EmbededSw/src/core/setup.c | 86 +++ EmbededSw/src/core/setup.h | 25 + EmbededSw/src/digipeaterMode/ModeDigipeater.c | 72 +++ EmbededSw/src/drivers/modem.c | 79 +++ EmbededSw/src/drivers/modem.h | 17 + EmbededSw/src/dropMsgMngt/DropMessage.c | 114 ++++ EmbededSw/src/dropMsgMngt/DropMessage.h | 29 + EmbededSw/src/errorMngt/error.h | 37 ++ EmbededSw/src/logMngt/log.c | 82 +++ EmbededSw/src/logMngt/log.h | 26 + EmbededSw/src/mailboxMode/mailbox.c | 572 ++++++++++++++++++ EmbededSw/src/mailboxMode/mailbox.h | 100 +++ EmbededSw/src/mailboxMode/modeMailbox.c | 48 ++ EmbededSw/src/mailboxMode/modeMailbox.h | 7 + EmbededSw/src/main.c | 46 ++ EmbededSw/src/simulation/SpinoSimuServerTCP.c | 289 +++++++++ EmbededSw/src/simulation/SpinoSimuServerTCP.h | 20 + EmbededSw/src/simulation/lecfic.c | 89 +++ EmbededSw/src/simulation/lefic.h | 13 + EmbededSw/src/surveyMode/survey.c | 38 ++ SPECIFICATIONS/todo.md | 41 ++ 31 files changed, 2875 insertions(+) create mode 100644 EmbededSw/src/Makefile create mode 100644 EmbededSw/src/ax25/ax25.c create mode 100644 EmbededSw/src/ax25/ax25.h create mode 100644 EmbededSw/src/core/command.c create mode 100644 EmbededSw/src/core/command.h create mode 100644 EmbededSw/src/core/configuration.h create mode 100644 EmbededSw/src/core/control.c create mode 100644 EmbededSw/src/core/control.h create mode 100644 EmbededSw/src/core/informationMessage.c create mode 100644 EmbededSw/src/core/informationMessage.h create mode 100644 EmbededSw/src/core/setup.c create mode 100644 EmbededSw/src/core/setup.h create mode 100644 EmbededSw/src/digipeaterMode/ModeDigipeater.c create mode 100644 EmbededSw/src/drivers/modem.c create mode 100644 EmbededSw/src/drivers/modem.h create mode 100644 EmbededSw/src/dropMsgMngt/DropMessage.c create mode 100644 EmbededSw/src/dropMsgMngt/DropMessage.h create mode 100644 EmbededSw/src/errorMngt/error.h create mode 100644 EmbededSw/src/logMngt/log.c create mode 100644 EmbededSw/src/logMngt/log.h create mode 100644 EmbededSw/src/mailboxMode/mailbox.c create mode 100644 EmbededSw/src/mailboxMode/mailbox.h create mode 100644 EmbededSw/src/mailboxMode/modeMailbox.c create mode 100644 EmbededSw/src/mailboxMode/modeMailbox.h create mode 100644 EmbededSw/src/main.c create mode 100644 EmbededSw/src/simulation/SpinoSimuServerTCP.c create mode 100644 EmbededSw/src/simulation/SpinoSimuServerTCP.h create mode 100644 EmbededSw/src/simulation/lecfic.c create mode 100644 EmbededSw/src/simulation/lefic.h create mode 100644 EmbededSw/src/surveyMode/survey.c create mode 100644 SPECIFICATIONS/todo.md diff --git a/EmbededSw/src/Makefile b/EmbededSw/src/Makefile new file mode 100644 index 0000000..8396e81 --- /dev/null +++ b/EmbededSw/src/Makefile @@ -0,0 +1,19 @@ +CC=gcc +CFLAGS=-W -Wall +LDFLAGS= -lws2_32 +EXEC=spinoSimulator + +all: $(EXEC) + +spinoSimulator: main.o ax25/ax25.o core/command.o core/control.o core/informationMessage.o core/setup.o digipeaterMode/ModeDigipeater.o drivers/modem.o dropMsgMngt/DropMessage.o logMngt/log.o mailboxMode/mailbox.o mailboxMode/modeMailbox.o simulation/SpinoSimuServerTCP.o simulation/lecfic.o surveyMode/survey.o + $(CC) -o $@ $^ $(LDFLAGS) + +%.o: %.c + $(CC) -o $@ -c $< $(CFLAGS) + +clean: + rm -rf *.o + +mrproper: clean + rm -rf $(EXEC) + diff --git a/EmbededSw/src/ax25/ax25.c b/EmbededSw/src/ax25/ax25.c new file mode 100644 index 0000000..6005f26 --- /dev/null +++ b/EmbededSw/src/ax25/ax25.c @@ -0,0 +1,84 @@ +#include +#include "../errorMngt/error.h" +#include "ax25.h" + + +void convertToAX25Header ( t_ax25_header *data, char *dest, char ssidDest, char *src, char ssidSrc) +{ + int i; + unsigned char c; + + data->ssidDestination = (unsigned char) (ssidDest<< 1 & 0xFE); + data->ssidSource = (unsigned char) (ssidSrc<< 1 & 0xFE); + for (i=0;i< 6; i++) + { + c =(unsigned char) dest[i]; + data->destinationAdress[i] = (unsigned char) (c<< 1 & 0xFE);; + } + + for (i=0;i< 6; i++) + { + c = (unsigned char) src[i]; + data->sourceAdress[i] = (unsigned char) (c<< 1 & 0xFE);; + } + +} + + +void encodeAX25Header(t_ax25_header *data) +{ + int i=0; + unsigned char c; + data->ssidDestination = (unsigned char) (data->ssidDestination<< 1 & 0xFE); + data->ssidSource = (unsigned char) (data->ssidSource<< 1 & 0xFE); + for (i=0;i< 6; i++) + { + c =(unsigned char) data->destinationAdress[i]; + data->destinationAdress[i] = (unsigned char) (c<< 1 & 0xFE);; + } + + for (i=0;i< 6; i++) + { + c = (unsigned char) data->sourceAdress[i]; + data->sourceAdress[i] = (unsigned char) (c<< 1 & 0xFE);; + } +} + + +int convertDataToAx25 (t_ax25_packet *data, char *rawdata, unsigned int size ) { + + int error = SUCCESS; + int i; + unsigned char c; + + + if (size < sizeof(t_ax25_packet)) + { + memcpy (data,rawdata, size); + + /* Convert */ + c = data->header.ssidDestination; + data->header.ssidDestination = c >> 1 & 0x7F; + c = data->header.ssidSource; + data->header.ssidSource = c >> 1 & 0x7F; + + for (i=0;i< 6; i++) + { + c = data->header.destinationAdress[i]; + data->header.destinationAdress[i] = c >> 1 & 0x7F ; + + } + + for (i=0;i< 6; i++) + { + c = data->header.sourceAdress[i]; + data->header.sourceAdress[i] = c >> 1 & 0x7F; + } + + } else { + error = ERROR_AX25_EXCEED_MAX_LENGH; + } + return error; + +} + diff --git a/EmbededSw/src/ax25/ax25.h b/EmbededSw/src/ax25/ax25.h new file mode 100644 index 0000000..e043540 --- /dev/null +++ b/EmbededSw/src/ax25/ax25.h @@ -0,0 +1,27 @@ +#ifndef AX25_H +#define AX25_H + +#define MAX_DATA_SIZE 256 +#define CALLSIGN_SIZE 6 + +typedef struct ax25_header { + char destinationAdress [6]; + unsigned char ssidDestination; + char sourceAdress[6]; + unsigned char ssidSource; + unsigned char ctrl; + unsigned char pid; + +} t_ax25_header; + +typedef struct ax25_packet { + t_ax25_header header; + char data[MAX_DATA_SIZE]; + +} t_ax25_packet; + +extern int convertDataToAx25 (t_ax25_packet *data, char *rawdata, unsigned int size ); +extern void convertToAX25Header ( t_ax25_header *data, char *dest, char ssidDest, char *src, char ssidSrc); +extern void encodeAX25Header(t_ax25_header *data); + +#endif // AX25_H \ No newline at end of file diff --git a/EmbededSw/src/core/command.c b/EmbededSw/src/core/command.c new file mode 100644 index 0000000..27f7fb9 --- /dev/null +++ b/EmbededSw/src/core/command.c @@ -0,0 +1,397 @@ + +/** + * \file command.c + * \brief perform treatment of standard SPINO Command + * \author Xtophe + * \version 0.2 + * \date 01/08/2022 + * + * \todo renforcer l'analyse par verfication de la taille des parametres pour la gestion des commandes + */ + +#include +#include +#include "setup.h" +#include "command.h" +#include "informationMessage.h" +#include "../logMngt/log.h" +#include "../dropMsgMngt/DropMessage.h" +#include "../errorMngt/error.h" + + + +extern void writeData ( t_ax25_packet ax25Frame, int length); + +/** + * \fn int reset() + * \brief réinitialise le logiciel SPINO + * + * \return SUCCESS if ok else + * ERROR_COMMAND_NOT_IMPLEMENTED + * + * \todo : int reset() is to be implemented + */ + +int reset(){ + + return ERROR_COMMAND_NOT_IMPLEMENTED; +} + + + +/** + * \fn int setValue(t_set_value value,t_tc_response *resp) + * \brief set value accordting to information in t_set_value strruture + * \param value structure with data to set + * \param *resp output structure with result of command + * \return SUCCESS if ok else + * ERROR_COMMAND_NOT_IMPLEMENTED + * + * \todo : int setValie() renforcer l'analyse par verfication de la taille des parametres + */ +int setValue(const t_set_value value,t_tc_response *resp) { + + + int returnValue = SUCCESS; +// t_field response; + +// response.field_id value.fied_id; +// response.size =0; + + resp->size = SIZE_HEADER_FIELD; + + switch (value.fied_id) { + + case VALUE_SPINO_DELAY : + gv_spinoConfig.telemetryDelay = (unsigned char) value.value[0]; + break; + + case VALUE_DELAY_INFO_MESSAGE : + memcpy (&gv_spinoConfig.delay_info_message,value.value,sizeof(gv_spinoConfig.delay_info_message)); + break; + + case VALUE_ACTIVE_INFO_MESSAGE : + memcpy (&gv_spinoConfig.info_message_actif,value.value,sizeof(gv_spinoConfig.info_message_actif)); + break; + + case VALUE_CALLSIGN_SRC_SPINO : + memcpy (&gv_spinoConfig.spinoSrcCallsign,value.value,CALLSIGN_SIZE); + break; + + case VALUE_CALLSIGN_DES_SPINO : + memcpy (&gv_spinoConfig.spinoDesCallsign,value.value,CALLSIGN_SIZE); + break; + + case VALUE_CALLSIGN_PAYLOAD_SPINO : + memcpy (&gv_spinoConfig.payloadCallsign,value.value,CALLSIGN_SIZE); + break; + + case VALUE_TIMESTAMP : + logger(LOG_LEVEL_INFO,"Commande VALUE_TIMESTAMP"); + memcpy (&gv_spino.timestamps,value.value,sizeof(gv_spino.timestamps)); + logger(LOG_LEVEL_INFO,"Commande VALUE_TIMESTAMP SET"); + break; + + case VALUE_LOG_LEVEL: + logger(LOG_LEVEL_INFO,"Commande VALUE_LOG_LEVEL"); + gv_SelectedLogLevel = (unsigned char) value.value[0]; + break; + default: + // generation code erreur + returnValue = ERROR_VALUE_FIELD_UNKNOW; + break; + } + // memcpy (resp->parameter,&response,resp->size ); + return returnValue; + +} +/** + * \fn int getValue(t_get_value value, t_tc_response *resp) + * \brief get value accordting to information in t_set_value strruture + * \param value structure with data to get. + * \param *resp output structure with result of command + * \return SUCCESS if ok else + * ERROR_COMMAND_NOT_IMPLEMENTED + * + * \todo : int getValue() renforcer l'analyse par verfication de la taille des parametres + */ +int getValue(const t_get_value value, t_tc_response *resp) +{ + int returnValue = SUCCESS; + t_field response; + + response.field_id = value.field_id; + + switch (value.field_id) { + + case VALUE_SPINO_VERSION : + response.size = sizeof(gv_version); + memcpy (response.field_value,&gv_version,response.size ); + resp->size = SIZE_HEADER_FIELD + response.size; + memcpy (resp->parameter,&response,resp->size ); + break; + + case VALUE_SPINO_DELAY : + + response.size = sizeof(gv_spinoConfig.telemetryDelay); + response.field_value [0] = gv_spinoConfig.telemetryDelay; + resp->size = SIZE_HEADER_FIELD + response.size; + memcpy (resp->parameter,&response,resp->size ); + break; + + case VALUE_CALLSIGN_SRC_SPINO : + response.size = 6; + memcpy (response.field_value,gv_spinoConfig.spinoSrcCallsign,6); + resp->size = SIZE_HEADER_FIELD + response.size; + memcpy (resp->parameter,&response,resp->size ); + break; + + case VALUE_CALLSIGN_DES_SPINO : + + response.size = 6; + memcpy (response.field_value,gv_spinoConfig.spinoDesCallsign,6); + resp->size = SIZE_HEADER_FIELD+response.size; + memcpy (resp->parameter,&response,resp->size ); + break; + + case VALUE_CALLSIGN_PAYLOAD_SPINO : + response.size = 6; + memcpy (response.field_value,gv_spinoConfig.payloadCallsign,6); + resp->size = SIZE_HEADER_FIELD+response.size; + memcpy (resp->parameter,&response,resp->size ); + break; + + case VALUE_LOG_LEVEL: + response.size = sizeof(gv_SelectedLogLevel); + memcpy (response.field_value,&gv_SelectedLogLevel,response.size ); + resp->size = SIZE_HEADER_FIELD + response.size; + memcpy (resp->parameter,&response,resp->size ); + break; + + case VALUE_ACTIVE_INFO_MESSAGE: + response.size = sizeof(gv_spinoConfig.info_message_actif); + memcpy (response.field_value,&gv_spinoConfig.info_message_actif,response.size ); + resp->size = SIZE_HEADER_FIELD + response.size; + memcpy (resp->parameter,&response,resp->size ); + break; + + case VALUE_DELAY_INFO_MESSAGE: + response.size = sizeof(gv_spinoConfig.delay_info_message); + memcpy (response.field_value,&gv_spinoConfig.delay_info_message,response.size ); + resp->size = SIZE_HEADER_FIELD + response.size; + memcpy (resp->parameter,&response,resp->size ); + break; + + case VALUE_TIMESTAMP : /*! Non implemented !*/ + default: + // generation code erreur + sprintf(gvLogMsg,"valeur inconnue %d \r\n",value.field_id); + logger(LOG_LEVEL_CRITICAL,gvLogMsg); + returnValue = ERROR_VALUE_FIELD_UNKNOW; + response.size = 0; + resp->size = SIZE_HEADER_FIELD; + memcpy (resp->parameter,&response,resp->size ); + break; + + } + +return returnValue; + +} +/** + * \fn t_tc_response interpretcommand(const t_command cmd) + * \brief interpretCommand + * \param cmd structure + * \return SUCCESS if ok else + * ERROR_COMMAND_NOT_IMPLEMENTED + * \todo implementer LOAD PROG + */ + +t_tc_response interpretcommand(t_command cmd) { + + + t_tc_response resp; + int reponse=SUCCESS; + + + resp.header.responseType = RESULT_CMD; + resp.header.timeStamp=gv_spino.timestamps; + resp.header.cmd_id = cmd.id; + + + switch (cmd.id) + { + case CMD_RESET: + logger(LOG_LEVEL_INFO,"Commande RESET"); + reponse = reset(); + break; + case SET_VALUE: /* modify configuration value */ + logger(LOG_LEVEL_INFO,"Commande SET VALUE"); + t_set_value setvalue; + memcpy(&setvalue, cmd.parameter, cmd.size); + reponse = setValue(setvalue,&resp); + break; + + case SET_STATE: /*modify mode */ + logger(LOG_LEVEL_INFO,"Commande SET STATE"); + if (cmd.size==1) + { + gv_spino.currentState = cmd.parameter[0]; + reponse=0; + } + resp.size=0; + break; + + case GET_VALUE: // return value of field + + logger(LOG_LEVEL_INFO,"Commande GET VALUE"); + t_get_value getvalue; + memcpy(&getvalue, cmd.parameter, cmd.size); + reponse = getValue(getvalue,&resp); + break; + + case GET_CONGIG: // return Configuration structure + logger(LOG_LEVEL_INFO,"Commande GET CONFIG"); + resp.size = sizeof(t_configuration_spino); + memcpy(resp.parameter, &gv_spinoConfig, sizeof(t_configuration_spino)); + break; + + case PROG_INIT: // initialise memory prog structure + logger(LOG_LEVEL_INFO,"Commande PROG INIT"); + gv_prog.indexCourrant=0; + for (int i=0;i MAX_MEM_PRG) + { + reponse = ERROR_PROG_INDEX_OUT_OF_BOUND; + } else if (gv_prog.indexCourrant==load_prg.index) + { + if (memcmp(load_prg.mem1,load_prg.mem2,MAX_MEM_PRG_LOAD)==0) + { + memcpy(&gv_prog.memory[gv_prog.indexCourrant],load_prg.mem1, MAX_MEM_PRG_LOAD); + gv_prog.indexCourrant += MAX_MEM_PRG_LOAD; + + t_field response; + response.field_id = PROG_INDEX; + response.size = sizeof(t_configuration_spino); + memcpy(resp.parameter, &gv_spinoConfig, sizeof(t_configuration_spino)); + resp.size = SIZE_HEADER_FIELD+response.size; + } + else + { + reponse = ERROR_PROG_MEM1_MEM2_NOT_EQUAL; + + } + + } else + { + reponse = ERROR_PROG_INDEX_NOT_EQUAL; + } + break; + case PROG_CHECK: + logger(LOG_LEVEL_INFO,"Commande PROG CHECK"); + reponse = ERROR_COMMAND_NOT_IMPLEMENTED; + resp.size =0; + break; + case PROG_SET_ADDRESS: + logger(LOG_LEVEL_INFO,"Commande SET ADRESS"); + logger(LOG_LEVEL_CRITICAL,gvLogMsg); + reponse = ERROR_COMMAND_NOT_IMPLEMENTED; + resp.size =0; + break; + case GET_LAST_DROPED_MESSAGE : + + logger(LOG_LEVEL_CRITICAL,"Commande GET_LAST_DROPED_MESSAGE"); + reponse = getLastDroppedMessage(&resp); + break; + case GET_ALL_DROPED_MESSAGE : + logger(LOG_LEVEL_INFO,"Commande GET_ALL_DROPED_MESSAGE"); + reponse = getAllDroppedMessage(&resp); + break; + case GET_LAST_LOG : + + logger(LOG_LEVEL_CRITICAL,"Commande GET_LAST_LOG"); + reponse = getLastLog(&resp); + + break; + case GET_ALL_LOG : + logger(LOG_LEVEL_INFO,"Commande GET_ALL_LOG"); + reponse = getAllLogs(&resp); + break; + + case SET_INFO_MESSAGE : + logger(LOG_LEVEL_INFO,"Commande SET_INFO_MESSAGE"); + reponse = setInfoMessage(cmd.parameter,&resp); + break ; + case DEL_INFO_MESSAGE: + logger(LOG_LEVEL_INFO,"Commande DEL_INFO_MESSAGE"); + reponse = delInfoMessage(cmd.parameter[0],&resp); + break; + + default: + // generation code erreur + logger(LOG_LEVEL_CRITICAL,"erreur cmd %d "); + reponse = ERROR_COMMAND_UNKNOW; + resp.size =0; + + break; + } + + + if (reponse != SUCCESS) + { + resp.header.error_code = reponse; + logger(LOG_LEVEL_INFO,"ERREUR COMMAND"); + } + else + { + resp.header.error_code = SUCCESS; + } + return resp; +} + + +void processCommand(t_ax25_packet data_ax25) { + + t_tc_response result ; + t_command cmd; + + + gv_spino.nbCommandeReceived++; + memcpy(&cmd,data_ax25.data,sizeof(t_command)); + if(cmd.key != gv_spino_cmd_key) + { + result.header.responseType = RESULT_CMD; + result.header.timeStamp=gv_spino.timestamps; + result.header.cmd_id = cmd.id; + result.header.error_code = ERROR_COMMAND_WITH_WRONG_KEY; + result.size=0; + } else + { + result = interpretcommand( cmd); + } + + if(result.header.error_code !=SUCCESS) + { + gv_spino.nbCommandeWithError++; + } + t_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + memcpy( ax25Frame.data,&result,TC_REPONSE_HEADER_SIZE+result.size); + /* envoyer la reponse de la commande */ + writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+result.size); + sprintf(gvLogMsg,"RESULT COMMAND %x %x ",result.header.cmd_id,result.header.error_code); + logger(LOG_LEVEL_CRITICAL,gvLogMsg); +} + + diff --git a/EmbededSw/src/core/command.h b/EmbededSw/src/core/command.h new file mode 100644 index 0000000..1fd05d0 --- /dev/null +++ b/EmbededSw/src/core/command.h @@ -0,0 +1,181 @@ + +#ifndef COMMAND_H +#define COMMAND_H + + +#define PARAMETER_SIZE 256 /*!< Max size of command parameter. */ +#define FIELD_SIZE 32 /*!< Max size of field parameter. */ + +/* define type of response */ + +#define RESULT_CMD 128 /*!< response type : Result from command received by SPINO */ +#define TELEMETRY 64 /*!< response type : SPINO Telemetry */ +#define INFORMATION_MSG 65 /*!< response type : SPINO Information Message */ +#define RESULT_DROP_MESSAGE 32 /*!< response type : Drop message */ + +/* COMMAND LIST */ +#define CMD_RESET 100 +#define SET_VALUE 101 +#define GET_VALUE 102 +#define GET_CONGIG 103 +#define GET_LAST_DROPED_MESSAGE 120 +#define GET_ALL_DROPED_MESSAGE 121 +#define GET_LAST_LOG 130 +#define GET_ALL_LOG 131 +#define SET_INFO_MESSAGE 132 +#define DEL_INFO_MESSAGE 133 + +#define SET_STATE 255 + +/* load new program */ +#define PROG_INIT 64 +#define PROG_LOAD 65 +#define PROG_CHECK 66 +#define PROG_SET_ADDRESS 67 + + + + + +/* SET GET VALUE */ + +#define VALUE_SPINO_VERSION 128 +#define VALUE_SPINO_DELAY 1 +#define VALUE_CALLSIGN_SRC_SPINO 2 +#define VALUE_CALLSIGN_DES_SPINO 3 +#define VALUE_CALLSIGN_PAYLOAD_SPINO 4 +#define VALUE_TIMESTAMP 5 +#define VALUE_LOG_LEVEL 6 +#define VALUE_ACTIVE_INFO_MESSAGE 7 +#define VALUE_DELAY_INFO_MESSAGE 8 + + + +#define PROG_INDEX 4 + + + + +typedef struct tm_tc_header { + unsigned long long timeStamp; + unsigned int spare; + unsigned char responseType; + unsigned char error_code; + unsigned short cmd_id; +} t_tm_tc_header; + +#define TC_REPONSE_HEADER_SIZE sizeof(t_tm_tc_header) + 2 // taille de la partie fixe + 2 pour taille de la size +typedef struct tc_response { + + t_tm_tc_header header; + unsigned short size; + char parameter [PARAMETER_SIZE]; +} t_tc_response; + + +#define SIZE_HEADER_FIELD 2 + +typedef struct field +{ + unsigned char field_id; + unsigned char size; + unsigned char field_value [FIELD_SIZE]; + +}t_field; + + +/* + +typedef struct tc_response_with_value { + t_tm_tc_header header; + char cmdID; + char error_code; + char size; + char value_id; + char parameter [PARAMETER_SIZE]; +} t_tc_response_with_value; + +*/ + + + + +/* typedef struct rep_header { + unsigned short id; + unsigned short cmd_id; + unsigned short error_code; + unsigned char size; +} t_res_header; */ + + + + +typedef struct command { + unsigned short key; /* clé */ + unsigned short id; /* command ID */ + unsigned char size ; /* parameter size */ + char parameter[PARAMETER_SIZE]; + } t_command; + + +/* +typedef struct command_resp { + t_res_header header; + unsigned char parameter[PARAMETER_SIZE]; +} t_command_resp; + +*/ + + + +typedef struct set_value +{ + unsigned char fied_id; + unsigned char size; + char value[FIELD_SIZE]; + +}t_set_value; + + +typedef struct get_value +{ + unsigned char field_id; + unsigned char size; + +}t_get_value; + + + + +/* +union u_command +{ + char data[PARAMETER_SIZE]; + t_command command; +} ; + +*/ + +#define MAX_MEM_PRG 4096 + +typedef struct prog_mngt +{ + long indexCourrant; + char *memory; +} t_prog_mngt; + + +#define MAX_MEM_PRG_LOAD 64 + +typedef struct load_prog +{ + long index; + char mem1[MAX_MEM_PRG_LOAD]; + char mem2[MAX_MEM_PRG_LOAD]; +} t_load_prg; + +extern t_tc_response interpretcommand( t_command cmd); +extern void processCommand(t_ax25_packet data_ax25); +extern void processDropMessage (char* data_ax25, int size); + +#endif // COMMAND_H diff --git a/EmbededSw/src/core/configuration.h b/EmbededSw/src/core/configuration.h new file mode 100644 index 0000000..3afd479 --- /dev/null +++ b/EmbededSw/src/core/configuration.h @@ -0,0 +1,54 @@ + + +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + + +#include "../ax25/ax25.h" +/* +* Define Spino configuration +*/ + +#define SSID_SPINO_TMTC 15 +#define SSID_SPINO_DIGIPEATER 3 +#define SSID_SPINO_MAILBOX 2 + + +#define RESET_CAUSE_STATE_UNKNOWN 1 + + +typedef struct configuration +{ + + long spinoTxFrequency; + long spinoRxFrequency; + unsigned short spinoTxModemSpeed; + unsigned short spinoRxModemSpeed; + unsigned char spinoRXModemMode; + unsigned char spinoTXModemMode; + unsigned char telemetryDelay; /* delay in seconde */ + unsigned char spare; /* delay in seconde */ + unsigned char info_message_actif; + unsigned char delay_info_message; + char spinoSrcCallsign [CALLSIGN_SIZE]; + char spinoDesCallsign [CALLSIGN_SIZE]; + char payloadCallsign [CALLSIGN_SIZE]; +} t_configuration_spino; + + + +typedef struct globalVariable +{ + + unsigned long nbCommandeReceived; + unsigned long nbCommandeWithError; + unsigned long nbFrameNotprocessed; + unsigned long nbDigipeaterMesssageProcessed; + unsigned long long timestamps; + unsigned short lastResetCause; + unsigned short currentState; +} t_globalVariable; + + +#endif // CONFIGURATION_H + diff --git a/EmbededSw/src/core/control.c b/EmbededSw/src/core/control.c new file mode 100644 index 0000000..643862e --- /dev/null +++ b/EmbededSw/src/core/control.c @@ -0,0 +1,98 @@ +#include +#include +#include "setup.h" +#include "../drivers/modem.h" +#include "informationMessage.h" +#include "control.h" + + +extern unsigned short survey(); +extern unsigned short digipeater(); +extern unsigned short modeMailbox (); + + +unsigned long long lv_spino_timeStampPrevious=0; + + + +void control() +{ + + while (1) + { + switch (gv_spino.currentState) + { + + case (int) STATE_INIT: + + logger(LOG_LEVEL_INFO,"STATE INIT"); + setupGlobalVariable(); + break; + case (int) STATE_SURVEY : + logger(LOG_LEVEL_INFO,"STATE SURVEY"); + gv_spino.currentState = survey(); + break; + + case (int) STATE_DIGIPEATER : + logger(LOG_LEVEL_INFO,"STATE DIGIPEATER"); + gv_spino.currentState = digipeater(); + break; + + case (int) STATE_MAILBOX : + sprintf(gvLogMsg,"State Mailbox \r\n"); + logger(LOG_LEVEL_INFO,"STATE MAILBOX"); + gv_spino.currentState = modeMailbox(); + break; + + case (int) STATE_EXPE_DATA: + logger(LOG_LEVEL_CRITICAL,"STATE EXPERIENCE DATA NOT IMPLEMENTED"); + gv_spino.currentState = STATE_SURVEY; + break; + + case (int) STATE_MAIN_PAYLOAD: + logger(LOG_LEVEL_CRITICAL,"STATE MAIN_PAYLOAD NOT IMPLEMENTED"); + gv_spino.currentState = STATE_SURVEY; + break; + + default: + /* remplacer par reinit */ + sprintf(gvLogMsg,"State default \r\n"); + logger(LOG_LEVEL_INFO,"STATE DEFAULT"); + gv_spino.currentState = STATE_INIT; + gv_spino.lastResetCause = RESET_CAUSE_STATE_UNKNOWN; + + break; + } + + Sleep(500); + gv_spino.timestamps= gv_spino.timestamps+500; + + if( gv_spino.timestamps > (lv_spino_timeStampPrevious + gv_spinoConfig.telemetryDelay*1000)) + { + + lv_spino_timeStampPrevious = gv_spino.timestamps; + + t_tc_response resp; + resp.header.responseType = TELEMETRY; + resp.header.error_code = 0; + resp.header.cmd_id =0; + resp.header.timeStamp = gv_spino.timestamps; + resp.size = sizeof(t_globalVariable); + memcpy(resp.parameter, &gv_spino, sizeof(t_globalVariable)); + logger(LOG_LEVEL_INFO,"Envoie TLM"); + + t_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + memcpy( ax25Frame.data,&resp,TC_REPONSE_HEADER_SIZE+resp.size); + /* envoyer la reponse de la commande */ + writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp.size); + sprintf(gvLogMsg,"TELEMETRY %x %x ",resp.header.cmd_id,resp.header.error_code); + logger(LOG_LEVEL_CRITICAL,gvLogMsg); + } + sendInfoMessage(); + + + } + + +} diff --git a/EmbededSw/src/core/control.h b/EmbededSw/src/core/control.h new file mode 100644 index 0000000..179efb2 --- /dev/null +++ b/EmbededSw/src/core/control.h @@ -0,0 +1,16 @@ + + + +#ifndef CONTROL_H +#define CONTROL_H + + +#define STATE_INIT 0 +#define STATE_SURVEY 1 +#define STATE_MAILBOX 2 +#define STATE_DIGIPEATER 3 +#define STATE_EXPE_DATA 4 +#define STATE_MAIN_PAYLOAD 5 + + +#endif // CONTROL_H diff --git a/EmbededSw/src/core/informationMessage.c b/EmbededSw/src/core/informationMessage.c new file mode 100644 index 0000000..b5c153d --- /dev/null +++ b/EmbededSw/src/core/informationMessage.c @@ -0,0 +1,138 @@ +/* + * informationMessage.c + * + * Created on: 21 août 2022 + * Author: chris + */ +#include +#include +#include "setup.h" +#include "informationMessage.h" +#include "../errorMngt/error.h" +#include "../logMngt/log.h" +#include "../drivers/modem.h" + +s_inf_msg gv_information_msg[MAX_INF_MESSAGE]; + +long long lv_spino_timeStampInfoMsgPrevious=0; +unsigned short lv_index_message_actif =0; + + + int setInfoMessage(char *data,t_tc_response *resp) + { + + int reponse = SUCCESS; + int index; + s_add_inf_msg info_msg; + + + memcpy(&info_msg,data, sizeof(s_add_inf_msg)); + index = info_msg.index; + logger(LOG_LEVEL_INFO,"SET INFO MESSAGE"); + if(info_msg.index < MAX_INF_MESSAGE) + { + gv_information_msg[index].used = INFO_MSG_USED; + strncpy(gv_information_msg[index].message, info_msg.message, MAX_SIZE_INF_MSG); + logger(LOG_LEVEL_INFO,"gv_information_msg[index].message"); + + } else + { + reponse = ERROR_INFO_MSG_INDEX_OUT_OF_BOUND; + } + + resp->size=0; + return reponse; + + } + + int delInfoMessage(char index ,t_tc_response *resp) + + { + int reponse = SUCCESS; + int ind = (int)index; + + if(index < MAX_INF_MESSAGE) + { + gv_information_msg[ind].used = (char)INFO_MSG_NOT_USED; + gv_information_msg[ind].message[0]=(char)0; + + } else + { + reponse = ERROR_INFO_MSG_INDEX_OUT_OF_BOUND; + } + resp->size=0; + return reponse; + } + + void sendInfoMessage() + { + int find =0; + int cpt=0; + + if(gv_spinoConfig.info_message_actif== INFO_MSG_USED) + { + + + if( gv_spino.timestamps > (lv_spino_timeStampInfoMsgPrevious + gv_spinoConfig.delay_info_message*1000)) + { + + lv_spino_timeStampInfoMsgPrevious = gv_spino.timestamps; + + t_tc_response resp; + resp.header.responseType = INFORMATION_MSG; + resp.header.error_code = 0; + resp.header.cmd_id =0; + resp.header.timeStamp = gv_spino.timestamps; + + + // recherche message actif + while(find==0) + { + cpt++; + lv_index_message_actif = (lv_index_message_actif + 1) % MAX_INF_MESSAGE; + if( gv_information_msg[lv_index_message_actif].used == INFO_MSG_USED) + { + find=1; + // envoie messgae + strcpy(resp.parameter, gv_information_msg[lv_index_message_actif].message); + resp.size = strlen(gv_information_msg[lv_index_message_actif].message); + t_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + memcpy( ax25Frame.data,&resp,TC_REPONSE_HEADER_SIZE+resp.size); + /* envoyer la reponse de la commande */ + writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp.size); + sprintf(gvLogMsg,"INFO MESSAGE %x %x ",resp.header.cmd_id,resp.header.error_code); + logger(LOG_LEVEL_CRITICAL,gvLogMsg); + + } + else if(cpt >MAX_INF_MESSAGE ) + { + find=1; + logger(LOG_LEVEL_CRITICAL,"NO MESSAGE INFO AVAILABLE"); + + } + + + + } + + + + resp.size = sizeof(t_globalVariable); + memcpy(resp.parameter, &gv_spino, sizeof(t_globalVariable)); + logger(LOG_LEVEL_INFO,"Envoie MESSAGE INFO"); + + t_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + memcpy( ax25Frame.data,&resp,TC_REPONSE_HEADER_SIZE+resp.size); + /* envoyer la reponse de la commande */ + writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp.size); + sprintf(gvLogMsg,"TELEMETRY %x %x ",resp.header.cmd_id,resp.header.error_code); + logger(LOG_LEVEL_WARNING,gvLogMsg); + } + } // do Nothing + + + + } + diff --git a/EmbededSw/src/core/informationMessage.h b/EmbededSw/src/core/informationMessage.h new file mode 100644 index 0000000..66f80c0 --- /dev/null +++ b/EmbededSw/src/core/informationMessage.h @@ -0,0 +1,31 @@ +#ifndef INFORMATION_MESSAGE_H +#define INFORMATION_MESSAGE_H + +#include "command.h" + +#define MAX_SIZE_INF_MSG 256 +#define MAX_INF_MESSAGE 10 + +#define INFO_MSG_NOT_USED 0 +#define INFO_MSG_USED 1 + + +typedef struct inf_msg{ + char message[MAX_SIZE_INF_MSG]; + char used; + +} s_inf_msg; + +typedef struct add_inf_msg { + char index; + char message[MAX_SIZE_INF_MSG]; +}s_add_inf_msg; + + + +extern int setInfoMessage(char *data,t_tc_response *resp); +extern int delInfoMessage(char index ,t_tc_response *resp); +extern void sendInfoMessage(); + + +#endif // INFORMATION_MESSAGE_H diff --git a/EmbededSw/src/core/setup.c b/EmbededSw/src/core/setup.c new file mode 100644 index 0000000..f824968 --- /dev/null +++ b/EmbededSw/src/core/setup.c @@ -0,0 +1,86 @@ +/** + * \file setup.c + * \brief initialise all global variables needed for SPINO embeded software. + * \author Xtophe + * \version 0.1 + * \date 01/08/2022 + * + * \todo [ ] split set in different function + * \todo [ ] Set define for number and Callsign + * + */ + +/*========= INCLUDES ==========================================================================*/ + +#include + +#include "setup.h" +#include "../dropMsgMngt/DropMessage.h" +#include "informationMessage.h" +#include "control.h" + +/*========= GLOBAL VARIABLES ===================================================================*/ + +t_configuration_spino gv_spinoConfig; +t_globalVariable gv_spino; +t_ax25_header gv_headerTlm; +t_unprocessedmessageList gv_unprocess_messages; +t_prog_mngt gv_prog; +char mem_prg[MAX_MEM_PRG]; +unsigned short gv_version = (unsigned short) 0x0103; + +unsigned short gv_spino_cmd_key = SPINO_CMD_KEY; + +/*========= FUNCTIONS ========================================================================*/ + +/*--------------------------------------------------------------------------------------------------------- + * + * setupGlobalVariable : + * \brief Setup SPINO global variable + * \details + * \param none + * \return void + * + ---------------------------------------------------------------------------------------------------------*/ +/** + * \fn void setupGlobalVariable(void) + * \brief initialise all global variable + * + */ + +void setupGlobalVariable() { + char cs[6] = { 'S', 'P', 'I', 'N', 'O', 'S' }; + char cd[6] = { 'S', 'P', 'I', 'N', 'O', 'D' }; + memcpy(gv_spinoConfig.spinoSrcCallsign, cs, 6); + memcpy(gv_spinoConfig.spinoDesCallsign, cd, 6); + gv_spinoConfig.telemetryDelay = 10; + gv_spinoConfig.spinoTxFrequency = 435000; + gv_spinoConfig.spinoTXModemMode = 1; + gv_spinoConfig.spinoTxModemSpeed = 1200; + gv_spinoConfig.spinoRxFrequency = 145000; + gv_spinoConfig.spinoRXModemMode = 1; + gv_spinoConfig.spinoRxModemSpeed = 9600; + gv_spinoConfig.delay_info_message = 30; + gv_spinoConfig.info_message_actif = INFO_MSG_NOT_USED; + + gv_headerTlm.pid = 255; + + convertToAX25Header(&gv_headerTlm, gv_spinoConfig.spinoDesCallsign, + gv_headerTlm.ssidDestination, gv_spinoConfig.spinoSrcCallsign, + gv_headerTlm.ssidSource); + + gv_prog.indexCourrant = 0; + gv_prog.memory = mem_prg; + gv_unprocess_messages.index = 0; + + int i = 0; + gv_unprocess_messages.index = 0; + for (i = 0; i < MAX_UNPROCESSED_MESSAGE_LIST_SIZE; i++) { + + gv_unprocess_messages.message[i].timestamps = 0; + gv_unprocess_messages.message[i].size = 0; + } + + gv_spino.currentState = STATE_SURVEY; + +} diff --git a/EmbededSw/src/core/setup.h b/EmbededSw/src/core/setup.h new file mode 100644 index 0000000..d1b3859 --- /dev/null +++ b/EmbededSw/src/core/setup.h @@ -0,0 +1,25 @@ + +#ifndef SETUP_H +#define SETUP_H + + +#include "configuration.h" +#include "../ax25/ax25.h" +#include "command.h" +#include "../logMngt/log.h" + + +#define SPINO_CMD_KEY 0x0FF0 + +extern unsigned short gv_spino_cmd_key; + + +extern t_configuration_spino gv_spinoConfig; +extern t_globalVariable gv_spino; +extern t_ax25_header gv_headerTlm; +extern unsigned short gv_version; +extern t_prog_mngt gv_prog; +extern char memory_reprog[]; +extern void setupGlobalVariable () ; + +#endif // SETUP_H diff --git a/EmbededSw/src/digipeaterMode/ModeDigipeater.c b/EmbededSw/src/digipeaterMode/ModeDigipeater.c new file mode 100644 index 0000000..8bcd4b3 --- /dev/null +++ b/EmbededSw/src/digipeaterMode/ModeDigipeater.c @@ -0,0 +1,72 @@ +/** + * \file digipeater.c + * \brief MOde Digipeater + * \author Xtophe + * \version 0.2 + * \date 01/08/2022 + * + */ + + +#include +#include +#include "../core/setup.h" +#include "../drivers/modem.h" +#include "../errorMngt/error.h" + + + + + +/** + * \fn unsigned short digipeater () + * \brief manage DIGIPEATER mode + * \return void + * + */ +unsigned short digipeater () +{ + char data[300]; + t_ax25_packet data_ax25; + + + int nbc = readData(data); + + if (nbc !=0) + { + /* traitement des donnees recues */ + int res = convertDataToAx25 (&data_ax25, data, nbc ); + if (res != SUCCESS) + { + logger(LOG_LEVEL_CRITICAL, "AX25 CONVESTION ISSUE"); + } + if (memcmp(gv_spinoConfig.spinoDesCallsign,data_ax25.header.destinationAdress,6)==0) + { + + if (data_ax25.header.ssidDestination == (unsigned char) SSID_SPINO_TMTC) + { + processCommand(data_ax25); + } else if ( data_ax25.header.ssidDestination == (unsigned char) SSID_SPINO_DIGIPEATER) + { + // renvoie la trame + memcpy( data_ax25.header.destinationAdress,data_ax25.header.sourceAdress,6); + data_ax25.header.ssidDestination = data_ax25.header.ssidSource; + memcpy(data_ax25.header.sourceAdress,gv_spinoConfig.spinoSrcCallsign,6); + data_ax25.header.ssidSource = SSID_SPINO_DIGIPEATER; + encodeAX25Header(&data_ax25.header); + nbc = nbc - sizeof(t_ax25_header); + writeData (data_ax25,nbc); + gv_spino.nbDigipeaterMesssageProcessed++; + } else + { + processDropMessage (data,nbc); + } + } else + { + // Message not awaited - message dropped + processDropMessage (data,nbc); + } + + } + return gv_spino.currentState; +} diff --git a/EmbededSw/src/drivers/modem.c b/EmbededSw/src/drivers/modem.c new file mode 100644 index 0000000..c5d5440 --- /dev/null +++ b/EmbededSw/src/drivers/modem.c @@ -0,0 +1,79 @@ +/** + * \file modem.c + * \brief modem simulation + * \author Xtophe + * \version 0.2 + * \date 01/08/2022 + * + * \todo To adapt with embeded target + */ + + +#include +#include "../ax25/ax25.h" +#include "../drivers/modem.h" +#include "../simulation/lefic.h" +#include "../simulation/SpinoSimuServerTCP.h" + + + +int gv_simu_mode = SIMU_MODE_TCP; + + + + +void open () +{ + if( gv_simu_mode == SIMU_MODE_FILE) + { + openfile("./header.bin"); + } + else if (gv_simu_mode == SIMU_MODE_TCP) + { + TCP_OpenAndWait (); + } +} + +int readData (char *data ) +{ + int taille = 0; + + if( gv_simu_mode == SIMU_MODE_FILE) + { + taille = lectureData (data); + + } + else if (gv_simu_mode == SIMU_MODE_TCP) + { + PerformSelect(gv_AcceptSocket, gv_m_client_list, 1); + if (gv_simu_nb_data_received!=0) + { + printf("data received %d",gv_simu_nb_data_received ); + taille = gv_simu_nb_data_received; + + memcpy (data,gv_simu_receiveddata,gv_simu_nb_data_received ); + data =(char *)gv_simu_receiveddata; + gv_simu_nb_data_received=0; + } + } + +return taille; + +} + + + +int writeData (const t_ax25_packet ax25Frame, const int length) { + + if( gv_simu_mode == SIMU_MODE_FILE) + { + writefiledata( ax25Frame,length ); + } + else if (gv_simu_mode == SIMU_MODE_TCP) + { + TCP_Send ((char*) &ax25Frame,length+sizeof(t_ax25_header)); + writefiledata( ax25Frame,length ); + } +return 0; + +} diff --git a/EmbededSw/src/drivers/modem.h b/EmbededSw/src/drivers/modem.h new file mode 100644 index 0000000..5716c9b --- /dev/null +++ b/EmbededSw/src/drivers/modem.h @@ -0,0 +1,17 @@ + +#ifndef MODEM_H +#define MODEM_H + +#include "../ax25/ax25.h" + + +#define SIMU_MODE_FILE 1 +#define SIMU_MODE_TCP 2 + + +extern int readData (char *data ); +extern int writeData ( t_ax25_packet ax25Frame, int length); + +extern int gv_simu_mode; + +#endif // MODEM_H diff --git a/EmbededSw/src/dropMsgMngt/DropMessage.c b/EmbededSw/src/dropMsgMngt/DropMessage.c new file mode 100644 index 0000000..e5879c9 --- /dev/null +++ b/EmbededSw/src/dropMsgMngt/DropMessage.c @@ -0,0 +1,114 @@ +/** + * \file DropMessage.c + * \brief manage message dropped + * \author Xtophe + * \version 0.2 + * \date 01/08/2022 + * + */ + +#include +#include +#include "../core/setup.h" +#include "../errorMngt/error.h" +#include "DropMessage.h" + +extern void writeData ( t_ax25_packet ax25Frame, int length); + + +/** + * \fn void processDropMessage (char* data_ax25, int size) + * \param message Ax25 dropped message + * \param size message size of dropped message + * \brief manage message dropped + * + * \return void + * + */ +extern t_unprocessedmessageList gv_unprocess_messages; + +void processDropMessage (char* data_ax25, int size) +{ + logger(LOG_LEVEL_CRITICAL,"MESSAGE DROPPED"); + gv_spino.nbFrameNotprocessed++; + + gv_unprocess_messages.index = (gv_unprocess_messages.index+1) % MAX_UNPROCESSED_MESSAGE_LIST_SIZE; + gv_unprocess_messages.message[gv_unprocess_messages.index].timestamps = gv_spino.timestamps; + + if (size > MAX_UNPROCESSED_MESSAGE_LENGHT) + { + // trunck to MAX_MESSAGE_SIZE + gv_unprocess_messages.message[gv_unprocess_messages.index].size = MAX_UNPROCESSED_MESSAGE_LENGHT; + + } else { + + gv_unprocess_messages.message[gv_unprocess_messages.index].size = size; + } + + logger(LOG_LEVEL_CRITICAL,data_ax25); + memcpy(&gv_unprocess_messages.message[gv_unprocess_messages.index].data,data_ax25, gv_unprocess_messages.message[gv_unprocess_messages.index].size ); + +} + +/** + * \fn int getLastDroppedMessage(t_tc_response *resp) + * \brief set to response the last dropped message + * \param *resp output structure with result of command + * \return SUCCESS + * + */ + +int getLastDroppedMessage(t_tc_response *resp) +{ + + logger(LOG_LEVEL_CRITICAL," GET_LAST_DROPED_MESSAGE"); + int taille_message = gv_unprocess_messages.message[gv_unprocess_messages.index].size; + taille_message =taille_message+ SIZE_HEADER_DROP; + if (taille_message > MAX_DATA_SIZE ) + { + taille_message = MAX_DATA_SIZE; + } + memcpy(resp->parameter,&gv_unprocess_messages.message[gv_unprocess_messages.index], taille_message ); + resp->size = taille_message; + return SUCCESS; + +} + +/** + * \fn int getLastDroppedMessage(t_tc_response *resp) + * \brief set to response the last dropped message + * \param *resp output structure with result of command + * \return SUCCESS + * + * \todo : suprimer répétition dernier message dropped + * + */ + +int getAllDroppedMessage(t_tc_response *resp) +{ + t_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + resp->header.error_code = SUCCESS; + + int taille_message; + int i=0; + + for (i=0; i < MAX_UNPROCESSED_MESSAGE_LIST_SIZE;i++) + { + + taille_message = gv_unprocess_messages.message[i].size; + taille_message =taille_message+ SIZE_HEADER_DROP; + if (taille_message > MAX_DATA_SIZE ) + { + taille_message = MAX_DATA_SIZE; + } + resp->size=taille_message; + memcpy(resp->parameter,&gv_unprocess_messages.message[i], taille_message ); + + memcpy( ax25Frame.data,resp,TC_REPONSE_HEADER_SIZE+resp->size); + /* envoyer la reponse de la commande */ + writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp->size); + } + return SUCCESS; + +} diff --git a/EmbededSw/src/dropMsgMngt/DropMessage.h b/EmbededSw/src/dropMsgMngt/DropMessage.h new file mode 100644 index 0000000..ba8b2a8 --- /dev/null +++ b/EmbededSw/src/dropMsgMngt/DropMessage.h @@ -0,0 +1,29 @@ + +#ifndef DOPMESSAGE_H +#define DOPMESSAGE_H + + +#define MAX_UNPROCESSED_MESSAGE_LENGHT 256 +#define MAX_UNPROCESSED_MESSAGE_LIST_SIZE 5 + +#define SIZE_HEADER_DROP 8+2 /*taille de la structure hors data */ +typedef struct unprocessedmessage { + unsigned long long timestamps; + unsigned short size; + char data[MAX_UNPROCESSED_MESSAGE_LENGHT]; +} t_unprocessedmessage; + + + +typedef struct unprocessedmessageList { + int index; + t_unprocessedmessage message[MAX_UNPROCESSED_MESSAGE_LIST_SIZE]; + +} t_unprocessedmessageList; + + +extern void processDropMessage (char* data_ax25, int size); +extern int getLastDroppedMessage(t_tc_response *resp); +extern int getAllDroppedMessage(t_tc_response *resp); + +#endif // DOPMESSAGE_H \ No newline at end of file diff --git a/EmbededSw/src/errorMngt/error.h b/EmbededSw/src/errorMngt/error.h new file mode 100644 index 0000000..e43804b --- /dev/null +++ b/EmbededSw/src/errorMngt/error.h @@ -0,0 +1,37 @@ +#ifndef ERROR_H +#define ERROR_H + + +#define ERROR 1 + +#define SUCCESS 0 + +/* Command analysis */ + +#define ERROR_COMMAND_UNKNOW 1 +#define ERROR_COMMAND_NOT_IMPLEMENTED 2 +#define ERROR_COMMAND_WITH_WRONG_KEY 3 + +#define ERROR_VALUE_FIELD_UNKNOW 101 + + +/* AX25 Error */ +#define ERROR_AX25_EXCEED_MAX_LENGH 100 + +/* PROG ERROR */ +#define ERROR_PROG_INDEX_NOT_EQUAL 128 +#define ERROR_PROG_MEM1_MEM2_NOT_EQUAL 129 +#define ERROR_PROG_INDEX_OUT_OF_BOUND 130 + +/* MAILBOX ERROR */ + +#define ERROR_MAILBOX_FULL 10 +#define ERROR_MAILBOX_NOT_FOUND 11 +#define ERROR_MAILBOX_EMPTY 12 +#define ERROR_ADD_MSG_EXCED_SIZE 13 +#define ERROR_GET_LAST_MSG_CALLSIGN_WRONG_SIZE 14 +#define ERROR_MESSAGE_EMPTY 15 + +#define ERROR_INFO_MSG_INDEX_OUT_OF_BOUND 135 + +#endif // ERROR_H diff --git a/EmbededSw/src/logMngt/log.c b/EmbededSw/src/logMngt/log.c new file mode 100644 index 0000000..ce92156 --- /dev/null +++ b/EmbededSw/src/logMngt/log.c @@ -0,0 +1,82 @@ +#include +#include +#include "../core/setup.h" +#include "../errorMngt/error.h" + +extern void writeData ( t_ax25_packet ax25Frame, int length); + + unsigned char gv_SelectedLogLevel=0; + +t_logs logs[MAX_LOG]; +int gvLogIndex =0; +char gvLogMsg[MAX_SIZE_MSG_LOG]; + +void logger(char level, char *message) +{ + + if(level >= gv_SelectedLogLevel ) + { + gvLogIndex = (gvLogIndex+1)%MAX_LOG; + logs[gvLogIndex].priority=level; + logs[gvLogIndex].timeStamps=gv_spino.timestamps; + strcpy(logs[gvLogIndex].log,message); + + printf("LOG : "); + printf(message); + printf("\r\n"); + } + + +} + +/** + * \fn int getLastLog(t_tc_response *resp) + * \brief set to response the last log + * \param *resp output structure with result of command + * \return SUCCESS + * + */ + +int getLastLog(t_tc_response *resp) +{ + + logger(LOG_LEVEL_CRITICAL," GET_LAST_DROPED_MESSAGE"); + int taille_message = sizeof(t_logs); + memcpy(resp->parameter,&logs[gvLogIndex], taille_message ); + resp->size = taille_message; + return SUCCESS; + +} + +/** + * \fn int getAllLogs(t_tc_response *resp) + * \brief send all logs + * \param *resp output structure with result of command + * \return SUCCESS + * + * \todo : suprimer répétition dernier logs + * + */ + +int getAllLogs(t_tc_response *resp) +{ + t_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + resp->header.error_code = SUCCESS; + + int i=0; + + for (i=0; i < MAX_LOG;i++) + { + printf("all index %d",i); + + resp->size= sizeof(t_logs); + memcpy(resp->parameter,&logs[i], resp->size ); + printf("taille %d",resp->size); + memcpy( ax25Frame.data,resp,TC_REPONSE_HEADER_SIZE+resp->size); + /* envoyer la reponse de la commande */ + writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp->size); + } + return SUCCESS; + +} diff --git a/EmbededSw/src/logMngt/log.h b/EmbededSw/src/logMngt/log.h new file mode 100644 index 0000000..6f68915 --- /dev/null +++ b/EmbededSw/src/logMngt/log.h @@ -0,0 +1,26 @@ + +#ifndef LOG_H +#define LOG_H + + +#define LOG_LEVEL_INFO 0 +#define LOG_LEVEL_WARNING 1 +#define LOG_LEVEL_CRITICAL 5 + +#define MAX_LOG 10 +#define MAX_SIZE_MSG_LOG 64 + +typedef struct logs { + long long timeStamps; + char priority; + char log[MAX_SIZE_MSG_LOG]; +} t_logs; + +extern unsigned char gv_SelectedLogLevel; + +extern void logger(char level, char *message); +extern char gvLogMsg[MAX_SIZE_MSG_LOG]; +extern int getAllLogs(t_tc_response *resp); +extern int getLastLog(t_tc_response *resp); + +#endif // LOG_H \ No newline at end of file diff --git a/EmbededSw/src/mailboxMode/mailbox.c b/EmbededSw/src/mailboxMode/mailbox.c new file mode 100644 index 0000000..6981136 --- /dev/null +++ b/EmbededSw/src/mailboxMode/mailbox.c @@ -0,0 +1,572 @@ +/** + * \file mailbox.c + * \brief mailbox management + * \author Xtophe + * \version 0.2 + * \date 01/08/2022 + * + */ + +#include +#include +#include "../core/setup.h" +#include "../drivers/modem.h" +#include "../mailboxMode/mailbox.h" +#include "../errorMngt/error.h" +#include "../ax25/ax25.h" + +t_mailboxes gvMailboxes; + + +/** + * \fn int initialise() + * \brief initialise mailboxes + * + * \return SUCCESS + * + */ + +int initialise() +{ + int i=0; + int j=0; + int k=0; + + gvMailboxes.indexfreeMailbox=0; + gvMailboxes.usedMailboxNumber=0; + gvMailboxes.nbMailboxCommandeReceived=0; + gvMailboxes.nbMailboxErrorCommandeReceived=0; + + for (i =0;icallsign,callsign,6); + + memcpy(pMailbox->messages[pMailbox->indexNextMessage].message,message,sizemMessage); + pMailbox->messages[pMailbox->indexNextMessage].timestamps = gv_spino.timestamps; + pMailbox->messages[pMailbox->indexNextMessage].size=sizemMessage; + + pMailbox->indexNextMessage =(pMailbox->indexNextMessage+1)%MAX_MAILBOX; + pMailbox->messageNumber++; + pMailbox->timestampCreation=gv_spino.timestamps; + + gvMailboxes.usedMailboxNumber++; + gvMailboxes.indexfreeMailbox++; + } else + { /* recherche si BAL existe */ + + int i = 0; + char find =0; + + while ((imessageNumber< MAX_MESSAGE) + { + memcpy(pMailbox->messages[pMailbox->indexNextMessage].message,message,sizemMessage); + pMailbox->messages[pMailbox->indexNextMessage].timestamps = gv_spino.timestamps; + pMailbox->messages[pMailbox->indexNextMessage].size=sizemMessage; + + pMailbox->indexNextMessage =(pMailbox->indexNextMessage+1)%MAX_MAILBOX; + pMailbox->messageNumber++; + + + } else + { + reponse= ERROR_MAILBOX_FULL; + } + find= 1; + } + //} + i++; + } + + if (find == 0) + { + // creation BAL + ajout Message + + if(gvMailboxes.usedMailboxNumbercallsign,callsign,6); + + + memcpy(pMailbox->messages[pMailbox->indexNextMessage].message,message,sizemMessage); + pMailbox->messages[pMailbox->indexNextMessage].timestamps = gv_spino.timestamps; + pMailbox->messages[pMailbox->indexNextMessage].size=sizemMessage; + pMailbox->indexNextMessage =(pMailbox->indexNextMessage+1)%MAX_MAILBOX; + + pMailbox->messageNumber++; + pMailbox->timestampCreation=gv_spino.timestamps; + + // recher de la nouvelle mailbox libre + while ((imessageNumber>0) + { + pMailbox->indexFreeMessage = (pMailbox->indexFreeMessage+1) % MAX_MESSAGE; + pMailbox->messageNumber--; + + // if nb message = 0 => the milbox remain active + // if (pMailbox->messageNumber==0) + // { + // gvMailboxes.usedMailboxNumber--; + // } + } else + { + reponse = ERROR_MAILBOX_EMPTY; + + } + + } + i++; + + } + + if (find ==0) + { + reponse = ERROR_MAILBOX_NOT_FOUND; + } + + + resp->size=0; + +return reponse; + +} +/** + * \fn int getListMailbox(t_tc_response *resp) + * \brief return the list of mailboxes + * + * \return SUCCESS else ERROR_MAILBOX_FULL, + * + * + */ + +int getListMailbox(t_tc_response *resp) +{ + t_list_mailbox list[MAX_MAILBOX]; + int response = SUCCESS; + int i; + + for (i=0; isize = sizeof(t_list_mailbox)*MAX_MAILBOX; + memcpy(resp->parameter,list,resp->size); + + return response; +} + + +/** + * \fn int deleteMailBox (char *callsign,t_tc_response *resp) + * \brief delette Mailbox + * + * \return SUCCESS else ERROR_MAILBOX_NOT_FOUND, + * + * + */ +int deleteMailBox (char *callsign,t_tc_response *resp) +{ + int i=0; + int j=0; + int find =0; + t_mailbox *pMailbox; + int reponse = SUCCESS; + + while ((iindexFreeMessage=MAX_MESSAGE -1; + pMailbox->indexNextMessage=0; + pMailbox->messageNumber=0; + pMailbox->timestampCreation=0; + + gvMailboxes.indexfreeMailbox=i; + gvMailboxes.usedMailboxNumber--; + for (j=0;jcallsign[j]=' '; + } + + find= 1; + + } + + i++; + + } + + if (find ==0) + { + reponse = ERROR_MAILBOX_NOT_FOUND; + + } + + resp->size=0; +return reponse; +} + +/** + * \fn int getLastMessage (char * callsign,t_tc_response *resp) + * \brief return the last message + * + * \return SUCCESS else ERROR_MAILBOX_NOT_FOUND, + * + * + */ + +int getLastMessage (char * callsign,t_tc_response *resp) +{ + + int i=0; + int find =0; + t_mailbox *pMailbox; + int reponse = SUCCESS; + t_get_message messagelue ; + logger(LOG_LEVEL_INFO,"Recherche Message"); + while ((iindexNextMessage-1)% MAX_MESSAGE; + if(message_index<0) + { + message_index = MAX_MESSAGE-1; + } + sprintf(gvLogMsg,"Taille INDEX %d LAST %d\r\n",pMailbox->indexNextMessage,message_index); + logger(LOG_LEVEL_CRITICAL,gvLogMsg); + messagelue.index =message_index; + memcpy(messagelue.callsign,callsign,6); + messagelue.timestamps = pMailbox->messages[message_index].timestamps; + sprintf(gvLogMsg,"Taille SIZE %d \r\n",pMailbox->messages[message_index].size); + memcpy(messagelue.message,pMailbox->messages[message_index].message,pMailbox->messages[message_index].size); + resp->size = pMailbox->messages[message_index].size+SIZE_T_GET_MESSAGE; + memcpy(resp->parameter, &messagelue,resp->size); + find= 1; + logger(LOG_LEVEL_INFO,"Mesage trouvé 2"); + } + logger(LOG_LEVEL_INFO,"Mesage non trouvé 3"); + } + i++; + logger(LOG_LEVEL_INFO,"Mesage non trouvé 5"); + } + + if (find ==0) + { + logger(LOG_LEVEL_INFO,"Mesage non trouvé 4"); + reponse = ERROR_MAILBOX_NOT_FOUND; + resp->size=0; + resp->header.error_code=ERROR_MAILBOX_NOT_FOUND; + } + + +return reponse; + +} + + +/* retroune le dernier message */ + +int getMessage (char * callsign, unsigned char index, t_tc_response *resp) +{ + int i=0; + int find =0; + t_mailbox *pMailbox; + int reponse = SUCCESS; + t_get_message messagelue ; + + sprintf(gvLogMsg,"Taille INDEX %d \r\n",index); + logger(LOG_LEVEL_CRITICAL,gvLogMsg); + + logger(LOG_LEVEL_INFO,"Recherche Message"); + while ((iindexNextMessage,index); + logger(LOG_LEVEL_CRITICAL,gvLogMsg); + if (pMailbox->messages[index].size !=0) + { + messagelue.index =index; + memcpy(messagelue.callsign,callsign,6); + messagelue.timestamps = pMailbox->messages[index].timestamps; + memcpy(messagelue.message,pMailbox->messages[index].message,pMailbox->messages[index].size); + resp->size = pMailbox->messages[index].size+SIZE_T_GET_MESSAGE; + memcpy(resp->parameter, &messagelue,resp->size); + } + else + { + resp->size =0; + resp->header.error_code = ERROR_MESSAGE_EMPTY; + } + + + find= 1; + logger(LOG_LEVEL_INFO,"Mesage trouvé 2"); + } + logger(LOG_LEVEL_INFO,"Mesage non trouvé 3"); + } + i++; + logger(LOG_LEVEL_INFO,"Mesage non trouvé 5"); + } + + if (find ==0) + { + logger(LOG_LEVEL_INFO,"Mesage non trouvé 4"); + reponse = ERROR_MAILBOX_NOT_FOUND; + resp->size=0; + resp->header.error_code=ERROR_MAILBOX_NOT_FOUND; + } + + +return reponse; +} + +int getAllMesage (char * callsign, char index) +{ +int reponse = ERROR_COMMAND_NOT_IMPLEMENTED; +return reponse; +} + +int dumpMailbox () +{ +int reponse = ERROR_COMMAND_NOT_IMPLEMENTED; +return reponse; +} + + + + +t_tc_response interpretMailBoxcommand( t_command cmd, char *callsign) { + + + t_tc_response resp; + int reponse=SUCCESS; + + + resp.header.responseType = RESULT_CMD; + resp.header.timeStamp=gv_spino.timestamps; + resp.header.cmd_id = cmd.id; + + + + switch (cmd.id) + { + + case CMD_MAILBOX_INIT: + logger(LOG_LEVEL_INFO,"Commande MAILBOX RESET"); + reponse = initialise(); + resp.size=0; + break; + break; + case CMD_MAILBOX_ADD_MSG : + logger(LOG_LEVEL_INFO,"Commande MAILBOX ADD MSG"); + if(cmd.size > MAX_LENGHT_MESSAGE) + { + reponse=ERROR_ADD_MSG_EXCED_SIZE; + } else + { + char message[MAX_LENGHT_MESSAGE]; + sprintf(gvLogMsg,"taille message %d \r\n",cmd.size); + logger(LOG_LEVEL_CRITICAL,gvLogMsg); + memcpy(message, cmd.parameter, cmd.size); + reponse = addMessage (callsign,message,cmd.size); + } + resp.size=0; + break; + break; + case CMD_MAILBOX_DEL_MSG : + logger(LOG_LEVEL_INFO,"Commande MAILBOX DELETE MSG !!!"); + reponse = deletteMessage (callsign,&resp); + resp.size=0; + break; + case CMD_MAILBOX_GET_LIST_BOX: + logger(LOG_LEVEL_INFO,"Commande MAILBOX LIST MAILBOXES"); + reponse = getListMailbox (&resp); + break; + case CMD_MAILBOX_DELETTE_BOX : + logger(LOG_LEVEL_INFO,"Commande MAILBOX DELETE MAILBOX"); + reponse = deleteMailBox (callsign,&resp); + resp.size=0; + break; + case CMD_MAILBOX_GET_LAST_MSG : + logger(LOG_LEVEL_INFO,"Commande MAILBOX GET LAST MESSAGE"); + if(cmd.size == 6) + { + char callsignMailbox[6]; + memcpy(callsignMailbox, cmd.parameter, cmd.size); + reponse = getLastMessage (callsignMailbox,&resp); + } else + { + reponse=ERROR_GET_LAST_MSG_CALLSIGN_WRONG_SIZE; + } + + break; + case CMD_MAILBOX_GET_MSG : + + logger(LOG_LEVEL_INFO,"Commande MAILBOX GET MESSAGE INDEX"); + reponse = getMessage (&cmd.parameter[1],cmd.parameter[0], &resp); + break; + + case CMD_MAILBOX_GET_ALL_MSG : + reponse = ERROR_COMMAND_NOT_IMPLEMENTED; + break; + case CMD_MAILBOX_DUMP_MAILBOX: + reponse = ERROR_COMMAND_NOT_IMPLEMENTED; + break; + default: + // generation code erreur + sprintf(gvLogMsg,"erreur mailbox cmd %d \r\n",cmd.id); + logger(LOG_LEVEL_CRITICAL,gvLogMsg); + reponse = ERROR_COMMAND_UNKNOW; + resp.size =0; + break; + } + + resp.header.error_code = reponse; + return resp; +} + + + +void processMailbox(t_ax25_packet data_ax25) { + + t_tc_response result ; + t_command cmd; + + gvMailboxes.nbMailboxCommandeReceived++; + memcpy(&cmd,data_ax25.data,sizeof(t_command)); + result = interpretMailBoxcommand( cmd,data_ax25.header.sourceAdress); + if(result.header.error_code !=SUCCESS) + { + gvMailboxes.nbMailboxErrorCommandeReceived++; + } + t_ax25_packet ax25Frame; + + memcpy(ax25Frame.header.sourceAdress,gv_spinoConfig.spinoDesCallsign,6); + ax25Frame.header.ssidSource = SSID_SPINO_DIGIPEATER; + memcpy(ax25Frame.header.destinationAdress,data_ax25.header.sourceAdress,6); + encodeAX25Header(&ax25Frame.header) ; + memcpy( ax25Frame.data,&result,TC_REPONSE_HEADER_SIZE+result.size); + /* envoyer la reponse de la commande */ + writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+result.size); + sprintf(gvLogMsg,"RESULT MAILBOX COMMAND %x %x ",result.header.cmd_id,result.header.error_code); + logger(LOG_LEVEL_CRITICAL,gvLogMsg); +} diff --git a/EmbededSw/src/mailboxMode/mailbox.h b/EmbededSw/src/mailboxMode/mailbox.h new file mode 100644 index 0000000..54ee8fe --- /dev/null +++ b/EmbededSw/src/mailboxMode/mailbox.h @@ -0,0 +1,100 @@ +#ifndef MAILBOX_H +#define MAILBOX_H + +#include "../ax25/ax25.h" + +#define MAX_MAILBOX 10 +#define MAX_MESSAGE 10 + +#define MAX_LENGHT_MESSAGE 256 +#define CALLSIGN_SIZE 6 + +/* COMMANDE MAILBOX */ + +#define CMD_MAILBOX_INIT 32 +#define CMD_MAILBOX_ADD_MSG 33 +#define CMD_MAILBOX_DEL_MSG 34 +#define CMD_MAILBOX_GET_LIST_BOX 35 +#define CMD_MAILBOX_DELETTE_BOX 36 +#define CMD_MAILBOX_GET_LAST_MSG 37 +#define CMD_MAILBOX_GET_MSG 38 +#define CMD_MAILBOX_GET_ALL_MSG 39 +#define CMD_MAILBOX_DUMP_MAILBOX 40 + + +/** + * \struct t_mailbox_message + * \brief define mailbox structure to store message for a dedicated Callsign + * + */ + +typedef struct mailbox_message { + long long timestamps; /*!< Time Stamps of message creation */ + unsigned short size; /*!< message size. Should <= MAX_LENGHT_MESSAGE*/ + char message[MAX_LENGHT_MESSAGE]; /*!< Message contents */ +}t_mailbox_message; + + + +/** + * \struct t_mailbox_message + * \brief define mailbox structure to store message for a dedicated Callsign + * + */ + +typedef struct mail_box +{ + char messageNumber; + unsigned char indexNextMessage; + char indexFreeMessage; + char callsign[CALLSIGN_SIZE]; + long long timestampCreation; + t_mailbox_message messages[MAX_MESSAGE]; + /* data */ +} t_mailbox; + + +typedef struct mailboxes +{ + + t_mailbox mailbox[MAX_MAILBOX]; + int usedMailboxNumber; + int indexfreeMailbox; + long nbMailboxCommandeReceived; + long nbMailboxErrorCommandeReceived; +} t_mailboxes; + +typedef struct listMailbox +{ + char callsign [6]; + char nb_message; +}t_list_mailbox; + + +typedef struct add_message +{ + char size; + char message[MAX_LENGHT_MESSAGE]; + +}t_add_message; + +#define SIZE_T_GET_MESSAGE 15 +typedef struct get_message +{ + long long timestamps; + char callsign[6]; + char index; + char message[MAX_LENGHT_MESSAGE]; + +} t_get_message; + +typedef struct cmd_get_message +{ + unsigned char index; + char callsign[6]; + +} t_cmd_get_message; + +extern void processMailbox(t_ax25_packet data_ax25); + +#endif // MAILBOX_H diff --git a/EmbededSw/src/mailboxMode/modeMailbox.c b/EmbededSw/src/mailboxMode/modeMailbox.c new file mode 100644 index 0000000..74a1d17 --- /dev/null +++ b/EmbededSw/src/mailboxMode/modeMailbox.c @@ -0,0 +1,48 @@ + +#include +#include +#include "../core/setup.h" +#include "../drivers/modem.h" +#include "../mailboxMode/mailbox.h" +#include "../errorMngt/error.h" + + + + +unsigned short modeMailbox () +{ + char data[300]; + t_ax25_packet data_ax25; + + + int nbc = readData(data); + + if (nbc !=0) + { + /* traitement des donnees recues */ + int res = convertDataToAx25 (&data_ax25, data, nbc ); + if (res != SUCCESS) + { + logger(LOG_LEVEL_CRITICAL, "AX25 CONVESTION ISSUE"); + } + + if (memcmp(gv_spinoConfig.spinoDesCallsign,data_ax25.header.destinationAdress,6)==0) + { + if (data_ax25.header.ssidDestination == (unsigned char) SSID_SPINO_TMTC) + { + processCommand(data_ax25); + } else if ( data_ax25.header.ssidDestination == (unsigned char) SSID_SPINO_MAILBOX) + { + logger(LOG_LEVEL_CRITICAL,"TRT COMMANDE MAILBOX"); + processMailbox(data_ax25); + + } else + { + // Message not awaited - message dropped + processDropMessage (data,nbc); + } + + } + } + return gv_spino.currentState; +} diff --git a/EmbededSw/src/mailboxMode/modeMailbox.h b/EmbededSw/src/mailboxMode/modeMailbox.h new file mode 100644 index 0000000..5425d0f --- /dev/null +++ b/EmbededSw/src/mailboxMode/modeMailbox.h @@ -0,0 +1,7 @@ + +#ifndef MODEMAILBOX +#define MODEMAILBOX + + + +#endif // MODEMAILBOX \ No newline at end of file diff --git a/EmbededSw/src/main.c b/EmbededSw/src/main.c new file mode 100644 index 0000000..b37c949 --- /dev/null +++ b/EmbededSw/src/main.c @@ -0,0 +1,46 @@ +/** + * \file main.c + * \brief launch simulator + * \author Xtophe + * \version 0.2 + * \date 01/08/2022 + * + */ + + +#include +#include +#include "./core/setup.h" + + +#define STATE_SURVEY 1 +#define STATE_MAILBOX 2 + +extern void control(); +extern void open (); + +/** + * \fn int main (void) + * \brief Entrée du programme. + * + * \return 0 - Arrêt normal du programme. + */ + +int main (void ) +{ + printf("Spino Emulation V0.3\n"); + + + setupGlobalVariable(); + + open(); + + control(); + + + printf ("END \n\r"); + + + + return 0; +} diff --git a/EmbededSw/src/simulation/SpinoSimuServerTCP.c b/EmbededSw/src/simulation/SpinoSimuServerTCP.c new file mode 100644 index 0000000..7787521 --- /dev/null +++ b/EmbededSw/src/simulation/SpinoSimuServerTCP.c @@ -0,0 +1,289 @@ + /*********************************************************************************************** + * + * File Name : tcpServer + * + * Description : manage tcp server for testing purpose + * + * Usage : for Spino simulator only + * + * nota : code based on : http://dwise1.net/pgm/sockets/blocking.html + * + * ********************************************************************************************* + * + * Autor : Xtophe + * + * date : 2022 / 08 /01 + * + * Version : 0.1 + * + * todo : + * + * ********************************************************************************************** + * + * You need to link the library: libws2_32.a + * OR + * -lwsock32 + * -lws2_32 + * from c:\TDM-GCC-64\x86_64-w64-mingw32\lib32\ + * OR + * c:\MinGW\lib\ + * if you using GCC on windows +***********************************************************************************************/ + + +/*========= INCLUDES ==========================================================================*/ + +#include +#include +#include +#include +#include "SpinoSimuServerTCP.h" + + +/*========= GLOBAL VARIABLES ===================================================================*/ + + + +char gv_simu_receiveddata[MAX_DATA]; +int gv_simu_nb_data_received =0; + + +SOCKET m_ServerSock; /* server's listening socket */ +SOCKET gv_m_client_list[MAX_CLIENTS]; +int m_iNumclients; +SOCKET gv_AcceptSocket; +SOCKET TCPServerSocket; + + +unsigned char test[6]={0x0,0x01,0x0F,0x10,0xF0,0xFF}; + + /*========= FUNCTIONS ========================================================================*/ + +/*--------------------------------------------------------------------------------------------------------- + * + * HandleClient(SOCKET AcceptSocket) : + * + * description : perform treatment when data are received + * + * + ---------------------------------------------------------------------------------------------------------*/ + +void HandleClient(SOCKET AcceptSocket) +{ +// STEP-7 Send Message to Client + gv_simu_nb_data_received =0; + gv_simu_nb_data_received = recv(AcceptSocket,gv_simu_receiveddata, MAX_DATA, 0); + if (gv_simu_nb_data_received == (unsigned int) SOCKET_ERROR) { + printf("SERVER: Receive Failed, Error: %d\n", WSAGetLastError()); + exit(-1); + gv_simu_nb_data_received=0; + } + +} + +/*--------------------------------------------------------------------------------------------------------- + * + * PerformSelect(SOCKET listeningSock, SOCKET clients[], int iNumClients)) : + * + * description : see http://dwise1.net/pgm/sockets/blocking.html#SELECT + * + * + ---------------------------------------------------------------------------------------------------------*/ + +void PerformSelect(SOCKET listeningSock, SOCKET clients[], int iNumClients) +{ + fd_set sockSet; /* Set of socket descriptors for select() */ + struct timeval selTimeout; /* Timeout for select() */ + int i; + int iResult; + + /* Zero socket descriptor vector and set for server sockets */ + /* This must be reset every time select() is called */ + FD_ZERO(&sockSet); + FD_SET(listeningSock, &sockSet); + for (i=0; i < iNumClients; i++) + FD_SET(clients[i], &sockSet); + + /* Timeout specification */ + /* This must be reset every time select() is called */ + selTimeout.tv_sec = 0; /* timeout (secs.) */ + selTimeout.tv_usec = 100000; /* 0 microseconds */ + + iResult = select(0, &sockSet, NULL, NULL, &selTimeout); + + if (iResult == -1) + { + /* an error occurred; process it (eg, display error message) */ + } + else if (iResult > 0) /* ie, if a socket is ready */ + { + // test this specific socket to see if it was one of the ones that was set + // if (FD_ISSET(listeningSock, &sockSet)) + // { + // AcceptNewClient(listeningSock); + // } + + /* Now test the client sockets */ + for (i=0; i < iNumClients; i++) + if (FD_ISSET(clients[i], &sockSet)) + { + /* do whatever it takes to read the socket and handle the client */ + /* Please note that this will involve reassociating the socket */ + /* with the client record */ + HandleClient(clients[i]); + } + } + + /* else iResult == 0, no socket is ready to be read, */ + /* so ignore them and move on. */ + +} + +/*--------------------------------------------------------------------------------------------------------- + * + * OpenAndWait ( ) : + * + * description : initialise and wait a client + * + * + ---------------------------------------------------------------------------------------------------------*/ + + +void TCP_OpenAndWait () +{ + printf("TCP SERVER\n"); + + WSADATA Winsockdata; + + struct sockaddr_in TCPServerAddr; + struct sockaddr_in TCPClientAddr; + int TCPClientAddrSize = sizeof(TCPClientAddr); + + + + // STEP-1 WSAStartUp + if (WSAStartup(MAKEWORD(2,2), &Winsockdata) != 0) { + printf("SERVER: WSAStartUp Failed"); + } + printf("SERVER: WSAStartUp Success\n"); + + // STEP-2 Fill TCPServerAddr Struct + TCPServerAddr.sin_family = AF_INET; + TCPServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); + TCPServerAddr.sin_port = htons(8888); + + //STEP-3 Create Socket + if ((TCPServerSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == INVALID_SOCKET) { + printf("SERVER: TCP Server: Create Socket Failed, Error: %d\n", WSAGetLastError()); + } + printf("SERVER: TCP Server: Create Socket Success\n"); + + //STEP-4 bind + if (bind(TCPServerSocket, (SOCKADDR*)&TCPServerAddr, sizeof(TCPServerAddr)) == SOCKET_ERROR) { + printf("SERVER: Binding Failed, Error: %d", WSAGetLastError()); + } + printf("SERVER: Binding Success\n"); + + //STEP-5 Listen + if (listen(TCPServerSocket, 2) == SOCKET_ERROR) { + printf("SERVER: Listen Failed, Error: %d", WSAGetLastError()); + } + printf("SERVER: Listen Success: Listening for incoming connection...\n"); + + // STEP-6 Accept + if ((gv_AcceptSocket = accept(TCPServerSocket, (SOCKADDR *)&TCPClientAddr, &TCPClientAddrSize)) == INVALID_SOCKET) { + printf("SERVER: Accept Failed, Error: %d\n", WSAGetLastError()); + } + printf("SERVER: Connection Accepted\n"); + m_ServerSock = 2; + gv_m_client_list[0]=gv_AcceptSocket; + +} + + +/*--------------------------------------------------------------------------------------------------------- + * + * TCP_closeALL ( ) : + * + * description : close all open port. + * + * + ---------------------------------------------------------------------------------------------------------*/ +void TCP_closeAll() +{ + // STEP-9 Close Socket + if (closesocket(TCPServerSocket) == SOCKET_ERROR) { + printf("SERVER: Close Socket Failed, Error: %d\n", WSAGetLastError()); + } + printf("SERVER: Close Socket Success\n"); + + // STEP-10 Clean + if (WSACleanup() == SOCKET_ERROR) { + printf("SERVER: WSACleanup Failed, Error: %d\n", WSAGetLastError()); + } + printf("SERVER: WSACleanup Success\n"); +} + +/*--------------------------------------------------------------------------------------------------------- + * + * TCP_send ( byte data, int nbdata ) : + * + * description : send data + * + * + ---------------------------------------------------------------------------------------------------------*/ + + void TCP_Send (char *data, int nb ) + { + if (send(gv_AcceptSocket,data, nb, 0) == SOCKET_ERROR) { + printf("SERVER: Send Failed Error: %d\n", WSAGetLastError()); + } + printf("SERVER: Message Sent!\n"); + } + + + + + +// int main() { + + // unsigned char test[6]={0x0,0x01,0x0F,0x10,0xF0,0xFF}; + // TCP_OpenAndWait (); + // int i; + // while (1) + // { + // PerformSelect(gv_AcceptSocket, gv_m_client_list, 1); + + // if (gv_simu_nb_data_received!=0) + // { + // printf("data recieved %d \r\n",gv_simu_nb_data_received ); + // gv_simu_nb_data_received=0; + // TCP_Send (test,6); +// +// } else +// { +// printf("wait", i++); +// } +// +// } + +//} + + + + +/* +run: + +TCP SERVER +SERVER: WSAStartUp Success +SERVER: TCP Server: Create Socket Success +SERVER: Binding Success +SERVER: Listen Success: Listening for incoming connection... +SERVER: Connection Accepted +SERVER: Message Sent! +SERVER: Received Message From Client: Hello from Client! +SERVER: Close Socket Success +SERVER: WSACleanup Success + +*/ diff --git a/EmbededSw/src/simulation/SpinoSimuServerTCP.h b/EmbededSw/src/simulation/SpinoSimuServerTCP.h new file mode 100644 index 0000000..5fb5310 --- /dev/null +++ b/EmbededSw/src/simulation/SpinoSimuServerTCP.h @@ -0,0 +1,20 @@ + +#ifndef SPINOSIMUSERVER_H +#define SPINOSIMUSERVER_H + +#include + +#define MAX_DATA 512 +#define MAX_CLIENTS 2 + + +extern char gv_simu_receiveddata[]; +extern int gv_simu_nb_data_received; +extern SOCKET gv_m_client_list[MAX_CLIENTS]; +extern SOCKET gv_AcceptSocket; + +extern void PerformSelect(SOCKET listeningSock, SOCKET clients[], int iNumClients); +extern void TCP_OpenAndWait (); +extern void TCP_Send (char *data, int nb ); + +#endif //SPINOSIMUSERVER_H diff --git a/EmbededSw/src/simulation/lecfic.c b/EmbededSw/src/simulation/lecfic.c new file mode 100644 index 0000000..e151cf6 --- /dev/null +++ b/EmbededSw/src/simulation/lecfic.c @@ -0,0 +1,89 @@ +#include +#include +#include + +#include "../ax25/ax25.h" + +#define TAILLE_BUF 300 /* valeur quelconque (en général, beaucoup plus grande) */ + + +FILE* fichier ; + +void openfile(char * filename) +{ + + fichier = fopen( filename, "rb") ; + if ( fichier==NULL ) + { + printf("Ouverture du fichier impossible !"); + exit(0); + } + +} + +int lectureData (char *data) +{ + int nb_val_lues; + + unsigned char taille; + // lecture taille data + nb_val_lues = fread( &taille, sizeof(char), 1, fichier); + if (nb_val_lues != 0) + nb_val_lues = fread( data, sizeof(char), taille, fichier); + return nb_val_lues; + +} + + +int lectureFile (char * filename, char *data) +{ + FILE* fic ; + + + // char [TAILLE_BUF]; /* ce tableau mémorisera les valeurs lues dans le fichier */ + short int nb_val_lues = TAILLE_BUF ; + /* Ouverture du fichier (en lecture binaire) : */ + fic = fopen( filename, "rb") ; + if ( fic==NULL ) + { + printf("Ouverture du fichier impossible !"); + exit(0); + } + /* Lecture dans le fichier : */ + printf("\n Liste des valeurs lues : \n"); + /*Remplissage du buffer et traitement, autant de fois que nécessaire jusqu'à la fin fichier : */ + while ( nb_val_lues == TAILLE_BUF ) /* vrai tant que fin du fichier non atteinte */ + { + + nb_val_lues = fread( data, sizeof(char), TAILLE_BUF, fic); + /* Traitement des valeurs stockées dans le buffer (ici, un simple affichage) : */ + // for (i=0; i +#include "../core/setup.h" +#include "../drivers/modem.h" +#include "../errorMngt/error.h" +#include "../dropMsgMngt/DropMessage.h" + +unsigned short survey() { + char data[300]; + t_ax25_packet data_ax25; + + int nbc = readData(data); + + if (nbc != 0) { + /* traitement des donnees recues */ + int res = convertDataToAx25(&data_ax25, data, nbc); + if (res != SUCCESS) + { + logger(LOG_LEVEL_CRITICAL, "AX25 CONVESTION ISSUE"); + } + // sprintf(gvLogMsg,"NB Data received %02x %02x %02x \r\n",data_ax25.header.destinationAdress[0],data_ax25.header.destinationAdress[1],data_ax25.header.destinationAdress[2]); + // logger(LOG_LEVEL_CRITICAL,gvLogMsg); + if (memcmp(gv_spinoConfig.spinoDesCallsign, + data_ax25.header.destinationAdress, 6) == 0) { + + if (data_ax25.header.ssidDestination + == (unsigned char) SSID_SPINO_TMTC) { + processCommand(data_ax25); + } + } else { + // Message not awaited - message dropped + processDropMessage(data, nbc); + + } + + } + return gv_spino.currentState; +} diff --git a/SPECIFICATIONS/todo.md b/SPECIFICATIONS/todo.md new file mode 100644 index 0000000..d1fd4ad --- /dev/null +++ b/SPECIFICATIONS/todo.md @@ -0,0 +1,41 @@ + +[X] gestion de l'entête AX25 envoie + +[X] gestion de la version + [X] indication version + [X] get Version + +[X] gestion de la télémesure + [X] trame de TLM + [X] positionnement du niveau de log + + +[X] possibilité de mettre à l'heure + [X] commande Set timeS + +[] gestion message d'information + [X] add info MSG + [X] del info MSG + [X] Active/ not active + [ ] envoie message info + [X] delai info message + +[X] gestion des logs + [X] recupération d'un message de log + [X] recupération de tous les messages de logs + +[X] gestion message dropped + [X] recupération d'un message dropped + [X] recupération de tous les messages dropped + +[X] ajout d'une clée pour la commande + +[X] gestion des size => passage de char a short + +[ ] Gestion du mode EXPERIMENTAL +[ ] Gestion du mode Main Payload + +[ ] Maiblox + [ ] timer de netoyage + +[ ] revisiter l'envoie TLM / + Message info -- GitLab From b8abb0be71a6d4a4c9fc6cbb665241d780f23a44 Mon Sep 17 00:00:00 2001 From: chris Date: Thu, 25 Aug 2022 00:06:13 +0200 Subject: [PATCH 05/12] Feat : information message struct --- EmbededSw/src/ax25/ax25.c | 6 +++-- EmbededSw/src/core/informationMessage.c | 27 +++++++++++++------ EmbededSw/src/core/informationMessage.h | 6 ++++- EmbededSw/src/digipeaterMode/ModeDigipeater.c | 2 +- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/EmbededSw/src/ax25/ax25.c b/EmbededSw/src/ax25/ax25.c index 6005f26..a5e7242 100644 --- a/EmbededSw/src/ax25/ax25.c +++ b/EmbededSw/src/ax25/ax25.c @@ -29,8 +29,10 @@ void encodeAX25Header(t_ax25_header *data) { int i=0; unsigned char c; - data->ssidDestination = (unsigned char) (data->ssidDestination<< 1 & 0xFE); - data->ssidSource = (unsigned char) (data->ssidSource<< 1 & 0xFE); + c =(unsigned char) (data->ssidDestination<< 1 & 0xFE); + data->ssidDestination = c; + c =(unsigned char) (data->ssidSource<< 1 & 0xFE); + data->ssidSource = c; for (i=0;i< 6; i++) { c =(unsigned char) data->destinationAdress[i]; diff --git a/EmbededSw/src/core/informationMessage.c b/EmbededSw/src/core/informationMessage.c index b5c153d..370c116 100644 --- a/EmbededSw/src/core/informationMessage.c +++ b/EmbededSw/src/core/informationMessage.c @@ -14,7 +14,7 @@ s_inf_msg gv_information_msg[MAX_INF_MESSAGE]; -long long lv_spino_timeStampInfoMsgPrevious=0; +unsigned long long lv_spino_timeStampInfoMsgPrevious=0; unsigned short lv_index_message_actif =0; @@ -32,8 +32,13 @@ unsigned short lv_index_message_actif =0; if(info_msg.index < MAX_INF_MESSAGE) { gv_information_msg[index].used = INFO_MSG_USED; - strncpy(gv_information_msg[index].message, info_msg.message, MAX_SIZE_INF_MSG); - logger(LOG_LEVEL_INFO,"gv_information_msg[index].message"); + if( strlen (info_msg.message)>=MAX_SIZE_INF_MSG ) + { + strncpy(gv_information_msg[index].message, info_msg.message, MAX_SIZE_INF_MSG); + } else + { + strcpy(gv_information_msg[index].message, info_msg.message); + } } else { @@ -79,6 +84,8 @@ unsigned short lv_index_message_actif =0; lv_spino_timeStampInfoMsgPrevious = gv_spino.timestamps; t_tc_response resp; + s_send_inf_msg infMsg; + resp.header.responseType = INFORMATION_MSG; resp.header.error_code = 0; resp.header.cmd_id =0; @@ -89,13 +96,17 @@ unsigned short lv_index_message_actif =0; while(find==0) { cpt++; - lv_index_message_actif = (lv_index_message_actif + 1) % MAX_INF_MESSAGE; + if( gv_information_msg[lv_index_message_actif].used == INFO_MSG_USED) { find=1; - // envoie messgae - strcpy(resp.parameter, gv_information_msg[lv_index_message_actif].message); - resp.size = strlen(gv_information_msg[lv_index_message_actif].message); + infMsg.index= lv_index_message_actif; + infMsg.used = gv_information_msg[lv_index_message_actif].used; + resp.size = strlen(gv_information_msg[lv_index_message_actif].message)+2; + strcpy(infMsg.message , gv_information_msg[lv_index_message_actif].message); + + // strcpy(resp.parameter, gv_information_msg[lv_index_message_actif].message); + memcpy( resp.parameter,&infMsg,resp.size); t_ax25_packet ax25Frame; ax25Frame.header = gv_headerTlm; memcpy( ax25Frame.data,&resp,TC_REPONSE_HEADER_SIZE+resp.size); @@ -111,7 +122,7 @@ unsigned short lv_index_message_actif =0; logger(LOG_LEVEL_CRITICAL,"NO MESSAGE INFO AVAILABLE"); } - + lv_index_message_actif = (lv_index_message_actif + 1) % MAX_INF_MESSAGE; } diff --git a/EmbededSw/src/core/informationMessage.h b/EmbededSw/src/core/informationMessage.h index 66f80c0..7d99866 100644 --- a/EmbededSw/src/core/informationMessage.h +++ b/EmbededSw/src/core/informationMessage.h @@ -21,7 +21,11 @@ typedef struct add_inf_msg { char message[MAX_SIZE_INF_MSG]; }s_add_inf_msg; - +typedef struct send_in_msg { + char index; + char used; + char message[MAX_SIZE_INF_MSG]; +}s_send_inf_msg; extern int setInfoMessage(char *data,t_tc_response *resp); extern int delInfoMessage(char index ,t_tc_response *resp); diff --git a/EmbededSw/src/digipeaterMode/ModeDigipeater.c b/EmbededSw/src/digipeaterMode/ModeDigipeater.c index 8bcd4b3..e0323c7 100644 --- a/EmbededSw/src/digipeaterMode/ModeDigipeater.c +++ b/EmbededSw/src/digipeaterMode/ModeDigipeater.c @@ -50,9 +50,9 @@ unsigned short digipeater () { // renvoie la trame memcpy( data_ax25.header.destinationAdress,data_ax25.header.sourceAdress,6); - data_ax25.header.ssidDestination = data_ax25.header.ssidSource; memcpy(data_ax25.header.sourceAdress,gv_spinoConfig.spinoSrcCallsign,6); data_ax25.header.ssidSource = SSID_SPINO_DIGIPEATER; + data_ax25.header.ssidDestination = data_ax25.header.ssidSource; encodeAX25Header(&data_ax25.header); nbc = nbc - sizeof(t_ax25_header); writeData (data_ax25,nbc); -- GitLab From 6d2afeca8eddb2756b7d21b439bba38ff24d85ed Mon Sep 17 00:00:00 2001 From: chris Date: Sat, 3 Sep 2022 09:42:54 +0200 Subject: [PATCH 06/12] feat add documentation --- EmbededSw/src/core/command.c | 8 +- EmbededSw/src/core/informationMessage.c | 100 ++++++++++++++---- EmbededSw/src/core/informationMessage.h | 1 + EmbededSw/src/core/setup.c | 5 + EmbededSw/src/dropMsgMngt/DropMessage.c | 1 + EmbededSw/src/errorMngt/error.h | 1 + EmbededSw/src/logMngt/log.c | 35 ++++-- EmbededSw/src/logMngt/log.h | 5 +- SPECIFICATIONS/Ground station to OBC.plantuml | 16 +++ SPECIFICATIONS/Ground_station_to_OBC.png | Bin 0 -> 29321 bytes SPECIFICATIONS/I2C register.plantuml | 12 +++ SPECIFICATIONS/I2C_register.png | Bin 0 -> 9922 bytes SPECIFICATIONS/OBC to Ground Station.plantuml | 17 +++ SPECIFICATIONS/OBC_to_Ground_Station.png | Bin 0 -> 34229 bytes SPECIFICATIONS/PrimaryPayloadMode.md | 45 ++++++++ SPECIFICATIONS/todo.md | 2 + 16 files changed, 213 insertions(+), 35 deletions(-) create mode 100644 SPECIFICATIONS/Ground station to OBC.plantuml create mode 100644 SPECIFICATIONS/Ground_station_to_OBC.png create mode 100644 SPECIFICATIONS/I2C register.plantuml create mode 100644 SPECIFICATIONS/I2C_register.png create mode 100644 SPECIFICATIONS/OBC to Ground Station.plantuml create mode 100644 SPECIFICATIONS/OBC_to_Ground_Station.png create mode 100644 SPECIFICATIONS/PrimaryPayloadMode.md diff --git a/EmbededSw/src/core/command.c b/EmbededSw/src/core/command.c index 27f7fb9..9824ec6 100644 --- a/EmbededSw/src/core/command.c +++ b/EmbededSw/src/core/command.c @@ -360,7 +360,13 @@ t_tc_response interpretcommand(t_command cmd) { return resp; } - +/** + * \fn void processCommand(t_ax25_packet data_ax25) + * \brief process command ax25 packet + * \param Ax25 packet + * \return SUCCESS if or Error code + * + */ void processCommand(t_ax25_packet data_ax25) { t_tc_response result ; diff --git a/EmbededSw/src/core/informationMessage.c b/EmbededSw/src/core/informationMessage.c index 370c116..8ae2f51 100644 --- a/EmbededSw/src/core/informationMessage.c +++ b/EmbededSw/src/core/informationMessage.c @@ -1,8 +1,10 @@ -/* - * informationMessage.c +/** + * \file InformationMessage.c + * \brief manage information message + * \author Xtophe + * \version 0.2 + * \date 21/08/2022 * - * Created on: 21 août 2022 - * Author: chris */ #include #include @@ -18,6 +20,38 @@ unsigned long long lv_spino_timeStampInfoMsgPrevious=0; unsigned short lv_index_message_actif =0; + +/** + * \fn void setupInfoMessage() + * \brief initialise information global variable + * \return void + * + */ + void setupInfoMessage() + { + int i=0; + int j=0; + for (i=0; i< MAX_INF_MESSAGE;i++) + { + gv_information_msg[i].used=INFO_MSG_NOT_USED; + for (j=0; j< MAX_SIZE_INF_MSG ;j++) + { + gv_information_msg[i].message[j]=0; + } + + } + } + + /** + * \fn int setInfoMessage(char *data,t_tc_response *resp) + * \param information data in raw => to be set in s_add_inf_msg structure + * \param *resp output structure with result of command + * + * \brief add information message + * + * \return SUCCESS or ERROR_INFO_MSG_INDEX_OUT_OF_BOUND + * + */ int setInfoMessage(char *data,t_tc_response *resp) { @@ -29,8 +63,15 @@ unsigned short lv_index_message_actif =0; memcpy(&info_msg,data, sizeof(s_add_inf_msg)); index = info_msg.index; logger(LOG_LEVEL_INFO,"SET INFO MESSAGE"); + + if(info_msg.index < MAX_INF_MESSAGE) { + gv_information_msg[index].message[0]=0; + gv_information_msg[index].used=INFO_MSG_USED; + strncat(gv_information_msg[index].message,info_msg.message,MAX_SIZE_INF_MSG); + + /* gv_information_msg[index].used = INFO_MSG_USED; if( strlen (info_msg.message)>=MAX_SIZE_INF_MSG ) { @@ -39,7 +80,7 @@ unsigned short lv_index_message_actif =0; { strcpy(gv_information_msg[index].message, info_msg.message); } - + */ } else { reponse = ERROR_INFO_MSG_INDEX_OUT_OF_BOUND; @@ -50,6 +91,17 @@ unsigned short lv_index_message_actif =0; } + /** + * \fn int delInfoMessage(char index ,t_tc_response *resp) + * \param index of message to remove + * \param *resp output structure with result of command + * + * \brief add information message + * + * \return SUCCESS or ERROR_INFO_MSG_INDEX_OUT_OF_BOUND or ERROR_INFO_MSG_ALREADY_NOT_USED + * + */ + int delInfoMessage(char index ,t_tc_response *resp) { @@ -58,6 +110,10 @@ unsigned short lv_index_message_actif =0; if(index < MAX_INF_MESSAGE) { + if(gv_information_msg[ind].used == INFO_MSG_NOT_USED) + { + reponse = ERROR_INFO_MSG_ALREADY_NOT_USED; + } gv_information_msg[ind].used = (char)INFO_MSG_NOT_USED; gv_information_msg[ind].message[0]=(char)0; @@ -69,6 +125,15 @@ unsigned short lv_index_message_actif =0; return reponse; } + /** + * \fn void sendInfoMessage() + * + * \brief Send information message when information mode is actif + * + * \return void + * + */ + void sendInfoMessage() { int find =0; @@ -99,11 +164,15 @@ unsigned short lv_index_message_actif =0; if( gv_information_msg[lv_index_message_actif].used == INFO_MSG_USED) { + + find=1; infMsg.index= lv_index_message_actif; infMsg.used = gv_information_msg[lv_index_message_actif].used; resp.size = strlen(gv_information_msg[lv_index_message_actif].message)+2; - strcpy(infMsg.message , gv_information_msg[lv_index_message_actif].message); + infMsg.message[0]=0; + + strncat(infMsg.message , gv_information_msg[lv_index_message_actif].message,MAX_SIZE_INF_MSG); // strcpy(resp.parameter, gv_information_msg[lv_index_message_actif].message); memcpy( resp.parameter,&infMsg,resp.size); @@ -112,14 +181,16 @@ unsigned short lv_index_message_actif =0; memcpy( ax25Frame.data,&resp,TC_REPONSE_HEADER_SIZE+resp.size); /* envoyer la reponse de la commande */ writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp.size); - sprintf(gvLogMsg,"INFO MESSAGE %x %x ",resp.header.cmd_id,resp.header.error_code); - logger(LOG_LEVEL_CRITICAL,gvLogMsg); + + logger(LOG_LEVEL_INFO,"MSG INFO SENT"); } else if(cpt >MAX_INF_MESSAGE ) { find=1; logger(LOG_LEVEL_CRITICAL,"NO MESSAGE INFO AVAILABLE"); + // stop information message transmission + gv_spinoConfig.info_message_actif = INFO_MSG_NOT_USED; } lv_index_message_actif = (lv_index_message_actif + 1) % MAX_INF_MESSAGE; @@ -127,19 +198,6 @@ unsigned short lv_index_message_actif =0; } - - - resp.size = sizeof(t_globalVariable); - memcpy(resp.parameter, &gv_spino, sizeof(t_globalVariable)); - logger(LOG_LEVEL_INFO,"Envoie MESSAGE INFO"); - - t_ax25_packet ax25Frame; - ax25Frame.header = gv_headerTlm; - memcpy( ax25Frame.data,&resp,TC_REPONSE_HEADER_SIZE+resp.size); - /* envoyer la reponse de la commande */ - writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp.size); - sprintf(gvLogMsg,"TELEMETRY %x %x ",resp.header.cmd_id,resp.header.error_code); - logger(LOG_LEVEL_WARNING,gvLogMsg); } } // do Nothing diff --git a/EmbededSw/src/core/informationMessage.h b/EmbededSw/src/core/informationMessage.h index 7d99866..a53cb27 100644 --- a/EmbededSw/src/core/informationMessage.h +++ b/EmbededSw/src/core/informationMessage.h @@ -30,6 +30,7 @@ typedef struct send_in_msg { extern int setInfoMessage(char *data,t_tc_response *resp); extern int delInfoMessage(char index ,t_tc_response *resp); extern void sendInfoMessage(); +extern void setupInfoMessage(); #endif // INFORMATION_MESSAGE_H diff --git a/EmbededSw/src/core/setup.c b/EmbededSw/src/core/setup.c index f824968..c9bb328 100644 --- a/EmbededSw/src/core/setup.c +++ b/EmbededSw/src/core/setup.c @@ -18,6 +18,7 @@ #include "../dropMsgMngt/DropMessage.h" #include "informationMessage.h" #include "control.h" +#include "informationMessage.h" /*========= GLOBAL VARIABLES ===================================================================*/ @@ -49,6 +50,10 @@ unsigned short gv_spino_cmd_key = SPINO_CMD_KEY; */ void setupGlobalVariable() { + + + setupInfoMessage(); + char cs[6] = { 'S', 'P', 'I', 'N', 'O', 'S' }; char cd[6] = { 'S', 'P', 'I', 'N', 'O', 'D' }; memcpy(gv_spinoConfig.spinoSrcCallsign, cs, 6); diff --git a/EmbededSw/src/dropMsgMngt/DropMessage.c b/EmbededSw/src/dropMsgMngt/DropMessage.c index e5879c9..dde962b 100644 --- a/EmbededSw/src/dropMsgMngt/DropMessage.c +++ b/EmbededSw/src/dropMsgMngt/DropMessage.c @@ -109,6 +109,7 @@ int getAllDroppedMessage(t_tc_response *resp) /* envoyer la reponse de la commande */ writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp->size); } + resp->size=0; return SUCCESS; } diff --git a/EmbededSw/src/errorMngt/error.h b/EmbededSw/src/errorMngt/error.h index e43804b..79889bf 100644 --- a/EmbededSw/src/errorMngt/error.h +++ b/EmbededSw/src/errorMngt/error.h @@ -33,5 +33,6 @@ #define ERROR_MESSAGE_EMPTY 15 #define ERROR_INFO_MSG_INDEX_OUT_OF_BOUND 135 +#define ERROR_INFO_MSG_ALREADY_NOT_USED 136 #endif // ERROR_H diff --git a/EmbededSw/src/logMngt/log.c b/EmbededSw/src/logMngt/log.c index ce92156..7fd6db0 100644 --- a/EmbededSw/src/logMngt/log.c +++ b/EmbededSw/src/logMngt/log.c @@ -7,10 +7,19 @@ extern void writeData ( t_ax25_packet ax25Frame, int length); unsigned char gv_SelectedLogLevel=0; -t_logs logs[MAX_LOG]; +s_logs logs[MAX_LOG]; int gvLogIndex =0; char gvLogMsg[MAX_SIZE_MSG_LOG]; + +/** + * \fn void logger(char level, char *message) + * \brief log message in log Table + * \param level define type of log + * \param message Ascii message + * \return void + * + */ void logger(char level, char *message) { @@ -19,8 +28,8 @@ void logger(char level, char *message) gvLogIndex = (gvLogIndex+1)%MAX_LOG; logs[gvLogIndex].priority=level; logs[gvLogIndex].timeStamps=gv_spino.timestamps; - strcpy(logs[gvLogIndex].log,message); - + logs[gvLogIndex].log[0]=0; + strncat(logs[gvLogIndex].log,message,MAX_SIZE_MSG_LOG-1); printf("LOG : "); printf(message); printf("\r\n"); @@ -35,13 +44,16 @@ void logger(char level, char *message) * \param *resp output structure with result of command * \return SUCCESS * + * \todo : optimise message lenght in response + * */ int getLastLog(t_tc_response *resp) { - logger(LOG_LEVEL_CRITICAL," GET_LAST_DROPED_MESSAGE"); - int taille_message = sizeof(t_logs); + logger(LOG_LEVEL_CRITICAL," GET_LAST_LOG_MESSAGE"); + int taille_message = strlen(logs[gvLogIndex].log)+SIZE_S_LOG+1; // +1 pour inclure le 0 + memcpy(resp->parameter,&logs[gvLogIndex], taille_message ); resp->size = taille_message; return SUCCESS; @@ -63,20 +75,21 @@ int getAllLogs(t_tc_response *resp) t_ax25_packet ax25Frame; ax25Frame.header = gv_headerTlm; resp->header.error_code = SUCCESS; - + logger(LOG_LEVEL_CRITICAL," GET_ALL_LOG_MESSAGE"); int i=0; for (i=0; i < MAX_LOG;i++) { - printf("all index %d",i); - - resp->size= sizeof(t_logs); - memcpy(resp->parameter,&logs[i], resp->size ); - printf("taille %d",resp->size); + + int taille_message = strlen(logs[i].log)+SIZE_S_LOG+1; // +1 pour inclure le 0 + memcpy(resp->parameter,&logs[i], taille_message ); + resp->size = taille_message; memcpy( ax25Frame.data,resp,TC_REPONSE_HEADER_SIZE+resp->size); /* envoyer la reponse de la commande */ writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp->size); } + /* return success of the command */ + resp->size= 0; return SUCCESS; } diff --git a/EmbededSw/src/logMngt/log.h b/EmbededSw/src/logMngt/log.h index 6f68915..3ab9a3a 100644 --- a/EmbededSw/src/logMngt/log.h +++ b/EmbededSw/src/logMngt/log.h @@ -10,11 +10,12 @@ #define MAX_LOG 10 #define MAX_SIZE_MSG_LOG 64 +#define SIZE_S_LOG 8+1 typedef struct logs { long long timeStamps; char priority; char log[MAX_SIZE_MSG_LOG]; -} t_logs; +} s_logs; extern unsigned char gv_SelectedLogLevel; @@ -23,4 +24,4 @@ extern char gvLogMsg[MAX_SIZE_MSG_LOG]; extern int getAllLogs(t_tc_response *resp); extern int getLastLog(t_tc_response *resp); -#endif // LOG_H \ No newline at end of file +#endif // LOG_H diff --git a/SPECIFICATIONS/Ground station to OBC.plantuml b/SPECIFICATIONS/Ground station to OBC.plantuml new file mode 100644 index 0000000..7a8f647 --- /dev/null +++ b/SPECIFICATIONS/Ground station to OBC.plantuml @@ -0,0 +1,16 @@ +@startuml + +CubesatGroundStation -> SPINO : send data to spino +SPINO -> SPINO : write data to I2CReceivedBuffer +SPINO -> SPINO : write nb data in I2CSatusReceivedBuffer +SPINO -> CubesatGroundStation : send acknolegment + +SPINO -> CubesatGroundStation : Send TLM with value of I2CSatusReceivedBuffer + +UVSQsat_OBC -> SPINO: check if I2CSatusReceivedBuffer not equal 0 +UVSQsat_OBC -> SPINO: read I2CReceivedBuffer +UVSQsat_OBC -> SPINO: set I2CSatusReceivedBuffer to 0 + +SPINO -> CubesatGroundStation : Send TLM with value of I2CSatusReceivedBuffer + +@enduml \ No newline at end of file diff --git a/SPECIFICATIONS/Ground_station_to_OBC.png b/SPECIFICATIONS/Ground_station_to_OBC.png new file mode 100644 index 0000000000000000000000000000000000000000..c187c221fbbb46831fb313b65af0df960da9c27f GIT binary patch literal 29321 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 HW#IQ;wBbwz literal 0 HcmV?d00001 diff --git a/SPECIFICATIONS/I2C register.plantuml b/SPECIFICATIONS/I2C register.plantuml new file mode 100644 index 0000000..c0405a9 --- /dev/null +++ b/SPECIFICATIONS/I2C register.plantuml @@ -0,0 +1,12 @@ +@startuml + +start +:I2C Communication between OBC and SPINO +<#red>|= action |= name |= size | +<#blue>|Transmit | I2CSatusTransmitBuffer| 1 octet | +<#blue>|Transmit | I2CTransmitBuffer | n(64) octet | +<#yellow>|Receive | I2CSatusReceivedBuffer| 1 octet | +<#yellow>|Receive | I2CReceivedBuffer | n(64) octet |> + + +@enduml \ No newline at end of file diff --git a/SPECIFICATIONS/I2C_register.png b/SPECIFICATIONS/I2C_register.png new file mode 100644 index 0000000000000000000000000000000000000000..1511833b5aaac7ccad3006022da55d9b8f69862b GIT binary patch literal 9922 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 literal 0 HcmV?d00001 diff --git a/SPECIFICATIONS/OBC to Ground Station.plantuml b/SPECIFICATIONS/OBC to Ground Station.plantuml new file mode 100644 index 0000000..f93b0ce --- /dev/null +++ b/SPECIFICATIONS/OBC to Ground Station.plantuml @@ -0,0 +1,17 @@ +@startuml + +UVSQsat_OBC -> SPINO: check if I2CSatusTransmitBuffer equal 0 +UVSQsat_OBC -> SPINO: write data in the TransmitBufer +UVSQsat_OBC -> SPINO: write nb byte in the I2CSatusTransmitBuffer +SPINO -> SPINO: when I2CSatusTransmitBuffer not Equal to 0 +SPINO -> SPINO: Transfert TransmitBufer in the SpinoDataBuffer +SPINO -> SPINO: write I2CSatusTransmitBuffer to 0 + +SPINO -> CubesatGroundStation : Send TLM with nb UVSQsat_OBC packet available + +CubesatGroundStation -> SPINO : Request data stored in SpinoDataBuffer +SPINO -> CubesatGroundStation : Send data to ground station +CubesatGroundStation -> SPINO : Request delete data stored in SpinoDataBuffer +SPINO -> CubesatGroundStation : erase data and send acknolegment + +@enduml \ No newline at end of file diff --git a/SPECIFICATIONS/OBC_to_Ground_Station.png b/SPECIFICATIONS/OBC_to_Ground_Station.png new file mode 100644 index 0000000000000000000000000000000000000000..342a73dc38197ab4dbe3180fa6ff4e6559b6e045 GIT binary patch literal 34229 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 j-Uc}zG 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 Date: Mon, 5 Sep 2022 07:21:38 +0200 Subject: [PATCH 07/12] feat Experimental mode --- EmbededSw/src/Makefile | 17 +++- EmbededSw/src/ax25/ax25.c | 40 ++++++++- EmbededSw/src/ax25/ax25.h | 8 ++ EmbededSw/src/core/command.c | 6 +- EmbededSw/src/core/command.h | 2 +- EmbededSw/src/core/configuration.h | 2 + EmbededSw/src/core/control.c | 13 +-- EmbededSw/src/errorMngt/error.h | 2 + EmbededSw/src/mailboxMode/mailbox.c | 131 +++++++++++++++++++++++++--- EmbededSw/src/mailboxMode/mailbox.h | 5 ++ EmbededSw/src/surveyMode/survey.c | 2 +- 11 files changed, 198 insertions(+), 30 deletions(-) diff --git a/EmbededSw/src/Makefile b/EmbededSw/src/Makefile index 8396e81..3a23d79 100644 --- a/EmbededSw/src/Makefile +++ b/EmbededSw/src/Makefile @@ -5,14 +5,25 @@ EXEC=spinoSimulator all: $(EXEC) -spinoSimulator: main.o ax25/ax25.o core/command.o core/control.o core/informationMessage.o core/setup.o digipeaterMode/ModeDigipeater.o drivers/modem.o dropMsgMngt/DropMessage.o logMngt/log.o mailboxMode/mailbox.o mailboxMode/modeMailbox.o simulation/SpinoSimuServerTCP.o simulation/lecfic.o surveyMode/survey.o +spinoSimulator: main.o ax25/ax25.o core/command.o core/control.o core/informationMessage.o core/setup.o digipeaterMode/ModeDigipeater.o drivers/modem.o dropMsgMngt/DropMessage.o logMngt/log.o mailboxMode/mailbox.o mailboxMode/modeMailbox.o simulation/SpinoSimuServerTCP.o simulation/lecfic.o surveyMode/survey.o payloadMode/payloadMode.o experimentalMode\experimentalMode.o $(CC) -o $@ $^ $(LDFLAGS) %.o: %.c $(CC) -o $@ -c $< $(CFLAGS) -clean: - rm -rf *.o +clean: + del .\*.o + del ax25\*.o + del core\*.o + del digipeaterMode\*.o + del drivers\*.o + del dropMsgMngt\*.o + del logMngt\*.o + del mailboxMode\*.o + del simulation\*.o + del surveyMode\*.o + del payloadMode\*.o + del experimentalMode\*.o mrproper: clean rm -rf $(EXEC) diff --git a/EmbededSw/src/ax25/ax25.c b/EmbededSw/src/ax25/ax25.c index a5e7242..45194f2 100644 --- a/EmbededSw/src/ax25/ax25.c +++ b/EmbededSw/src/ax25/ax25.c @@ -1,7 +1,27 @@ +/** + * \file ax25.c + * \brief ax25 driver + * \author Xtophe + * \version 0.2 + * \date 01/08/2022 + */ + #include #include "../errorMngt/error.h" #include "ax25.h" +/** + * \fn void convertToAX25Header ( t_ax25_header *data, char *dest, char ssidDest, char *src, char ssidSrc) + * \brief convert header structure to AX25 Header + * \param header structure + * \param destination callsign + * \param SSID destionation + * \param source callsign + * \param SSID source + * + * \return void + * + */ void convertToAX25Header ( t_ax25_header *data, char *dest, char ssidDest, char *src, char ssidSrc) { @@ -23,7 +43,14 @@ void convertToAX25Header ( t_ax25_header *data, char *dest, char ssidDest, char } } - +/** + * \fn void encodeAX25Header(t_ax25_header *data) + * \brief encode callsign + * \param SSID source + * + * \return void + * + */ void encodeAX25Header(t_ax25_header *data) { @@ -46,7 +73,16 @@ void encodeAX25Header(t_ax25_header *data) } } - +/** + * \fn int convertDataToAx25 (t_ax25_packet *data, char *rawdata, unsigned int size ) + * \brief Decode calssign from AX25 + * \param ax25 structure + * \param raw data + * \param raw data size + * + * \return error value SUCCES or ERROR_AX25_EXCEED_MAX_LENGH + * + */ int convertDataToAx25 (t_ax25_packet *data, char *rawdata, unsigned int size ) { int error = SUCCESS; diff --git a/EmbededSw/src/ax25/ax25.h b/EmbededSw/src/ax25/ax25.h index e043540..7240625 100644 --- a/EmbededSw/src/ax25/ax25.h +++ b/EmbededSw/src/ax25/ax25.h @@ -1,3 +1,11 @@ +/** + * \file ax25.h + * \brief ax25 driver + * \author Xtophe + * \version 0.2 + * \date 01/08/2022 + */ + #ifndef AX25_H #define AX25_H diff --git a/EmbededSw/src/core/command.c b/EmbededSw/src/core/command.c index 9824ec6..c41ee50 100644 --- a/EmbededSw/src/core/command.c +++ b/EmbededSw/src/core/command.c @@ -53,11 +53,8 @@ int setValue(const t_set_value value,t_tc_response *resp) { int returnValue = SUCCESS; -// t_field response; - -// response.field_id value.fied_id; -// response.size =0; + printf("set value"); resp->size = SIZE_HEADER_FIELD; switch (value.fied_id) { @@ -229,6 +226,7 @@ t_tc_response interpretcommand(t_command cmd) { logger(LOG_LEVEL_INFO,"Commande SET VALUE"); t_set_value setvalue; memcpy(&setvalue, cmd.parameter, cmd.size); + printf("Size %d",setvalue.size); reponse = setValue(setvalue,&resp); break; diff --git a/EmbededSw/src/core/command.h b/EmbededSw/src/core/command.h index 1fd05d0..91b3d11 100644 --- a/EmbededSw/src/core/command.h +++ b/EmbededSw/src/core/command.h @@ -113,7 +113,7 @@ typedef struct tc_response_with_value { typedef struct command { unsigned short key; /* clé */ unsigned short id; /* command ID */ - unsigned char size ; /* parameter size */ + unsigned short size ; /* parameter size */ char parameter[PARAMETER_SIZE]; } t_command; diff --git a/EmbededSw/src/core/configuration.h b/EmbededSw/src/core/configuration.h index 3afd479..fc94130 100644 --- a/EmbededSw/src/core/configuration.h +++ b/EmbededSw/src/core/configuration.h @@ -12,6 +12,8 @@ #define SSID_SPINO_TMTC 15 #define SSID_SPINO_DIGIPEATER 3 #define SSID_SPINO_MAILBOX 2 +#define SSID_SPINO_CUBESAT 4 +#define SSID_SPINO_EXPERIMENTAL 5 #define RESET_CAUSE_STATE_UNKNOWN 1 diff --git a/EmbededSw/src/core/control.c b/EmbededSw/src/core/control.c index 643862e..0efc354 100644 --- a/EmbededSw/src/core/control.c +++ b/EmbededSw/src/core/control.c @@ -9,7 +9,8 @@ extern unsigned short survey(); extern unsigned short digipeater(); extern unsigned short modeMailbox (); - +extern unsigned short payloadMode(); +extern unsigned short experimentalMode(); unsigned long long lv_spino_timeStampPrevious=0; @@ -39,19 +40,19 @@ void control() break; case (int) STATE_MAILBOX : - sprintf(gvLogMsg,"State Mailbox \r\n"); + logger(LOG_LEVEL_INFO,"STATE MAILBOX"); gv_spino.currentState = modeMailbox(); break; case (int) STATE_EXPE_DATA: - logger(LOG_LEVEL_CRITICAL,"STATE EXPERIENCE DATA NOT IMPLEMENTED"); - gv_spino.currentState = STATE_SURVEY; + logger(LOG_LEVEL_INFO,"STATE EXPE"); + gv_spino.currentState = experimentalMode(); break; case (int) STATE_MAIN_PAYLOAD: - logger(LOG_LEVEL_CRITICAL,"STATE MAIN_PAYLOAD NOT IMPLEMENTED"); - gv_spino.currentState = STATE_SURVEY; + logger(LOG_LEVEL_CRITICAL,"STATE_MAIN_PAYLOAD"); + gv_spino.currentState = payloadMode(); break; default: diff --git a/EmbededSw/src/errorMngt/error.h b/EmbededSw/src/errorMngt/error.h index 79889bf..36e0bfd 100644 --- a/EmbededSw/src/errorMngt/error.h +++ b/EmbededSw/src/errorMngt/error.h @@ -35,4 +35,6 @@ #define ERROR_INFO_MSG_INDEX_OUT_OF_BOUND 135 #define ERROR_INFO_MSG_ALREADY_NOT_USED 136 +#define ERROR_TLE_WRONG_SIZE 140 + #endif // ERROR_H diff --git a/EmbededSw/src/mailboxMode/mailbox.c b/EmbededSw/src/mailboxMode/mailbox.c index 6981136..2448c9b 100644 --- a/EmbededSw/src/mailboxMode/mailbox.c +++ b/EmbededSw/src/mailboxMode/mailbox.c @@ -196,11 +196,6 @@ int deletteMessage ( char *callsign, t_tc_response *resp) pMailbox->indexFreeMessage = (pMailbox->indexFreeMessage+1) % MAX_MESSAGE; pMailbox->messageNumber--; - // if nb message = 0 => the milbox remain active - // if (pMailbox->messageNumber==0) - // { - // gvMailboxes.usedMailboxNumber--; - // } } else { reponse = ERROR_MAILBOX_EMPTY; @@ -337,7 +332,7 @@ int getLastMessage (char * callsign,t_tc_response *resp) { // retourn message logger(LOG_LEVEL_INFO,"Mesage trouvé"); pMailbox = &gvMailboxes.mailbox[i]; - unsigned char message_index = (pMailbox->indexNextMessage-1)% MAX_MESSAGE; + int message_index = (pMailbox->indexNextMessage-1)% MAX_MESSAGE; if(message_index<0) { message_index = MAX_MESSAGE-1; @@ -374,7 +369,17 @@ return reponse; } -/* retroune le dernier message */ +/** + * \fn int getMessage (char * callsign, unsigned char index, t_tc_response *resp) + * \brief return message from the callsign + * \param callsign + * \param index message index + * \param response structure + * + * \return SUCCESS else ERROR_MAILBOX_NOT_FOUND, + * + */ + int getMessage (char * callsign, unsigned char index, t_tc_response *resp) { @@ -439,14 +444,114 @@ int getMessage (char * callsign, unsigned char index, t_tc_response *resp) return reponse; } -int getAllMesage (char * callsign, char index) + +/** + * \fn int getAllMesage (char * callsign) + * \brief return all message from the callsign + * \param callsign + * + * \return SUCCESS else ERROR_MAILBOX_NOT_FOUND, + * + */ + +int getAllMesage (char * callsign) { -int reponse = ERROR_COMMAND_NOT_IMPLEMENTED; + + int i=0; + int find =0; + t_mailbox *pMailbox; + int reponse = SUCCESS; + t_get_message messagelue ; + + + t_tc_response resp; + t_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + + logger(LOG_LEVEL_CRITICAL," GET_ALL_MESSAGE"); + + + memcpy(messagelue.callsign,callsign,6); + + + while ((imessages[j].size!=0 ) + { + messagelue.index=j; + messagelue.timestamps = pMailbox->messages[j].timestamps; + memcpy(messagelue.message,pMailbox->messages[j].message,pMailbox->messages[j].size); + resp.size = pMailbox->messages[j].size+SIZE_T_GET_MESSAGE; + memcpy(resp.parameter, &messagelue,resp.size); + memcpy( ax25Frame.data,&resp,TC_REPONSE_HEADER_SIZE+resp.size); + /* envoyer la reponse de la commande */ + writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp.size); + + } + } + + find= 1; + logger(LOG_LEVEL_INFO,"Mesage trouvé 2"); + } + logger(LOG_LEVEL_INFO,"Mesage non trouvé 3"); + } + i++; + logger(LOG_LEVEL_INFO,"Mesage non trouvé 5"); + } + + if (find ==0) + { + logger(LOG_LEVEL_INFO,"Mesage non trouvé 4"); + reponse = ERROR_MAILBOX_NOT_FOUND; + + } + return reponse; } + +/** + * \fn int dumpMailbox () + * \brief return all message from all mailbox + * \param none + * \return SUCCESS else ERROR_MAILBOX_NOT_FOUND, + * + */ + int dumpMailbox () { + + int i=0; + int response = SUCCESS; + for (i=0;i MAX_LENGHT_MESSAGE) @@ -484,14 +589,13 @@ t_tc_response interpretMailBoxcommand( t_command cmd, char *callsign) { } else { char message[MAX_LENGHT_MESSAGE]; - sprintf(gvLogMsg,"taille message %d \r\n",cmd.size); logger(LOG_LEVEL_CRITICAL,gvLogMsg); memcpy(message, cmd.parameter, cmd.size); reponse = addMessage (callsign,message,cmd.size); } resp.size=0; break; - break; + case CMD_MAILBOX_DEL_MSG : logger(LOG_LEVEL_INFO,"Commande MAILBOX DELETE MSG !!!"); reponse = deletteMessage (callsign,&resp); @@ -526,7 +630,8 @@ t_tc_response interpretMailBoxcommand( t_command cmd, char *callsign) { break; case CMD_MAILBOX_GET_ALL_MSG : - reponse = ERROR_COMMAND_NOT_IMPLEMENTED; + reponse = getAllMesage (callsign); + resp.size=0; break; case CMD_MAILBOX_DUMP_MAILBOX: reponse = ERROR_COMMAND_NOT_IMPLEMENTED; diff --git a/EmbededSw/src/mailboxMode/mailbox.h b/EmbededSw/src/mailboxMode/mailbox.h index 54ee8fe..fca9b48 100644 --- a/EmbededSw/src/mailboxMode/mailbox.h +++ b/EmbededSw/src/mailboxMode/mailbox.h @@ -96,5 +96,10 @@ typedef struct cmd_get_message } t_cmd_get_message; extern void processMailbox(t_ax25_packet data_ax25); +extern int getListMailbox(t_tc_response *resp); +extern int addMessage (char *callsign, char *message,const unsigned short sizemMessage); +extern int deleteMailBox (char *callsign,t_tc_response *resp); +extern int initialise(); +extern int getAllMesage (char * callsign); #endif // MAILBOX_H diff --git a/EmbededSw/src/surveyMode/survey.c b/EmbededSw/src/surveyMode/survey.c index 1afb099..eb47503 100644 --- a/EmbededSw/src/surveyMode/survey.c +++ b/EmbededSw/src/surveyMode/survey.c @@ -10,7 +10,7 @@ unsigned short survey() { t_ax25_packet data_ax25; int nbc = readData(data); - + printf(" NB car Recu %d",nbc); if (nbc != 0) { /* traitement des donnees recues */ int res = convertDataToAx25(&data_ax25, data, nbc); -- GitLab From 3c22094ee6b7dbf03e5278d2f7169a24a4488053 Mon Sep 17 00:00:00 2001 From: chris Date: Sat, 10 Sep 2022 14:43:47 +0200 Subject: [PATCH 08/12] feat : add chnage stage control doc : states --- EmbededSw/src/core/control.c | 152 +++++++--- EmbededSw/src/core/setup.c | 3 + EmbededSw/src/digipeaterMode/ModeDigipeater.c | 3 +- EmbededSw/src/errorMngt/error.h | 2 + .../src/experimentalMode/experimentalMode.c | 276 ++++++++++++++++++ .../src/experimentalMode/experimentalMode.h | 0 EmbededSw/src/mailboxMode/mailbox.c | 6 +- EmbededSw/src/mailboxMode/modeMailbox.c | 5 +- EmbededSw/src/payloadMode/payloadMode.c | 176 +++++++++++ EmbededSw/src/payloadMode/payloadMode.h | 12 + EmbededSw/src/surveyMode/survey.c | 4 +- SPECIFICATIONS/AX25_Usage_on_Spino.md | 41 +-- SPECIFICATIONS/MailboxMode.md | 67 ++++- SPECIFICATIONS/States.md | 23 +- .../{FailsafeMode.md => SurveyMode.md} | 7 +- SPECIFICATIONS/commande.md | 38 +++ SPECIFICATIONS/state.puml | 15 + 17 files changed, 745 insertions(+), 85 deletions(-) create mode 100644 EmbededSw/src/experimentalMode/experimentalMode.c create mode 100644 EmbededSw/src/experimentalMode/experimentalMode.h create mode 100644 EmbededSw/src/payloadMode/payloadMode.c create mode 100644 EmbededSw/src/payloadMode/payloadMode.h rename SPECIFICATIONS/{FailsafeMode.md => SurveyMode.md} (71%) create mode 100644 SPECIFICATIONS/commande.md create mode 100644 SPECIFICATIONS/state.puml diff --git a/EmbededSw/src/core/control.c b/EmbededSw/src/core/control.c index 0efc354..6394a52 100644 --- a/EmbededSw/src/core/control.c +++ b/EmbededSw/src/core/control.c @@ -1,10 +1,12 @@ #include #include #include "setup.h" +#include "../errorMngt/error.h" #include "../drivers/modem.h" #include "informationMessage.h" #include "control.h" +#define SLEEP_TIME 500 extern unsigned short survey(); extern unsigned short digipeater(); @@ -13,86 +15,160 @@ extern unsigned short payloadMode(); extern unsigned short experimentalMode(); unsigned long long lv_spino_timeStampPrevious=0; +t_tc_response resptlm; +void inittlm() +{ + resptlm.header.responseType = TELEMETRY; + resptlm.header.error_code = 0; + resptlm.header.cmd_id =0; + resptlm.size = sizeof(t_globalVariable); +} + +void sendTLM() +{ + if( gv_spino.timestamps > (lv_spino_timeStampPrevious + gv_spinoConfig.telemetryDelay*1000)) + { + t_ax25_packet ax25Frame; + lv_spino_timeStampPrevious = gv_spino.timestamps; + resptlm.header.timeStamp = gv_spino.timestamps; + memcpy(resptlm.parameter, &gv_spino, sizeof(t_globalVariable)); + ax25Frame.header = gv_headerTlm; + memcpy( ax25Frame.data,&resptlm,TC_REPONSE_HEADER_SIZE+resptlm.size); + writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resptlm.size); + logger(LOG_LEVEL_INFO,"Envoie TLM"); + } +} + + +int changeState (short state) + { + + int response = SUCCESS; + + switch (gv_spino.currentState) + { + + case (int) STATE_INIT: + gv_spino.currentState=STATE_INIT; + break; + case (int) STATE_SURVEY : + gv_spino.currentState = STATE_SURVEY; + break; + + case (int) STATE_DIGIPEATER : + if(gv_spino.currentState==STATE_SURVEY) + { + gv_spino.currentState = STATE_DIGIPEATER; + } + else + { + logger(LOG_LEVEL_CRITICAL,"ERROR_WRONG_STATE"); + response = ERROR_WRONG_STATE; + } + break; + + case (int) STATE_MAILBOX : + if(gv_spino.currentState==STATE_SURVEY) + { + gv_spino.currentState = STATE_MAILBOX; + } + else + { + logger(LOG_LEVEL_CRITICAL,"ERROR_WRONG_STATE"); + response = ERROR_WRONG_STATE; + } + break; + + case (int) STATE_EXPE_DATA: + if(gv_spino.currentState==STATE_SURVEY) + { + gv_spino.currentState = STATE_EXPE_DATA; + } + else + { + logger(LOG_LEVEL_CRITICAL,"ERROR_WRONG_STATE"); + response = ERROR_WRONG_STATE; + } + break; + case (int) STATE_MAIN_PAYLOAD: + if(gv_spino.currentState==STATE_SURVEY) + { + gv_spino.currentState = STATE_MAIN_PAYLOAD; + } + else + { + logger(LOG_LEVEL_CRITICAL,"ERROR_WRONG_STATE"); + response = ERROR_WRONG_STATE; + } + break; + + default: + /* remplacer par reinit */ + + logger(LOG_LEVEL_CRITICAL,"ERROR_WRONG_STATE"); + response = ERROR_WRONG_STATE; + break; + } + + return response; + } + void control() { + inittlm(); while (1) { switch (gv_spino.currentState) { - case (int) STATE_INIT: + case STATE_INIT: logger(LOG_LEVEL_INFO,"STATE INIT"); setupGlobalVariable(); break; - case (int) STATE_SURVEY : + case STATE_SURVEY : logger(LOG_LEVEL_INFO,"STATE SURVEY"); gv_spino.currentState = survey(); break; - case (int) STATE_DIGIPEATER : + case STATE_DIGIPEATER : logger(LOG_LEVEL_INFO,"STATE DIGIPEATER"); gv_spino.currentState = digipeater(); break; - case (int) STATE_MAILBOX : + case STATE_MAILBOX : logger(LOG_LEVEL_INFO,"STATE MAILBOX"); gv_spino.currentState = modeMailbox(); break; - case (int) STATE_EXPE_DATA: + case STATE_EXPE_DATA: logger(LOG_LEVEL_INFO,"STATE EXPE"); gv_spino.currentState = experimentalMode(); break; - case (int) STATE_MAIN_PAYLOAD: - logger(LOG_LEVEL_CRITICAL,"STATE_MAIN_PAYLOAD"); + case STATE_MAIN_PAYLOAD: + logger(LOG_LEVEL_INFO,"STATE_MAIN_PAYLOAD"); gv_spino.currentState = payloadMode(); break; default: /* remplacer par reinit */ - sprintf(gvLogMsg,"State default \r\n"); - logger(LOG_LEVEL_INFO,"STATE DEFAULT"); + sprintf(gvLogMsg,"State default %d \r\n",gv_spino.currentState); + logger(LOG_LEVEL_CRITICAL,"STATE DEFAULT"); gv_spino.currentState = STATE_INIT; gv_spino.lastResetCause = RESET_CAUSE_STATE_UNKNOWN; - break; } - Sleep(500); - gv_spino.timestamps= gv_spino.timestamps+500; - - if( gv_spino.timestamps > (lv_spino_timeStampPrevious + gv_spinoConfig.telemetryDelay*1000)) - { - - lv_spino_timeStampPrevious = gv_spino.timestamps; - - t_tc_response resp; - resp.header.responseType = TELEMETRY; - resp.header.error_code = 0; - resp.header.cmd_id =0; - resp.header.timeStamp = gv_spino.timestamps; - resp.size = sizeof(t_globalVariable); - memcpy(resp.parameter, &gv_spino, sizeof(t_globalVariable)); - logger(LOG_LEVEL_INFO,"Envoie TLM"); - - t_ax25_packet ax25Frame; - ax25Frame.header = gv_headerTlm; - memcpy( ax25Frame.data,&resp,TC_REPONSE_HEADER_SIZE+resp.size); - /* envoyer la reponse de la commande */ - writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp.size); - sprintf(gvLogMsg,"TELEMETRY %x %x ",resp.header.cmd_id,resp.header.error_code); - logger(LOG_LEVEL_CRITICAL,gvLogMsg); - } - sendInfoMessage(); - - + Sleep(SLEEP_TIME); + gv_spino.timestamps= gv_spino.timestamps+SLEEP_TIME; + sendTLM(); + sendInfoMessage(); } diff --git a/EmbededSw/src/core/setup.c b/EmbededSw/src/core/setup.c index c9bb328..bfbb537 100644 --- a/EmbededSw/src/core/setup.c +++ b/EmbededSw/src/core/setup.c @@ -20,6 +20,8 @@ #include "control.h" #include "informationMessage.h" +extern void initExpe(); + /*========= GLOBAL VARIABLES ===================================================================*/ t_configuration_spino gv_spinoConfig; @@ -53,6 +55,7 @@ void setupGlobalVariable() { setupInfoMessage(); + initExpe(); char cs[6] = { 'S', 'P', 'I', 'N', 'O', 'S' }; char cd[6] = { 'S', 'P', 'I', 'N', 'O', 'D' }; diff --git a/EmbededSw/src/digipeaterMode/ModeDigipeater.c b/EmbededSw/src/digipeaterMode/ModeDigipeater.c index e0323c7..7a36d93 100644 --- a/EmbededSw/src/digipeaterMode/ModeDigipeater.c +++ b/EmbededSw/src/digipeaterMode/ModeDigipeater.c @@ -16,8 +16,6 @@ - - /** * \fn unsigned short digipeater () * \brief manage DIGIPEATER mode @@ -59,6 +57,7 @@ unsigned short digipeater () gv_spino.nbDigipeaterMesssageProcessed++; } else { + logger(LOG_LEVEL_CRITICAL, "WRONG SSID"); processDropMessage (data,nbc); } } else diff --git a/EmbededSw/src/errorMngt/error.h b/EmbededSw/src/errorMngt/error.h index 36e0bfd..a774285 100644 --- a/EmbededSw/src/errorMngt/error.h +++ b/EmbededSw/src/errorMngt/error.h @@ -11,6 +11,7 @@ #define ERROR_COMMAND_UNKNOW 1 #define ERROR_COMMAND_NOT_IMPLEMENTED 2 #define ERROR_COMMAND_WITH_WRONG_KEY 3 +#define ERROR_WRONG_STATE 4 #define ERROR_VALUE_FIELD_UNKNOW 101 @@ -37,4 +38,5 @@ #define ERROR_TLE_WRONG_SIZE 140 + #endif // ERROR_H diff --git a/EmbededSw/src/experimentalMode/experimentalMode.c b/EmbededSw/src/experimentalMode/experimentalMode.c new file mode 100644 index 0000000..2519459 --- /dev/null +++ b/EmbededSw/src/experimentalMode/experimentalMode.c @@ -0,0 +1,276 @@ + +#include +#include +#include "../core/setup.h" +#include "../drivers/modem.h" +#include "../mailboxMode/mailbox.h" +#include "../errorMngt/error.h" + +int gv_experiemntal_command_nb = 0; +int gv_experiemntal_command_error_nb = 0; +unsigned long long lv_spino_expe_timeStampPrevious; + +#define SIZE_TLE 70 +#define CMD_LOAD_TLE_1 70 +#define CMD_LOAD_TLE_2 71 +#define CMD_DOWNLOAD_TLE 72 +#define CMD_DOWNLOAD_TLE_1 73 +#define CMD_DOWNLOAD_TLE_2 74 +#define CMD_EXP_ADD_DATA 75 +#define CMD_EXPE_GET_LIST 76 +#define CMD_EXPE_DELETTE_ALL 77 +#define CMD_EXPE_GET_ALL_DATA 78 +#define CMD_EXPE_INIT 79 +#define CMD_SET_EXPE_BEACON_DELAY 80 + +typedef struct tle +{ + char tleLine1[SIZE_TLE]; + char tleLine2[SIZE_TLE]; + +} s_tle; + +typedef struct experimental_beacon +{ + long long date; + short id; + short delay; + +} s_experimental_beacon; + +t_tc_response respexpBeacon; + + +s_tle gv_tle; +s_experimental_beacon expBeacon; + + +void initExpe() +{ + + expBeacon.id=0; + expBeacon.delay=10; + + respexpBeacon.header.responseType = TELEMETRY; + respexpBeacon.header.error_code = 0; + respexpBeacon.header.cmd_id =0; + respexpBeacon.size = sizeof(s_experimental_beacon); + +} + + +int expDownloadTLE(t_tc_response *resp) +{ + + t_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + + int taille_message = SIZE_TLE; + resp->header.cmd_id = CMD_DOWNLOAD_TLE_1; + resp->parameter[0] = 0; + strncat(resp->parameter, gv_tle.tleLine1, SIZE_TLE); + resp->size = taille_message; + memcpy(ax25Frame.data, resp, TC_REPONSE_HEADER_SIZE + resp->size); + /* envoyer la reponse de la commande */ + writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + resp->size); + resp->header.cmd_id = CMD_DOWNLOAD_TLE_2; + resp->parameter[0] = 0; + strncat(resp->parameter, gv_tle.tleLine2, SIZE_TLE); + resp->size = taille_message; + memcpy(ax25Frame.data, resp, TC_REPONSE_HEADER_SIZE + resp->size); + /* envoyer la reponse de la commande */ + writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + resp->size); + + return SUCCESS; +} + +t_tc_response interpretExperimentalCommmand(t_command cmd, char *callsign) +{ + + t_tc_response resp; + + resp.header.responseType = RESULT_CMD; + resp.header.timeStamp = gv_spino.timestamps; + resp.header.cmd_id = cmd.id; + resp.header.error_code = SUCCESS; + + switch (cmd.id) + { + + case CMD_EXPE_INIT: + logger(LOG_LEVEL_INFO, "Commande EXP BOX RESET"); + resp.header.error_code = initialise(); + resp.size = 0; + break; + + case CMD_SET_EXPE_BEACON_DELAY: + logger(LOG_LEVEL_INFO, "Commande CMD_SET_EXPE_BEACON_DELAY"); + t_set_value setvalue; + memcpy(&setvalue, cmd.parameter, cmd.size); + expBeacon.delay = (unsigned short) setvalue.value[0]; + resp.header.error_code =SUCCESS; + resp.size = 0; + break; + + case CMD_LOAD_TLE_1: + logger(LOG_LEVEL_INFO, "Commande CMD_LOAD_TLE_1"); + if (cmd.size != SIZE_TLE) + { + gv_tle.tleLine1[0] = 0; + strncat(gv_tle.tleLine1, cmd.parameter, SIZE_TLE); + } + else + { + resp.header.error_code = ERROR_TLE_WRONG_SIZE; + resp.size = 0; + } + break; + case CMD_LOAD_TLE_2: + logger(LOG_LEVEL_INFO, "Commande CMD_LOAD_TLE_2"); + if (cmd.size != SIZE_TLE) + { + gv_tle.tleLine1[0] = 0; + strncat(gv_tle.tleLine2, cmd.parameter, SIZE_TLE); + } + else + { + resp.header.error_code = ERROR_TLE_WRONG_SIZE; + resp.size = 0; + } + break; + case CMD_DOWNLOAD_TLE: + logger(LOG_LEVEL_INFO, "Commande CMD_DOWNLOAD_TLE"); + resp.header.error_code = expDownloadTLE(&resp); + resp.size = 0; + break; + case CMD_EXP_ADD_DATA: + logger(LOG_LEVEL_INFO, "Commande CMD_EXP_ADD_DATA"); + if (cmd.size > MAX_LENGHT_MESSAGE) + { + resp.header.error_code = ERROR_ADD_MSG_EXCED_SIZE; + } + else + { + char message[MAX_LENGHT_MESSAGE]; + memcpy(message, cmd.parameter, cmd.size); + resp.header.error_code = addMessage(callsign, message, cmd.size); + } + resp.size = 0; + break; + case CMD_EXPE_GET_LIST: + logger(LOG_LEVEL_INFO, "Commande CMD_EXPE_GET_LIST"); + resp.header.error_code = getListMailbox(&resp); + resp.size = 0; + break; + case CMD_EXPE_DELETTE_ALL: + logger(LOG_LEVEL_INFO, "Commande MAILBOX DELETE MAILBOX"); + resp.header.error_code = deleteMailBox(callsign, &resp); + resp.size = 0; + break; + case CMD_EXPE_GET_ALL_DATA: + resp.header.error_code = getAllMesage(callsign); + resp.size = 0; + break; + + default: + sprintf(gvLogMsg, "erreur Experimental cmd %d \r\n", cmd.id); + logger(LOG_LEVEL_CRITICAL, gvLogMsg); + resp.header.error_code = ERROR_COMMAND_UNKNOW; + resp.size = 0; + break; + } + return resp; +} + + + void sendBeaconExpe() + { + + if( gv_spino.timestamps > (lv_spino_expe_timeStampPrevious + gv_spinoConfig.telemetryDelay*1000)) + { + t_ax25_packet ax25Frame; + lv_spino_expe_timeStampPrevious = gv_spino.timestamps; + respexpBeacon.header.timeStamp = gv_spino.timestamps; + memcpy(respexpBeacon.parameter, &expBeacon, sizeof(s_experimental_beacon)); + ax25Frame.header = gv_headerTlm; + memcpy( ax25Frame.data,&respexpBeacon,TC_REPONSE_HEADER_SIZE+respexpBeacon.size); + writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+respexpBeacon.size); + logger(LOG_LEVEL_INFO,"Envoie TLM"); + } + + + } + + +void processExperimental(t_ax25_packet data_ax25) +{ + + t_tc_response result; + t_command cmd; + + gv_experiemntal_command_nb++; + memcpy(&cmd, data_ax25.data, sizeof(t_command)); + result = interpretExperimentalCommmand(cmd, data_ax25.header.sourceAdress); + if (result.header.error_code != SUCCESS) + { + gv_experiemntal_command_error_nb++; + } + t_ax25_packet ax25Frame; + + ax25Frame.header = gv_headerTlm; + memcpy( ax25Frame.data,&result,TC_REPONSE_HEADER_SIZE+result.size); + /* envoyer la reponse de la commande */ + writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+result.size); + sprintf(gvLogMsg, "RESULT EXPE COMMAND %x %x ", result.header.cmd_id, result.header.error_code); + logger(LOG_LEVEL_CRITICAL, gvLogMsg); + + + +} + +unsigned short experimentalMode() +{ + char data[300]; + t_ax25_packet data_ax25; + + + logger(LOG_LEVEL_CRITICAL, "EXPERIMENTAL MODE "); + int nbc = readData(data); + + if (nbc != 0) + { + /* traitement des donnees recues */ + int res = convertDataToAx25(&data_ax25, data, nbc); + if (res != SUCCESS) + { + logger(LOG_LEVEL_CRITICAL, "AX25 CONVESTION ISSUE"); + } + + if (memcmp(gv_spinoConfig.spinoDesCallsign, data_ax25.header.destinationAdress, 6) == 0) + { + if (data_ax25.header.ssidDestination == (unsigned char)SSID_SPINO_TMTC) + { + logger(LOG_LEVEL_CRITICAL, "TRT COMMANDE NORMAL"); + processCommand(data_ax25); + } + else if (data_ax25.header.ssidDestination == (unsigned char)SSID_SPINO_EXPERIMENTAL) + { + logger(LOG_LEVEL_CRITICAL, "TRT COMMANDE EXPE"); + processExperimental(data_ax25); + } + else + { + // Message not awaited - message dropped + processDropMessage(data, nbc); + } + } + else + { + processDropMessage(data, nbc); + } + } + + sendBeaconExpe(); + + return gv_spino.currentState; +} diff --git a/EmbededSw/src/experimentalMode/experimentalMode.h b/EmbededSw/src/experimentalMode/experimentalMode.h new file mode 100644 index 0000000..e69de29 diff --git a/EmbededSw/src/mailboxMode/mailbox.c b/EmbededSw/src/mailboxMode/mailbox.c index 2448c9b..6e99ea4 100644 --- a/EmbededSw/src/mailboxMode/mailbox.c +++ b/EmbededSw/src/mailboxMode/mailbox.c @@ -666,12 +666,12 @@ void processMailbox(t_ax25_packet data_ax25) { t_ax25_packet ax25Frame; memcpy(ax25Frame.header.sourceAdress,gv_spinoConfig.spinoDesCallsign,6); - ax25Frame.header.ssidSource = SSID_SPINO_DIGIPEATER; + ax25Frame.header.ssidSource = SSID_SPINO_MAILBOX; memcpy(ax25Frame.header.destinationAdress,data_ax25.header.sourceAdress,6); + ax25Frame.header.ssidDestination = SSID_SPINO_MAILBOX; encodeAX25Header(&ax25Frame.header) ; memcpy( ax25Frame.data,&result,TC_REPONSE_HEADER_SIZE+result.size); /* envoyer la reponse de la commande */ writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+result.size); - sprintf(gvLogMsg,"RESULT MAILBOX COMMAND %x %x ",result.header.cmd_id,result.header.error_code); - logger(LOG_LEVEL_CRITICAL,gvLogMsg); + } diff --git a/EmbededSw/src/mailboxMode/modeMailbox.c b/EmbededSw/src/mailboxMode/modeMailbox.c index 74a1d17..4d618e6 100644 --- a/EmbededSw/src/mailboxMode/modeMailbox.c +++ b/EmbededSw/src/mailboxMode/modeMailbox.c @@ -33,7 +33,6 @@ unsigned short modeMailbox () processCommand(data_ax25); } else if ( data_ax25.header.ssidDestination == (unsigned char) SSID_SPINO_MAILBOX) { - logger(LOG_LEVEL_CRITICAL,"TRT COMMANDE MAILBOX"); processMailbox(data_ax25); } else @@ -42,6 +41,10 @@ unsigned short modeMailbox () processDropMessage (data,nbc); } + } else + { + // Message not awaited - message dropped + processDropMessage (data,nbc); } } return gv_spino.currentState; diff --git a/EmbededSw/src/payloadMode/payloadMode.c b/EmbededSw/src/payloadMode/payloadMode.c new file mode 100644 index 0000000..97ebdc7 --- /dev/null +++ b/EmbededSw/src/payloadMode/payloadMode.c @@ -0,0 +1,176 @@ +/** + * \file experienceMode.c + * \brief manage Expérience mode + * \author Xtophe + * \version 0.2 + * \date 01/08/2022 + * + * \todo gestion de l'I2C + * \todo faire le .h + * \todo download data + */ + +#include"stdio.h" +#include +#include "../core/setup.h" +#include "../drivers/modem.h" +#include "../errorMngt/error.h" +#include "payloadMode.h" + + + + +static unsigned char I2CReadDataStatus; +static unsigned char I2CWriteDataStatus; +static unsigned char I2CReadData [I2CMAXSIZE]; +static unsigned char I2CWriteData[I2CMAXSIZE]; + +s_I2C_data gv_I2C_Write_Data[I2CMAXDATA]; +int gv_nb_I2CMAXDATA; + + +void init() +{ + I2CReadDataStatus=0; + I2CWriteDataStatus=0; +} + +int getAllI2Cdata(t_tc_response *resp) +{ + t_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + resp->header.error_code = SUCCESS; + + int i=0; + + + for(i=0; i< gv_nb_I2CMAXDATA; i++) + { + resp->size=sizeof(s_I2C_data); + memcpy(resp->parameter,&gv_I2C_Write_Data[i].data, resp->size ); + memcpy( ax25Frame.data,resp,TC_REPONSE_HEADER_SIZE+resp->size); + writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp->size); + } + + resp->size=0; + return SUCCESS; + +} + + +t_tc_response interpretcommandPayload(t_command cmd) { + + + t_tc_response resp; + + + resp.header.responseType = RESULT_CMD; + resp.header.timeStamp=gv_spino.timestamps; + resp.header.cmd_id = cmd.id; + resp.header.error_code =SUCCESS; + + + switch (cmd.id) + { + case CMD_PAYLOAD_LOAD_DATA: + logger(LOG_LEVEL_INFO,"Commande CMD_PAYLOAD_LOAD_DATA"); + s_I2C_data data; + memcpy(&data, cmd.parameter, cmd.size); + I2CReadDataStatus = data.size; + memcpy(&I2CReadData, data.data, data.size); + resp.header.error_code=SUCCESS; + break; + + case CMD_PAYLOAD_READ_DATA: /* modify configuration value */ + logger(LOG_LEVEL_INFO,"Commande CMD_PAYLOAD_READ_DATA"); + resp.header.error_code = getAllI2Cdata(&resp); + break; + default: + resp.header.error_code = ERROR_COMMAND_UNKNOW; + } + return resp; +} + + + + +/** + * \fn void processCommand(t_ax25_packet data_ax25) + * \brief process command ax25 packet + * \param Ax25 packet + * \return SUCCESS if or Error code + * + */ +void processCommandePayload(t_ax25_packet data_ax25) { + + t_tc_response result ; + t_command cmd; + + + gv_spino.nbCommandeReceived++; + memcpy(&cmd,data_ax25.data,sizeof(t_command)); + if(cmd.key != gv_spino_cmd_key) + { + result.header.responseType = RESULT_CMD; + result.header.timeStamp=gv_spino.timestamps; + result.header.cmd_id = cmd.id; + result.header.error_code = ERROR_COMMAND_WITH_WRONG_KEY; + result.size=0; + } else + { + result = interpretcommandPayload( cmd); + + } + + if(result.header.error_code !=SUCCESS) + { + gv_spino.nbCommandeWithError++; + } + t_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + memcpy( ax25Frame.data,&result,TC_REPONSE_HEADER_SIZE+result.size); + /* envoyer la reponse de la commande */ + writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+result.size); + +} + + + +unsigned short payloadMode() { + char data[300]; + t_ax25_packet data_ax25; + + int nbc = readData(data); + + if (nbc != 0) { + /* traitement des donnees recues */ + int res = convertDataToAx25(&data_ax25, data, nbc); + if (res != SUCCESS) + { + logger(LOG_LEVEL_CRITICAL, "AX25 CONVERSION ISSUE"); + } + + if (memcmp(gv_spinoConfig.spinoDesCallsign, + data_ax25.header.destinationAdress, 6) == 0) { + + if (data_ax25.header.ssidDestination + == (unsigned char) SSID_SPINO_TMTC) { + processCommand(data_ax25); + } else if (data_ax25.header.ssidDestination + == (unsigned char) SSID_SPINO_CUBESAT) { + processCommandePayload(data_ax25); + } else { + logger(LOG_LEVEL_CRITICAL, "MESSAGE DROPED"); + processDropMessage(data, nbc); + + } + + } else { + // Message not awaited - message dropped + processDropMessage(data, nbc); + logger(LOG_LEVEL_CRITICAL, "MESSAGE DROPED"); + } + + } + return gv_spino.currentState; +} diff --git a/EmbededSw/src/payloadMode/payloadMode.h b/EmbededSw/src/payloadMode/payloadMode.h new file mode 100644 index 0000000..3e6f01f --- /dev/null +++ b/EmbededSw/src/payloadMode/payloadMode.h @@ -0,0 +1,12 @@ +#define I2CMAXSIZE 64 +#define I2CMAXDATA 10 + +#define CMD_PAYLOAD_LOAD_DATA 10 +#define CMD_PAYLOAD_READ_DATA 11 + +typedef struct I2C_data +{ + unsigned char size; + char data[I2CMAXSIZE]; + +}s_I2C_data; \ No newline at end of file diff --git a/EmbededSw/src/surveyMode/survey.c b/EmbededSw/src/surveyMode/survey.c index eb47503..f2db072 100644 --- a/EmbededSw/src/surveyMode/survey.c +++ b/EmbededSw/src/surveyMode/survey.c @@ -10,7 +10,6 @@ unsigned short survey() { t_ax25_packet data_ax25; int nbc = readData(data); - printf(" NB car Recu %d",nbc); if (nbc != 0) { /* traitement des donnees recues */ int res = convertDataToAx25(&data_ax25, data, nbc); @@ -18,8 +17,7 @@ unsigned short survey() { { logger(LOG_LEVEL_CRITICAL, "AX25 CONVESTION ISSUE"); } - // sprintf(gvLogMsg,"NB Data received %02x %02x %02x \r\n",data_ax25.header.destinationAdress[0],data_ax25.header.destinationAdress[1],data_ax25.header.destinationAdress[2]); - // logger(LOG_LEVEL_CRITICAL,gvLogMsg); + if (memcmp(gv_spinoConfig.spinoDesCallsign, data_ax25.header.destinationAdress, 6) == 0) { diff --git a/SPECIFICATIONS/AX25_Usage_on_Spino.md b/SPECIFICATIONS/AX25_Usage_on_Spino.md index 7ded5d4..c2e82b6 100644 --- a/SPECIFICATIONS/AX25_Usage_on_Spino.md +++ b/SPECIFICATIONS/AX25_Usage_on_Spino.md @@ -59,25 +59,28 @@ Spino allows two usages : A dedicated callsign is defined for Hamradio experimentation. If the associated capability of the spino is not active all packet with the correponding SSID are droped - | SSID | Usage | Comments | link to the description | -|------|-----------------------|---------------------------------------------------------------------|-------------------------| -| 0 | Not used | | | -| 1 | Telemetry | used for Spino telemetry | | -| 2 | Short message mailbox | Used for Short message mailbox capability | | -| 3 | | | | -| 4 | | | | -| 5 | | | | -| 6 | | | | -| 7 | | | | -| 8 | | | | -| 9 | | | | -| 10 | | | | -| 11 | | | | -| 12 | | | | -| 13 | | | | -| 14 | | | | -| 15 | SPINO TM/TC | Reserved to team in charge of Spino experiment (Command & Control) | | + | SSID | Usage | Comments | Mode | link to the description | +|------|-----------------------|---------------------------------------------------------------------|------|-------------------------| +| 0 | Not used | | | | +| 1 | Telemetry | used for Spino telemetry | ALL | | +| 2 | Short message mailbox | Used for Short message mailbox capability | Mailbox | | +| 3 | Digipeater | received a message and broadcast message | Digipeater | | +| 4 | Payload usage | allows data exchange with cubesat OBC | Payload | | +| 5 | Experimental | | Experimental | | +| 6 | Not used | | | | +| 7 | Not used | | | | +| 8 | Not used | | | | +| 9 | Not used | | | | +| 10 | Not used | | | | +| 11 | Not used | | | | +| 12 | Not used | | | | +| 13 | Not used | | | | +| 14 | Not used | | | | +| 15 | SPINO TM/TC | Reserved to team in charge of Spino experiment (Command & Control) | | | + + + #### Telecomand/telemetry management for satellite -TBD +TBD \ No newline at end of file diff --git a/SPECIFICATIONS/MailboxMode.md b/SPECIFICATIONS/MailboxMode.md index b919f53..c103292 100644 --- a/SPECIFICATIONS/MailboxMode.md +++ b/SPECIFICATIONS/MailboxMode.md @@ -19,16 +19,34 @@ Allows to the users to create a temporary dedicated mailbox to a user and allow - Automatic expiration of users as soon as the mailbox is empty - Messages are managed like a FIFO stack -## Usage +## Commands + + + ### Sending a message Scenario to send a message (AX25 header ignored, the considered protocol layer is encapsulated in the payload): -The "ARSxyz" station sends a message to the "ARSuvw" station +The "ARSxyz" station sends a message to the mailbox -> sending "ARSxyz" station identified by its call in the AX25 header --> AX25 payload consisting of : call destination station + reference counter + message (424 bytes max) -<- ACK from SPINO (or NACK : limit of the destination mailbox exceeded, or impossible to create a new mailbox) +-> AX25 payload consisting of : Command add message + message +<- SPINO send an acknowledgment message Success or NACK : limit of the destination mailbox exceeded, or impossible to create a new mailbox + +Command : CMD_MAILBOX_ADD_MSG +parameters : message to store + +### request last message + +Command : CMD_MAILBOX_GET_LAST_MSG : +parameters : none + + +### request all mailbox message + + +Command : CMD_MAILBOX_GET_ALL_MSG +parameters : none ### viewing the list of messages of a box @@ -39,6 +57,10 @@ If the mailbox exist, the satellite send following information : - list of message information : Message id & time If the mailbox does not exist, the satellite send a acknolegment with the error message : Mailbox not available +Command : +parameters : + + ### read a message @@ -51,21 +73,33 @@ If the message in the mailbox exist, the satellite send following information : If the message in the mailbox does not exist, the satellite send a acknolegment with the error message : Message not available If the mailbox does not exist, the satellite send a acknolegment with the error message : Mailbox not available - +Command : CMD_MAILBOX_GET_MSG +parameters : message index +parameters : Mailbox Callsign + -### delete a message +### delete the first message -User send request *Delette message* to Satellite with Mailbox Callsign and Message ID +User send request *Delette message* to Satellite. If the message in the mailbox exist, the satellite send a acknolegment with the information : message deleted If the message in the mailbox does not exist, the satellite send a acknolegment with the error message : Message not available If the mailbox does not exist, the satellite send a acknolegment with the error message : Mailbox not available +Command : CMD_MAILBOX_DEL_MSG +parameters : none + + ### viewing the list of active mailboxes User send request *List all mailbox* to Satellite The satellite send following information : -- number of mailbox -- list of mailbox callsign + +- list of mailbox callsign +- number of message available + +Command : CMD_MAILBOX_GET_LIST_BOX +parameters : none + ### delete a mailbox @@ -73,7 +107,8 @@ User send request *Delete mailbox* to Satellite with Mailbox Callsign If the message in the mailbox exist, the satellite send a acknolegment with the information : mailbox deleted If the mailbox does not exist, the satellite send a acknolegment with the error message : Mailbox not available - +Command : CMD_MAILBOX_DELETTE_BOX +parameters : none ### flush of mailboxes (Service Message) @@ -81,9 +116,19 @@ User send request *Flush all mailbox* to Satellite the satellite delette all mailbox and message the satellite send a acknolegment with the information : mailboxes deleted + + +Command : CMD_MAILBOX_INIT +parameters : none + +### Dump all Mailbox + +Command : CMD_MAILBOX_DUMP_MAILBOX +parameters : none + + ## Activation - - based on AX25 protocol - Service message (protected by a private key as head of the payload) are read/write of configuration registers allowing : - diff --git a/SPECIFICATIONS/States.md b/SPECIFICATIONS/States.md index 6efb6a9..dccbef1 100644 --- a/SPECIFICATIONS/States.md +++ b/SPECIFICATIONS/States.md @@ -6,6 +6,25 @@ # States diagram ![State diagram](./States.svg) +* + +- [Survey Mode](./SurveyMode.md) +- [Digipeater Mode] (./DigipeaterMode.md) +- [Mailbox Mode] (./MailboxMode.md) +- [Experimental Mode] (./ExperimentalMode.md) +- [Payload Mode] (./PayloadMode.md) + + +# Capability versus mode + +| Capabilties | Survey | Digipeater | Mailbox | Experimental | Payload | +|:---------------|:------:|:----------:|:-------:|:------------:|:-------:| +| Spino Beacon | X | X | X | X | X | +| Command core | X | X | X | X | X | +| retransmit msg | | X | | | | +| Mailbox | | | X | X (1) | | +| TLE data | | | | X | | +| Expe Beacon | | | | X | | +| Exchange OBC | | | | | X | + -- [Failsafe Mode](./FailsafeMode.md) -- \ No newline at end of file diff --git a/SPECIFICATIONS/FailsafeMode.md b/SPECIFICATIONS/SurveyMode.md similarity index 71% rename from SPECIFICATIONS/FailsafeMode.md rename to SPECIFICATIONS/SurveyMode.md index e95b673..104bd0a 100644 --- a/SPECIFICATIONS/FailsafeMode.md +++ b/SPECIFICATIONS/SurveyMode.md @@ -4,7 +4,7 @@ | 21/02/2022 | Draft | -# Failsafe mode +# Survey mode ## scope @@ -19,8 +19,3 @@ After communications to the community via WEBsite and Twitter, other modulations ## Usage -### system reset (Service Message) - -### setting of modulations used (Service Message) - -### activation / deactivation of a beacon mode and periodicity (Service Message) \ No newline at end of file diff --git a/SPECIFICATIONS/commande.md b/SPECIFICATIONS/commande.md new file mode 100644 index 0000000..71fd114 --- /dev/null +++ b/SPECIFICATIONS/commande.md @@ -0,0 +1,38 @@ + +| Last modification | Status | +|-------------------- |--------- | +| 10/09/2022 | Draft | + + +# Command list + +| Command Name | Commande value | parameters | comment | +|:-----------------------------:|:--------------:|:--------------------------------------------------------:|:-------:| +| Reset | 100 | none | | +| set value | 101 | see set value parameters | | +| get value | 102 | Data Id : 2 byte (see data ID | | +| get config | 103 | Mailbox Name : (Callsign) 6 byte | | +| get last message dropped | 120 | none | | +| get all messages dropped | 121 | none | | +| get last log | 130 | none | | +| get all log | 131 | none | | +| set information message | 132 | | | +| set information message | 133 | | | + + + + + +# set value parameters + +| data name | Id | RW | comment | +| :------------: | :------------: | :------------: | :------------: | +|VALUE_SPINO_VERSION | 128 | R | | +| VALUE_SPINO_DELAY | 1 | R/W | | +| VALUE_CALLSIGN_SRC_SPINO | 2 | R/W | | +|VALUE_CALLSIGN_DES_SPINO | 3| R/W | | +| VALUE_CALLSIGN_PAYLOAD_SPINO | 4 | R/W | | +| VALUE_TIMESTAMP | 5 | R/W | | +| VALUE_LOG_LEVEL | 6 | R/W | | +| VALUE_ACTIVE_INFO_MESSAGE | 7 | R/W | | +| VALUE_DELAY_INFO_MESSAGE | 8 | R/W | | \ No newline at end of file diff --git a/SPECIFICATIONS/state.puml b/SPECIFICATIONS/state.puml new file mode 100644 index 0000000..5cee7f5 --- /dev/null +++ b/SPECIFICATIONS/state.puml @@ -0,0 +1,15 @@ +@startuml + +[*] --> Init +Init --> Survey +Survey --> Digipeater +Survey --> Mailbox +Survey --> Experimental +Survey --> Payload + +Digipeater --> Survey +Mailbox --> Survey +Experimental --> Survey +Payload --> Survey + +@enduml \ No newline at end of file -- GitLab From 30e64ca0ebd98db38e711783d28d9a68e789f6ea Mon Sep 17 00:00:00 2001 From: chris Date: Sat, 10 Sep 2022 14:49:39 +0200 Subject: [PATCH 09/12] doc : update state doc --- .../{PrimaryPayloadMode.md => PayloadMode.md} | 0 SPECIFICATIONS/States.svg | 37 +++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) rename SPECIFICATIONS/{PrimaryPayloadMode.md => PayloadMode.md} (100%) diff --git a/SPECIFICATIONS/PrimaryPayloadMode.md b/SPECIFICATIONS/PayloadMode.md similarity index 100% rename from SPECIFICATIONS/PrimaryPayloadMode.md rename to SPECIFICATIONS/PayloadMode.md diff --git a/SPECIFICATIONS/States.svg b/SPECIFICATIONS/States.svg index f0eee17..2401233 100644 --- a/SPECIFICATIONS/States.svg +++ b/SPECIFICATIONS/States.svg @@ -1,4 +1,33 @@ - - - -

Failsafe

Failsafe

Short Message Mailbox

Short Message Mailbox

Digital Transponder

Digital Transponder
MailBoxCommande
MailBoxCommande
TransponderCommande
TransponderCommande
TranspondeurCommandeOFF
TranspondeurCommandeOFF
PowerOn
PowerOn
Text is not SVG - cannot display
\ No newline at end of file +InitSurveyDigipeaterMailboxExperimentalPayload \ No newline at end of file -- GitLab From 84d0ad66fa1b3b3544045614a7ade351cb99fa30 Mon Sep 17 00:00:00 2001 From: chris Date: Mon, 12 Sep 2022 07:13:54 +0200 Subject: [PATCH 10/12] improve experimental mode --- EmbededSw/src/core/command.c | 7 ++--- EmbededSw/src/core/command.h | 1 + EmbededSw/src/core/control.c | 5 +++- EmbededSw/src/core/control.h | 1 + EmbededSw/src/errorMngt/error.h | 4 +-- .../src/experimentalMode/experimentalMode.c | 26 ++++++++++++------- 6 files changed, 28 insertions(+), 16 deletions(-) diff --git a/EmbededSw/src/core/command.c b/EmbededSw/src/core/command.c index c41ee50..348e852 100644 --- a/EmbededSw/src/core/command.c +++ b/EmbededSw/src/core/command.c @@ -21,7 +21,7 @@ extern void writeData ( t_ax25_packet ax25Frame, int length); - +extern int changeState (short state) ; /** * \fn int reset() * \brief réinitialise le logiciel SPINO @@ -234,8 +234,9 @@ t_tc_response interpretcommand(t_command cmd) { logger(LOG_LEVEL_INFO,"Commande SET STATE"); if (cmd.size==1) { - gv_spino.currentState = cmd.parameter[0]; - reponse=0; + // gv_spino.currentState = cmd.parameter[0]; + reponse = changeState ((short) cmd.parameter[0]) ; + } resp.size=0; break; diff --git a/EmbededSw/src/core/command.h b/EmbededSw/src/core/command.h index 91b3d11..a7e0a3d 100644 --- a/EmbededSw/src/core/command.h +++ b/EmbededSw/src/core/command.h @@ -12,6 +12,7 @@ #define TELEMETRY 64 /*!< response type : SPINO Telemetry */ #define INFORMATION_MSG 65 /*!< response type : SPINO Information Message */ #define RESULT_DROP_MESSAGE 32 /*!< response type : Drop message */ +#define EXPEBEACON 16 /*!< response type : Drop message */ /* COMMAND LIST */ #define CMD_RESET 100 diff --git a/EmbededSw/src/core/control.c b/EmbededSw/src/core/control.c index 6394a52..5b80020 100644 --- a/EmbededSw/src/core/control.c +++ b/EmbededSw/src/core/control.c @@ -14,6 +14,8 @@ extern unsigned short modeMailbox (); extern unsigned short payloadMode(); extern unsigned short experimentalMode(); +extern initExpe(); + unsigned long long lv_spino_timeStampPrevious=0; t_tc_response resptlm; @@ -46,7 +48,7 @@ int changeState (short state) int response = SUCCESS; - switch (gv_spino.currentState) + switch (state) { case (int) STATE_INIT: @@ -84,6 +86,7 @@ int changeState (short state) if(gv_spino.currentState==STATE_SURVEY) { gv_spino.currentState = STATE_EXPE_DATA; + initExpe(); } else { diff --git a/EmbededSw/src/core/control.h b/EmbededSw/src/core/control.h index 179efb2..5533124 100644 --- a/EmbededSw/src/core/control.h +++ b/EmbededSw/src/core/control.h @@ -13,4 +13,5 @@ #define STATE_MAIN_PAYLOAD 5 +extern int changeState (short state) ; #endif // CONTROL_H diff --git a/EmbededSw/src/errorMngt/error.h b/EmbededSw/src/errorMngt/error.h index a774285..49bdf14 100644 --- a/EmbededSw/src/errorMngt/error.h +++ b/EmbededSw/src/errorMngt/error.h @@ -2,8 +2,8 @@ #define ERROR_H -#define ERROR 1 - +/* #define ERROR 1 +*/ #define SUCCESS 0 /* Command analysis */ diff --git a/EmbededSw/src/experimentalMode/experimentalMode.c b/EmbededSw/src/experimentalMode/experimentalMode.c index 2519459..b5a72e5 100644 --- a/EmbededSw/src/experimentalMode/experimentalMode.c +++ b/EmbededSw/src/experimentalMode/experimentalMode.c @@ -32,9 +32,9 @@ typedef struct tle typedef struct experimental_beacon { - long long date; short id; short delay; + char value[4]; } s_experimental_beacon; @@ -48,13 +48,17 @@ s_experimental_beacon expBeacon; void initExpe() { - expBeacon.id=0; + expBeacon.id=128; expBeacon.delay=10; - - respexpBeacon.header.responseType = TELEMETRY; + expBeacon.value[0]='A'; + expBeacon.value[1]='B'; + expBeacon.value[2]='C'; + expBeacon.value[3]='D'; + respexpBeacon.header.responseType = EXPEBEACON; respexpBeacon.header.error_code = 0; respexpBeacon.header.cmd_id =0; respexpBeacon.size = sizeof(s_experimental_beacon); + } @@ -98,7 +102,7 @@ t_tc_response interpretExperimentalCommmand(t_command cmd, char *callsign) { case CMD_EXPE_INIT: - logger(LOG_LEVEL_INFO, "Commande EXP BOX RESET"); + logger(LOG_LEVEL_INFO, "Commande EXP RESET"); resp.header.error_code = initialise(); resp.size = 0; break; @@ -116,28 +120,31 @@ t_tc_response interpretExperimentalCommmand(t_command cmd, char *callsign) logger(LOG_LEVEL_INFO, "Commande CMD_LOAD_TLE_1"); if (cmd.size != SIZE_TLE) { + logger(LOG_LEVEL_INFO, "Commande CMD_LOAD_TLE_1 SIZE OK"); gv_tle.tleLine1[0] = 0; strncat(gv_tle.tleLine1, cmd.parameter, SIZE_TLE); } else { resp.header.error_code = ERROR_TLE_WRONG_SIZE; - resp.size = 0; + } + resp.size = 0; break; case CMD_LOAD_TLE_2: logger(LOG_LEVEL_INFO, "Commande CMD_LOAD_TLE_2"); if (cmd.size != SIZE_TLE) { - gv_tle.tleLine1[0] = 0; + gv_tle.tleLine2[0] = 0; strncat(gv_tle.tleLine2, cmd.parameter, SIZE_TLE); } else { resp.header.error_code = ERROR_TLE_WRONG_SIZE; - resp.size = 0; } + resp.size = 0; break; + case CMD_DOWNLOAD_TLE: logger(LOG_LEVEL_INFO, "Commande CMD_DOWNLOAD_TLE"); resp.header.error_code = expDownloadTLE(&resp); @@ -160,7 +167,6 @@ t_tc_response interpretExperimentalCommmand(t_command cmd, char *callsign) case CMD_EXPE_GET_LIST: logger(LOG_LEVEL_INFO, "Commande CMD_EXPE_GET_LIST"); resp.header.error_code = getListMailbox(&resp); - resp.size = 0; break; case CMD_EXPE_DELETTE_ALL: logger(LOG_LEVEL_INFO, "Commande MAILBOX DELETE MAILBOX"); @@ -186,7 +192,7 @@ t_tc_response interpretExperimentalCommmand(t_command cmd, char *callsign) void sendBeaconExpe() { - if( gv_spino.timestamps > (lv_spino_expe_timeStampPrevious + gv_spinoConfig.telemetryDelay*1000)) + if( gv_spino.timestamps > (lv_spino_expe_timeStampPrevious + (expBeacon.delay *1000))) { t_ax25_packet ax25Frame; lv_spino_expe_timeStampPrevious = gv_spino.timestamps; -- GitLab From 5905e1ca7ca6c07466b666c5f774c8d59587bc0f Mon Sep 17 00:00:00 2001 From: chris Date: Wed, 14 Sep 2022 22:28:05 +0200 Subject: [PATCH 11/12] update --- EmbededSw/src/experimentalMode/experimentalMode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EmbededSw/src/experimentalMode/experimentalMode.c b/EmbededSw/src/experimentalMode/experimentalMode.c index b5a72e5..5a27a3f 100644 --- a/EmbededSw/src/experimentalMode/experimentalMode.c +++ b/EmbededSw/src/experimentalMode/experimentalMode.c @@ -159,7 +159,8 @@ t_tc_response interpretExperimentalCommmand(t_command cmd, char *callsign) else { char message[MAX_LENGHT_MESSAGE]; - memcpy(message, cmd.parameter, cmd.size); + memcpy(message, &cmd.parameter, cmd.size); + logger(LOG_LEVEL_INFO, message); resp.header.error_code = addMessage(callsign, message, cmd.size); } resp.size = 0; -- GitLab From 5bf804a26a9e3385639797ec711de95a9b0cf107 Mon Sep 17 00:00:00 2001 From: chris Date: Sun, 18 Sep 2022 11:01:05 +0200 Subject: [PATCH 12/12] Qualimetry - add new GCC option and apply correction on soucrce code --- EmbededSw/src/Makefile | 2 +- EmbededSw/src/ax25/ax25.c | 137 ++- EmbededSw/src/ax25/ax25.h | 29 +- EmbededSw/src/core/command.c | 629 +++++----- EmbededSw/src/core/command.h | 162 +-- EmbededSw/src/core/configuration.h | 67 +- EmbededSw/src/core/control.c | 298 +++-- EmbededSw/src/core/control.h | 7 +- EmbededSw/src/core/informationMessage.c | 324 +++--- EmbededSw/src/core/informationMessage.h | 24 +- EmbededSw/src/core/setup.c | 11 +- EmbededSw/src/core/setup.h | 18 +- EmbededSw/src/digipeaterMode/ModeDigipeater.c | 87 +- EmbededSw/src/drivers/modem.c | 81 +- EmbededSw/src/drivers/modem.h | 7 +- EmbededSw/src/dropMsgMngt/DropMessage.c | 122 +- EmbededSw/src/dropMsgMngt/DropMessage.h | 27 +- EmbededSw/src/errorMngt/error.h | 9 +- .../src/experimentalMode/experimentalMode.c | 453 ++++---- .../src/experimentalMode/experimentalMode.h | 34 + EmbededSw/src/logMngt/log.c | 99 +- EmbededSw/src/logMngt/log.h | 14 +- EmbededSw/src/mailboxMode/mailbox.c | 1027 ++++++++--------- EmbededSw/src/mailboxMode/mailbox.h | 123 +- EmbededSw/src/mailboxMode/modeMailbox.c | 66 +- EmbededSw/src/mailboxMode/modeMailbox.h | 5 +- EmbededSw/src/main.c | 23 +- EmbededSw/src/payloadMode/payloadMode.c | 171 ++- EmbededSw/src/payloadMode/payloadMode.h | 10 +- EmbededSw/src/simulation/SpinoSimuServerTCP.c | 382 +++--- EmbededSw/src/simulation/SpinoSimuServerTCP.h | 13 +- EmbededSw/src/simulation/lecfic.c | 128 +- EmbededSw/src/simulation/lefic.h | 10 +- EmbededSw/src/surveyMode/survey.c | 9 +- 34 files changed, 2141 insertions(+), 2467 deletions(-) diff --git a/EmbededSw/src/Makefile b/EmbededSw/src/Makefile index 3a23d79..97cfb74 100644 --- a/EmbededSw/src/Makefile +++ b/EmbededSw/src/Makefile @@ -1,5 +1,5 @@ CC=gcc -CFLAGS=-W -Wall +CFLAGS=-W -std=c99 -Wall -Wbad-function-cast -Wcast-align -Wconversion -Wnull-dereference -Wshadow -Wswitch-enum -Wduplicated-branches -Wduplicated-cond -Wformat-signedness -Wswitch-default -Wjump-misses-init -Wlogical-op -Wnested-externs -Wnormalized -Wsuggest-attribute=format LDFLAGS= -lws2_32 EXEC=spinoSimulator diff --git a/EmbededSw/src/ax25/ax25.c b/EmbededSw/src/ax25/ax25.c index 45194f2..f14deac 100644 --- a/EmbededSw/src/ax25/ax25.c +++ b/EmbededSw/src/ax25/ax25.c @@ -23,24 +23,24 @@ * */ -void convertToAX25Header ( t_ax25_header *data, char *dest, char ssidDest, char *src, char ssidSrc) -{ - int i; - unsigned char c; - - data->ssidDestination = (unsigned char) (ssidDest<< 1 & 0xFE); - data->ssidSource = (unsigned char) (ssidSrc<< 1 & 0xFE); - for (i=0;i< 6; i++) - { - c =(unsigned char) dest[i]; - data->destinationAdress[i] = (unsigned char) (c<< 1 & 0xFE);; - } - - for (i=0;i< 6; i++) - { - c = (unsigned char) src[i]; - data->sourceAdress[i] = (unsigned char) (c<< 1 & 0xFE);; - } +void convertToAX25Header(s_ax25_header *data, unsigned char *dest, + unsigned char ssidDest, unsigned char *src, unsigned char ssidSrc) { + int i; + unsigned char c; + + data->ssidDestination = (unsigned char) (ssidDest << 1 & 0xFE); + data->ssidSource = (unsigned char) (ssidSrc << 1 & 0xFE); + for (i = 0; i < 6; i++) { + c = (unsigned char) dest[i]; + data->destinationAdress[i] = (unsigned char) (c << 1 & 0xFE); + ; + } + + for (i = 0; i < 6; i++) { + c = (unsigned char) src[i]; + data->sourceAdress[i] = (unsigned char) (c << 1 & 0xFE); + ; + } } /** @@ -52,25 +52,24 @@ void convertToAX25Header ( t_ax25_header *data, char *dest, char ssidDest, char * */ -void encodeAX25Header(t_ax25_header *data) -{ - int i=0; - unsigned char c; - c =(unsigned char) (data->ssidDestination<< 1 & 0xFE); - data->ssidDestination = c; - c =(unsigned char) (data->ssidSource<< 1 & 0xFE); - data->ssidSource = c; - for (i=0;i< 6; i++) - { - c =(unsigned char) data->destinationAdress[i]; - data->destinationAdress[i] = (unsigned char) (c<< 1 & 0xFE);; - } - - for (i=0;i< 6; i++) - { - c = (unsigned char) data->sourceAdress[i]; - data->sourceAdress[i] = (unsigned char) (c<< 1 & 0xFE);; - } +void encodeAX25Header(s_ax25_header *data) { + int i = 0; + unsigned char c; + c = (unsigned char) (data->ssidDestination << 1 & 0xFE); + data->ssidDestination = c; + c = (unsigned char) (data->ssidSource << 1 & 0xFE); + data->ssidSource = c; + for (i = 0; i < 6; i++) { + c = (unsigned char) data->destinationAdress[i]; + data->destinationAdress[i] = (unsigned char) (c << 1 & 0xFE); + ; + } + + for (i = 0; i < 6; i++) { + c = (unsigned char) data->sourceAdress[i]; + data->sourceAdress[i] = (unsigned char) (c << 1 & 0xFE); + ; + } } /** @@ -83,40 +82,36 @@ void encodeAX25Header(t_ax25_header *data) * \return error value SUCCES or ERROR_AX25_EXCEED_MAX_LENGH * */ -int convertDataToAx25 (t_ax25_packet *data, char *rawdata, unsigned int size ) { - - int error = SUCCESS; - int i; - unsigned char c; - - - if (size < sizeof(t_ax25_packet)) - { - memcpy (data,rawdata, size); - - /* Convert */ - c = data->header.ssidDestination; - data->header.ssidDestination = c >> 1 & 0x7F; - c = data->header.ssidSource; - data->header.ssidSource = c >> 1 & 0x7F; - - for (i=0;i< 6; i++) - { - c = data->header.destinationAdress[i]; - data->header.destinationAdress[i] = c >> 1 & 0x7F ; - - } - - for (i=0;i< 6; i++) - { - c = data->header.sourceAdress[i]; - data->header.sourceAdress[i] = c >> 1 & 0x7F; - } - - } else { - error = ERROR_AX25_EXCEED_MAX_LENGH; - } - return error; +int convertDataToAx25(s_ax25_packet *data, char *rawdata, int size) { + + int error = SUCCESS; + int i; + unsigned char c; + + if (size < (int) sizeof(s_ax25_packet)) { + memcpy(data, rawdata, (size_t) size); + + /* Convert */ + c = data->header.ssidDestination; + data->header.ssidDestination = c >> 1 & 0x7F; + c = data->header.ssidSource; + data->header.ssidSource = c >> 1 & 0x7F; + + for (i = 0; i < 6; i++) { + c = data->header.destinationAdress[i]; + data->header.destinationAdress[i] = c >> 1 & 0x7F; + + } + + for (i = 0; i < 6; i++) { + c = data->header.sourceAdress[i]; + data->header.sourceAdress[i] = c >> 1 & 0x7F; + } + + } else { + error = ERROR_AX25_EXCEED_MAX_LENGH; + } + return error; } diff --git a/EmbededSw/src/ax25/ax25.h b/EmbededSw/src/ax25/ax25.h index 7240625..6fffaed 100644 --- a/EmbededSw/src/ax25/ax25.h +++ b/EmbededSw/src/ax25/ax25.h @@ -13,23 +13,24 @@ #define CALLSIGN_SIZE 6 typedef struct ax25_header { - char destinationAdress [6]; - unsigned char ssidDestination; - char sourceAdress[6]; - unsigned char ssidSource; - unsigned char ctrl; - unsigned char pid; + unsigned char destinationAdress[6]; + unsigned char ssidDestination; + unsigned char sourceAdress[6]; + unsigned char ssidSource; + unsigned char ctrl; + unsigned char pid; -} t_ax25_header; +} s_ax25_header; typedef struct ax25_packet { - t_ax25_header header; - char data[MAX_DATA_SIZE]; + s_ax25_header header; + char data[MAX_DATA_SIZE]; -} t_ax25_packet; +} s_ax25_packet; -extern int convertDataToAx25 (t_ax25_packet *data, char *rawdata, unsigned int size ); -extern void convertToAX25Header ( t_ax25_header *data, char *dest, char ssidDest, char *src, char ssidSrc); -extern void encodeAX25Header(t_ax25_header *data); +extern int convertDataToAx25(s_ax25_packet *data, char *rawdata, int size); +extern void convertToAX25Header(s_ax25_header *data, unsigned char *dest, + unsigned char ssidDest, unsigned char *src, unsigned char ssidSrc); +extern void encodeAX25Header(s_ax25_header *data); -#endif // AX25_H \ No newline at end of file +#endif // AX25_H diff --git a/EmbededSw/src/core/command.c b/EmbededSw/src/core/command.c index 348e852..b14e81e 100644 --- a/EmbededSw/src/core/command.c +++ b/EmbededSw/src/core/command.c @@ -1,4 +1,3 @@ - /** * \file command.c * \brief perform treatment of standard SPINO Command @@ -18,10 +17,8 @@ #include "../dropMsgMngt/DropMessage.h" #include "../errorMngt/error.h" - - -extern void writeData ( t_ax25_packet ax25Frame, int length); -extern int changeState (short state) ; +extern void writeData(s_ax25_packet ax25Frame, int length); +extern int changeState(short state); /** * \fn int reset() * \brief réinitialise le logiciel SPINO @@ -32,13 +29,11 @@ extern int changeState (short state) ; * \todo : int reset() is to be implemented */ -int reset(){ +static unsigned char reset() { - return ERROR_COMMAND_NOT_IMPLEMENTED; + return ERROR_COMMAND_NOT_IMPLEMENTED; } - - /** * \fn int setValue(t_set_value value,t_tc_response *resp) * \brief set value accordting to information in t_set_value strruture @@ -49,57 +44,57 @@ int reset(){ * * \todo : int setValie() renforcer l'analyse par verfication de la taille des parametres */ -int setValue(const t_set_value value,t_tc_response *resp) { - - - int returnValue = SUCCESS; - - printf("set value"); - resp->size = SIZE_HEADER_FIELD; - - switch (value.fied_id) { - - case VALUE_SPINO_DELAY : - gv_spinoConfig.telemetryDelay = (unsigned char) value.value[0]; - break; - - case VALUE_DELAY_INFO_MESSAGE : - memcpy (&gv_spinoConfig.delay_info_message,value.value,sizeof(gv_spinoConfig.delay_info_message)); - break; - - case VALUE_ACTIVE_INFO_MESSAGE : - memcpy (&gv_spinoConfig.info_message_actif,value.value,sizeof(gv_spinoConfig.info_message_actif)); - break; - - case VALUE_CALLSIGN_SRC_SPINO : - memcpy (&gv_spinoConfig.spinoSrcCallsign,value.value,CALLSIGN_SIZE); - break; - - case VALUE_CALLSIGN_DES_SPINO : - memcpy (&gv_spinoConfig.spinoDesCallsign,value.value,CALLSIGN_SIZE); - break; - - case VALUE_CALLSIGN_PAYLOAD_SPINO : - memcpy (&gv_spinoConfig.payloadCallsign,value.value,CALLSIGN_SIZE); - break; - - case VALUE_TIMESTAMP : - logger(LOG_LEVEL_INFO,"Commande VALUE_TIMESTAMP"); - memcpy (&gv_spino.timestamps,value.value,sizeof(gv_spino.timestamps)); - logger(LOG_LEVEL_INFO,"Commande VALUE_TIMESTAMP SET"); - break; - - case VALUE_LOG_LEVEL: - logger(LOG_LEVEL_INFO,"Commande VALUE_LOG_LEVEL"); - gv_SelectedLogLevel = (unsigned char) value.value[0]; - break; - default: - // generation code erreur - returnValue = ERROR_VALUE_FIELD_UNKNOW; - break; - } - // memcpy (resp->parameter,&response,resp->size ); - return returnValue; +static unsigned char setValue(const s_set_value value, t_tc_response *resp) { + + unsigned char returnValue = SUCCESS; + + resp->size = SIZE_HEADER_FIELD; + + switch (value.fied_id) { + + case VALUE_SPINO_DELAY: + gv_spinoConfig.telemetryDelay = (unsigned char) value.value[0]; + break; + + case VALUE_DELAY_INFO_MESSAGE: + memcpy(&gv_spinoConfig.delay_info_message, value.value, + sizeof(gv_spinoConfig.delay_info_message)); + break; + + case VALUE_ACTIVE_INFO_MESSAGE: + memcpy(&gv_spinoConfig.info_message_actif, value.value, + sizeof(gv_spinoConfig.info_message_actif)); + break; + + case VALUE_CALLSIGN_SRC_SPINO: + memcpy(&gv_spinoConfig.spinoSrcCallsign, value.value, CALLSIGN_SIZE); + break; + + case VALUE_CALLSIGN_DES_SPINO: + memcpy(&gv_spinoConfig.spinoDesCallsign, value.value, CALLSIGN_SIZE); + break; + + case VALUE_CALLSIGN_PAYLOAD_SPINO: + memcpy(&gv_spinoConfig.payloadCallsign, value.value, CALLSIGN_SIZE); + break; + + case VALUE_TIMESTAMP: + logger(LOG_LEVEL_INFO, "Commande VALUE_TIMESTAMP"); + memcpy(&gv_spino.timestamps, value.value, sizeof(gv_spino.timestamps)); + logger(LOG_LEVEL_INFO, "Commande VALUE_TIMESTAMP SET"); + break; + + case VALUE_LOG_LEVEL: + logger(LOG_LEVEL_INFO, "Commande VALUE_LOG_LEVEL"); + gv_SelectedLogLevel = (unsigned char) value.value[0]; + break; + default: + // generation code erreur + returnValue = ERROR_VALUE_FIELD_UNKNOW; + break; + } + // memcpy (resp->parameter,&response,resp->size ); + return returnValue; } /** @@ -112,87 +107,88 @@ int setValue(const t_set_value value,t_tc_response *resp) { * * \todo : int getValue() renforcer l'analyse par verfication de la taille des parametres */ -int getValue(const t_get_value value, t_tc_response *resp) -{ - int returnValue = SUCCESS; - t_field response; - - response.field_id = value.field_id; - - switch (value.field_id) { - - case VALUE_SPINO_VERSION : - response.size = sizeof(gv_version); - memcpy (response.field_value,&gv_version,response.size ); - resp->size = SIZE_HEADER_FIELD + response.size; - memcpy (resp->parameter,&response,resp->size ); - break; - - case VALUE_SPINO_DELAY : - - response.size = sizeof(gv_spinoConfig.telemetryDelay); - response.field_value [0] = gv_spinoConfig.telemetryDelay; - resp->size = SIZE_HEADER_FIELD + response.size; - memcpy (resp->parameter,&response,resp->size ); - break; - - case VALUE_CALLSIGN_SRC_SPINO : - response.size = 6; - memcpy (response.field_value,gv_spinoConfig.spinoSrcCallsign,6); - resp->size = SIZE_HEADER_FIELD + response.size; - memcpy (resp->parameter,&response,resp->size ); - break; - - case VALUE_CALLSIGN_DES_SPINO : - - response.size = 6; - memcpy (response.field_value,gv_spinoConfig.spinoDesCallsign,6); - resp->size = SIZE_HEADER_FIELD+response.size; - memcpy (resp->parameter,&response,resp->size ); - break; - - case VALUE_CALLSIGN_PAYLOAD_SPINO : - response.size = 6; - memcpy (response.field_value,gv_spinoConfig.payloadCallsign,6); - resp->size = SIZE_HEADER_FIELD+response.size; - memcpy (resp->parameter,&response,resp->size ); - break; - - case VALUE_LOG_LEVEL: - response.size = sizeof(gv_SelectedLogLevel); - memcpy (response.field_value,&gv_SelectedLogLevel,response.size ); - resp->size = SIZE_HEADER_FIELD + response.size; - memcpy (resp->parameter,&response,resp->size ); - break; - - case VALUE_ACTIVE_INFO_MESSAGE: - response.size = sizeof(gv_spinoConfig.info_message_actif); - memcpy (response.field_value,&gv_spinoConfig.info_message_actif,response.size ); - resp->size = SIZE_HEADER_FIELD + response.size; - memcpy (resp->parameter,&response,resp->size ); - break; - - case VALUE_DELAY_INFO_MESSAGE: - response.size = sizeof(gv_spinoConfig.delay_info_message); - memcpy (response.field_value,&gv_spinoConfig.delay_info_message,response.size ); - resp->size = SIZE_HEADER_FIELD + response.size; - memcpy (resp->parameter,&response,resp->size ); - break; - - case VALUE_TIMESTAMP : /*! Non implemented !*/ - default: - // generation code erreur - sprintf(gvLogMsg,"valeur inconnue %d \r\n",value.field_id); - logger(LOG_LEVEL_CRITICAL,gvLogMsg); - returnValue = ERROR_VALUE_FIELD_UNKNOW; - response.size = 0; - resp->size = SIZE_HEADER_FIELD; - memcpy (resp->parameter,&response,resp->size ); - break; - - } - -return returnValue; +static unsigned char getValue(const s_get_value value, t_tc_response *resp) { + unsigned char returnValue = SUCCESS; + s_field response; + + response.field_id = value.field_id; + + switch (value.field_id) { + + case VALUE_SPINO_VERSION: + response.size = sizeof(gv_version); + memcpy(response.field_value, &gv_version, response.size); + resp->size = SIZE_HEADER_FIELD + response.size; + memcpy(resp->parameter, &response, resp->size); + break; + + case VALUE_SPINO_DELAY: + + response.size = sizeof(gv_spinoConfig.telemetryDelay); + response.field_value[0] = gv_spinoConfig.telemetryDelay; + resp->size = SIZE_HEADER_FIELD + response.size; + memcpy(resp->parameter, &response, resp->size); + break; + + case VALUE_CALLSIGN_SRC_SPINO: + response.size = 6; + memcpy(response.field_value, gv_spinoConfig.spinoSrcCallsign, 6); + resp->size = SIZE_HEADER_FIELD + response.size; + memcpy(resp->parameter, &response, resp->size); + break; + + case VALUE_CALLSIGN_DES_SPINO: + + response.size = 6; + memcpy(response.field_value, gv_spinoConfig.spinoDesCallsign, 6); + resp->size = SIZE_HEADER_FIELD + response.size; + memcpy(resp->parameter, &response, resp->size); + break; + + case VALUE_CALLSIGN_PAYLOAD_SPINO: + response.size = 6; + memcpy(response.field_value, gv_spinoConfig.payloadCallsign, 6); + resp->size = SIZE_HEADER_FIELD + response.size; + memcpy(resp->parameter, &response, resp->size); + break; + + case VALUE_LOG_LEVEL: + response.size = sizeof(gv_SelectedLogLevel); + memcpy(response.field_value, &gv_SelectedLogLevel, response.size); + resp->size = SIZE_HEADER_FIELD + response.size; + memcpy(resp->parameter, &response, resp->size); + break; + + case VALUE_ACTIVE_INFO_MESSAGE: + response.size = sizeof(gv_spinoConfig.info_message_actif); + memcpy(response.field_value, &gv_spinoConfig.info_message_actif, + response.size); + resp->size = SIZE_HEADER_FIELD + response.size; + memcpy(resp->parameter, &response, resp->size); + break; + + case VALUE_DELAY_INFO_MESSAGE: + response.size = sizeof(gv_spinoConfig.delay_info_message); + memcpy(response.field_value, &gv_spinoConfig.delay_info_message, + response.size); + resp->size = SIZE_HEADER_FIELD + response.size; + memcpy(resp->parameter, &response, resp->size); + break; + + case VALUE_TIMESTAMP: /*! Non implemented !*/ + default: + // generation code erreur + sprintf(gvLogMsg, "valeur inconnue %d \r\n", value.field_id); + logger(LOG_LEVEL_CRITICAL, gvLogMsg); + returnValue = ERROR_VALUE_FIELD_UNKNOW; + response.size = 0; + resp->size = SIZE_HEADER_FIELD; + memcpy(resp->parameter, &response, resp->size); + break; + + } + + return returnValue; } /** @@ -204,159 +200,144 @@ return returnValue; * \todo implementer LOAD PROG */ -t_tc_response interpretcommand(t_command cmd) { - - - t_tc_response resp; - int reponse=SUCCESS; - - - resp.header.responseType = RESULT_CMD; - resp.header.timeStamp=gv_spino.timestamps; - resp.header.cmd_id = cmd.id; - - - switch (cmd.id) - { - case CMD_RESET: - logger(LOG_LEVEL_INFO,"Commande RESET"); - reponse = reset(); - break; - case SET_VALUE: /* modify configuration value */ - logger(LOG_LEVEL_INFO,"Commande SET VALUE"); - t_set_value setvalue; - memcpy(&setvalue, cmd.parameter, cmd.size); - printf("Size %d",setvalue.size); - reponse = setValue(setvalue,&resp); - break; - - case SET_STATE: /*modify mode */ - logger(LOG_LEVEL_INFO,"Commande SET STATE"); - if (cmd.size==1) - { - // gv_spino.currentState = cmd.parameter[0]; - reponse = changeState ((short) cmd.parameter[0]) ; - - } - resp.size=0; - break; - - case GET_VALUE: // return value of field - - logger(LOG_LEVEL_INFO,"Commande GET VALUE"); - t_get_value getvalue; - memcpy(&getvalue, cmd.parameter, cmd.size); - reponse = getValue(getvalue,&resp); - break; - - case GET_CONGIG: // return Configuration structure - logger(LOG_LEVEL_INFO,"Commande GET CONFIG"); - resp.size = sizeof(t_configuration_spino); - memcpy(resp.parameter, &gv_spinoConfig, sizeof(t_configuration_spino)); - break; - - case PROG_INIT: // initialise memory prog structure - logger(LOG_LEVEL_INFO,"Commande PROG INIT"); - gv_prog.indexCourrant=0; - for (int i=0;i MAX_MEM_PRG) - { - reponse = ERROR_PROG_INDEX_OUT_OF_BOUND; - } else if (gv_prog.indexCourrant==load_prg.index) - { - if (memcmp(load_prg.mem1,load_prg.mem2,MAX_MEM_PRG_LOAD)==0) - { - memcpy(&gv_prog.memory[gv_prog.indexCourrant],load_prg.mem1, MAX_MEM_PRG_LOAD); - gv_prog.indexCourrant += MAX_MEM_PRG_LOAD; - - t_field response; - response.field_id = PROG_INDEX; - response.size = sizeof(t_configuration_spino); - memcpy(resp.parameter, &gv_spinoConfig, sizeof(t_configuration_spino)); - resp.size = SIZE_HEADER_FIELD+response.size; - } - else - { - reponse = ERROR_PROG_MEM1_MEM2_NOT_EQUAL; - - } - - } else - { - reponse = ERROR_PROG_INDEX_NOT_EQUAL; - } - break; - case PROG_CHECK: - logger(LOG_LEVEL_INFO,"Commande PROG CHECK"); - reponse = ERROR_COMMAND_NOT_IMPLEMENTED; - resp.size =0; - break; - case PROG_SET_ADDRESS: - logger(LOG_LEVEL_INFO,"Commande SET ADRESS"); - logger(LOG_LEVEL_CRITICAL,gvLogMsg); - reponse = ERROR_COMMAND_NOT_IMPLEMENTED; - resp.size =0; - break; - case GET_LAST_DROPED_MESSAGE : - - logger(LOG_LEVEL_CRITICAL,"Commande GET_LAST_DROPED_MESSAGE"); - reponse = getLastDroppedMessage(&resp); - break; - case GET_ALL_DROPED_MESSAGE : - logger(LOG_LEVEL_INFO,"Commande GET_ALL_DROPED_MESSAGE"); - reponse = getAllDroppedMessage(&resp); - break; - case GET_LAST_LOG : - - logger(LOG_LEVEL_CRITICAL,"Commande GET_LAST_LOG"); - reponse = getLastLog(&resp); - - break; - case GET_ALL_LOG : - logger(LOG_LEVEL_INFO,"Commande GET_ALL_LOG"); - reponse = getAllLogs(&resp); - break; - - case SET_INFO_MESSAGE : - logger(LOG_LEVEL_INFO,"Commande SET_INFO_MESSAGE"); - reponse = setInfoMessage(cmd.parameter,&resp); - break ; - case DEL_INFO_MESSAGE: - logger(LOG_LEVEL_INFO,"Commande DEL_INFO_MESSAGE"); - reponse = delInfoMessage(cmd.parameter[0],&resp); - break; - - default: - // generation code erreur - logger(LOG_LEVEL_CRITICAL,"erreur cmd %d "); - reponse = ERROR_COMMAND_UNKNOW; - resp.size =0; - - break; - } - - - if (reponse != SUCCESS) - { - resp.header.error_code = reponse; - logger(LOG_LEVEL_INFO,"ERREUR COMMAND"); - } - else - { - resp.header.error_code = SUCCESS; - } - return resp; +t_tc_response interpretcommand(s_command cmd) { + + t_tc_response resp; + unsigned char reponse = SUCCESS; + + resp.header.responseType = RESULT_CMD; + resp.header.timeStamp = gv_spino.timestamps; + resp.header.cmd_id = cmd.id; + + switch (cmd.id) { + case CMD_RESET: + logger(LOG_LEVEL_INFO, "Commande RESET"); + reponse = reset(); + break; + case SET_VALUE: /* modify configuration value */ + logger(LOG_LEVEL_INFO, "Commande SET VALUE"); + s_set_value setvalue; + memcpy(&setvalue, cmd.parameter, cmd.size); + reponse = setValue(setvalue, &resp); + break; + + case SET_STATE: /*modify mode */ + logger(LOG_LEVEL_INFO, "Commande SET STATE"); + if (cmd.size == 1) { + // gv_spino.currentState = cmd.parameter[0]; + reponse = changeState((int) cmd.parameter[0]); + + } + resp.size = 0; + break; + + case GET_VALUE: // return value of field + + logger(LOG_LEVEL_INFO, "Commande GET VALUE"); + s_get_value getvalue; + memcpy(&getvalue, cmd.parameter, cmd.size); + reponse = getValue(getvalue, &resp); + break; + + case GET_CONGIG: // return Configuration structure + logger(LOG_LEVEL_INFO, "Commande GET CONFIG"); + resp.size = sizeof(s_configuration_spino); + memcpy(resp.parameter, &gv_spinoConfig, sizeof(s_configuration_spino)); + break; + + case PROG_INIT: // initialise memory prog structure + logger(LOG_LEVEL_INFO, "Commande PROG INIT"); + gv_prog.indexCourrant = 0; + for (int i = 0; i < MAX_MEM_PRG; i++) { + gv_prog.memory[i] = 0; + } + resp.size = 0; + break; + + case PROG_LOAD: + logger(LOG_LEVEL_INFO, "Commande PROG LOAD"); + s_load_prg load_prg; + memcpy(&load_prg, cmd.parameter, sizeof(s_load_prg)); + // check index + if (load_prg.index + MAX_MEM_PRG_LOAD > MAX_MEM_PRG) { + reponse = ERROR_PROG_INDEX_OUT_OF_BOUND; + } else if (gv_prog.indexCourrant == load_prg.index) { + if (memcmp(load_prg.mem1, load_prg.mem2, MAX_MEM_PRG_LOAD) == 0) { + memcpy(&gv_prog.memory[gv_prog.indexCourrant], load_prg.mem1, + MAX_MEM_PRG_LOAD); + gv_prog.indexCourrant += MAX_MEM_PRG_LOAD; + + s_field response; + response.field_id = PROG_INDEX; + response.size = sizeof(s_configuration_spino); + memcpy(resp.parameter, &gv_spinoConfig, + sizeof(s_configuration_spino)); + resp.size = SIZE_HEADER_FIELD + response.size; + } else { + reponse = ERROR_PROG_MEM1_MEM2_NOT_EQUAL; + + } + + } else { + reponse = ERROR_PROG_INDEX_NOT_EQUAL; + } + break; + case PROG_CHECK: + logger(LOG_LEVEL_INFO, "Commande PROG CHECK"); + reponse = ERROR_COMMAND_NOT_IMPLEMENTED; + resp.size = 0; + break; + case PROG_SET_ADDRESS: + logger(LOG_LEVEL_INFO, "Commande SET ADRESS"); + logger(LOG_LEVEL_CRITICAL, gvLogMsg); + reponse = ERROR_COMMAND_NOT_IMPLEMENTED; + resp.size = 0; + break; + case GET_LAST_DROPED_MESSAGE: + + logger(LOG_LEVEL_CRITICAL, "Commande GET_LAST_DROPED_MESSAGE"); + reponse = getLastDroppedMessage(&resp); + break; + case GET_ALL_DROPED_MESSAGE: + logger(LOG_LEVEL_INFO, "Commande GET_ALL_DROPED_MESSAGE"); + reponse = getAllDroppedMessage(&resp); + break; + case GET_LAST_LOG: + + logger(LOG_LEVEL_CRITICAL, "Commande GET_LAST_LOG"); + reponse = getLastLog(&resp); + + break; + case GET_ALL_LOG: + logger(LOG_LEVEL_INFO, "Commande GET_ALL_LOG"); + reponse = getAllLogs(&resp); + break; + + case SET_INFO_MESSAGE: + logger(LOG_LEVEL_INFO, "Commande SET_INFO_MESSAGE"); + reponse = setInfoMessage(cmd.parameter, &resp); + break; + case DEL_INFO_MESSAGE: + logger(LOG_LEVEL_INFO, "Commande DEL_INFO_MESSAGE"); + reponse = delInfoMessage(cmd.parameter[0], &resp); + break; + + default: + // generation code erreur + logger(LOG_LEVEL_CRITICAL, "erreur cmd %d "); + reponse = ERROR_COMMAND_UNKNOW; + resp.size = 0; + + break; + } + + if (reponse != SUCCESS) { + resp.header.error_code = reponse; + logger(LOG_LEVEL_INFO, "ERREUR COMMAND"); + } else { + resp.header.error_code = SUCCESS; + } + return resp; } /** @@ -366,37 +347,33 @@ t_tc_response interpretcommand(t_command cmd) { * \return SUCCESS if or Error code * */ -void processCommand(t_ax25_packet data_ax25) { - - t_tc_response result ; - t_command cmd; - - - gv_spino.nbCommandeReceived++; - memcpy(&cmd,data_ax25.data,sizeof(t_command)); - if(cmd.key != gv_spino_cmd_key) - { - result.header.responseType = RESULT_CMD; - result.header.timeStamp=gv_spino.timestamps; - result.header.cmd_id = cmd.id; - result.header.error_code = ERROR_COMMAND_WITH_WRONG_KEY; - result.size=0; - } else - { - result = interpretcommand( cmd); - } - - if(result.header.error_code !=SUCCESS) - { - gv_spino.nbCommandeWithError++; - } - t_ax25_packet ax25Frame; - ax25Frame.header = gv_headerTlm; - memcpy( ax25Frame.data,&result,TC_REPONSE_HEADER_SIZE+result.size); - /* envoyer la reponse de la commande */ - writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+result.size); - sprintf(gvLogMsg,"RESULT COMMAND %x %x ",result.header.cmd_id,result.header.error_code); - logger(LOG_LEVEL_CRITICAL,gvLogMsg); +void processCommand(s_ax25_packet data_ax25) { + + t_tc_response result; + s_command cmd; + + gv_spino.nbCommandeReceived++; + memcpy(&cmd, data_ax25.data, sizeof(s_command)); + if (cmd.key != gv_spino_cmd_key) { + result.header.responseType = RESULT_CMD; + result.header.timeStamp = gv_spino.timestamps; + result.header.cmd_id = cmd.id; + result.header.error_code = ERROR_COMMAND_WITH_WRONG_KEY; + result.size = 0; + } else { + result = interpretcommand(cmd); + } + + if (result.header.error_code != SUCCESS) { + gv_spino.nbCommandeWithError++; + } + s_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + memcpy(ax25Frame.data, &result, TC_REPONSE_HEADER_SIZE + result.size); + /* envoyer la reponse de la commande */ + writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + result.size); + sprintf(gvLogMsg, "RESULT COMMAND %x %x ", result.header.cmd_id, + result.header.error_code); + logger(LOG_LEVEL_CRITICAL, gvLogMsg); } - diff --git a/EmbededSw/src/core/command.h b/EmbededSw/src/core/command.h index a7e0a3d..a08b9be 100644 --- a/EmbededSw/src/core/command.h +++ b/EmbededSw/src/core/command.h @@ -1,12 +1,10 @@ - #ifndef COMMAND_H #define COMMAND_H - #define PARAMETER_SIZE 256 /*!< Max size of command parameter. */ #define FIELD_SIZE 32 /*!< Max size of field parameter. */ -/* define type of response */ +/* define type of response */ #define RESULT_CMD 128 /*!< response type : Result from command received by SPINO */ #define TELEMETRY 64 /*!< response type : SPINO Telemetry */ @@ -14,7 +12,7 @@ #define RESULT_DROP_MESSAGE 32 /*!< response type : Drop message */ #define EXPEBEACON 16 /*!< response type : Drop message */ -/* COMMAND LIST */ +/* COMMAND LIST */ #define CMD_RESET 100 #define SET_VALUE 101 #define GET_VALUE 102 @@ -34,11 +32,7 @@ #define PROG_CHECK 66 #define PROG_SET_ADDRESS 67 - - - - -/* SET GET VALUE */ +/* SET GET VALUE */ #define VALUE_SPINO_VERSION 128 #define VALUE_SPINO_DELAY 1 @@ -50,133 +44,71 @@ #define VALUE_ACTIVE_INFO_MESSAGE 7 #define VALUE_DELAY_INFO_MESSAGE 8 - - #define PROG_INDEX 4 +typedef struct tm_tc_header { + unsigned long long timeStamp; + unsigned int spare; + unsigned char responseType; + unsigned char error_code; + unsigned short cmd_id; +} s_tm_tc_header; +#define TC_REPONSE_HEADER_SIZE sizeof(s_tm_tc_header) + 2 // taille de la partie fixe + 2 pour taille de la size +typedef struct tc_response { -typedef struct tm_tc_header { - unsigned long long timeStamp; - unsigned int spare; - unsigned char responseType; - unsigned char error_code; - unsigned short cmd_id; -} t_tm_tc_header; - -#define TC_REPONSE_HEADER_SIZE sizeof(t_tm_tc_header) + 2 // taille de la partie fixe + 2 pour taille de la size -typedef struct tc_response { - - t_tm_tc_header header; - unsigned short size; - char parameter [PARAMETER_SIZE]; + s_tm_tc_header header; + unsigned short size; + char parameter[PARAMETER_SIZE]; } t_tc_response; - #define SIZE_HEADER_FIELD 2 -typedef struct field -{ - unsigned char field_id; - unsigned char size; - unsigned char field_value [FIELD_SIZE]; - -}t_field; - - -/* - -typedef struct tc_response_with_value { - t_tm_tc_header header; - char cmdID; - char error_code; - char size; - char value_id; - char parameter [PARAMETER_SIZE]; -} t_tc_response_with_value; - -*/ - +typedef struct field { + unsigned char field_id; + unsigned char size; + unsigned char field_value[FIELD_SIZE]; +} s_field; +typedef struct command { + unsigned short key; /* clé */ + unsigned short id; /* command ID */ + unsigned short size; /* parameter size */ + char parameter[PARAMETER_SIZE]; +} s_command; -/* typedef struct rep_header { - unsigned short id; - unsigned short cmd_id; - unsigned short error_code; - unsigned char size; -} t_res_header; */ +typedef struct set_value { + unsigned char fied_id; + unsigned char size; + char value[FIELD_SIZE]; +} s_set_value; +typedef struct get_value { + unsigned char field_id; + unsigned char size; - -typedef struct command { - unsigned short key; /* clé */ - unsigned short id; /* command ID */ - unsigned short size ; /* parameter size */ - char parameter[PARAMETER_SIZE]; - } t_command; - - -/* -typedef struct command_resp { - t_res_header header; - unsigned char parameter[PARAMETER_SIZE]; -} t_command_resp; - -*/ - - - -typedef struct set_value -{ - unsigned char fied_id; - unsigned char size; - char value[FIELD_SIZE]; - -}t_set_value; - - -typedef struct get_value -{ - unsigned char field_id; - unsigned char size; - -}t_get_value; - - - - -/* -union u_command -{ - char data[PARAMETER_SIZE]; - t_command command; -} ; - -*/ +} s_get_value; #define MAX_MEM_PRG 4096 -typedef struct prog_mngt -{ - long indexCourrant; - char *memory; -} t_prog_mngt; - +typedef struct prog_mngt { + long indexCourrant; + char *memory; +} s_prog_mngt; #define MAX_MEM_PRG_LOAD 64 -typedef struct load_prog -{ - long index; - char mem1[MAX_MEM_PRG_LOAD]; - char mem2[MAX_MEM_PRG_LOAD]; -} t_load_prg; +typedef struct load_prog { + long index; + char mem1[MAX_MEM_PRG_LOAD]; + char mem2[MAX_MEM_PRG_LOAD]; +} s_load_prg; -extern t_tc_response interpretcommand( t_command cmd); -extern void processCommand(t_ax25_packet data_ax25); -extern void processDropMessage (char* data_ax25, int size); +extern t_tc_response interpretcommand(s_command cmd); +extern void processCommand(s_ax25_packet data_ax25); +extern void processDropMessage(char *data_ax25, unsigned short size); #endif // COMMAND_H diff --git a/EmbededSw/src/core/configuration.h b/EmbededSw/src/core/configuration.h index fc94130..e0b8a67 100644 --- a/EmbededSw/src/core/configuration.h +++ b/EmbededSw/src/core/configuration.h @@ -1,13 +1,11 @@ - #ifndef CONFIGURATION_H #define CONFIGURATION_H - #include "../ax25/ax25.h" /* -* Define Spino configuration -*/ + * Define Spino configuration + */ #define SSID_SPINO_TMTC 15 #define SSID_SPINO_DIGIPEATER 3 @@ -15,42 +13,35 @@ #define SSID_SPINO_CUBESAT 4 #define SSID_SPINO_EXPERIMENTAL 5 - #define RESET_CAUSE_STATE_UNKNOWN 1 - -typedef struct configuration -{ - - long spinoTxFrequency; - long spinoRxFrequency; - unsigned short spinoTxModemSpeed; - unsigned short spinoRxModemSpeed; - unsigned char spinoRXModemMode; - unsigned char spinoTXModemMode; - unsigned char telemetryDelay; /* delay in seconde */ - unsigned char spare; /* delay in seconde */ - unsigned char info_message_actif; - unsigned char delay_info_message; - char spinoSrcCallsign [CALLSIGN_SIZE]; - char spinoDesCallsign [CALLSIGN_SIZE]; - char payloadCallsign [CALLSIGN_SIZE]; -} t_configuration_spino; - - - -typedef struct globalVariable -{ - - unsigned long nbCommandeReceived; - unsigned long nbCommandeWithError; - unsigned long nbFrameNotprocessed; - unsigned long nbDigipeaterMesssageProcessed; - unsigned long long timestamps; - unsigned short lastResetCause; - unsigned short currentState; -} t_globalVariable; - +typedef struct configuration { + + long spinoTxFrequency; + long spinoRxFrequency; + unsigned short spinoTxModemSpeed; + unsigned short spinoRxModemSpeed; + unsigned char spinoRXModemMode; + unsigned char spinoTXModemMode; + unsigned char telemetryDelay; /* delay in seconde */ + unsigned char spare; /* delay in seconde */ + unsigned char info_message_actif; + unsigned char delay_info_message; + unsigned char spinoSrcCallsign[CALLSIGN_SIZE]; + unsigned char spinoDesCallsign[CALLSIGN_SIZE]; + unsigned char payloadCallsign[CALLSIGN_SIZE]; +} s_configuration_spino; + +typedef struct globalVariable { + + unsigned long nbCommandeReceived; + unsigned long nbCommandeWithError; + unsigned long nbFrameNotprocessed; + unsigned long nbDigipeaterMesssageProcessed; + unsigned long long timestamps; + unsigned short lastResetCause; + unsigned short currentState; +} s_globalVariable; #endif // CONFIGURATION_H diff --git a/EmbededSw/src/core/control.c b/EmbededSw/src/core/control.c index 5b80020..5d4bd28 100644 --- a/EmbededSw/src/core/control.c +++ b/EmbededSw/src/core/control.c @@ -1,3 +1,12 @@ +/** + * \file control.c + * \brief manage spino mode + * \author Xtophe + * \version 0.2 + * \date 01/08/2022 + * + */ + #include #include #include "setup.h" @@ -6,173 +15,150 @@ #include "informationMessage.h" #include "control.h" -#define SLEEP_TIME 500 +#define SLEEP_TIME 500 /* sleep time */ extern unsigned short survey(); extern unsigned short digipeater(); -extern unsigned short modeMailbox (); +extern unsigned short modeMailbox(); extern unsigned short payloadMode(); extern unsigned short experimentalMode(); +extern void initExpe(); -extern initExpe(); - -unsigned long long lv_spino_timeStampPrevious=0; -t_tc_response resptlm; +unsigned long long lv_spino_timeStampPrevious = 0; +t_tc_response resptlm; -void inittlm() -{ - resptlm.header.responseType = TELEMETRY; - resptlm.header.error_code = 0; - resptlm.header.cmd_id =0; - resptlm.size = sizeof(t_globalVariable); +static void inittlm() { + resptlm.header.responseType = TELEMETRY; + resptlm.header.error_code = 0; + resptlm.header.cmd_id = 0; + resptlm.size = sizeof(s_globalVariable); } -void sendTLM() -{ - if( gv_spino.timestamps > (lv_spino_timeStampPrevious + gv_spinoConfig.telemetryDelay*1000)) - { - t_ax25_packet ax25Frame; - lv_spino_timeStampPrevious = gv_spino.timestamps; - resptlm.header.timeStamp = gv_spino.timestamps; - memcpy(resptlm.parameter, &gv_spino, sizeof(t_globalVariable)); - ax25Frame.header = gv_headerTlm; - memcpy( ax25Frame.data,&resptlm,TC_REPONSE_HEADER_SIZE+resptlm.size); - writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resptlm.size); - logger(LOG_LEVEL_INFO,"Envoie TLM"); - } +static void sendTLM() { + if (gv_spino.timestamps + > (lv_spino_timeStampPrevious + gv_spinoConfig.telemetryDelay * 1000)) { + s_ax25_packet ax25Frame; + lv_spino_timeStampPrevious = gv_spino.timestamps; + resptlm.header.timeStamp = gv_spino.timestamps; + memcpy(resptlm.parameter, &gv_spino, sizeof(s_globalVariable)); + ax25Frame.header = gv_headerTlm; + memcpy(ax25Frame.data, &resptlm, TC_REPONSE_HEADER_SIZE + resptlm.size); + writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + resptlm.size); + logger(LOG_LEVEL_INFO, "Envoie TLM"); + } } +unsigned char changeState(int state) { + + unsigned char response = SUCCESS; + + switch (state) { + + case STATE_INIT: + gv_spino.currentState = STATE_INIT; + break; + case STATE_SURVEY: + gv_spino.currentState = STATE_SURVEY; + break; + + case STATE_DIGIPEATER: + if (gv_spino.currentState == STATE_SURVEY) { + gv_spino.currentState = STATE_DIGIPEATER; + } else { + logger(LOG_LEVEL_CRITICAL, "ERROR_WRONG_STATE"); + response = ERROR_WRONG_STATE; + } + break; + + case STATE_MAILBOX: + if (gv_spino.currentState == STATE_SURVEY) { + gv_spino.currentState = STATE_MAILBOX; + } else { + logger(LOG_LEVEL_CRITICAL, "ERROR_WRONG_STATE"); + response = ERROR_WRONG_STATE; + } + break; + + case STATE_EXPE_DATA: + if (gv_spino.currentState == STATE_SURVEY) { + gv_spino.currentState = STATE_EXPE_DATA; + initExpe(); + } else { + logger(LOG_LEVEL_CRITICAL, "ERROR_WRONG_STATE"); + response = ERROR_WRONG_STATE; + } + break; + + case STATE_MAIN_PAYLOAD: + if (gv_spino.currentState == STATE_SURVEY) { + gv_spino.currentState = STATE_MAIN_PAYLOAD; + } else { + logger(LOG_LEVEL_CRITICAL, "ERROR_WRONG_STATE"); + response = ERROR_WRONG_STATE; + } + break; + + default: + /* remplacer par reinit */ + + logger(LOG_LEVEL_CRITICAL, "ERROR_WRONG_STATE"); + response = ERROR_WRONG_STATE; + break; + } + + return response; +} -int changeState (short state) - { - - int response = SUCCESS; - - switch (state) - { - - case (int) STATE_INIT: - gv_spino.currentState=STATE_INIT; - break; - case (int) STATE_SURVEY : - gv_spino.currentState = STATE_SURVEY; - break; - - case (int) STATE_DIGIPEATER : - if(gv_spino.currentState==STATE_SURVEY) - { - gv_spino.currentState = STATE_DIGIPEATER; - } - else - { - logger(LOG_LEVEL_CRITICAL,"ERROR_WRONG_STATE"); - response = ERROR_WRONG_STATE; - } - break; - - case (int) STATE_MAILBOX : - if(gv_spino.currentState==STATE_SURVEY) - { - gv_spino.currentState = STATE_MAILBOX; - } - else - { - logger(LOG_LEVEL_CRITICAL,"ERROR_WRONG_STATE"); - response = ERROR_WRONG_STATE; - } - break; - - case (int) STATE_EXPE_DATA: - if(gv_spino.currentState==STATE_SURVEY) - { - gv_spino.currentState = STATE_EXPE_DATA; - initExpe(); - } - else - { - logger(LOG_LEVEL_CRITICAL,"ERROR_WRONG_STATE"); - response = ERROR_WRONG_STATE; - } - break; - - case (int) STATE_MAIN_PAYLOAD: - if(gv_spino.currentState==STATE_SURVEY) - { - gv_spino.currentState = STATE_MAIN_PAYLOAD; - } - else - { - logger(LOG_LEVEL_CRITICAL,"ERROR_WRONG_STATE"); - response = ERROR_WRONG_STATE; - } - break; - - default: - /* remplacer par reinit */ - - logger(LOG_LEVEL_CRITICAL,"ERROR_WRONG_STATE"); - response = ERROR_WRONG_STATE; - break; - } - - return response; - } - - -void control() -{ - inittlm(); - - while (1) - { - switch (gv_spino.currentState) - { - - case STATE_INIT: - - logger(LOG_LEVEL_INFO,"STATE INIT"); - setupGlobalVariable(); - break; - case STATE_SURVEY : - logger(LOG_LEVEL_INFO,"STATE SURVEY"); - gv_spino.currentState = survey(); - break; - - case STATE_DIGIPEATER : - logger(LOG_LEVEL_INFO,"STATE DIGIPEATER"); - gv_spino.currentState = digipeater(); - break; - - case STATE_MAILBOX : - - logger(LOG_LEVEL_INFO,"STATE MAILBOX"); - gv_spino.currentState = modeMailbox(); - break; - - case STATE_EXPE_DATA: - logger(LOG_LEVEL_INFO,"STATE EXPE"); - gv_spino.currentState = experimentalMode(); - break; - - case STATE_MAIN_PAYLOAD: - logger(LOG_LEVEL_INFO,"STATE_MAIN_PAYLOAD"); - gv_spino.currentState = payloadMode(); - break; - - default: - /* remplacer par reinit */ - sprintf(gvLogMsg,"State default %d \r\n",gv_spino.currentState); - logger(LOG_LEVEL_CRITICAL,"STATE DEFAULT"); - gv_spino.currentState = STATE_INIT; - gv_spino.lastResetCause = RESET_CAUSE_STATE_UNKNOWN; - break; - } - - Sleep(SLEEP_TIME); - gv_spino.timestamps= gv_spino.timestamps+SLEEP_TIME; - sendTLM(); - sendInfoMessage(); - } - +void control() { + inittlm(); + + while (1) { + switch (gv_spino.currentState) { + + case STATE_INIT: + + logger(LOG_LEVEL_INFO, "STATE INIT"); + setupGlobalVariable(); + break; + case STATE_SURVEY: + logger(LOG_LEVEL_INFO, "STATE SURVEY"); + gv_spino.currentState = survey(); + break; + + case STATE_DIGIPEATER: + logger(LOG_LEVEL_INFO, "STATE DIGIPEATER"); + gv_spino.currentState = digipeater(); + break; + + case STATE_MAILBOX: + + logger(LOG_LEVEL_INFO, "STATE MAILBOX"); + gv_spino.currentState = modeMailbox(); + break; + + case STATE_EXPE_DATA: + logger(LOG_LEVEL_INFO, "STATE EXPE"); + gv_spino.currentState = experimentalMode(); + break; + + case STATE_MAIN_PAYLOAD: + logger(LOG_LEVEL_INFO, "STATE_MAIN_PAYLOAD"); + gv_spino.currentState = payloadMode(); + break; + + default: + /* remplacer par reinit */ + sprintf(gvLogMsg, "State default %d \r\n", gv_spino.currentState); + logger(LOG_LEVEL_CRITICAL, "STATE DEFAULT"); + gv_spino.currentState = STATE_INIT; + gv_spino.lastResetCause = RESET_CAUSE_STATE_UNKNOWN; + break; + } + + Sleep(SLEEP_TIME); + gv_spino.timestamps = gv_spino.timestamps + SLEEP_TIME; + sendTLM(); + sendInfoMessage(); + } } diff --git a/EmbededSw/src/core/control.h b/EmbededSw/src/core/control.h index 5533124..88aadeb 100644 --- a/EmbededSw/src/core/control.h +++ b/EmbededSw/src/core/control.h @@ -1,10 +1,7 @@ - - #ifndef CONTROL_H #define CONTROL_H - #define STATE_INIT 0 #define STATE_SURVEY 1 #define STATE_MAILBOX 2 @@ -12,6 +9,6 @@ #define STATE_EXPE_DATA 4 #define STATE_MAIN_PAYLOAD 5 - -extern int changeState (short state) ; +extern unsigned char changeState(int state); +extern void control(); #endif // CONTROL_H diff --git a/EmbededSw/src/core/informationMessage.c b/EmbededSw/src/core/informationMessage.c index 8ae2f51..5177be0 100644 --- a/EmbededSw/src/core/informationMessage.c +++ b/EmbededSw/src/core/informationMessage.c @@ -16,10 +16,8 @@ s_inf_msg gv_information_msg[MAX_INF_MESSAGE]; -unsigned long long lv_spino_timeStampInfoMsgPrevious=0; -unsigned short lv_index_message_actif =0; - - +unsigned long long lv_spino_timeStampInfoMsgPrevious = 0; +unsigned char lv_index_message_actif = 0; /** * \fn void setupInfoMessage() @@ -27,181 +25,169 @@ unsigned short lv_index_message_actif =0; * \return void * */ - void setupInfoMessage() - { - int i=0; - int j=0; - for (i=0; i< MAX_INF_MESSAGE;i++) - { - gv_information_msg[i].used=INFO_MSG_NOT_USED; - for (j=0; j< MAX_SIZE_INF_MSG ;j++) +void setupInfoMessage() { + int i = 0; + int j = 0; + for (i = 0; i < MAX_INF_MESSAGE; i++) { + gv_information_msg[i].used = INFO_MSG_NOT_USED; + for (j = 0; j < MAX_SIZE_INF_MSG; j++) { + gv_information_msg[i].message[j] = 0; + } + + } +} + +/** + * \fn int setInfoMessage(char *data,t_tc_response *resp) + * \param information data in raw => to be set in s_add_inf_msg structure + * \param *resp output structure with result of command + * + * \brief add information message + * + * \return SUCCESS or ERROR_INFO_MSG_INDEX_OUT_OF_BOUND + * + */ +unsigned char setInfoMessage(char *data, t_tc_response *resp) { + + unsigned char reponse = SUCCESS; + int index; + s_add_inf_msg info_msg; + + memcpy(&info_msg, data, sizeof(s_add_inf_msg)); + index = info_msg.index; + logger(LOG_LEVEL_INFO, "SET INFO MESSAGE"); + + if (info_msg.index < MAX_INF_MESSAGE) { + gv_information_msg[index].message[0] = 0; + gv_information_msg[index].used = INFO_MSG_USED; + strncat(gv_information_msg[index].message, info_msg.message, + MAX_SIZE_INF_MSG); + + /* + gv_information_msg[index].used = INFO_MSG_USED; + if( strlen (info_msg.message)>=MAX_SIZE_INF_MSG ) + { + strncpy(gv_information_msg[index].message, info_msg.message, MAX_SIZE_INF_MSG); + } else { - gv_information_msg[i].message[j]=0; + strcpy(gv_information_msg[index].message, info_msg.message); } + */ + } else { + reponse = ERROR_INFO_MSG_INDEX_OUT_OF_BOUND; + } + + resp->size = 0; + return reponse; + +} + +/** + * \fn int delInfoMessage(char index ,t_tc_response *resp) + * \param index of message to remove + * \param *resp output structure with result of command + * + * \brief add information message + * + * \return SUCCESS or ERROR_INFO_MSG_INDEX_OUT_OF_BOUND or ERROR_INFO_MSG_ALREADY_NOT_USED + * + */ + +unsigned char delInfoMessage(char index, t_tc_response *resp) + +{ + unsigned char reponse = SUCCESS; + int ind = (int) index; + + if (index < MAX_INF_MESSAGE) { + if (gv_information_msg[ind].used == INFO_MSG_NOT_USED) { + reponse = ERROR_INFO_MSG_ALREADY_NOT_USED; + } + gv_information_msg[ind].used = (char) INFO_MSG_NOT_USED; + gv_information_msg[ind].message[0] = (char) 0; + + } else { + reponse = ERROR_INFO_MSG_INDEX_OUT_OF_BOUND; + } + resp->size = 0; + return reponse; +} + +/** + * \fn void sendInfoMessage() + * + * \brief Send information message when information mode is actif + * + * \return void + * + */ + +void sendInfoMessage() { + int find = 0; + int cpt = 0; + + if (gv_spinoConfig.info_message_actif == INFO_MSG_USED) { + + if (gv_spino.timestamps + > (lv_spino_timeStampInfoMsgPrevious + + gv_spinoConfig.delay_info_message * 1000)) { + + lv_spino_timeStampInfoMsgPrevious = gv_spino.timestamps; + + t_tc_response resp; + s_send_inf_msg infMsg; + + resp.header.responseType = INFORMATION_MSG; + resp.header.error_code = 0; + resp.header.cmd_id = 0; + resp.header.timeStamp = gv_spino.timestamps; + + // recherche message actif + while (find == 0) { + cpt++; - } - } - - /** - * \fn int setInfoMessage(char *data,t_tc_response *resp) - * \param information data in raw => to be set in s_add_inf_msg structure - * \param *resp output structure with result of command - * - * \brief add information message - * - * \return SUCCESS or ERROR_INFO_MSG_INDEX_OUT_OF_BOUND - * - */ - int setInfoMessage(char *data,t_tc_response *resp) - { - - int reponse = SUCCESS; - int index; - s_add_inf_msg info_msg; - - - memcpy(&info_msg,data, sizeof(s_add_inf_msg)); - index = info_msg.index; - logger(LOG_LEVEL_INFO,"SET INFO MESSAGE"); - - - if(info_msg.index < MAX_INF_MESSAGE) - { - gv_information_msg[index].message[0]=0; - gv_information_msg[index].used=INFO_MSG_USED; - strncat(gv_information_msg[index].message,info_msg.message,MAX_SIZE_INF_MSG); - - /* - gv_information_msg[index].used = INFO_MSG_USED; - if( strlen (info_msg.message)>=MAX_SIZE_INF_MSG ) - { - strncpy(gv_information_msg[index].message, info_msg.message, MAX_SIZE_INF_MSG); - } else - { - strcpy(gv_information_msg[index].message, info_msg.message); - } - */ - } else - { - reponse = ERROR_INFO_MSG_INDEX_OUT_OF_BOUND; - } - - resp->size=0; - return reponse; - - } - - /** - * \fn int delInfoMessage(char index ,t_tc_response *resp) - * \param index of message to remove - * \param *resp output structure with result of command - * - * \brief add information message - * - * \return SUCCESS or ERROR_INFO_MSG_INDEX_OUT_OF_BOUND or ERROR_INFO_MSG_ALREADY_NOT_USED - * - */ - - int delInfoMessage(char index ,t_tc_response *resp) - - { - int reponse = SUCCESS; - int ind = (int)index; - - if(index < MAX_INF_MESSAGE) - { - if(gv_information_msg[ind].used == INFO_MSG_NOT_USED) - { - reponse = ERROR_INFO_MSG_ALREADY_NOT_USED; - } - gv_information_msg[ind].used = (char)INFO_MSG_NOT_USED; - gv_information_msg[ind].message[0]=(char)0; - - } else - { - reponse = ERROR_INFO_MSG_INDEX_OUT_OF_BOUND; - } - resp->size=0; - return reponse; - } - - /** - * \fn void sendInfoMessage() - * - * \brief Send information message when information mode is actif - * - * \return void - * - */ - - void sendInfoMessage() - { - int find =0; - int cpt=0; - - if(gv_spinoConfig.info_message_actif== INFO_MSG_USED) - { - - - if( gv_spino.timestamps > (lv_spino_timeStampInfoMsgPrevious + gv_spinoConfig.delay_info_message*1000)) - { - - lv_spino_timeStampInfoMsgPrevious = gv_spino.timestamps; - - t_tc_response resp; - s_send_inf_msg infMsg; - - resp.header.responseType = INFORMATION_MSG; - resp.header.error_code = 0; - resp.header.cmd_id =0; - resp.header.timeStamp = gv_spino.timestamps; - - - // recherche message actif - while(find==0) - { - cpt++; - - if( gv_information_msg[lv_index_message_actif].used == INFO_MSG_USED) - { - - - find=1; - infMsg.index= lv_index_message_actif; - infMsg.used = gv_information_msg[lv_index_message_actif].used; - resp.size = strlen(gv_information_msg[lv_index_message_actif].message)+2; - infMsg.message[0]=0; - - strncat(infMsg.message , gv_information_msg[lv_index_message_actif].message,MAX_SIZE_INF_MSG); - - // strcpy(resp.parameter, gv_information_msg[lv_index_message_actif].message); - memcpy( resp.parameter,&infMsg,resp.size); - t_ax25_packet ax25Frame; - ax25Frame.header = gv_headerTlm; - memcpy( ax25Frame.data,&resp,TC_REPONSE_HEADER_SIZE+resp.size); - /* envoyer la reponse de la commande */ - writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp.size); + if (gv_information_msg[lv_index_message_actif].used + == INFO_MSG_USED) { - logger(LOG_LEVEL_INFO,"MSG INFO SENT"); + find = 1; + infMsg.index = lv_index_message_actif; + infMsg.used = + gv_information_msg[lv_index_message_actif].used; + resp.size = (unsigned short) strlen( + gv_information_msg[lv_index_message_actif].message) + + 2; + infMsg.message[0] = 0; - } - else if(cpt >MAX_INF_MESSAGE ) - { - find=1; - logger(LOG_LEVEL_CRITICAL,"NO MESSAGE INFO AVAILABLE"); - // stop information message transmission - gv_spinoConfig.info_message_actif = INFO_MSG_NOT_USED; + strncat(infMsg.message, + gv_information_msg[lv_index_message_actif].message, + MAX_SIZE_INF_MSG); - } - lv_index_message_actif = (lv_index_message_actif + 1) % MAX_INF_MESSAGE; + // strcpy(resp.parameter, gv_information_msg[lv_index_message_actif].message); + memcpy(resp.parameter, &infMsg, resp.size); + s_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + memcpy(ax25Frame.data, &resp, + TC_REPONSE_HEADER_SIZE + resp.size); + /* envoyer la reponse de la commande */ + writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + resp.size); + logger(LOG_LEVEL_INFO, "MSG INFO SENT"); - } + } else if (cpt > MAX_INF_MESSAGE) { + find = 1; + logger(LOG_LEVEL_CRITICAL, "NO MESSAGE INFO AVAILABLE"); + // stop information message transmission + gv_spinoConfig.info_message_actif = INFO_MSG_NOT_USED; - } - } // do Nothing + } + lv_index_message_actif = + (unsigned char) ((lv_index_message_actif + 1) + % MAX_INF_MESSAGE); + } + } + } // do Nothing - } +} diff --git a/EmbededSw/src/core/informationMessage.h b/EmbededSw/src/core/informationMessage.h index a53cb27..3f11f9e 100644 --- a/EmbededSw/src/core/informationMessage.h +++ b/EmbededSw/src/core/informationMessage.h @@ -9,28 +9,26 @@ #define INFO_MSG_NOT_USED 0 #define INFO_MSG_USED 1 - -typedef struct inf_msg{ +typedef struct inf_msg { char message[MAX_SIZE_INF_MSG]; - char used; + unsigned char used; } s_inf_msg; typedef struct add_inf_msg { - char index; + unsigned char index; char message[MAX_SIZE_INF_MSG]; -}s_add_inf_msg; +} s_add_inf_msg; typedef struct send_in_msg { - char index; - char used; + unsigned char index; + unsigned char used; char message[MAX_SIZE_INF_MSG]; -}s_send_inf_msg; - -extern int setInfoMessage(char *data,t_tc_response *resp); -extern int delInfoMessage(char index ,t_tc_response *resp); -extern void sendInfoMessage(); -extern void setupInfoMessage(); +} s_send_inf_msg; +extern unsigned char setInfoMessage(char *data, t_tc_response *resp); +extern unsigned char delInfoMessage(char index, t_tc_response *resp); +extern void sendInfoMessage(); +extern void setupInfoMessage(); #endif // INFORMATION_MESSAGE_H diff --git a/EmbededSw/src/core/setup.c b/EmbededSw/src/core/setup.c index bfbb537..b862c5b 100644 --- a/EmbededSw/src/core/setup.c +++ b/EmbededSw/src/core/setup.c @@ -24,11 +24,11 @@ extern void initExpe(); /*========= GLOBAL VARIABLES ===================================================================*/ -t_configuration_spino gv_spinoConfig; -t_globalVariable gv_spino; -t_ax25_header gv_headerTlm; -t_unprocessedmessageList gv_unprocess_messages; -t_prog_mngt gv_prog; +s_configuration_spino gv_spinoConfig; +s_globalVariable gv_spino; +s_ax25_header gv_headerTlm; +s_unprocessedmessageList gv_unprocess_messages; +s_prog_mngt gv_prog; char mem_prg[MAX_MEM_PRG]; unsigned short gv_version = (unsigned short) 0x0103; @@ -53,7 +53,6 @@ unsigned short gv_spino_cmd_key = SPINO_CMD_KEY; void setupGlobalVariable() { - setupInfoMessage(); initExpe(); diff --git a/EmbededSw/src/core/setup.h b/EmbededSw/src/core/setup.h index d1b3859..6f6cd28 100644 --- a/EmbededSw/src/core/setup.h +++ b/EmbededSw/src/core/setup.h @@ -1,25 +1,21 @@ - #ifndef SETUP_H #define SETUP_H - #include "configuration.h" #include "../ax25/ax25.h" #include "command.h" #include "../logMngt/log.h" - #define SPINO_CMD_KEY 0x0FF0 extern unsigned short gv_spino_cmd_key; - -extern t_configuration_spino gv_spinoConfig; -extern t_globalVariable gv_spino; -extern t_ax25_header gv_headerTlm; -extern unsigned short gv_version; -extern t_prog_mngt gv_prog; -extern char memory_reprog[]; -extern void setupGlobalVariable () ; +extern s_configuration_spino gv_spinoConfig; +extern s_globalVariable gv_spino; +extern s_ax25_header gv_headerTlm; +extern unsigned short gv_version; +extern s_prog_mngt gv_prog; +extern char memory_reprog[]; +extern void setupGlobalVariable(); #endif // SETUP_H diff --git a/EmbededSw/src/digipeaterMode/ModeDigipeater.c b/EmbededSw/src/digipeaterMode/ModeDigipeater.c index 7a36d93..182b021 100644 --- a/EmbededSw/src/digipeaterMode/ModeDigipeater.c +++ b/EmbededSw/src/digipeaterMode/ModeDigipeater.c @@ -7,65 +7,58 @@ * */ - #include #include #include "../core/setup.h" #include "../drivers/modem.h" #include "../errorMngt/error.h" - - /** * \fn unsigned short digipeater () * \brief manage DIGIPEATER mode * \return void * */ -unsigned short digipeater () -{ - char data[300]; - t_ax25_packet data_ax25; - - - int nbc = readData(data); +unsigned short digipeater() { + char data[300]; + s_ax25_packet data_ax25; + + int nbc = readData(data); + + if (nbc != 0) { + /* traitement des donnees recues */ + int res = convertDataToAx25(&data_ax25, data, nbc); + if (res != SUCCESS) { + logger(LOG_LEVEL_CRITICAL, "AX25 CONVESTION ISSUE"); + } + if (memcmp(gv_spinoConfig.spinoDesCallsign, + data_ax25.header.destinationAdress, 6) == 0) { - if (nbc !=0) - { - /* traitement des donnees recues */ - int res = convertDataToAx25 (&data_ax25, data, nbc ); - if (res != SUCCESS) - { - logger(LOG_LEVEL_CRITICAL, "AX25 CONVESTION ISSUE"); - } - if (memcmp(gv_spinoConfig.spinoDesCallsign,data_ax25.header.destinationAdress,6)==0) - { + if (data_ax25.header.ssidDestination + == (unsigned char) SSID_SPINO_TMTC) { + processCommand(data_ax25); + } else if (data_ax25.header.ssidDestination + == (unsigned char) SSID_SPINO_DIGIPEATER) { + // renvoie la trame + memcpy(data_ax25.header.destinationAdress, + data_ax25.header.sourceAdress, 6); + memcpy(data_ax25.header.sourceAdress, + gv_spinoConfig.spinoSrcCallsign, 6); + data_ax25.header.ssidSource = SSID_SPINO_DIGIPEATER; + data_ax25.header.ssidDestination = data_ax25.header.ssidSource; + encodeAX25Header(&data_ax25.header); + nbc = nbc - (int) sizeof(s_ax25_header); + writeData(data_ax25, nbc); + gv_spino.nbDigipeaterMesssageProcessed++; + } else { + logger(LOG_LEVEL_CRITICAL, "WRONG SSID"); + processDropMessage(data, (unsigned short) nbc); + } + } else { + // Message not awaited - message dropped + processDropMessage(data, (unsigned short) nbc); + } - if (data_ax25.header.ssidDestination == (unsigned char) SSID_SPINO_TMTC) - { - processCommand(data_ax25); - } else if ( data_ax25.header.ssidDestination == (unsigned char) SSID_SPINO_DIGIPEATER) - { - // renvoie la trame - memcpy( data_ax25.header.destinationAdress,data_ax25.header.sourceAdress,6); - memcpy(data_ax25.header.sourceAdress,gv_spinoConfig.spinoSrcCallsign,6); - data_ax25.header.ssidSource = SSID_SPINO_DIGIPEATER; - data_ax25.header.ssidDestination = data_ax25.header.ssidSource; - encodeAX25Header(&data_ax25.header); - nbc = nbc - sizeof(t_ax25_header); - writeData (data_ax25,nbc); - gv_spino.nbDigipeaterMesssageProcessed++; - } else - { - logger(LOG_LEVEL_CRITICAL, "WRONG SSID"); - processDropMessage (data,nbc); - } - } else - { - // Message not awaited - message dropped - processDropMessage (data,nbc); - } - - } - return gv_spino.currentState; + } + return gv_spino.currentState; } diff --git a/EmbededSw/src/drivers/modem.c b/EmbededSw/src/drivers/modem.c index c5d5440..5515015 100644 --- a/EmbededSw/src/drivers/modem.c +++ b/EmbededSw/src/drivers/modem.c @@ -8,72 +8,53 @@ * \todo To adapt with embeded target */ - #include #include "../ax25/ax25.h" #include "../drivers/modem.h" #include "../simulation/lefic.h" #include "../simulation/SpinoSimuServerTCP.h" - - int gv_simu_mode = SIMU_MODE_TCP; - - - -void open () -{ - if( gv_simu_mode == SIMU_MODE_FILE) - { - openfile("./header.bin"); - } - else if (gv_simu_mode == SIMU_MODE_TCP) - { - TCP_OpenAndWait (); - } +void open() { + if (gv_simu_mode == SIMU_MODE_FILE) { + openfile("./header.bin"); + } else if (gv_simu_mode == SIMU_MODE_TCP) { + TCP_OpenAndWait(); + } } -int readData (char *data ) -{ - int taille = 0; - - if( gv_simu_mode == SIMU_MODE_FILE) - { - taille = lectureData (data); - - } - else if (gv_simu_mode == SIMU_MODE_TCP) - { - PerformSelect(gv_AcceptSocket, gv_m_client_list, 1); - if (gv_simu_nb_data_received!=0) - { - printf("data received %d",gv_simu_nb_data_received ); - taille = gv_simu_nb_data_received; +int readData(char *data) { + int taille = 0; - memcpy (data,gv_simu_receiveddata,gv_simu_nb_data_received ); - data =(char *)gv_simu_receiveddata; - gv_simu_nb_data_received=0; - } - } + if (gv_simu_mode == SIMU_MODE_FILE) { + taille = lectureData(data); -return taille; + } else if (gv_simu_mode == SIMU_MODE_TCP) { + PerformSelect(gv_AcceptSocket, gv_m_client_list, 1); + if (gv_simu_nb_data_received != 0) { + printf("data received %d", gv_simu_nb_data_received); + taille = gv_simu_nb_data_received; -} + memcpy(data, gv_simu_receiveddata, + (size_t) gv_simu_nb_data_received); + data = (char*) gv_simu_receiveddata; + gv_simu_nb_data_received = 0; + } + } + return taille; +} -int writeData (const t_ax25_packet ax25Frame, const int length) { +int writeData(const s_ax25_packet ax25Frame, const int length) { - if( gv_simu_mode == SIMU_MODE_FILE) - { - writefiledata( ax25Frame,length ); - } - else if (gv_simu_mode == SIMU_MODE_TCP) - { - TCP_Send ((char*) &ax25Frame,length+sizeof(t_ax25_header)); - writefiledata( ax25Frame,length ); - } -return 0; + if (gv_simu_mode == SIMU_MODE_FILE) { + writefiledata(ax25Frame, length); + } else if (gv_simu_mode == SIMU_MODE_TCP) { + TCP_Send((char*) &ax25Frame, length + (int) sizeof(s_ax25_header)); + writefiledata(ax25Frame, length); + } + return 0; } diff --git a/EmbededSw/src/drivers/modem.h b/EmbededSw/src/drivers/modem.h index 5716c9b..c71968f 100644 --- a/EmbededSw/src/drivers/modem.h +++ b/EmbededSw/src/drivers/modem.h @@ -1,16 +1,13 @@ - #ifndef MODEM_H #define MODEM_H #include "../ax25/ax25.h" - #define SIMU_MODE_FILE 1 #define SIMU_MODE_TCP 2 - -extern int readData (char *data ); -extern int writeData ( t_ax25_packet ax25Frame, int length); +extern int readData(char *data); +extern int writeData(s_ax25_packet ax25Frame, int length); extern int gv_simu_mode; diff --git a/EmbededSw/src/dropMsgMngt/DropMessage.c b/EmbededSw/src/dropMsgMngt/DropMessage.c index dde962b..8b5d4c4 100644 --- a/EmbededSw/src/dropMsgMngt/DropMessage.c +++ b/EmbededSw/src/dropMsgMngt/DropMessage.c @@ -13,8 +13,7 @@ #include "../errorMngt/error.h" #include "DropMessage.h" -extern void writeData ( t_ax25_packet ax25Frame, int length); - +extern void writeData(s_ax25_packet ax25Frame, int length); /** * \fn void processDropMessage (char* data_ax25, int size) @@ -25,29 +24,32 @@ extern void writeData ( t_ax25_packet ax25Frame, int length); * \return void * */ -extern t_unprocessedmessageList gv_unprocess_messages; +extern s_unprocessedmessageList gv_unprocess_messages; + +void processDropMessage(char *data_ax25, unsigned short size) { + logger(LOG_LEVEL_CRITICAL, "MESSAGE DROPPED"); + gv_spino.nbFrameNotprocessed++; -void processDropMessage (char* data_ax25, int size) -{ - logger(LOG_LEVEL_CRITICAL,"MESSAGE DROPPED"); - gv_spino.nbFrameNotprocessed++; + gv_unprocess_messages.index = (gv_unprocess_messages.index + 1) + % MAX_UNPROCESSED_MESSAGE_LIST_SIZE; + gv_unprocess_messages.message[gv_unprocess_messages.index].timestamps = + gv_spino.timestamps; - gv_unprocess_messages.index = (gv_unprocess_messages.index+1) % MAX_UNPROCESSED_MESSAGE_LIST_SIZE; - gv_unprocess_messages.message[gv_unprocess_messages.index].timestamps = gv_spino.timestamps; + if (size > MAX_UNPROCESSED_MESSAGE_LENGHT) { + // trunck to MAX_MESSAGE_SIZE + gv_unprocess_messages.message[gv_unprocess_messages.index].size = + MAX_UNPROCESSED_MESSAGE_LENGHT; - if (size > MAX_UNPROCESSED_MESSAGE_LENGHT) - { - // trunck to MAX_MESSAGE_SIZE - gv_unprocess_messages.message[gv_unprocess_messages.index].size = MAX_UNPROCESSED_MESSAGE_LENGHT; + } else { - } else { - - gv_unprocess_messages.message[gv_unprocess_messages.index].size = size; - } + gv_unprocess_messages.message[gv_unprocess_messages.index].size = size; + } + + logger(LOG_LEVEL_CRITICAL, data_ax25); + memcpy(&gv_unprocess_messages.message[gv_unprocess_messages.index].data, + data_ax25, + gv_unprocess_messages.message[gv_unprocess_messages.index].size); - logger(LOG_LEVEL_CRITICAL,data_ax25); - memcpy(&gv_unprocess_messages.message[gv_unprocess_messages.index].data,data_ax25, gv_unprocess_messages.message[gv_unprocess_messages.index].size ); - } /** @@ -58,19 +60,20 @@ void processDropMessage (char* data_ax25, int size) * */ -int getLastDroppedMessage(t_tc_response *resp) -{ - - logger(LOG_LEVEL_CRITICAL," GET_LAST_DROPED_MESSAGE"); - int taille_message = gv_unprocess_messages.message[gv_unprocess_messages.index].size; - taille_message =taille_message+ SIZE_HEADER_DROP; - if (taille_message > MAX_DATA_SIZE ) - { - taille_message = MAX_DATA_SIZE; - } - memcpy(resp->parameter,&gv_unprocess_messages.message[gv_unprocess_messages.index], taille_message ); - resp->size = taille_message; - return SUCCESS; +unsigned char getLastDroppedMessage(t_tc_response *resp) { + + logger(LOG_LEVEL_CRITICAL, " GET_LAST_DROPED_MESSAGE"); + unsigned short taille_message = + gv_unprocess_messages.message[gv_unprocess_messages.index].size; + taille_message = taille_message + (unsigned short) SIZE_HEADER_DROP; + if (taille_message > MAX_DATA_SIZE) { + taille_message = MAX_DATA_SIZE; + } + memcpy(resp->parameter, + &gv_unprocess_messages.message[gv_unprocess_messages.index], + (size_t) taille_message); + resp->size = taille_message; + return SUCCESS; } @@ -84,32 +87,31 @@ int getLastDroppedMessage(t_tc_response *resp) * */ -int getAllDroppedMessage(t_tc_response *resp) -{ - t_ax25_packet ax25Frame; - ax25Frame.header = gv_headerTlm; - resp->header.error_code = SUCCESS; - - int taille_message; - int i=0; - - for (i=0; i < MAX_UNPROCESSED_MESSAGE_LIST_SIZE;i++) - { - - taille_message = gv_unprocess_messages.message[i].size; - taille_message =taille_message+ SIZE_HEADER_DROP; - if (taille_message > MAX_DATA_SIZE ) - { - taille_message = MAX_DATA_SIZE; - } - resp->size=taille_message; - memcpy(resp->parameter,&gv_unprocess_messages.message[i], taille_message ); - - memcpy( ax25Frame.data,resp,TC_REPONSE_HEADER_SIZE+resp->size); - /* envoyer la reponse de la commande */ - writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp->size); - } - resp->size=0; - return SUCCESS; +unsigned char getAllDroppedMessage(t_tc_response *resp) { + s_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + resp->header.error_code = SUCCESS; + + unsigned short taille_message; + int i = 0; + + for (i = 0; i < MAX_UNPROCESSED_MESSAGE_LIST_SIZE; i++) { + + taille_message = gv_unprocess_messages.message[i].size; + taille_message = taille_message + SIZE_HEADER_DROP; + if (taille_message > MAX_DATA_SIZE) { + taille_message = MAX_DATA_SIZE; + } + resp->size = taille_message; + memcpy(resp->parameter, &gv_unprocess_messages.message[i], + (size_t) taille_message); + + memcpy(ax25Frame.data, resp, + (size_t) (TC_REPONSE_HEADER_SIZE + resp->size)); + /* envoyer la reponse de la commande */ + writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + resp->size); + } + resp->size = 0; + return SUCCESS; } diff --git a/EmbededSw/src/dropMsgMngt/DropMessage.h b/EmbededSw/src/dropMsgMngt/DropMessage.h index ba8b2a8..702c2aa 100644 --- a/EmbededSw/src/dropMsgMngt/DropMessage.h +++ b/EmbededSw/src/dropMsgMngt/DropMessage.h @@ -1,29 +1,24 @@ - #ifndef DOPMESSAGE_H #define DOPMESSAGE_H - #define MAX_UNPROCESSED_MESSAGE_LENGHT 256 #define MAX_UNPROCESSED_MESSAGE_LIST_SIZE 5 #define SIZE_HEADER_DROP 8+2 /*taille de la structure hors data */ typedef struct unprocessedmessage { - unsigned long long timestamps; - unsigned short size; - char data[MAX_UNPROCESSED_MESSAGE_LENGHT]; -} t_unprocessedmessage; - - + unsigned long long timestamps; + unsigned short size; + char data[MAX_UNPROCESSED_MESSAGE_LENGHT]; +} s_unprocessedmessage; typedef struct unprocessedmessageList { - int index; - t_unprocessedmessage message[MAX_UNPROCESSED_MESSAGE_LIST_SIZE]; - -} t_unprocessedmessageList; + int index; + s_unprocessedmessage message[MAX_UNPROCESSED_MESSAGE_LIST_SIZE]; +} s_unprocessedmessageList; -extern void processDropMessage (char* data_ax25, int size); -extern int getLastDroppedMessage(t_tc_response *resp); -extern int getAllDroppedMessage(t_tc_response *resp); +extern void processDropMessage(char *data_ax25, unsigned short size); +extern unsigned char getLastDroppedMessage(t_tc_response *resp); +extern unsigned char getAllDroppedMessage(t_tc_response *resp); -#endif // DOPMESSAGE_H \ No newline at end of file +#endif // DOPMESSAGE_H diff --git a/EmbededSw/src/errorMngt/error.h b/EmbededSw/src/errorMngt/error.h index 49bdf14..f040ef4 100644 --- a/EmbededSw/src/errorMngt/error.h +++ b/EmbededSw/src/errorMngt/error.h @@ -1,9 +1,8 @@ #ifndef ERROR_H #define ERROR_H - /* #define ERROR 1 -*/ + */ #define SUCCESS 0 /* Command analysis */ @@ -15,16 +14,15 @@ #define ERROR_VALUE_FIELD_UNKNOW 101 - /* AX25 Error */ #define ERROR_AX25_EXCEED_MAX_LENGH 100 -/* PROG ERROR */ +/* PROG ERROR */ #define ERROR_PROG_INDEX_NOT_EQUAL 128 #define ERROR_PROG_MEM1_MEM2_NOT_EQUAL 129 #define ERROR_PROG_INDEX_OUT_OF_BOUND 130 -/* MAILBOX ERROR */ +/* MAILBOX ERROR */ #define ERROR_MAILBOX_FULL 10 #define ERROR_MAILBOX_NOT_FOUND 11 @@ -38,5 +36,4 @@ #define ERROR_TLE_WRONG_SIZE 140 - #endif // ERROR_H diff --git a/EmbededSw/src/experimentalMode/experimentalMode.c b/EmbededSw/src/experimentalMode/experimentalMode.c index 5a27a3f..ac3a76b 100644 --- a/EmbededSw/src/experimentalMode/experimentalMode.c +++ b/EmbededSw/src/experimentalMode/experimentalMode.c @@ -1,3 +1,11 @@ +/** + * \file experimentalMode.c + * \brief manage experimental mode + * \author Xtophe + * \version 0.2 + * \date 01/08/2022 + * + */ #include #include @@ -5,279 +13,222 @@ #include "../drivers/modem.h" #include "../mailboxMode/mailbox.h" #include "../errorMngt/error.h" +#include "experimentalMode.h" int gv_experiemntal_command_nb = 0; int gv_experiemntal_command_error_nb = 0; unsigned long long lv_spino_expe_timeStampPrevious; -#define SIZE_TLE 70 -#define CMD_LOAD_TLE_1 70 -#define CMD_LOAD_TLE_2 71 -#define CMD_DOWNLOAD_TLE 72 -#define CMD_DOWNLOAD_TLE_1 73 -#define CMD_DOWNLOAD_TLE_2 74 -#define CMD_EXP_ADD_DATA 75 -#define CMD_EXPE_GET_LIST 76 -#define CMD_EXPE_DELETTE_ALL 77 -#define CMD_EXPE_GET_ALL_DATA 78 -#define CMD_EXPE_INIT 79 -#define CMD_SET_EXPE_BEACON_DELAY 80 - -typedef struct tle -{ - char tleLine1[SIZE_TLE]; - char tleLine2[SIZE_TLE]; - -} s_tle; - -typedef struct experimental_beacon -{ - short id; - short delay; - char value[4]; - -} s_experimental_beacon; - -t_tc_response respexpBeacon; - - +t_tc_response respexpBeacon; s_tle gv_tle; s_experimental_beacon expBeacon; +void initExpe() { -void initExpe() -{ - - expBeacon.id=128; - expBeacon.delay=10; - expBeacon.value[0]='A'; - expBeacon.value[1]='B'; - expBeacon.value[2]='C'; - expBeacon.value[3]='D'; - respexpBeacon.header.responseType = EXPEBEACON; - respexpBeacon.header.error_code = 0; - respexpBeacon.header.cmd_id =0; - respexpBeacon.size = sizeof(s_experimental_beacon); - + expBeacon.id = 128; + expBeacon.delay = 10; + expBeacon.value[0] = 'A'; + expBeacon.value[1] = 'B'; + expBeacon.value[2] = 'C'; + expBeacon.value[3] = 'D'; + respexpBeacon.header.responseType = EXPEBEACON; + respexpBeacon.header.error_code = 0; + respexpBeacon.header.cmd_id = 0; + respexpBeacon.size = sizeof(s_experimental_beacon); } - -int expDownloadTLE(t_tc_response *resp) -{ - - t_ax25_packet ax25Frame; - ax25Frame.header = gv_headerTlm; - - int taille_message = SIZE_TLE; - resp->header.cmd_id = CMD_DOWNLOAD_TLE_1; - resp->parameter[0] = 0; - strncat(resp->parameter, gv_tle.tleLine1, SIZE_TLE); - resp->size = taille_message; - memcpy(ax25Frame.data, resp, TC_REPONSE_HEADER_SIZE + resp->size); - /* envoyer la reponse de la commande */ - writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + resp->size); - resp->header.cmd_id = CMD_DOWNLOAD_TLE_2; - resp->parameter[0] = 0; - strncat(resp->parameter, gv_tle.tleLine2, SIZE_TLE); - resp->size = taille_message; - memcpy(ax25Frame.data, resp, TC_REPONSE_HEADER_SIZE + resp->size); - /* envoyer la reponse de la commande */ - writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + resp->size); - - return SUCCESS; +static unsigned char expDownloadTLE(t_tc_response *resp) { + + s_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + + unsigned short taille_message = SIZE_TLE; + resp->header.cmd_id = CMD_DOWNLOAD_TLE_1; + resp->parameter[0] = 0; + strncat(resp->parameter, gv_tle.tleLine1, SIZE_TLE); + resp->size = taille_message; + memcpy(ax25Frame.data, resp, TC_REPONSE_HEADER_SIZE + resp->size); + /* envoyer la reponse de la commande */ + writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + resp->size); + resp->header.cmd_id = CMD_DOWNLOAD_TLE_2; + resp->parameter[0] = 0; + strncat(resp->parameter, gv_tle.tleLine2, SIZE_TLE); + resp->size = taille_message; + memcpy(ax25Frame.data, resp, TC_REPONSE_HEADER_SIZE + resp->size); + /* envoyer la reponse de la commande */ + writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + resp->size); + + return SUCCESS; } -t_tc_response interpretExperimentalCommmand(t_command cmd, char *callsign) -{ - - t_tc_response resp; - - resp.header.responseType = RESULT_CMD; - resp.header.timeStamp = gv_spino.timestamps; - resp.header.cmd_id = cmd.id; - resp.header.error_code = SUCCESS; - - switch (cmd.id) - { - - case CMD_EXPE_INIT: - logger(LOG_LEVEL_INFO, "Commande EXP RESET"); - resp.header.error_code = initialise(); - resp.size = 0; - break; - - case CMD_SET_EXPE_BEACON_DELAY: - logger(LOG_LEVEL_INFO, "Commande CMD_SET_EXPE_BEACON_DELAY"); - t_set_value setvalue; - memcpy(&setvalue, cmd.parameter, cmd.size); - expBeacon.delay = (unsigned short) setvalue.value[0]; - resp.header.error_code =SUCCESS; - resp.size = 0; - break; - - case CMD_LOAD_TLE_1: - logger(LOG_LEVEL_INFO, "Commande CMD_LOAD_TLE_1"); - if (cmd.size != SIZE_TLE) - { - logger(LOG_LEVEL_INFO, "Commande CMD_LOAD_TLE_1 SIZE OK"); - gv_tle.tleLine1[0] = 0; - strncat(gv_tle.tleLine1, cmd.parameter, SIZE_TLE); - } - else - { - resp.header.error_code = ERROR_TLE_WRONG_SIZE; - - } - resp.size = 0; - break; - case CMD_LOAD_TLE_2: - logger(LOG_LEVEL_INFO, "Commande CMD_LOAD_TLE_2"); - if (cmd.size != SIZE_TLE) - { - gv_tle.tleLine2[0] = 0; - strncat(gv_tle.tleLine2, cmd.parameter, SIZE_TLE); - } - else - { - resp.header.error_code = ERROR_TLE_WRONG_SIZE; - } - resp.size = 0; - break; - - case CMD_DOWNLOAD_TLE: - logger(LOG_LEVEL_INFO, "Commande CMD_DOWNLOAD_TLE"); - resp.header.error_code = expDownloadTLE(&resp); - resp.size = 0; - break; - case CMD_EXP_ADD_DATA: - logger(LOG_LEVEL_INFO, "Commande CMD_EXP_ADD_DATA"); - if (cmd.size > MAX_LENGHT_MESSAGE) - { - resp.header.error_code = ERROR_ADD_MSG_EXCED_SIZE; - } - else - { - char message[MAX_LENGHT_MESSAGE]; - memcpy(message, &cmd.parameter, cmd.size); - logger(LOG_LEVEL_INFO, message); - resp.header.error_code = addMessage(callsign, message, cmd.size); - } - resp.size = 0; - break; - case CMD_EXPE_GET_LIST: - logger(LOG_LEVEL_INFO, "Commande CMD_EXPE_GET_LIST"); - resp.header.error_code = getListMailbox(&resp); - break; - case CMD_EXPE_DELETTE_ALL: - logger(LOG_LEVEL_INFO, "Commande MAILBOX DELETE MAILBOX"); - resp.header.error_code = deleteMailBox(callsign, &resp); - resp.size = 0; - break; - case CMD_EXPE_GET_ALL_DATA: - resp.header.error_code = getAllMesage(callsign); - resp.size = 0; - break; - - default: - sprintf(gvLogMsg, "erreur Experimental cmd %d \r\n", cmd.id); - logger(LOG_LEVEL_CRITICAL, gvLogMsg); - resp.header.error_code = ERROR_COMMAND_UNKNOW; - resp.size = 0; - break; - } - return resp; +t_tc_response interpretExperimentalCommmand(s_command cmd, + unsigned char *callsign) { + + t_tc_response resp; + + resp.header.responseType = RESULT_CMD; + resp.header.timeStamp = gv_spino.timestamps; + resp.header.cmd_id = cmd.id; + resp.header.error_code = SUCCESS; + + switch (cmd.id) { + + case CMD_EXPE_INIT: + logger(LOG_LEVEL_INFO, "Commande EXP RESET"); + resp.header.error_code = initialise(); + resp.size = 0; + break; + + case CMD_SET_EXPE_BEACON_DELAY: + logger(LOG_LEVEL_INFO, "Commande CMD_SET_EXPE_BEACON_DELAY"); + s_set_value setvalue; + memcpy(&setvalue, cmd.parameter, cmd.size); + expBeacon.delay = (unsigned short) setvalue.value[0]; + resp.header.error_code = SUCCESS; + resp.size = 0; + break; + + case CMD_LOAD_TLE_1: + logger(LOG_LEVEL_INFO, "Commande CMD_LOAD_TLE_1"); + if (cmd.size != SIZE_TLE) { + logger(LOG_LEVEL_INFO, "Commande CMD_LOAD_TLE_1 SIZE OK"); + gv_tle.tleLine1[0] = 0; + strncat(gv_tle.tleLine1, cmd.parameter, SIZE_TLE); + } else { + resp.header.error_code = ERROR_TLE_WRONG_SIZE; + + } + resp.size = 0; + break; + case CMD_LOAD_TLE_2: + logger(LOG_LEVEL_INFO, "Commande CMD_LOAD_TLE_2"); + if (cmd.size != SIZE_TLE) { + gv_tle.tleLine2[0] = 0; + strncat(gv_tle.tleLine2, cmd.parameter, SIZE_TLE); + } else { + resp.header.error_code = ERROR_TLE_WRONG_SIZE; + } + resp.size = 0; + break; + + case CMD_DOWNLOAD_TLE: + logger(LOG_LEVEL_INFO, "Commande CMD_DOWNLOAD_TLE"); + resp.header.error_code = expDownloadTLE(&resp); + resp.size = 0; + break; + case CMD_EXP_ADD_DATA: + logger(LOG_LEVEL_INFO, "Commande CMD_EXP_ADD_DATA"); + if (cmd.size > MAX_LENGHT_MESSAGE) { + resp.header.error_code = ERROR_ADD_MSG_EXCED_SIZE; + } else { + char message[MAX_LENGHT_MESSAGE]; + memcpy(message, &cmd.parameter, cmd.size); + logger(LOG_LEVEL_INFO, message); + resp.header.error_code = addMessage(callsign, message, cmd.size); + } + resp.size = 0; + break; + case CMD_EXPE_GET_LIST: + logger(LOG_LEVEL_INFO, "Commande CMD_EXPE_GET_LIST"); + resp.header.error_code = getListMailbox(&resp); + break; + case CMD_EXPE_DELETTE_ALL: + logger(LOG_LEVEL_INFO, "Commande MAILBOX DELETE MAILBOX"); + resp.header.error_code = deleteMailBox(callsign, &resp); + resp.size = 0; + break; + case CMD_EXPE_GET_ALL_DATA: + resp.header.error_code = getAllMesage(callsign); + resp.size = 0; + break; + + default: + sprintf(gvLogMsg, "erreur Experimental cmd %d \r\n", cmd.id); + logger(LOG_LEVEL_CRITICAL, gvLogMsg); + resp.header.error_code = ERROR_COMMAND_UNKNOW; + resp.size = 0; + break; + } + return resp; } +void sendBeaconExpe() { + + if (gv_spino.timestamps + > (lv_spino_expe_timeStampPrevious + + (unsigned long long) (expBeacon.delay * 1000))) { + s_ax25_packet ax25Frame; + lv_spino_expe_timeStampPrevious = gv_spino.timestamps; + respexpBeacon.header.timeStamp = gv_spino.timestamps; + memcpy(respexpBeacon.parameter, &expBeacon, + sizeof(s_experimental_beacon)); + ax25Frame.header = gv_headerTlm; + memcpy(ax25Frame.data, &respexpBeacon, + TC_REPONSE_HEADER_SIZE + respexpBeacon.size); + writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + respexpBeacon.size); + logger(LOG_LEVEL_INFO, "Envoie TLM"); + } - void sendBeaconExpe() - { - - if( gv_spino.timestamps > (lv_spino_expe_timeStampPrevious + (expBeacon.delay *1000))) - { - t_ax25_packet ax25Frame; - lv_spino_expe_timeStampPrevious = gv_spino.timestamps; - respexpBeacon.header.timeStamp = gv_spino.timestamps; - memcpy(respexpBeacon.parameter, &expBeacon, sizeof(s_experimental_beacon)); - ax25Frame.header = gv_headerTlm; - memcpy( ax25Frame.data,&respexpBeacon,TC_REPONSE_HEADER_SIZE+respexpBeacon.size); - writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+respexpBeacon.size); - logger(LOG_LEVEL_INFO,"Envoie TLM"); - } - - - } - - -void processExperimental(t_ax25_packet data_ax25) -{ - - t_tc_response result; - t_command cmd; +} - gv_experiemntal_command_nb++; - memcpy(&cmd, data_ax25.data, sizeof(t_command)); - result = interpretExperimentalCommmand(cmd, data_ax25.header.sourceAdress); - if (result.header.error_code != SUCCESS) - { - gv_experiemntal_command_error_nb++; - } - t_ax25_packet ax25Frame; +static void processExperimental(s_ax25_packet data_ax25) { - ax25Frame.header = gv_headerTlm; - memcpy( ax25Frame.data,&result,TC_REPONSE_HEADER_SIZE+result.size); - /* envoyer la reponse de la commande */ - writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+result.size); - sprintf(gvLogMsg, "RESULT EXPE COMMAND %x %x ", result.header.cmd_id, result.header.error_code); - logger(LOG_LEVEL_CRITICAL, gvLogMsg); + t_tc_response result; + s_command cmd; + gv_experiemntal_command_nb++; + memcpy(&cmd, data_ax25.data, sizeof(s_command)); + result = interpretExperimentalCommmand(cmd, data_ax25.header.sourceAdress); + if (result.header.error_code != SUCCESS) { + gv_experiemntal_command_error_nb++; + } + s_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + memcpy(ax25Frame.data, &result, TC_REPONSE_HEADER_SIZE + result.size); + /* envoyer la reponse de la commande */ + writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + result.size); + sprintf(gvLogMsg, "RESULT EXPE COMMAND %x %x ", result.header.cmd_id, + result.header.error_code); + logger(LOG_LEVEL_CRITICAL, gvLogMsg); } -unsigned short experimentalMode() -{ - char data[300]; - t_ax25_packet data_ax25; - - - logger(LOG_LEVEL_CRITICAL, "EXPERIMENTAL MODE "); - int nbc = readData(data); - - if (nbc != 0) - { - /* traitement des donnees recues */ - int res = convertDataToAx25(&data_ax25, data, nbc); - if (res != SUCCESS) - { - logger(LOG_LEVEL_CRITICAL, "AX25 CONVESTION ISSUE"); - } - - if (memcmp(gv_spinoConfig.spinoDesCallsign, data_ax25.header.destinationAdress, 6) == 0) - { - if (data_ax25.header.ssidDestination == (unsigned char)SSID_SPINO_TMTC) - { - logger(LOG_LEVEL_CRITICAL, "TRT COMMANDE NORMAL"); - processCommand(data_ax25); - } - else if (data_ax25.header.ssidDestination == (unsigned char)SSID_SPINO_EXPERIMENTAL) - { - logger(LOG_LEVEL_CRITICAL, "TRT COMMANDE EXPE"); - processExperimental(data_ax25); - } - else - { - // Message not awaited - message dropped - processDropMessage(data, nbc); - } - } - else - { - processDropMessage(data, nbc); - } - } - - sendBeaconExpe(); - - return gv_spino.currentState; +unsigned short experimentalMode() { + char data[300]; + s_ax25_packet data_ax25; + + logger(LOG_LEVEL_CRITICAL, "EXPERIMENTAL MODE "); + int nbc = readData(data); + + if (nbc != 0) { + /* traitement des donnees recues */ + int res = convertDataToAx25(&data_ax25, data, nbc); + if (res != SUCCESS) { + logger(LOG_LEVEL_CRITICAL, "AX25 CONVESTION ISSUE"); + } + + if (memcmp(gv_spinoConfig.spinoDesCallsign, + data_ax25.header.destinationAdress, 6) == 0) { + if (data_ax25.header.ssidDestination + == (unsigned char) SSID_SPINO_TMTC) { + logger(LOG_LEVEL_CRITICAL, "TRT COMMANDE NORMAL"); + processCommand(data_ax25); + } else if (data_ax25.header.ssidDestination + == (unsigned char) SSID_SPINO_EXPERIMENTAL) { + logger(LOG_LEVEL_CRITICAL, "TRT COMMANDE EXPE"); + processExperimental(data_ax25); + } else { + // Message not awaited - message dropped + processDropMessage(data, (unsigned short) nbc); + } + } else { + processDropMessage(data, (unsigned short) nbc); + } + } + + sendBeaconExpe(); + + return gv_spino.currentState; } diff --git a/EmbededSw/src/experimentalMode/experimentalMode.h b/EmbededSw/src/experimentalMode/experimentalMode.h index e69de29..e71092e 100644 --- a/EmbededSw/src/experimentalMode/experimentalMode.h +++ b/EmbededSw/src/experimentalMode/experimentalMode.h @@ -0,0 +1,34 @@ +#ifndef EXPERIMENTAL_MODE_H +#define EXPERIMENTAL_MODE_H + +#define SIZE_TLE 70 +#define CMD_LOAD_TLE_1 70 +#define CMD_LOAD_TLE_2 71 +#define CMD_DOWNLOAD_TLE 72 +#define CMD_DOWNLOAD_TLE_1 73 +#define CMD_DOWNLOAD_TLE_2 74 +#define CMD_EXP_ADD_DATA 75 +#define CMD_EXPE_GET_LIST 76 +#define CMD_EXPE_DELETTE_ALL 77 +#define CMD_EXPE_GET_ALL_DATA 78 +#define CMD_EXPE_INIT 79 +#define CMD_SET_EXPE_BEACON_DELAY 80 + +typedef struct tle { + char tleLine1[SIZE_TLE]; + char tleLine2[SIZE_TLE]; + +} s_tle; + +typedef struct experimental_beacon { + short id; + short delay; + char value[4]; + +} s_experimental_beacon; + +extern void initExpe(); +extern void sendBeaconExpe(); +extern unsigned short experimentalMode(); + +#endif //EXPERIMENTAL_MODE_H diff --git a/EmbededSw/src/logMngt/log.c b/EmbededSw/src/logMngt/log.c index 7fd6db0..d56c867 100644 --- a/EmbededSw/src/logMngt/log.c +++ b/EmbededSw/src/logMngt/log.c @@ -1,17 +1,25 @@ +/** + * \file log.c + * \brief manage log + * \author Xtophe + * \version 0.2 + * \date 01/08/2022 + * + */ + #include #include #include "../core/setup.h" #include "../errorMngt/error.h" -extern void writeData ( t_ax25_packet ax25Frame, int length); +extern void writeData(s_ax25_packet ax25Frame, int length); - unsigned char gv_SelectedLogLevel=0; +unsigned char gv_SelectedLogLevel = 0; s_logs logs[MAX_LOG]; -int gvLogIndex =0; +int gvLogIndex = 0; char gvLogMsg[MAX_SIZE_MSG_LOG]; - /** * \fn void logger(char level, char *message) * \brief log message in log Table @@ -20,21 +28,18 @@ char gvLogMsg[MAX_SIZE_MSG_LOG]; * \return void * */ -void logger(char level, char *message) -{ - - if(level >= gv_SelectedLogLevel ) - { - gvLogIndex = (gvLogIndex+1)%MAX_LOG; - logs[gvLogIndex].priority=level; - logs[gvLogIndex].timeStamps=gv_spino.timestamps; - logs[gvLogIndex].log[0]=0; - strncat(logs[gvLogIndex].log,message,MAX_SIZE_MSG_LOG-1); - printf("LOG : "); - printf(message); - printf("\r\n"); - } - +void logger(char level, char *message) { + + if (level >= gv_SelectedLogLevel) { + gvLogIndex = (gvLogIndex + 1) % MAX_LOG; + logs[gvLogIndex].priority = level; + logs[gvLogIndex].timeStamps = gv_spino.timestamps; + logs[gvLogIndex].log[0] = 0; + strncat(logs[gvLogIndex].log, message, MAX_SIZE_MSG_LOG - 1); + printf("LOG : "); + printf(message); + printf("\r\n"); + } } @@ -48,15 +53,14 @@ void logger(char level, char *message) * */ -int getLastLog(t_tc_response *resp) -{ - - logger(LOG_LEVEL_CRITICAL," GET_LAST_LOG_MESSAGE"); - int taille_message = strlen(logs[gvLogIndex].log)+SIZE_S_LOG+1; // +1 pour inclure le 0 +unsigned char getLastLog(t_tc_response *resp) { - memcpy(resp->parameter,&logs[gvLogIndex], taille_message ); - resp->size = taille_message; - return SUCCESS; + logger(LOG_LEVEL_INFO, " GET_LAST_LOG_MESSAGE"); + unsigned short taille_message = (unsigned short) strlen( + logs[gvLogIndex].log) + SIZE_S_LOG + 1; // +1 pour inclure le 0 + memcpy(resp->parameter, &logs[gvLogIndex], taille_message); + resp->size = taille_message; + return SUCCESS; } @@ -70,26 +74,25 @@ int getLastLog(t_tc_response *resp) * */ -int getAllLogs(t_tc_response *resp) -{ - t_ax25_packet ax25Frame; - ax25Frame.header = gv_headerTlm; - resp->header.error_code = SUCCESS; - logger(LOG_LEVEL_CRITICAL," GET_ALL_LOG_MESSAGE"); - int i=0; - - for (i=0; i < MAX_LOG;i++) - { - - int taille_message = strlen(logs[i].log)+SIZE_S_LOG+1; // +1 pour inclure le 0 - memcpy(resp->parameter,&logs[i], taille_message ); - resp->size = taille_message; - memcpy( ax25Frame.data,resp,TC_REPONSE_HEADER_SIZE+resp->size); - /* envoyer la reponse de la commande */ - writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp->size); - } - /* return success of the command */ - resp->size= 0; - return SUCCESS; +unsigned char getAllLogs(t_tc_response *resp) { + s_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + resp->header.error_code = SUCCESS; + logger(LOG_LEVEL_CRITICAL, " GET_ALL_LOG_MESSAGE"); + int i = 0; + + for (i = 0; i < MAX_LOG; i++) { + + unsigned short taille_message = (unsigned short) strlen(logs[i].log) + + SIZE_S_LOG + 1; // +1 pour inclure le 0 + memcpy(resp->parameter, &logs[i], taille_message); + resp->size = taille_message; + memcpy(ax25Frame.data, resp, TC_REPONSE_HEADER_SIZE + resp->size); + /* envoyer la reponse de la commande */ + writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + resp->size); + } + /* return success of the command */ + resp->size = 0; + return SUCCESS; } diff --git a/EmbededSw/src/logMngt/log.h b/EmbededSw/src/logMngt/log.h index 3ab9a3a..0f42efb 100644 --- a/EmbededSw/src/logMngt/log.h +++ b/EmbededSw/src/logMngt/log.h @@ -1,8 +1,6 @@ - #ifndef LOG_H #define LOG_H - #define LOG_LEVEL_INFO 0 #define LOG_LEVEL_WARNING 1 #define LOG_LEVEL_CRITICAL 5 @@ -12,16 +10,16 @@ #define SIZE_S_LOG 8+1 typedef struct logs { - long long timeStamps; - char priority; - char log[MAX_SIZE_MSG_LOG]; + unsigned long long timeStamps; + char priority; + char log[MAX_SIZE_MSG_LOG]; } s_logs; -extern unsigned char gv_SelectedLogLevel; +extern unsigned char gv_SelectedLogLevel; extern void logger(char level, char *message); extern char gvLogMsg[MAX_SIZE_MSG_LOG]; -extern int getAllLogs(t_tc_response *resp); -extern int getLastLog(t_tc_response *resp); +extern unsigned char getAllLogs(t_tc_response *resp); +extern unsigned char getLastLog(t_tc_response *resp); #endif // LOG_H diff --git a/EmbededSw/src/mailboxMode/mailbox.c b/EmbededSw/src/mailboxMode/mailbox.c index 6e99ea4..4579bfe 100644 --- a/EmbededSw/src/mailboxMode/mailbox.c +++ b/EmbededSw/src/mailboxMode/mailbox.c @@ -11,12 +11,11 @@ #include #include "../core/setup.h" #include "../drivers/modem.h" -#include "../mailboxMode/mailbox.h" +#include "mailbox.h" #include "../errorMngt/error.h" #include "../ax25/ax25.h" -t_mailboxes gvMailboxes; - +s_mailboxes gvMailboxes; /** * \fn int initialise() @@ -26,41 +25,35 @@ t_mailboxes gvMailboxes; * */ -int initialise() -{ - int i=0; - int j=0; - int k=0; - - gvMailboxes.indexfreeMailbox=0; - gvMailboxes.usedMailboxNumber=0; - gvMailboxes.nbMailboxCommandeReceived=0; - gvMailboxes.nbMailboxErrorCommandeReceived=0; - - for (i =0;icallsign,callsign,6); - - memcpy(pMailbox->messages[pMailbox->indexNextMessage].message,message,sizemMessage); - pMailbox->messages[pMailbox->indexNextMessage].timestamps = gv_spino.timestamps; - pMailbox->messages[pMailbox->indexNextMessage].size=sizemMessage; - - pMailbox->indexNextMessage =(pMailbox->indexNextMessage+1)%MAX_MAILBOX; - pMailbox->messageNumber++; - pMailbox->timestampCreation=gv_spino.timestamps; - - gvMailboxes.usedMailboxNumber++; - gvMailboxes.indexfreeMailbox++; - } else - { /* recherche si BAL existe */ - - int i = 0; - char find =0; - - while ((imessageNumber< MAX_MESSAGE) - { - memcpy(pMailbox->messages[pMailbox->indexNextMessage].message,message,sizemMessage); - pMailbox->messages[pMailbox->indexNextMessage].timestamps = gv_spino.timestamps; - pMailbox->messages[pMailbox->indexNextMessage].size=sizemMessage; - - pMailbox->indexNextMessage =(pMailbox->indexNextMessage+1)%MAX_MAILBOX; - pMailbox->messageNumber++; - - - } else - { - reponse= ERROR_MAILBOX_FULL; - } - find= 1; - } - //} - i++; - } - - if (find == 0) - { - // creation BAL + ajout Message - - if(gvMailboxes.usedMailboxNumbercallsign,callsign,6); - - - memcpy(pMailbox->messages[pMailbox->indexNextMessage].message,message,sizemMessage); - pMailbox->messages[pMailbox->indexNextMessage].timestamps = gv_spino.timestamps; - pMailbox->messages[pMailbox->indexNextMessage].size=sizemMessage; - pMailbox->indexNextMessage =(pMailbox->indexNextMessage+1)%MAX_MAILBOX; - - pMailbox->messageNumber++; - pMailbox->timestampCreation=gv_spino.timestamps; - - // recher de la nouvelle mailbox libre - while ((icallsign, callsign, 6); + + memcpy(pMailbox->messages[pMailbox->indexNextMessage].message, message, + sizemMessage); + pMailbox->messages[pMailbox->indexNextMessage].timestamps = + gv_spino.timestamps; + pMailbox->messages[pMailbox->indexNextMessage].size = sizemMessage; + + pMailbox->indexNextMessage = + (unsigned char) ((pMailbox->indexNextMessage + 1) % MAX_MAILBOX); + pMailbox->messageNumber++; + pMailbox->timestampCreation = gv_spino.timestamps; + + gvMailboxes.usedMailboxNumber++; + gvMailboxes.indexfreeMailbox++; + } else { /* recherche si BAL existe */ + + int i = 0; + char find = 0; + + while ((i < MAX_MAILBOX) & (find == 0)) { + //if (gvMailboxes.mailbox[i].messageNumber != 0) + //{ + if ((memcmp(gvMailboxes.mailbox[i].callsign, callsign, 6) == 0)) + + { // ajout de message + + pMailbox = &gvMailboxes.mailbox[i]; + // verifie place dispo + if (pMailbox->messageNumber < MAX_MESSAGE) { + memcpy( + pMailbox->messages[pMailbox->indexNextMessage].message, + message, sizemMessage); + pMailbox->messages[pMailbox->indexNextMessage].timestamps = + gv_spino.timestamps; + pMailbox->messages[pMailbox->indexNextMessage].size = + sizemMessage; + + pMailbox->indexNextMessage = + (unsigned char) ((pMailbox->indexNextMessage + 1) + % MAX_MAILBOX); + pMailbox->messageNumber++; + + } else { + reponse = ERROR_MAILBOX_FULL; + } + find = 1; + } + //} + i++; + } + + if (find == 0) { + // creation BAL + ajout Message + + if (gvMailboxes.usedMailboxNumber < MAX_MAILBOX) { + // reste de la place + pMailbox = &gvMailboxes.mailbox[gvMailboxes.indexfreeMailbox]; + // creation de la mailbox + memcpy(pMailbox->callsign, callsign, 6); + + memcpy(pMailbox->messages[pMailbox->indexNextMessage].message, + message, sizemMessage); + pMailbox->messages[pMailbox->indexNextMessage].timestamps = + gv_spino.timestamps; + pMailbox->messages[pMailbox->indexNextMessage].size = + sizemMessage; + pMailbox->indexNextMessage = + (unsigned char) ((pMailbox->indexNextMessage + 1) + % MAX_MAILBOX); + + pMailbox->messageNumber++; + pMailbox->timestampCreation = gv_spino.timestamps; + + // recher de la nouvelle mailbox libre + while ((i < MAX_MAILBOX) & (find == 0)) { + if (gvMailboxes.mailbox[i].messageNumber == 0) { + find = 1; + gvMailboxes.indexfreeMailbox = i; + } else { + i++; + } + } + + } + /* TODO MCR Cas ou pas trouvé verifier qua pas de PB */ + } + } + return reponse; } /** @@ -178,44 +172,40 @@ int addMessage (char *callsign, char *message,const unsigned short sizemMessage * */ -int deletteMessage ( char *callsign, t_tc_response *resp) -{ - int i=0; - int find =0; - t_mailbox *pMailbox; - int reponse = SUCCESS; - while ((imessageNumber>0) - { - pMailbox->indexFreeMessage = (pMailbox->indexFreeMessage+1) % MAX_MESSAGE; - pMailbox->messageNumber--; - - } else - { - reponse = ERROR_MAILBOX_EMPTY; - - } - - } - i++; - - } - - if (find ==0) - { - reponse = ERROR_MAILBOX_NOT_FOUND; - } - - - resp->size=0; - -return reponse; +static unsigned char deletteMessage(unsigned char *callsign, + t_tc_response *resp) { + int i = 0; + int find = 0; + s_mailbox *pMailbox; + unsigned char reponse = SUCCESS; + while ((i < MAX_MAILBOX) & (find == 0)) { + + if ((memcmp(gvMailboxes.mailbox[i].callsign, callsign, 6) == 0)) { // delete message + find = 1; + pMailbox = &gvMailboxes.mailbox[i]; + if (gvMailboxes.mailbox->messageNumber > 0) { + pMailbox->indexFreeMessage = + (unsigned char) ((pMailbox->indexFreeMessage + 1) + % MAX_MESSAGE); + pMailbox->messageNumber--; + + } else { + reponse = ERROR_MAILBOX_EMPTY; + + } + + } + i++; + + } + + if (find == 0) { + reponse = ERROR_MAILBOX_NOT_FOUND; + } + + resp->size = 0; + + return reponse; } /** @@ -227,28 +217,24 @@ return reponse; * */ -int getListMailbox(t_tc_response *resp) -{ - t_list_mailbox list[MAX_MAILBOX]; - int response = SUCCESS; - int i; +unsigned char getListMailbox(t_tc_response *resp) { + s_list_mailbox list[MAX_MAILBOX]; + unsigned char response = SUCCESS; + int i; - for (i=0; isize = sizeof(t_list_mailbox)*MAX_MAILBOX; - memcpy(resp->parameter,list,resp->size); + resp->size = sizeof(s_list_mailbox) * MAX_MAILBOX; + memcpy(resp->parameter, list, resp->size); - return response; + return response; } - /** * \fn int deleteMailBox (char *callsign,t_tc_response *resp) * \brief delette Mailbox @@ -257,50 +243,45 @@ int getListMailbox(t_tc_response *resp) * * */ -int deleteMailBox (char *callsign,t_tc_response *resp) -{ - int i=0; - int j=0; - int find =0; - t_mailbox *pMailbox; - int reponse = SUCCESS; +unsigned char deleteMailBox(unsigned char *callsign, t_tc_response *resp) { + int i = 0; + int j = 0; + int find = 0; + s_mailbox *pMailbox; + unsigned char reponse = SUCCESS; - while ((iindexFreeMessage=MAX_MESSAGE -1; - pMailbox->indexNextMessage=0; - pMailbox->messageNumber=0; - pMailbox->timestampCreation=0; + pMailbox->indexFreeMessage = MAX_MESSAGE - 1; + pMailbox->indexNextMessage = 0; + pMailbox->messageNumber = 0; + pMailbox->timestampCreation = 0; - gvMailboxes.indexfreeMailbox=i; - gvMailboxes.usedMailboxNumber--; - for (j=0;jcallsign[j]=' '; - } + gvMailboxes.indexfreeMailbox = i; + gvMailboxes.usedMailboxNumber--; + for (j = 0; j < CALLSIGN_SIZE; j++) { + pMailbox->callsign[j] = ' '; + } - find= 1; + find = 1; - } + } - i++; + i++; - } + } - if (find ==0) - { - reponse = ERROR_MAILBOX_NOT_FOUND; + if (find == 0) { + reponse = ERROR_MAILBOX_NOT_FOUND; - } - - resp->size=0; -return reponse; + } + + resp->size = 0; + return reponse; } /** @@ -312,63 +293,63 @@ return reponse; * */ -int getLastMessage (char * callsign,t_tc_response *resp) -{ - - int i=0; - int find =0; - t_mailbox *pMailbox; - int reponse = SUCCESS; - t_get_message messagelue ; - logger(LOG_LEVEL_INFO,"Recherche Message"); - while ((iindexNextMessage-1)% MAX_MESSAGE; - if(message_index<0) - { - message_index = MAX_MESSAGE-1; - } - sprintf(gvLogMsg,"Taille INDEX %d LAST %d\r\n",pMailbox->indexNextMessage,message_index); - logger(LOG_LEVEL_CRITICAL,gvLogMsg); - messagelue.index =message_index; - memcpy(messagelue.callsign,callsign,6); - messagelue.timestamps = pMailbox->messages[message_index].timestamps; - sprintf(gvLogMsg,"Taille SIZE %d \r\n",pMailbox->messages[message_index].size); - memcpy(messagelue.message,pMailbox->messages[message_index].message,pMailbox->messages[message_index].size); - resp->size = pMailbox->messages[message_index].size+SIZE_T_GET_MESSAGE; - memcpy(resp->parameter, &messagelue,resp->size); - find= 1; - logger(LOG_LEVEL_INFO,"Mesage trouvé 2"); - } - logger(LOG_LEVEL_INFO,"Mesage non trouvé 3"); - } - i++; - logger(LOG_LEVEL_INFO,"Mesage non trouvé 5"); - } - - if (find ==0) - { - logger(LOG_LEVEL_INFO,"Mesage non trouvé 4"); - reponse = ERROR_MAILBOX_NOT_FOUND; - resp->size=0; - resp->header.error_code=ERROR_MAILBOX_NOT_FOUND; - } - - -return reponse; +static unsigned char getLastMessage(unsigned char *callsign, + t_tc_response *resp) { + + int i = 0; + int find = 0; + s_mailbox *pMailbox; + unsigned char reponse = SUCCESS; + s_get_message messagelue; + + while ((i < MAX_MAILBOX) & (find == 0)) { + + if (gvMailboxes.mailbox[i].messageNumber != 0) { + + if ((memcmp(gvMailboxes.mailbox[i].callsign, callsign, 6) == 0)) { // retourn message + + pMailbox = &gvMailboxes.mailbox[i]; + int message_index = ((pMailbox->indexNextMessage - 1) + % MAX_MESSAGE); + if (message_index < 0) { + message_index = MAX_MESSAGE - 1; + } + + sprintf(gvLogMsg, "Taille INDEX %d LAST %d\r\n", + pMailbox->indexNextMessage, message_index); + logger(LOG_LEVEL_CRITICAL, gvLogMsg); + messagelue.index = (unsigned char) message_index; + memcpy(messagelue.callsign, callsign, 6); + messagelue.timestamps = + pMailbox->messages[message_index].timestamps; + sprintf(gvLogMsg, "Taille SIZE %d \r\n", + pMailbox->messages[message_index].size); + memcpy(messagelue.message, + pMailbox->messages[message_index].message, + pMailbox->messages[message_index].size); + resp->size = pMailbox->messages[message_index].size + + SIZE_T_GET_MESSAGE; + memcpy(resp->parameter, &messagelue, resp->size); + find = 1; + + } + + } + i++; + + } + + if (find == 0) { + logger(LOG_LEVEL_INFO, "Mesage non trouvé 4"); + reponse = ERROR_MAILBOX_NOT_FOUND; + resp->size = 0; + resp->header.error_code = ERROR_MAILBOX_NOT_FOUND; + } + + return reponse; } - /** * \fn int getMessage (char * callsign, unsigned char index, t_tc_response *resp) * \brief return message from the callsign @@ -380,71 +361,60 @@ return reponse; * */ - -int getMessage (char * callsign, unsigned char index, t_tc_response *resp) -{ - int i=0; - int find =0; - t_mailbox *pMailbox; - int reponse = SUCCESS; - t_get_message messagelue ; - - sprintf(gvLogMsg,"Taille INDEX %d \r\n",index); - logger(LOG_LEVEL_CRITICAL,gvLogMsg); - - logger(LOG_LEVEL_INFO,"Recherche Message"); - while ((iindexNextMessage,index); - logger(LOG_LEVEL_CRITICAL,gvLogMsg); - if (pMailbox->messages[index].size !=0) - { - messagelue.index =index; - memcpy(messagelue.callsign,callsign,6); - messagelue.timestamps = pMailbox->messages[index].timestamps; - memcpy(messagelue.message,pMailbox->messages[index].message,pMailbox->messages[index].size); - resp->size = pMailbox->messages[index].size+SIZE_T_GET_MESSAGE; - memcpy(resp->parameter, &messagelue,resp->size); - } - else - { - resp->size =0; - resp->header.error_code = ERROR_MESSAGE_EMPTY; - } - - - find= 1; - logger(LOG_LEVEL_INFO,"Mesage trouvé 2"); - } - logger(LOG_LEVEL_INFO,"Mesage non trouvé 3"); - } - i++; - logger(LOG_LEVEL_INFO,"Mesage non trouvé 5"); - } - - if (find ==0) - { - logger(LOG_LEVEL_INFO,"Mesage non trouvé 4"); - reponse = ERROR_MAILBOX_NOT_FOUND; - resp->size=0; - resp->header.error_code=ERROR_MAILBOX_NOT_FOUND; - } - - -return reponse; +static unsigned char getMessage(unsigned char *callsign, unsigned char index, + t_tc_response *resp) { + int i = 0; + int find = 0; + s_mailbox *pMailbox; + unsigned char reponse = SUCCESS; + s_get_message messagelue; + + while ((i < MAX_MAILBOX) & (find == 0)) { + + if (gvMailboxes.mailbox[i].messageNumber != 0) { + + if ((memcmp(gvMailboxes.mailbox[i].callsign, callsign, 6) == 0)) { // retourn message + + pMailbox = &gvMailboxes.mailbox[i]; + + sprintf(gvLogMsg, "Taille INDEX %d LAST %d\r\n", + pMailbox->indexNextMessage, index); + logger(LOG_LEVEL_CRITICAL, gvLogMsg); + if (pMailbox->messages[index].size != 0) { + messagelue.index = index; + memcpy(messagelue.callsign, callsign, 6); + messagelue.timestamps = + pMailbox->messages[index].timestamps; + memcpy(messagelue.message, + pMailbox->messages[index].message, + pMailbox->messages[index].size); + resp->size = pMailbox->messages[index].size + + SIZE_T_GET_MESSAGE; + memcpy(resp->parameter, &messagelue, resp->size); + } else { + resp->size = 0; + resp->header.error_code = ERROR_MESSAGE_EMPTY; + } + + find = 1; + + } + + } + i++; + logger(LOG_LEVEL_INFO, "Mesage non trouvé 5"); + } + + if (find == 0) { + logger(LOG_LEVEL_INFO, "Mesage non trouvé 4"); + reponse = ERROR_MAILBOX_NOT_FOUND; + resp->size = 0; + resp->header.error_code = ERROR_MAILBOX_NOT_FOUND; + } + + return reponse; } - /** * \fn int getAllMesage (char * callsign) * \brief return all message from the callsign @@ -454,80 +424,74 @@ return reponse; * */ -int getAllMesage (char * callsign) -{ - - int i=0; - int find =0; - t_mailbox *pMailbox; - int reponse = SUCCESS; - t_get_message messagelue ; - - - t_tc_response resp; - t_ax25_packet ax25Frame; - ax25Frame.header = gv_headerTlm; - - logger(LOG_LEVEL_CRITICAL," GET_ALL_MESSAGE"); - - - memcpy(messagelue.callsign,callsign,6); - - - while ((imessages[j].size!=0 ) - { - messagelue.index=j; - messagelue.timestamps = pMailbox->messages[j].timestamps; - memcpy(messagelue.message,pMailbox->messages[j].message,pMailbox->messages[j].size); - resp.size = pMailbox->messages[j].size+SIZE_T_GET_MESSAGE; - memcpy(resp.parameter, &messagelue,resp.size); - memcpy( ax25Frame.data,&resp,TC_REPONSE_HEADER_SIZE+resp.size); - /* envoyer la reponse de la commande */ - writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp.size); - - } - } - - find= 1; - logger(LOG_LEVEL_INFO,"Mesage trouvé 2"); - } - logger(LOG_LEVEL_INFO,"Mesage non trouvé 3"); - } - i++; - logger(LOG_LEVEL_INFO,"Mesage non trouvé 5"); - } - - if (find ==0) - { - logger(LOG_LEVEL_INFO,"Mesage non trouvé 4"); - reponse = ERROR_MAILBOX_NOT_FOUND; - - } - -return reponse; -} +unsigned char getAllMesage(unsigned char *callsign) { + + int i = 0; + int find = 0; + s_mailbox *pMailbox; + unsigned char reponse = SUCCESS; + s_get_message messagelue; + + t_tc_response resp; + s_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + + logger(LOG_LEVEL_CRITICAL, " GET_ALL_MESSAGE"); + + memcpy(messagelue.callsign, callsign, 6); + while ((i < MAX_MAILBOX) & (find == 0)) { + + if (gvMailboxes.mailbox[i].messageNumber != 0) { + + if ((memcmp(gvMailboxes.mailbox[i].callsign, callsign, 6) == 0)) { // retourn message + + pMailbox = &gvMailboxes.mailbox[i]; + + // envoie des messages de la boite + unsigned char j; + resp.header.cmd_id = CMD_MAILBOX_GET_MSG; + resp.header.error_code = SUCCESS; + resp.header.responseType = RESULT_CMD; + resp.header.spare = 0; + resp.header.timeStamp = gv_spino.timestamps; + for (j = 0; j < (unsigned char) MAX_MESSAGE; j++) { + if (pMailbox->messages[j].size != 0) { + messagelue.index = j; + messagelue.timestamps = + pMailbox->messages[j].timestamps; + memcpy(messagelue.message, + pMailbox->messages[j].message, + pMailbox->messages[j].size); + resp.size = pMailbox->messages[j].size + + SIZE_T_GET_MESSAGE; + memcpy(resp.parameter, &messagelue, resp.size); + memcpy(ax25Frame.data, &resp, + TC_REPONSE_HEADER_SIZE + resp.size); + /* envoyer la reponse de la commande */ + writeData(ax25Frame, + TC_REPONSE_HEADER_SIZE + resp.size); + + } + } + + find = 1; + + } + + } + i++; + + } + + if (find == 0) { + + reponse = ERROR_MAILBOX_NOT_FOUND; + + } + + return reponse; +} /** * \fn int dumpMailbox () @@ -537,141 +501,124 @@ return reponse; * */ -int dumpMailbox () -{ +static unsigned char dumpMailbox() { - int i=0; - int response = SUCCESS; - for (i=0;i MAX_LENGHT_MESSAGE) - { - reponse=ERROR_ADD_MSG_EXCED_SIZE; - } else - { - char message[MAX_LENGHT_MESSAGE]; - logger(LOG_LEVEL_CRITICAL,gvLogMsg); - memcpy(message, cmd.parameter, cmd.size); - reponse = addMessage (callsign,message,cmd.size); - } - resp.size=0; - break; - - case CMD_MAILBOX_DEL_MSG : - logger(LOG_LEVEL_INFO,"Commande MAILBOX DELETE MSG !!!"); - reponse = deletteMessage (callsign,&resp); - resp.size=0; - break; - case CMD_MAILBOX_GET_LIST_BOX: - logger(LOG_LEVEL_INFO,"Commande MAILBOX LIST MAILBOXES"); - reponse = getListMailbox (&resp); - break; - case CMD_MAILBOX_DELETTE_BOX : - logger(LOG_LEVEL_INFO,"Commande MAILBOX DELETE MAILBOX"); - reponse = deleteMailBox (callsign,&resp); - resp.size=0; - break; - case CMD_MAILBOX_GET_LAST_MSG : - logger(LOG_LEVEL_INFO,"Commande MAILBOX GET LAST MESSAGE"); - if(cmd.size == 6) - { - char callsignMailbox[6]; - memcpy(callsignMailbox, cmd.parameter, cmd.size); - reponse = getLastMessage (callsignMailbox,&resp); - } else - { - reponse=ERROR_GET_LAST_MSG_CALLSIGN_WRONG_SIZE; - } - - break; - case CMD_MAILBOX_GET_MSG : - - logger(LOG_LEVEL_INFO,"Commande MAILBOX GET MESSAGE INDEX"); - reponse = getMessage (&cmd.parameter[1],cmd.parameter[0], &resp); - break; - - case CMD_MAILBOX_GET_ALL_MSG : - reponse = getAllMesage (callsign); - resp.size=0; - break; - case CMD_MAILBOX_DUMP_MAILBOX: - reponse = ERROR_COMMAND_NOT_IMPLEMENTED; - break; - default: - // generation code erreur - sprintf(gvLogMsg,"erreur mailbox cmd %d \r\n",cmd.id); - logger(LOG_LEVEL_CRITICAL,gvLogMsg); - reponse = ERROR_COMMAND_UNKNOW; - resp.size =0; - break; - } - - resp.header.error_code = reponse; - return resp; +static t_tc_response interpretMailBoxcommand(s_command cmd, + unsigned char *callsign) { + + t_tc_response resp; + unsigned char reponse = SUCCESS; + + resp.header.responseType = RESULT_CMD; + resp.header.timeStamp = gv_spino.timestamps; + resp.header.cmd_id = cmd.id; + + switch (cmd.id) { + + case CMD_MAILBOX_INIT: + logger(LOG_LEVEL_INFO, "Commande MAILBOX RESET"); + reponse = initialise(); + resp.size = 0; + break; + + case CMD_MAILBOX_ADD_MSG: + logger(LOG_LEVEL_INFO, "Commande MAILBOX ADD MSG"); + if (cmd.size > MAX_LENGHT_MESSAGE) { + reponse = ERROR_ADD_MSG_EXCED_SIZE; + } else { + char message[MAX_LENGHT_MESSAGE]; + logger(LOG_LEVEL_CRITICAL, gvLogMsg); + memcpy(message, cmd.parameter, cmd.size); + reponse = addMessage(callsign, message, cmd.size); + } + resp.size = 0; + break; + + case CMD_MAILBOX_DEL_MSG: + logger(LOG_LEVEL_INFO, "Commande MAILBOX DELETE MSG !!!"); + reponse = deletteMessage(callsign, &resp); + resp.size = 0; + break; + case CMD_MAILBOX_GET_LIST_BOX: + logger(LOG_LEVEL_INFO, "Commande MAILBOX LIST MAILBOXES"); + reponse = getListMailbox(&resp); + break; + case CMD_MAILBOX_DELETTE_BOX: + logger(LOG_LEVEL_INFO, "Commande MAILBOX DELETE MAILBOX"); + reponse = deleteMailBox(callsign, &resp); + resp.size = 0; + break; + case CMD_MAILBOX_GET_LAST_MSG: + logger(LOG_LEVEL_INFO, "Commande MAILBOX GET LAST MESSAGE"); + if (cmd.size == 6) { + unsigned char callsignMailbox[6]; + memcpy(callsignMailbox, cmd.parameter, cmd.size); + reponse = getLastMessage(callsignMailbox, &resp); + } else { + reponse = ERROR_GET_LAST_MSG_CALLSIGN_WRONG_SIZE; + } + + break; + case CMD_MAILBOX_GET_MSG: + + logger(LOG_LEVEL_INFO, "Commande MAILBOX GET MESSAGE INDEX"); + reponse = getMessage((unsigned char*) &cmd.parameter[1], + (unsigned char) cmd.parameter[0], &resp); + break; + + case CMD_MAILBOX_GET_ALL_MSG: + reponse = getAllMesage(callsign); + resp.size = 0; + break; + case CMD_MAILBOX_DUMP_MAILBOX: + reponse = dumpMailbox(); + break; + default: + // generation code erreur + sprintf(gvLogMsg, "erreur mailbox cmd %d \r\n", cmd.id); + logger(LOG_LEVEL_CRITICAL, gvLogMsg); + reponse = ERROR_COMMAND_UNKNOW; + resp.size = 0; + break; + } + + resp.header.error_code = reponse; + return resp; } - - -void processMailbox(t_ax25_packet data_ax25) { - - t_tc_response result ; - t_command cmd; - - gvMailboxes.nbMailboxCommandeReceived++; - memcpy(&cmd,data_ax25.data,sizeof(t_command)); - result = interpretMailBoxcommand( cmd,data_ax25.header.sourceAdress); - if(result.header.error_code !=SUCCESS) - { - gvMailboxes.nbMailboxErrorCommandeReceived++; - } - t_ax25_packet ax25Frame; - - memcpy(ax25Frame.header.sourceAdress,gv_spinoConfig.spinoDesCallsign,6); - ax25Frame.header.ssidSource = SSID_SPINO_MAILBOX; - memcpy(ax25Frame.header.destinationAdress,data_ax25.header.sourceAdress,6); - ax25Frame.header.ssidDestination = SSID_SPINO_MAILBOX; - encodeAX25Header(&ax25Frame.header) ; - memcpy( ax25Frame.data,&result,TC_REPONSE_HEADER_SIZE+result.size); - /* envoyer la reponse de la commande */ - writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+result.size); +void processMailbox(s_ax25_packet data_ax25) { + + t_tc_response result; + s_command cmd; + + gvMailboxes.nbMailboxCommandeReceived++; + memcpy(&cmd, data_ax25.data, sizeof(s_command)); + result = interpretMailBoxcommand(cmd, data_ax25.header.sourceAdress); + if (result.header.error_code != SUCCESS) { + gvMailboxes.nbMailboxErrorCommandeReceived++; + } + s_ax25_packet ax25Frame; + + memcpy(ax25Frame.header.sourceAdress, gv_spinoConfig.spinoDesCallsign, 6); + ax25Frame.header.ssidSource = SSID_SPINO_MAILBOX; + memcpy(ax25Frame.header.destinationAdress, data_ax25.header.sourceAdress, + 6); + ax25Frame.header.ssidDestination = SSID_SPINO_MAILBOX; + encodeAX25Header(&ax25Frame.header); + memcpy(ax25Frame.data, &result, TC_REPONSE_HEADER_SIZE + result.size); + /* envoyer la reponse de la commande */ + writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + result.size); } diff --git a/EmbededSw/src/mailboxMode/mailbox.h b/EmbededSw/src/mailboxMode/mailbox.h index fca9b48..b2c6ac5 100644 --- a/EmbededSw/src/mailboxMode/mailbox.h +++ b/EmbededSw/src/mailboxMode/mailbox.h @@ -9,7 +9,7 @@ #define MAX_LENGHT_MESSAGE 256 #define CALLSIGN_SIZE 6 -/* COMMANDE MAILBOX */ +/* COMMANDE MAILBOX */ #define CMD_MAILBOX_INIT 32 #define CMD_MAILBOX_ADD_MSG 33 @@ -21,7 +21,6 @@ #define CMD_MAILBOX_GET_ALL_MSG 39 #define CMD_MAILBOX_DUMP_MAILBOX 40 - /** * \struct t_mailbox_message * \brief define mailbox structure to store message for a dedicated Callsign @@ -29,77 +28,69 @@ */ typedef struct mailbox_message { - long long timestamps; /*!< Time Stamps of message creation */ - unsigned short size; /*!< message size. Should <= MAX_LENGHT_MESSAGE*/ - char message[MAX_LENGHT_MESSAGE]; /*!< Message contents */ -}t_mailbox_message; - - + unsigned long long timestamps; /*!< Time Stamps of message creation */ + unsigned short size; /*!< message size. Should <= MAX_LENGHT_MESSAGE*/ + char message[MAX_LENGHT_MESSAGE]; /*!< Message contents */ +} s_mailbox_message; /** * \struct t_mailbox_message * \brief define mailbox structure to store message for a dedicated Callsign * */ - -typedef struct mail_box -{ - char messageNumber; - unsigned char indexNextMessage; - char indexFreeMessage; - char callsign[CALLSIGN_SIZE]; - long long timestampCreation; - t_mailbox_message messages[MAX_MESSAGE]; - /* data */ -} t_mailbox; - - -typedef struct mailboxes -{ - - t_mailbox mailbox[MAX_MAILBOX]; - int usedMailboxNumber; - int indexfreeMailbox; - long nbMailboxCommandeReceived; - long nbMailboxErrorCommandeReceived; -} t_mailboxes; - -typedef struct listMailbox -{ - char callsign [6]; - char nb_message; -}t_list_mailbox; - - -typedef struct add_message -{ - char size; - char message[MAX_LENGHT_MESSAGE]; - -}t_add_message; + +typedef struct mail_box { + char messageNumber; + unsigned char indexNextMessage; + unsigned char indexFreeMessage; + unsigned char callsign[CALLSIGN_SIZE]; + unsigned long long timestampCreation; + s_mailbox_message messages[MAX_MESSAGE]; + /* data */ +} s_mailbox; + +typedef struct mailboxes { + + s_mailbox mailbox[MAX_MAILBOX]; + int usedMailboxNumber; + int indexfreeMailbox; + long nbMailboxCommandeReceived; + long nbMailboxErrorCommandeReceived; +} s_mailboxes; + +typedef struct listMailbox { + char callsign[6]; + char nb_message; +} s_list_mailbox; + +typedef struct add_message { + char size; + char message[MAX_LENGHT_MESSAGE]; + +} s_add_message; #define SIZE_T_GET_MESSAGE 15 -typedef struct get_message -{ - long long timestamps; - char callsign[6]; - char index; - char message[MAX_LENGHT_MESSAGE]; - -} t_get_message; - -typedef struct cmd_get_message -{ - unsigned char index; - char callsign[6]; - -} t_cmd_get_message; - -extern void processMailbox(t_ax25_packet data_ax25); -extern int getListMailbox(t_tc_response *resp); -extern int addMessage (char *callsign, char *message,const unsigned short sizemMessage); -extern int deleteMailBox (char *callsign,t_tc_response *resp); -extern int initialise(); -extern int getAllMesage (char * callsign); +typedef struct get_message { + unsigned long long timestamps; + char callsign[6]; + unsigned char index; + char message[MAX_LENGHT_MESSAGE]; + +} s_get_message; + +typedef struct cmd_get_message { + unsigned char index; + char callsign[6]; + +} s_cmd_get_message; + +extern void processMailbox(s_ax25_packet data_ax25); +extern unsigned char getListMailbox(t_tc_response *resp); +extern unsigned char addMessage(unsigned char *callsign, char *message, + const unsigned short sizemMessage); +extern unsigned char deleteMailBox(unsigned char *callsign, + t_tc_response *resp); +extern unsigned char initialise(); +extern unsigned char getAllMesage(unsigned char *callsign); #endif // MAILBOX_H diff --git a/EmbededSw/src/mailboxMode/modeMailbox.c b/EmbededSw/src/mailboxMode/modeMailbox.c index 4d618e6..0ea04c2 100644 --- a/EmbededSw/src/mailboxMode/modeMailbox.c +++ b/EmbededSw/src/mailboxMode/modeMailbox.c @@ -1,4 +1,3 @@ - #include #include #include "../core/setup.h" @@ -6,46 +5,37 @@ #include "../mailboxMode/mailbox.h" #include "../errorMngt/error.h" +unsigned short modeMailbox() { + char data[300]; + s_ax25_packet data_ax25; + int nbc = readData(data); + if (nbc != 0) { + /* traitement des donnees recues */ + int res = convertDataToAx25(&data_ax25, data, nbc); + if (res != SUCCESS) { + logger(LOG_LEVEL_CRITICAL, "AX25 CONVESTION ISSUE"); + } -unsigned short modeMailbox () -{ - char data[300]; - t_ax25_packet data_ax25; - - - int nbc = readData(data); + if (memcmp(gv_spinoConfig.spinoDesCallsign, + data_ax25.header.destinationAdress, 6) == 0) { + if (data_ax25.header.ssidDestination + == (unsigned char) SSID_SPINO_TMTC) { + processCommand(data_ax25); + } else if (data_ax25.header.ssidDestination + == (unsigned char) SSID_SPINO_MAILBOX) { + processMailbox(data_ax25); - if (nbc !=0) - { - /* traitement des donnees recues */ - int res = convertDataToAx25 (&data_ax25, data, nbc ); - if (res != SUCCESS) - { - logger(LOG_LEVEL_CRITICAL, "AX25 CONVESTION ISSUE"); - } + } else { + // Message not awaited - message dropped + processDropMessage(data, (unsigned short) nbc); + } - if (memcmp(gv_spinoConfig.spinoDesCallsign,data_ax25.header.destinationAdress,6)==0) - { - if (data_ax25.header.ssidDestination == (unsigned char) SSID_SPINO_TMTC) - { - processCommand(data_ax25); - } else if ( data_ax25.header.ssidDestination == (unsigned char) SSID_SPINO_MAILBOX) - { - processMailbox(data_ax25); - - } else - { - // Message not awaited - message dropped - processDropMessage (data,nbc); - } - - } else - { - // Message not awaited - message dropped - processDropMessage (data,nbc); - } - } - return gv_spino.currentState; + } else { + // Message not awaited - message dropped + processDropMessage(data, (unsigned short) nbc); + } + } + return gv_spino.currentState; } diff --git a/EmbededSw/src/mailboxMode/modeMailbox.h b/EmbededSw/src/mailboxMode/modeMailbox.h index 5425d0f..43ea519 100644 --- a/EmbededSw/src/mailboxMode/modeMailbox.h +++ b/EmbededSw/src/mailboxMode/modeMailbox.h @@ -1,7 +1,4 @@ - #ifndef MODEMAILBOX #define MODEMAILBOX - - -#endif // MODEMAILBOX \ No newline at end of file +#endif // MODEMAILBOX diff --git a/EmbededSw/src/main.c b/EmbededSw/src/main.c index b37c949..b2c6d03 100644 --- a/EmbededSw/src/main.c +++ b/EmbededSw/src/main.c @@ -7,17 +7,15 @@ * */ - #include #include #include "./core/setup.h" - #define STATE_SURVEY 1 #define STATE_MAILBOX 2 extern void control(); -extern void open (); +extern void open(); /** * \fn int main (void) @@ -26,21 +24,16 @@ extern void open (); * \return 0 - Arrêt normal du programme. */ -int main (void ) -{ - printf("Spino Emulation V0.3\n"); - - - setupGlobalVariable(); - - open(); +int main(void) { + printf("Spino Emulation V0.3\n"); - control(); + setupGlobalVariable(); + open(); - printf ("END \n\r"); - + control(); + printf("END \n\r"); - return 0; + return 0; } diff --git a/EmbededSw/src/payloadMode/payloadMode.c b/EmbededSw/src/payloadMode/payloadMode.c index 97ebdc7..ca46ac8 100644 --- a/EmbededSw/src/payloadMode/payloadMode.c +++ b/EmbededSw/src/payloadMode/payloadMode.c @@ -17,83 +17,67 @@ #include "../errorMngt/error.h" #include "payloadMode.h" - - - static unsigned char I2CReadDataStatus; static unsigned char I2CWriteDataStatus; -static unsigned char I2CReadData [I2CMAXSIZE]; +static unsigned char I2CReadData[I2CMAXSIZE]; static unsigned char I2CWriteData[I2CMAXSIZE]; s_I2C_data gv_I2C_Write_Data[I2CMAXDATA]; int gv_nb_I2CMAXDATA; - -void init() -{ - I2CReadDataStatus=0; - I2CWriteDataStatus=0; +void init() { + I2CReadDataStatus = 0; + I2CWriteDataStatus = 0; } -int getAllI2Cdata(t_tc_response *resp) -{ - t_ax25_packet ax25Frame; - ax25Frame.header = gv_headerTlm; - resp->header.error_code = SUCCESS; - - int i=0; +unsigned char getAllI2Cdata(t_tc_response *resp) { + s_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + resp->header.error_code = SUCCESS; + int i = 0; - for(i=0; i< gv_nb_I2CMAXDATA; i++) - { - resp->size=sizeof(s_I2C_data); - memcpy(resp->parameter,&gv_I2C_Write_Data[i].data, resp->size ); - memcpy( ax25Frame.data,resp,TC_REPONSE_HEADER_SIZE+resp->size); - writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+resp->size); + for (i = 0; i < gv_nb_I2CMAXDATA; i++) { + resp->size = sizeof(s_I2C_data); + memcpy(resp->parameter, &gv_I2C_Write_Data[i].data, resp->size); + memcpy(ax25Frame.data, resp, TC_REPONSE_HEADER_SIZE + resp->size); + writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + resp->size); } - resp->size=0; - return SUCCESS; + resp->size = 0; + return SUCCESS; } - -t_tc_response interpretcommandPayload(t_command cmd) { - - - t_tc_response resp; - - - resp.header.responseType = RESULT_CMD; - resp.header.timeStamp=gv_spino.timestamps; - resp.header.cmd_id = cmd.id; - resp.header.error_code =SUCCESS; - - - switch (cmd.id) - { - case CMD_PAYLOAD_LOAD_DATA: - logger(LOG_LEVEL_INFO,"Commande CMD_PAYLOAD_LOAD_DATA"); - s_I2C_data data; - memcpy(&data, cmd.parameter, cmd.size); - I2CReadDataStatus = data.size; - memcpy(&I2CReadData, data.data, data.size); - resp.header.error_code=SUCCESS; - break; - - case CMD_PAYLOAD_READ_DATA: /* modify configuration value */ - logger(LOG_LEVEL_INFO,"Commande CMD_PAYLOAD_READ_DATA"); - resp.header.error_code = getAllI2Cdata(&resp); - break; - default: - resp.header.error_code = ERROR_COMMAND_UNKNOW; - } - return resp; +t_tc_response interpretcommandPayload(s_command cmd) { + + t_tc_response resp; + + resp.header.responseType = RESULT_CMD; + resp.header.timeStamp = gv_spino.timestamps; + resp.header.cmd_id = cmd.id; + resp.header.error_code = SUCCESS; + + switch (cmd.id) { + case CMD_PAYLOAD_LOAD_DATA: + logger(LOG_LEVEL_INFO, "Commande CMD_PAYLOAD_LOAD_DATA"); + s_I2C_data data; + memcpy(&data, cmd.parameter, cmd.size); + I2CReadDataStatus = data.size; + memcpy(&I2CReadData, data.data, data.size); + resp.header.error_code = SUCCESS; + break; + + case CMD_PAYLOAD_READ_DATA: /* modify configuration value */ + logger(LOG_LEVEL_INFO, "Commande CMD_PAYLOAD_READ_DATA"); + resp.header.error_code = getAllI2Cdata(&resp); + break; + default: + resp.header.error_code = ERROR_COMMAND_UNKNOW; + } + return resp; } - - - /** * \fn void processCommand(t_ax25_packet data_ax25) * \brief process command ax25 packet @@ -101,52 +85,45 @@ t_tc_response interpretcommandPayload(t_command cmd) { * \return SUCCESS if or Error code * */ -void processCommandePayload(t_ax25_packet data_ax25) { - - t_tc_response result ; - t_command cmd; - - - gv_spino.nbCommandeReceived++; - memcpy(&cmd,data_ax25.data,sizeof(t_command)); - if(cmd.key != gv_spino_cmd_key) - { - result.header.responseType = RESULT_CMD; - result.header.timeStamp=gv_spino.timestamps; - result.header.cmd_id = cmd.id; - result.header.error_code = ERROR_COMMAND_WITH_WRONG_KEY; - result.size=0; - } else - { - result = interpretcommandPayload( cmd); - - } - - if(result.header.error_code !=SUCCESS) - { - gv_spino.nbCommandeWithError++; - } - t_ax25_packet ax25Frame; - ax25Frame.header = gv_headerTlm; - memcpy( ax25Frame.data,&result,TC_REPONSE_HEADER_SIZE+result.size); - /* envoyer la reponse de la commande */ - writeData (ax25Frame,TC_REPONSE_HEADER_SIZE+result.size); +void processCommandePayload(s_ax25_packet data_ax25) { + + t_tc_response result; + s_command cmd; + + gv_spino.nbCommandeReceived++; + memcpy(&cmd, data_ax25.data, sizeof(s_command)); + if (cmd.key != gv_spino_cmd_key) { + result.header.responseType = RESULT_CMD; + result.header.timeStamp = gv_spino.timestamps; + result.header.cmd_id = cmd.id; + result.header.error_code = ERROR_COMMAND_WITH_WRONG_KEY; + result.size = 0; + } else { + result = interpretcommandPayload(cmd); -} + } + if (result.header.error_code != SUCCESS) { + gv_spino.nbCommandeWithError++; + } + s_ax25_packet ax25Frame; + ax25Frame.header = gv_headerTlm; + memcpy(ax25Frame.data, &result, TC_REPONSE_HEADER_SIZE + result.size); + /* envoyer la reponse de la commande */ + writeData(ax25Frame, TC_REPONSE_HEADER_SIZE + result.size); +} unsigned short payloadMode() { char data[300]; - t_ax25_packet data_ax25; + s_ax25_packet data_ax25; int nbc = readData(data); if (nbc != 0) { /* traitement des donnees recues */ int res = convertDataToAx25(&data_ax25, data, nbc); - if (res != SUCCESS) - { + if (res != SUCCESS) { logger(LOG_LEVEL_CRITICAL, "AX25 CONVERSION ISSUE"); } @@ -160,15 +137,15 @@ unsigned short payloadMode() { == (unsigned char) SSID_SPINO_CUBESAT) { processCommandePayload(data_ax25); } else { - logger(LOG_LEVEL_CRITICAL, "MESSAGE DROPED"); - processDropMessage(data, nbc); + logger(LOG_LEVEL_CRITICAL, "MESSAGE DROPED"); + processDropMessage(data, (unsigned short) nbc); } } else { // Message not awaited - message dropped - processDropMessage(data, nbc); - logger(LOG_LEVEL_CRITICAL, "MESSAGE DROPED"); + processDropMessage(data, (unsigned short) nbc); + logger(LOG_LEVEL_CRITICAL, "MESSAGE DROPED"); } } diff --git a/EmbededSw/src/payloadMode/payloadMode.h b/EmbededSw/src/payloadMode/payloadMode.h index 3e6f01f..0593735 100644 --- a/EmbededSw/src/payloadMode/payloadMode.h +++ b/EmbededSw/src/payloadMode/payloadMode.h @@ -1,12 +1,16 @@ +#ifndef PAYLOG_MODE_H +#define PAYLOG_MODE_H + #define I2CMAXSIZE 64 #define I2CMAXDATA 10 #define CMD_PAYLOAD_LOAD_DATA 10 #define CMD_PAYLOAD_READ_DATA 11 -typedef struct I2C_data -{ +typedef struct I2C_data { unsigned char size; char data[I2CMAXSIZE]; -}s_I2C_data; \ No newline at end of file +} s_I2C_data; + +#endif // PAYLOG_MODE_H diff --git a/EmbededSw/src/simulation/SpinoSimuServerTCP.c b/EmbededSw/src/simulation/SpinoSimuServerTCP.c index 7787521..fe0de7e 100644 --- a/EmbededSw/src/simulation/SpinoSimuServerTCP.c +++ b/EmbededSw/src/simulation/SpinoSimuServerTCP.c @@ -1,63 +1,57 @@ - /*********************************************************************************************** - * - * File Name : tcpServer - * - * Description : manage tcp server for testing purpose - * - * Usage : for Spino simulator only - * - * nota : code based on : http://dwise1.net/pgm/sockets/blocking.html - * - * ********************************************************************************************* - * - * Autor : Xtophe - * - * date : 2022 / 08 /01 - * - * Version : 0.1 - * - * todo : - * - * ********************************************************************************************** - * - * You need to link the library: libws2_32.a - * OR - * -lwsock32 - * -lws2_32 - * from c:\TDM-GCC-64\x86_64-w64-mingw32\lib32\ +/*********************************************************************************************** + * + * File Name : tcpServer + * + * Description : manage tcp server for testing purpose + * + * Usage : for Spino simulator only + * + * nota : code based on : http://dwise1.net/pgm/sockets/blocking.html + * + * ********************************************************************************************* + * + * Autor : Xtophe + * + * date : 2022 / 08 /01 + * + * Version : 0.1 + * + * todo : + * + * ********************************************************************************************** + * + * You need to link the library: libws2_32.a + * OR + * -lwsock32 + * -lws2_32 + * from c:\TDM-GCC-64\x86_64-w64-mingw32\lib32\ * OR - * c:\MinGW\lib\ + * c:\MinGW\lib\ * if you using GCC on windows -***********************************************************************************************/ - - + ***********************************************************************************************/ + /*========= INCLUDES ==========================================================================*/ - + #include #include #include #include #include "SpinoSimuServerTCP.h" - /*========= GLOBAL VARIABLES ===================================================================*/ - - char gv_simu_receiveddata[MAX_DATA]; -int gv_simu_nb_data_received =0; - +int gv_simu_nb_data_received = 0; -SOCKET m_ServerSock; /* server's listening socket */ +SOCKET m_ServerSock; /* server's listening socket */ SOCKET gv_m_client_list[MAX_CLIENTS]; -int m_iNumclients; +int m_iNumclients; SOCKET gv_AcceptSocket; SOCKET TCPServerSocket; +unsigned char test[6] = { 0x0, 0x01, 0x0F, 0x10, 0xF0, 0xFF }; -unsigned char test[6]={0x0,0x01,0x0F,0x10,0xF0,0xFF}; - - /*========= FUNCTIONS ========================================================================*/ +/*========= FUNCTIONS ========================================================================*/ /*--------------------------------------------------------------------------------------------------------- * @@ -68,16 +62,16 @@ unsigned char test[6]={0x0,0x01,0x0F,0x10,0xF0,0xFF}; * ---------------------------------------------------------------------------------------------------------*/ -void HandleClient(SOCKET AcceptSocket) -{ +void HandleClient(SOCKET AcceptSocket) { // STEP-7 Send Message to Client - gv_simu_nb_data_received =0; - gv_simu_nb_data_received = recv(AcceptSocket,gv_simu_receiveddata, MAX_DATA, 0); - if (gv_simu_nb_data_received == (unsigned int) SOCKET_ERROR) { - printf("SERVER: Receive Failed, Error: %d\n", WSAGetLastError()); - exit(-1); - gv_simu_nb_data_received=0; - } + gv_simu_nb_data_received = 0; + gv_simu_nb_data_received = recv(AcceptSocket, gv_simu_receiveddata, + MAX_DATA, 0); + if (gv_simu_nb_data_received == (int) SOCKET_ERROR) { + printf("SERVER: Receive Failed, Error: %d\n", WSAGetLastError()); + exit(-1); + gv_simu_nb_data_received = 0; + } } @@ -90,55 +84,51 @@ void HandleClient(SOCKET AcceptSocket) * ---------------------------------------------------------------------------------------------------------*/ -void PerformSelect(SOCKET listeningSock, SOCKET clients[], int iNumClients) -{ - fd_set sockSet; /* Set of socket descriptors for select() */ - struct timeval selTimeout; /* Timeout for select() */ - int i; - int iResult; - - /* Zero socket descriptor vector and set for server sockets */ - /* This must be reset every time select() is called */ - FD_ZERO(&sockSet); - FD_SET(listeningSock, &sockSet); - for (i=0; i < iNumClients; i++) - FD_SET(clients[i], &sockSet); - - /* Timeout specification */ - /* This must be reset every time select() is called */ - selTimeout.tv_sec = 0; /* timeout (secs.) */ - selTimeout.tv_usec = 100000; /* 0 microseconds */ - - iResult = select(0, &sockSet, NULL, NULL, &selTimeout); - - if (iResult == -1) - { - /* an error occurred; process it (eg, display error message) */ - } - else if (iResult > 0) /* ie, if a socket is ready */ - { - // test this specific socket to see if it was one of the ones that was set - // if (FD_ISSET(listeningSock, &sockSet)) - // { - // AcceptNewClient(listeningSock); - // } - - /* Now test the client sockets */ - for (i=0; i < iNumClients; i++) - if (FD_ISSET(clients[i], &sockSet)) - { - /* do whatever it takes to read the socket and handle the client */ - /* Please note that this will involve reassociating the socket */ - /* with the client record */ - HandleClient(clients[i]); - } - } - - /* else iResult == 0, no socket is ready to be read, */ - /* so ignore them and move on. */ +void PerformSelect(SOCKET listeningSock, SOCKET clients[], int iNumClients) { + fd_set sockSet; /* Set of socket descriptors for select() */ + struct timeval selTimeout; /* Timeout for select() */ + int i; + int iResult; + + /* Zero socket descriptor vector and set for server sockets */ + /* This must be reset every time select() is called */ + FD_ZERO(&sockSet); + FD_SET(listeningSock, &sockSet); + for (i = 0; i < iNumClients; i++) + FD_SET(clients[i], &sockSet); + + /* Timeout specification */ + /* This must be reset every time select() is called */ + selTimeout.tv_sec = 0; /* timeout (secs.) */ + selTimeout.tv_usec = 100000; /* 0 microseconds */ + + iResult = select(0, &sockSet, NULL, NULL, &selTimeout); + + if (iResult == -1) { + /* an error occurred; process it (eg, display error message) */ + } else if (iResult > 0) /* ie, if a socket is ready */ + { + // test this specific socket to see if it was one of the ones that was set + // if (FD_ISSET(listeningSock, &sockSet)) + // { + // AcceptNewClient(listeningSock); + // } + + /* Now test the client sockets */ + for (i = 0; i < iNumClients; i++) + if (FD_ISSET(clients[i], &sockSet)) { + /* do whatever it takes to read the socket and handle the client */ + /* Please note that this will involve reassociating the socket */ + /* with the client record */ + HandleClient(clients[i]); + } + } + + /* else iResult == 0, no socket is ready to be read, */ + /* so ignore them and move on. */ } - + /*--------------------------------------------------------------------------------------------------------- * * OpenAndWait ( ) : @@ -148,59 +138,58 @@ void PerformSelect(SOCKET listeningSock, SOCKET clients[], int iNumClients) * ---------------------------------------------------------------------------------------------------------*/ - -void TCP_OpenAndWait () -{ - printf("TCP SERVER\n"); - - WSADATA Winsockdata; - - struct sockaddr_in TCPServerAddr; - struct sockaddr_in TCPClientAddr; - int TCPClientAddrSize = sizeof(TCPClientAddr); - - - - // STEP-1 WSAStartUp - if (WSAStartup(MAKEWORD(2,2), &Winsockdata) != 0) { - printf("SERVER: WSAStartUp Failed"); - } - printf("SERVER: WSAStartUp Success\n"); - - // STEP-2 Fill TCPServerAddr Struct - TCPServerAddr.sin_family = AF_INET; - TCPServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); - TCPServerAddr.sin_port = htons(8888); - - //STEP-3 Create Socket - if ((TCPServerSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == INVALID_SOCKET) { - printf("SERVER: TCP Server: Create Socket Failed, Error: %d\n", WSAGetLastError()); - } - printf("SERVER: TCP Server: Create Socket Success\n"); - - //STEP-4 bind - if (bind(TCPServerSocket, (SOCKADDR*)&TCPServerAddr, sizeof(TCPServerAddr)) == SOCKET_ERROR) { - printf("SERVER: Binding Failed, Error: %d", WSAGetLastError()); - } - printf("SERVER: Binding Success\n"); - - //STEP-5 Listen - if (listen(TCPServerSocket, 2) == SOCKET_ERROR) { - printf("SERVER: Listen Failed, Error: %d", WSAGetLastError()); - } - printf("SERVER: Listen Success: Listening for incoming connection...\n"); - - // STEP-6 Accept - if ((gv_AcceptSocket = accept(TCPServerSocket, (SOCKADDR *)&TCPClientAddr, &TCPClientAddrSize)) == INVALID_SOCKET) { - printf("SERVER: Accept Failed, Error: %d\n", WSAGetLastError()); - } - printf("SERVER: Connection Accepted\n"); - m_ServerSock = 2; - gv_m_client_list[0]=gv_AcceptSocket; +void TCP_OpenAndWait() { + printf("TCP SERVER\n"); + + WSADATA Winsockdata; + + struct sockaddr_in TCPServerAddr; + struct sockaddr_in TCPClientAddr; + int TCPClientAddrSize = sizeof(TCPClientAddr); + + // STEP-1 WSAStartUp + if (WSAStartup(MAKEWORD(2, 2), &Winsockdata) != 0) { + printf("SERVER: WSAStartUp Failed"); + } + printf("SERVER: WSAStartUp Success\n"); + + // STEP-2 Fill TCPServerAddr Struct + TCPServerAddr.sin_family = AF_INET; + TCPServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); + TCPServerAddr.sin_port = htons(8888); + + //STEP-3 Create Socket + if ((TCPServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) + == INVALID_SOCKET) { + printf("SERVER: TCP Server: Create Socket Failed, Error: %d\n", + WSAGetLastError()); + } + printf("SERVER: TCP Server: Create Socket Success\n"); + + //STEP-4 bind + if (bind(TCPServerSocket, (SOCKADDR*) &TCPServerAddr, + sizeof(TCPServerAddr)) == SOCKET_ERROR) { + printf("SERVER: Binding Failed, Error: %d", WSAGetLastError()); + } + printf("SERVER: Binding Success\n"); + + //STEP-5 Listen + if (listen(TCPServerSocket, 2) == SOCKET_ERROR) { + printf("SERVER: Listen Failed, Error: %d", WSAGetLastError()); + } + printf("SERVER: Listen Success: Listening for incoming connection...\n"); + + // STEP-6 Accept + if ((gv_AcceptSocket = accept(TCPServerSocket, (SOCKADDR*) &TCPClientAddr, + &TCPClientAddrSize)) == INVALID_SOCKET) { + printf("SERVER: Accept Failed, Error: %d\n", WSAGetLastError()); + } + printf("SERVER: Connection Accepted\n"); + m_ServerSock = 2; + gv_m_client_list[0] = gv_AcceptSocket; } - /*--------------------------------------------------------------------------------------------------------- * * TCP_closeALL ( ) : @@ -209,19 +198,18 @@ void TCP_OpenAndWait () * * ---------------------------------------------------------------------------------------------------------*/ -void TCP_closeAll() -{ - // STEP-9 Close Socket - if (closesocket(TCPServerSocket) == SOCKET_ERROR) { - printf("SERVER: Close Socket Failed, Error: %d\n", WSAGetLastError()); - } - printf("SERVER: Close Socket Success\n"); - - // STEP-10 Clean - if (WSACleanup() == SOCKET_ERROR) { - printf("SERVER: WSACleanup Failed, Error: %d\n", WSAGetLastError()); - } - printf("SERVER: WSACleanup Success\n"); +void TCP_closeAll() { + // STEP-9 Close Socket + if (closesocket(TCPServerSocket) == SOCKET_ERROR) { + printf("SERVER: Close Socket Failed, Error: %d\n", WSAGetLastError()); + } + printf("SERVER: Close Socket Success\n"); + + // STEP-10 Clean + if (WSACleanup() == SOCKET_ERROR) { + printf("SERVER: WSACleanup Failed, Error: %d\n", WSAGetLastError()); + } + printf("SERVER: WSACleanup Success\n"); } /*--------------------------------------------------------------------------------------------------------- @@ -233,32 +221,27 @@ void TCP_closeAll() * ---------------------------------------------------------------------------------------------------------*/ - void TCP_Send (char *data, int nb ) - { - if (send(gv_AcceptSocket,data, nb, 0) == SOCKET_ERROR) { - printf("SERVER: Send Failed Error: %d\n", WSAGetLastError()); - } - printf("SERVER: Message Sent!\n"); - } - - - - +void TCP_Send(char *data, int nb) { + if (send(gv_AcceptSocket, data, nb, 0) == SOCKET_ERROR) { + printf("SERVER: Send Failed Error: %d\n", WSAGetLastError()); + } + printf("SERVER: Message Sent!\n"); +} // int main() { - - // unsigned char test[6]={0x0,0x01,0x0F,0x10,0xF0,0xFF}; - // TCP_OpenAndWait (); - // int i; - // while (1) - // { - // PerformSelect(gv_AcceptSocket, gv_m_client_list, 1); - - // if (gv_simu_nb_data_received!=0) - // { - // printf("data recieved %d \r\n",gv_simu_nb_data_received ); - // gv_simu_nb_data_received=0; - // TCP_Send (test,6); + +// unsigned char test[6]={0x0,0x01,0x0F,0x10,0xF0,0xFF}; +// TCP_OpenAndWait (); +// int i; +// while (1) +// { +// PerformSelect(gv_AcceptSocket, gv_m_client_list, 1); + +// if (gv_simu_nb_data_received!=0) +// { +// printf("data recieved %d \r\n",gv_simu_nb_data_received ); +// gv_simu_nb_data_received=0; +// TCP_Send (test,6); // // } else // { @@ -268,22 +251,19 @@ void TCP_closeAll() // } //} - - - - + /* -run: + run: -TCP SERVER -SERVER: WSAStartUp Success -SERVER: TCP Server: Create Socket Success -SERVER: Binding Success -SERVER: Listen Success: Listening for incoming connection... -SERVER: Connection Accepted -SERVER: Message Sent! -SERVER: Received Message From Client: Hello from Client! -SERVER: Close Socket Success -SERVER: WSACleanup Success + TCP SERVER + SERVER: WSAStartUp Success + SERVER: TCP Server: Create Socket Success + SERVER: Binding Success + SERVER: Listen Success: Listening for incoming connection... + SERVER: Connection Accepted + SERVER: Message Sent! + SERVER: Received Message From Client: Hello from Client! + SERVER: Close Socket Success + SERVER: WSACleanup Success -*/ + */ diff --git a/EmbededSw/src/simulation/SpinoSimuServerTCP.h b/EmbededSw/src/simulation/SpinoSimuServerTCP.h index 5fb5310..f1953dc 100644 --- a/EmbededSw/src/simulation/SpinoSimuServerTCP.h +++ b/EmbededSw/src/simulation/SpinoSimuServerTCP.h @@ -1,4 +1,3 @@ - #ifndef SPINOSIMUSERVER_H #define SPINOSIMUSERVER_H @@ -7,14 +6,14 @@ #define MAX_DATA 512 #define MAX_CLIENTS 2 - -extern char gv_simu_receiveddata[]; -extern int gv_simu_nb_data_received; +extern char gv_simu_receiveddata[]; +extern int gv_simu_nb_data_received; extern SOCKET gv_m_client_list[MAX_CLIENTS]; extern SOCKET gv_AcceptSocket; -extern void PerformSelect(SOCKET listeningSock, SOCKET clients[], int iNumClients); -extern void TCP_OpenAndWait (); -extern void TCP_Send (char *data, int nb ); +extern void PerformSelect(SOCKET listeningSock, SOCKET clients[], + int iNumClients); +extern void TCP_OpenAndWait(); +extern void TCP_Send(char *data, int nb); #endif //SPINOSIMUSERVER_H diff --git a/EmbededSw/src/simulation/lecfic.c b/EmbededSw/src/simulation/lecfic.c index e151cf6..9b1d6e1 100644 --- a/EmbededSw/src/simulation/lecfic.c +++ b/EmbededSw/src/simulation/lecfic.c @@ -6,84 +6,74 @@ #define TAILLE_BUF 300 /* valeur quelconque (en général, beaucoup plus grande) */ +FILE *fichier; -FILE* fichier ; +void openfile(char *filename) { -void openfile(char * filename) -{ - - fichier = fopen( filename, "rb") ; - if ( fichier==NULL ) - { - printf("Ouverture du fichier impossible !"); - exit(0); - } + fichier = fopen(filename, "rb"); + if (fichier == NULL) { + printf("Ouverture du fichier impossible !"); + exit(0); + } } -int lectureData (char *data) -{ - int nb_val_lues; +int lectureData(char *data) { + int nb_val_lues; - unsigned char taille; - // lecture taille data - nb_val_lues = fread( &taille, sizeof(char), 1, fichier); - if (nb_val_lues != 0) - nb_val_lues = fread( data, sizeof(char), taille, fichier); - return nb_val_lues; + unsigned char taille; + // lecture taille data + nb_val_lues = (int) fread(&taille, sizeof(char), 1, fichier); + if (nb_val_lues != 0) + nb_val_lues = (int) fread(data, sizeof(char), (size_t) taille, fichier); + return nb_val_lues; } - -int lectureFile (char * filename, char *data) -{ - FILE* fic ; - - - // char [TAILLE_BUF]; /* ce tableau mémorisera les valeurs lues dans le fichier */ - short int nb_val_lues = TAILLE_BUF ; - /* Ouverture du fichier (en lecture binaire) : */ - fic = fopen( filename, "rb") ; - if ( fic==NULL ) - { - printf("Ouverture du fichier impossible !"); - exit(0); - } - /* Lecture dans le fichier : */ - printf("\n Liste des valeurs lues : \n"); - /*Remplissage du buffer et traitement, autant de fois que nécessaire jusqu'à la fin fichier : */ - while ( nb_val_lues == TAILLE_BUF ) /* vrai tant que fin du fichier non atteinte */ - { - - nb_val_lues = fread( data, sizeof(char), TAILLE_BUF, fic); - /* Traitement des valeurs stockées dans le buffer (ici, un simple affichage) : */ - // for (i=0; i