#12: multiple capabilities in user task, user init function, cleanup message handling in main, clearer api
This commit is contained in:
parent
16cf7655f0
commit
c105eef969
|
@ -9,16 +9,20 @@
|
||||||
class GwApi{
|
class GwApi{
|
||||||
public:
|
public:
|
||||||
virtual GwRequestQueue *getQueue()=0;
|
virtual GwRequestQueue *getQueue()=0;
|
||||||
virtual void sendN2kMessage(const tN2kMsg &msg)=0;
|
virtual void sendN2kMessage(const tN2kMsg &msg, bool convert=true)=0;
|
||||||
virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId)=0;
|
virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId,bool convert=true)=0;
|
||||||
virtual int getSourceId()=0;
|
virtual int getSourceId()=0;
|
||||||
virtual GwConfigHandler *getConfig()=0;
|
virtual GwConfigHandler *getConfig()=0;
|
||||||
virtual GwLog *getLogger()=0;
|
virtual GwLog *getLogger()=0;
|
||||||
virtual GwBoatData *getBoatData()=0;
|
virtual GwBoatData *getBoatData()=0;
|
||||||
|
virtual ~GwApi(){}
|
||||||
};
|
};
|
||||||
#ifndef DECLARE_USERTASK
|
#ifndef DECLARE_USERTASK
|
||||||
#define DECLARE_USERTASK(task)
|
#define DECLARE_USERTASK(task)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef DECLARE_INITFUNCTION
|
||||||
|
#define DECLARE_INITFUNCTION(task)
|
||||||
|
#endif
|
||||||
#ifndef DECLARE_CAPABILITY
|
#ifndef DECLARE_CAPABILITY
|
||||||
#define DECLARE_CAPABILITY(name,value)
|
#define DECLARE_CAPABILITY(name,value)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,6 +4,12 @@
|
||||||
#include "GwExampleTask.h"
|
#include "GwExampleTask.h"
|
||||||
#include "GwApi.h"
|
#include "GwApi.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* an init function that ist being called before other initializations from the core
|
||||||
|
*/
|
||||||
|
void exampleInit(GwApi *api){
|
||||||
|
api->getLogger()->logDebug(GwLog::LOG,"example init running");
|
||||||
|
}
|
||||||
#define INVALID_COORD -99999
|
#define INVALID_COORD -99999
|
||||||
class GetBoatDataRequest: public GwMessage{
|
class GetBoatDataRequest: public GwMessage{
|
||||||
private:
|
private:
|
||||||
|
@ -32,8 +38,7 @@ class GetBoatDataRequest: public GwMessage{
|
||||||
longitude=api->getBoatData()->Longitude->getDataWithDefault(INVALID_COORD);
|
longitude=api->getBoatData()->Longitude->getDataWithDefault(INVALID_COORD);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
void exampleTask(void *param){
|
void exampleTask(GwApi *api){
|
||||||
GwApi *api=(GwApi*)param;
|
|
||||||
GwLog *logger=api->getLogger();
|
GwLog *logger=api->getLogger();
|
||||||
//get some configuration data
|
//get some configuration data
|
||||||
bool exampleSwitch=api->getConfig()->getConfigItem(
|
bool exampleSwitch=api->getConfig()->getConfigItem(
|
||||||
|
|
|
@ -23,11 +23,19 @@
|
||||||
//brightness 0...255
|
//brightness 0...255
|
||||||
#define GWLED_BRIGHTNESS 64
|
#define GWLED_BRIGHTNESS 64
|
||||||
|
|
||||||
void exampleTask(void *param);
|
void exampleTask(GwApi *param);
|
||||||
|
void exampleInit(GwApi *param);
|
||||||
//make the task known to the core
|
//make the task known to the core
|
||||||
|
//the task function should not return (unless you delete the task - see example code)
|
||||||
DECLARE_USERTASK(exampleTask);
|
DECLARE_USERTASK(exampleTask);
|
||||||
|
//let the core call an init function before the
|
||||||
|
//N2K Stuff and the communication is set up
|
||||||
|
//normally you should not need this at all
|
||||||
|
//this function must return when done - otherwise the core will not start up
|
||||||
|
DECLARE_INITFUNCTION(exampleInit);
|
||||||
//we declare a capability that we can
|
//we declare a capability that we can
|
||||||
//use in config.json to only show some
|
//use in config.json to only show some
|
||||||
//elements when this capability is set correctly
|
//elements when this capability is set correctly
|
||||||
DECLARE_CAPABILITY(testboard,true);
|
DECLARE_CAPABILITY(testboard,true);
|
||||||
|
DECLARE_CAPABILITY(testboard2,true);
|
||||||
#endif
|
#endif
|
|
@ -1,7 +1,7 @@
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "exampleConfig",
|
"name": "exampleConfig",
|
||||||
"label": "logging on",
|
"label": "monitor position",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": "false",
|
"default": "false",
|
||||||
"description": "switch on logging of position acquired/failed",
|
"description": "switch on logging of position acquired/failed",
|
||||||
|
|
|
@ -17,10 +17,7 @@ NMEA0183DataToN2K::NMEA0183DataToN2K(GwLog *logger, GwBoatData *boatData,N2kSend
|
||||||
LOG_DEBUG(GwLog::LOG,"NMEA0183DataToN2K created %p",this);
|
LOG_DEBUG(GwLog::LOG,"NMEA0183DataToN2K created %p",this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NMEA0183DataToN2K::parseAndSend(const char *buffer, int sourceId) {
|
|
||||||
LOG_DEBUG(GwLog::DEBUG,"NMEA0183DataToN2K[%d] parsing %s",sourceId,buffer)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
class SNMEA0183Msg : public tNMEA0183Msg{
|
class SNMEA0183Msg : public tNMEA0183Msg{
|
||||||
public:
|
public:
|
||||||
|
@ -821,6 +818,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual bool parseAndSend(const char *buffer, int sourceId)
|
virtual bool parseAndSend(const char *buffer, int sourceId)
|
||||||
{
|
{
|
||||||
LOG_DEBUG(GwLog::DEBUG + 1, "NMEA0183DataToN2K[%d] parsing %s", sourceId, buffer)
|
LOG_DEBUG(GwLog::DEBUG + 1, "NMEA0183DataToN2K[%d] parsing %s", sourceId, buffer)
|
||||||
|
@ -843,7 +841,6 @@ public:
|
||||||
}
|
}
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned long *handledPgns()
|
virtual unsigned long *handledPgns()
|
||||||
{
|
{
|
||||||
return converters.handledPgns();
|
return converters.handledPgns();
|
||||||
|
|
|
@ -13,7 +13,7 @@ class NMEA0183DataToN2K{
|
||||||
N2kSender sender;
|
N2kSender sender;
|
||||||
public:
|
public:
|
||||||
NMEA0183DataToN2K(GwLog *logger,GwBoatData *boatData,N2kSender callback);
|
NMEA0183DataToN2K(GwLog *logger,GwBoatData *boatData,N2kSender callback);
|
||||||
virtual bool parseAndSend(const char *buffer, int sourceId);
|
virtual bool parseAndSend(const char *buffer, int sourceId)=0;
|
||||||
virtual unsigned long *handledPgns()=0;
|
virtual unsigned long *handledPgns()=0;
|
||||||
virtual int numConverters()=0;
|
virtual int numConverters()=0;
|
||||||
virtual String handledKeys()=0;
|
virtual String handledKeys()=0;
|
||||||
|
|
|
@ -1,29 +1,35 @@
|
||||||
#include "GwUserCode.h"
|
#include "GwUserCode.h"
|
||||||
|
#include "GwSynchronized.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
//user task handling
|
//user task handling
|
||||||
class UserTask{
|
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<GwUserTask> userTasks;
|
||||||
|
std::vector<GwUserTask> initTasks;
|
||||||
|
GwUserCode::Capabilities userCapabilities;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class GwUserTaskDef{
|
||||||
public:
|
public:
|
||||||
String name;
|
GwUserTaskDef(TaskFunction_t task,String name){
|
||||||
TaskFunction_t task;
|
userTasks.push_back(GwUserTask(name,task));
|
||||||
UserTask(String name,TaskFunction_t task){
|
}
|
||||||
this->name=name;
|
GwUserTaskDef(GwUserTaskFunction task,String name){
|
||||||
this->task=task;
|
userTasks.push_back(GwUserTask(name,task));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<UserTask> userTasks;
|
class GwInitTask{
|
||||||
GwUserCode::Capabilities userCapabilities;
|
|
||||||
|
|
||||||
void registerUserTask(TaskFunction_t task,String name){
|
|
||||||
userTasks.push_back(UserTask(name,task));
|
|
||||||
}
|
|
||||||
|
|
||||||
class GwUserTask{
|
|
||||||
public:
|
public:
|
||||||
GwUserTask(TaskFunction_t task,String name){
|
GwInitTask(TaskFunction_t task, String name){
|
||||||
registerUserTask(task,name);
|
initTasks.push_back(GwUserTask(name,task));
|
||||||
|
}
|
||||||
|
GwInitTask(GwUserTaskFunction task, String name){
|
||||||
|
initTasks.push_back(GwUserTask(name,task));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
class GwUserCapability{
|
class GwUserCapability{
|
||||||
|
@ -32,32 +38,37 @@ class GwUserCapability{
|
||||||
userCapabilities[name]=value;
|
userCapabilities[name]=value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#define DECLARE_USERTASK(task) GwUserTask __##task##__(task,#task);
|
#define DECLARE_USERTASK(task) GwUserTaskDef __##task##__(task,#task);
|
||||||
#define DECLARE_CAPABILITY(name,value) GwUserCapability __CAP##name__(#name,#value);
|
#define DECLARE_INITFUNCTION(task) GwInitTask __Init##task##__(task,#task);
|
||||||
#include "GwUserTasks.h"
|
#define DECLARE_CAPABILITY(name,value) GwUserCapability __CAP##name##__(#name,#value);
|
||||||
#include "GwApi.h"
|
#include "GwApi.h"
|
||||||
|
#include "GwUserTasks.h"
|
||||||
class TaskApi : public GwApi
|
class TaskApi : public GwApi
|
||||||
{
|
{
|
||||||
GwApi *api;
|
GwApi *api;
|
||||||
int sourceId;
|
int sourceId;
|
||||||
|
SemaphoreHandle_t *mainLock;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TaskApi(GwApi *api, int sourceId)
|
TaskApi(GwApi *api, int sourceId, SemaphoreHandle_t *mainLock)
|
||||||
{
|
{
|
||||||
this->sourceId = sourceId;
|
this->sourceId = sourceId;
|
||||||
this->api = api;
|
this->api = api;
|
||||||
|
this->mainLock=mainLock;
|
||||||
}
|
}
|
||||||
virtual GwRequestQueue *getQueue()
|
virtual GwRequestQueue *getQueue()
|
||||||
{
|
{
|
||||||
return api->getQueue();
|
return api->getQueue();
|
||||||
}
|
}
|
||||||
virtual void sendN2kMessage(const tN2kMsg &msg)
|
virtual void sendN2kMessage(const tN2kMsg &msg,bool convert)
|
||||||
{
|
{
|
||||||
api->sendN2kMessage(msg);
|
GWSYNCHRONIZED(mainLock);
|
||||||
|
api->sendN2kMessage(msg,convert);
|
||||||
}
|
}
|
||||||
virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId)
|
virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId, bool convert)
|
||||||
{
|
{
|
||||||
api->sendNMEA0183Message(msg, sourceId);
|
GWSYNCHRONIZED(mainLock);
|
||||||
|
api->sendNMEA0183Message(msg, this->sourceId,convert);
|
||||||
}
|
}
|
||||||
virtual int getSourceId()
|
virtual int getSourceId()
|
||||||
{
|
{
|
||||||
|
@ -75,27 +86,50 @@ public:
|
||||||
{
|
{
|
||||||
return api->getBoatData();
|
return api->getBoatData();
|
||||||
}
|
}
|
||||||
|
virtual ~TaskApi(){};
|
||||||
};
|
};
|
||||||
|
|
||||||
GwUserCode::GwUserCode(GwApi *api){
|
GwUserCode::GwUserCode(GwApi *api,SemaphoreHandle_t *mainLock){
|
||||||
this->logger=api->getLogger();
|
this->logger=api->getLogger();
|
||||||
this->api=api;
|
this->api=api;
|
||||||
|
this->mainLock=mainLock;
|
||||||
}
|
}
|
||||||
static void startAddOnTask(GwApi *api,TaskFunction_t task,int sourceId){
|
void userTaskStart(void *p){
|
||||||
TaskApi* taskApi=new TaskApi(api,sourceId);
|
GwUserTask *task=(GwUserTask*)p;
|
||||||
xTaskCreate(task,"user",2000,taskApi,3,NULL);
|
if (task->isUserTask){
|
||||||
|
task->usertask(task->api);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
task->task(task->api);
|
||||||
|
}
|
||||||
|
delete task->api;
|
||||||
|
task->api=NULL;
|
||||||
|
}
|
||||||
|
void GwUserCode::startAddOnTask(GwApi *api,GwUserTask *task,int sourceId,String name){
|
||||||
|
task->api=new TaskApi(api,sourceId,mainLock);
|
||||||
|
xTaskCreate(userTaskStart,name.c_str(),2000,task,3,NULL);
|
||||||
}
|
}
|
||||||
void GwUserCode::startUserTasks(int baseId){
|
void GwUserCode::startUserTasks(int baseId){
|
||||||
LOG_DEBUG(GwLog::DEBUG,"starting %d user tasks",userTasks.size());
|
LOG_DEBUG(GwLog::DEBUG,"starting %d user tasks",userTasks.size());
|
||||||
for (auto it=userTasks.begin();it != userTasks.end();it++){
|
for (auto it=userTasks.begin();it != userTasks.end();it++){
|
||||||
LOG_DEBUG(GwLog::LOG,"starting user task %s with id %d",it->name.c_str(),baseId);
|
LOG_DEBUG(GwLog::LOG,"starting user task %s with id %d",it->name.c_str(),baseId);
|
||||||
startAddOnTask(api,it->task,baseId);
|
startAddOnTask(api,&(*it),baseId,it->name);
|
||||||
|
baseId++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void GwUserCode::startInitTasks(int baseId){
|
||||||
|
LOG_DEBUG(GwLog::DEBUG,"starting %d user init tasks",initTasks.size());
|
||||||
|
for (auto it=initTasks.begin();it != initTasks.end();it++){
|
||||||
|
LOG_DEBUG(GwLog::LOG,"starting user init task %s with id %d",it->name.c_str(),baseId);
|
||||||
|
it->api=new TaskApi(api,baseId,mainLock);
|
||||||
|
userTaskStart(&(*it));
|
||||||
baseId++;
|
baseId++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void GwUserCode::startAddonTask(String name, TaskFunction_t task, int id){
|
void GwUserCode::startAddonTask(String name, TaskFunction_t task, int id){
|
||||||
LOG_DEBUG(GwLog::LOG,"starting addon task %s with id %d",name.c_str(),id);
|
LOG_DEBUG(GwLog::LOG,"starting addon task %s with id %d",name.c_str(),id);
|
||||||
startAddOnTask(api,task,id);
|
GwUserTask *userTask=new GwUserTask(name,task); //memory leak - acceptable as only during startup
|
||||||
|
startAddOnTask(api,userTask,id,userTask->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
GwUserCode::Capabilities * GwUserCode::getCapabilities(){
|
GwUserCode::Capabilities * GwUserCode::getCapabilities(){
|
||||||
|
|
|
@ -4,13 +4,34 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
class GwLog;
|
class GwLog;
|
||||||
class GwApi;
|
class GwApi;
|
||||||
|
typedef void (*GwUserTaskFunction)(GwApi *);
|
||||||
|
class GwUserTask{
|
||||||
|
public:
|
||||||
|
String name;
|
||||||
|
TaskFunction_t task=NULL;
|
||||||
|
GwUserTaskFunction usertask=NULL;
|
||||||
|
bool isUserTask=false;
|
||||||
|
GwApi *api=NULL;
|
||||||
|
GwUserTask(String name,TaskFunction_t task){
|
||||||
|
this->name=name;
|
||||||
|
this->task=task;
|
||||||
|
}
|
||||||
|
GwUserTask(String name, GwUserTaskFunction task){
|
||||||
|
this->name=name;
|
||||||
|
this->usertask=task;
|
||||||
|
this->isUserTask=true;
|
||||||
|
}
|
||||||
|
};
|
||||||
class GwUserCode{
|
class GwUserCode{
|
||||||
GwLog *logger;
|
GwLog *logger;
|
||||||
GwApi *api;
|
GwApi *api;
|
||||||
|
SemaphoreHandle_t *mainLock;
|
||||||
|
void startAddOnTask(GwApi *api,GwUserTask *task,int sourceId,String name);
|
||||||
public:
|
public:
|
||||||
typedef std::map<String,String> Capabilities;
|
typedef std::map<String,String> Capabilities;
|
||||||
GwUserCode(GwApi *api);
|
GwUserCode(GwApi *api, SemaphoreHandle_t *mainLock);
|
||||||
void startUserTasks(int baseId);
|
void startUserTasks(int baseId);
|
||||||
|
void startInitTasks(int baseId);
|
||||||
void startAddonTask(String name,TaskFunction_t task, int id);
|
void startAddonTask(String name,TaskFunction_t task, int id);
|
||||||
Capabilities *getCapabilities();
|
Capabilities *getCapabilities();
|
||||||
};
|
};
|
||||||
|
|
186
src/main.cpp
186
src/main.cpp
|
@ -61,6 +61,7 @@ const unsigned long HEAP_REPORT_TIME=2000; //set to 0 to disable heap reporting
|
||||||
#include "GwLeds.h"
|
#include "GwLeds.h"
|
||||||
#include "GwCounter.h"
|
#include "GwCounter.h"
|
||||||
#include "GwXDRMappings.h"
|
#include "GwXDRMappings.h"
|
||||||
|
#include "GwSynchronized.h"
|
||||||
#include "GwUserCode.h"
|
#include "GwUserCode.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,6 +73,8 @@ const unsigned long HEAP_REPORT_TIME=2000; //set to 0 to disable heap reporting
|
||||||
#define SERIAL1_CHANNEL_ID 2
|
#define SERIAL1_CHANNEL_ID 2
|
||||||
#define MIN_TCP_CHANNEL_ID 3
|
#define MIN_TCP_CHANNEL_ID 3
|
||||||
|
|
||||||
|
#define MIN_USER_TASK 200
|
||||||
|
|
||||||
#define MAX_NMEA2000_MESSAGE_SEASMART_SIZE 500
|
#define MAX_NMEA2000_MESSAGE_SEASMART_SIZE 500
|
||||||
#define MAX_NMEA0183_MESSAGE_SIZE 150 // For AIS
|
#define MAX_NMEA0183_MESSAGE_SIZE 150 // For AIS
|
||||||
|
|
||||||
|
@ -100,10 +103,9 @@ N2kDataToNMEA0183 *nmea0183Converter=NULL;
|
||||||
NMEA0183DataToN2K *toN2KConverter=NULL;
|
NMEA0183DataToN2K *toN2KConverter=NULL;
|
||||||
tActisenseReader *actisenseReader=NULL;
|
tActisenseReader *actisenseReader=NULL;
|
||||||
Stream *usbStream=NULL;
|
Stream *usbStream=NULL;
|
||||||
|
SemaphoreHandle_t mainLock;
|
||||||
|
|
||||||
|
|
||||||
void SendNMEA0183Message(const tNMEA0183Msg &NMEA0183Msg,int id);
|
|
||||||
|
|
||||||
GwRequestQueue mainQueue(&logger,20);
|
GwRequestQueue mainQueue(&logger,20);
|
||||||
GwWebServer webserver(&logger,&mainQueue,80);
|
GwWebServer webserver(&logger,&mainQueue,80);
|
||||||
|
|
||||||
|
@ -182,6 +184,81 @@ bool serCanRead=true;
|
||||||
GwSerial *usbSerial = new GwSerial(NULL, 0, USB_CHANNEL_ID);
|
GwSerial *usbSerial = new GwSerial(NULL, 0, USB_CHANNEL_ID);
|
||||||
GwSerial *serial1=NULL;
|
GwSerial *serial1=NULL;
|
||||||
|
|
||||||
|
void sendBufferToChannels(const char * buffer, int sourceId){
|
||||||
|
if (sendTCP->asBoolean() && checkFilter(buffer,MIN_TCP_CHANNEL_ID,false)){
|
||||||
|
socketServer.sendToClients(buffer,sourceId);
|
||||||
|
updateNMEACounter(MIN_TCP_CHANNEL_ID,buffer,false);
|
||||||
|
}
|
||||||
|
if (! actisenseReader && sendUsb->asBoolean() && checkFilter(buffer,USB_CHANNEL_ID,false)){
|
||||||
|
usbSerial->sendToClients(buffer,sourceId);
|
||||||
|
updateNMEACounter(USB_CHANNEL_ID,buffer,false);
|
||||||
|
}
|
||||||
|
if (serial1 && serCanWrite && checkFilter(buffer,SERIAL1_CHANNEL_ID,false)){
|
||||||
|
serial1->sendToClients(buffer,sourceId);
|
||||||
|
updateNMEACounter(SERIAL1_CHANNEL_ID,buffer,false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
typedef enum {
|
||||||
|
N2KT_MSGIN, //from CAN
|
||||||
|
N2KT_MSGINT, //from internal source
|
||||||
|
N2KT_MSGOUT, //from converter
|
||||||
|
N2KT_MSGACT //from actisense
|
||||||
|
} N2K_MsgDirection;
|
||||||
|
void handleN2kMessage(const tN2kMsg &n2kMsg,N2K_MsgDirection direction)
|
||||||
|
{
|
||||||
|
logger.logDebug(GwLog::DEBUG + 1, "N2K: pgn %d, dir %d",
|
||||||
|
n2kMsg.PGN,(int)direction);
|
||||||
|
if (direction == N2KT_MSGIN){
|
||||||
|
countNMEA2KIn.add(n2kMsg.PGN);
|
||||||
|
}
|
||||||
|
if (sendSeasmart->asBoolean())
|
||||||
|
{
|
||||||
|
char buf[MAX_NMEA2000_MESSAGE_SEASMART_SIZE];
|
||||||
|
if (N2kToSeasmart(n2kMsg, millis(), buf, MAX_NMEA2000_MESSAGE_SEASMART_SIZE) == 0)
|
||||||
|
return;
|
||||||
|
socketServer.sendToClients(buf, N2K_CHANNEL_ID);
|
||||||
|
}
|
||||||
|
if (actisenseReader && direction != N2KT_MSGACT && usbStream && usbSendActisens->asBoolean())
|
||||||
|
{
|
||||||
|
countUSBOut.add(String(n2kMsg.PGN));
|
||||||
|
n2kMsg.SendInActisenseFormat(usbStream);
|
||||||
|
}
|
||||||
|
if (direction != N2KT_MSGOUT){
|
||||||
|
nmea0183Converter->HandleMsg(n2kMsg);
|
||||||
|
}
|
||||||
|
if (direction != N2KT_MSGIN){
|
||||||
|
countNMEA2KOut.add(n2kMsg.PGN);
|
||||||
|
NMEA2000.SendMsg(n2kMsg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void handleReceivedNmeaMessage(const char *buf, int sourceId){
|
||||||
|
if (! checkFilter(buf,sourceId,true)) return;
|
||||||
|
updateNMEACounter(sourceId,buf,true);
|
||||||
|
if ( (sourceId >= MIN_USER_TASK) ||
|
||||||
|
(sourceId == USB_CHANNEL_ID && n2kFromUSB->asBoolean())||
|
||||||
|
(sourceId >= MIN_TCP_CHANNEL_ID && n2kFromTCP->asBoolean())||
|
||||||
|
(sourceId == SERIAL1_CHANNEL_ID && n2kFromSerial->asBoolean())
|
||||||
|
)
|
||||||
|
toN2KConverter->parseAndSend(buf,sourceId);
|
||||||
|
sendBufferToChannels(buf,sourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
void SendNMEA0183Message(const tNMEA0183Msg &NMEA0183Msg, int sourceId,bool convert=false) {
|
||||||
|
logger.logDebug(GwLog::DEBUG+2,"SendNMEA0183(1)");
|
||||||
|
char buf[MAX_NMEA0183_MESSAGE_SIZE+3];
|
||||||
|
if ( !NMEA0183Msg.GetMessage(buf, MAX_NMEA0183_MESSAGE_SIZE) ) return;
|
||||||
|
logger.logDebug(GwLog::DEBUG+2,"SendNMEA0183: %s",buf);
|
||||||
|
if (convert){
|
||||||
|
toN2KConverter->parseAndSend(buf,sourceId);
|
||||||
|
}
|
||||||
|
size_t len=strlen(buf);
|
||||||
|
buf[len]=0x0d;
|
||||||
|
buf[len+1]=0x0a;
|
||||||
|
buf[len+2]=0;
|
||||||
|
sendBufferToChannels(buf,sourceId);
|
||||||
|
}
|
||||||
|
|
||||||
class GwSerialLog : public GwLogWriter{
|
class GwSerialLog : public GwLogWriter{
|
||||||
static const size_t bufferSize=4096;
|
static const size_t bufferSize=4096;
|
||||||
|
@ -216,6 +293,7 @@ class GwSerialLog : public GwLogWriter{
|
||||||
|
|
||||||
GwSerialLog logWriter;
|
GwSerialLog logWriter;
|
||||||
|
|
||||||
|
|
||||||
class ApiImpl : public GwApi
|
class ApiImpl : public GwApi
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -230,13 +308,14 @@ public:
|
||||||
{
|
{
|
||||||
return &mainQueue;
|
return &mainQueue;
|
||||||
}
|
}
|
||||||
virtual void sendN2kMessage(const tN2kMsg &msg)
|
virtual void sendN2kMessage(const tN2kMsg &msg,bool convert)
|
||||||
{
|
{
|
||||||
NMEA2000.SendMsg(msg);
|
handleN2kMessage(msg,convert?N2KT_MSGINT:N2KT_MSGOUT);
|
||||||
|
|
||||||
}
|
}
|
||||||
virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId)
|
virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId,bool convert)
|
||||||
{
|
{
|
||||||
SendNMEA0183Message(msg, sourceId);
|
SendNMEA0183Message(msg, sourceId,convert);
|
||||||
}
|
}
|
||||||
virtual int getSourceId()
|
virtual int getSourceId()
|
||||||
{
|
{
|
||||||
|
@ -252,6 +331,7 @@ public:
|
||||||
virtual GwBoatData *getBoatData(){
|
virtual GwBoatData *getBoatData(){
|
||||||
return &boatData;
|
return &boatData;
|
||||||
}
|
}
|
||||||
|
virtual ~ApiImpl(){}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool delayedRestart(){
|
bool delayedRestart(){
|
||||||
|
@ -264,7 +344,7 @@ bool delayedRestart(){
|
||||||
},"reset",1000,&logger,0,NULL) == pdPASS;
|
},"reset",1000,&logger,0,NULL) == pdPASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
GwUserCode userCodeHandler(new ApiImpl(200));
|
GwUserCode userCodeHandler(new ApiImpl(MIN_USER_TASK),&mainLock);
|
||||||
|
|
||||||
#define JSON_OK "{\"status\":\"OK\"}"
|
#define JSON_OK "{\"status\":\"OK\"}"
|
||||||
|
|
||||||
|
@ -488,25 +568,10 @@ protected:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//received or converted N2K message
|
|
||||||
void handleN2kMessage(const tN2kMsg &n2kMsg){
|
|
||||||
if ( sendSeasmart->asBoolean() ) {
|
|
||||||
char buf[MAX_NMEA2000_MESSAGE_SEASMART_SIZE];
|
|
||||||
if ( N2kToSeasmart(n2kMsg, millis(), buf, MAX_NMEA2000_MESSAGE_SEASMART_SIZE) == 0 ) return;
|
|
||||||
socketServer.sendToClients(buf,N2K_CHANNEL_ID);
|
|
||||||
}
|
|
||||||
logger.logDebug(GwLog::DEBUG+1,"handling pgn %d",n2kMsg.PGN);
|
|
||||||
nmea0183Converter->HandleMsg(n2kMsg);
|
|
||||||
logger.logDebug(GwLog::DEBUG+1,"done pgn %d",n2kMsg.PGN);
|
|
||||||
};
|
|
||||||
void trySendActisense(const tN2kMsg &n2kMsg){
|
|
||||||
if (actisenseReader && usbStream && usbSendActisens->asBoolean()){
|
|
||||||
countUSBOut.add(String(n2kMsg.PGN));
|
|
||||||
n2kMsg.SendInActisenseFormat(usbStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void setup() {
|
|
||||||
|
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
mainLock=xSemaphoreCreateMutex();
|
||||||
uint8_t chipid[6];
|
uint8_t chipid[6];
|
||||||
uint32_t id = 0;
|
uint32_t id = 0;
|
||||||
config.loadConfig();
|
config.loadConfig();
|
||||||
|
@ -533,6 +598,7 @@ void setup() {
|
||||||
logger.logDebug(GwLog::LOG,"created GwSerial for USB port");
|
logger.logDebug(GwLog::LOG,"created GwSerial for USB port");
|
||||||
}
|
}
|
||||||
logger.logDebug(GwLog::LOG,"config: %s", config.toString().c_str());
|
logger.logDebug(GwLog::LOG,"config: %s", config.toString().c_str());
|
||||||
|
userCodeHandler.startInitTasks(MIN_USER_TASK);
|
||||||
#ifdef GWSERIAL_MODE
|
#ifdef GWSERIAL_MODE
|
||||||
int serialrx=-1;
|
int serialrx=-1;
|
||||||
int serialtx=-1;
|
int serialtx=-1;
|
||||||
|
@ -623,13 +689,14 @@ void setup() {
|
||||||
logger.flush();
|
logger.flush();
|
||||||
|
|
||||||
nmea0183Converter= N2kDataToNMEA0183::create(&logger, &boatData,
|
nmea0183Converter= N2kDataToNMEA0183::create(&logger, &boatData,
|
||||||
SendNMEA0183Message, N2K_CHANNEL_ID,config.getString(config.talkerId,String("GP")),&xdrMappings);
|
[](const tNMEA0183Msg &msg, int sourceId){
|
||||||
|
SendNMEA0183Message(msg,sourceId,false);
|
||||||
|
}
|
||||||
|
, N2K_CHANNEL_ID,config.getString(config.talkerId,String("GP")),&xdrMappings);
|
||||||
|
|
||||||
toN2KConverter= NMEA0183DataToN2K::create(&logger,&boatData,[](const tN2kMsg &msg)->bool{
|
toN2KConverter= NMEA0183DataToN2K::create(&logger,&boatData,[](const tN2kMsg &msg)->bool{
|
||||||
logger.logDebug(GwLog::DEBUG+2,"send N2K %ld",msg.PGN);
|
logger.logDebug(GwLog::DEBUG+2,"send N2K %ld",msg.PGN);
|
||||||
countNMEA2KOut.add(msg.PGN);
|
handleN2kMessage(msg,N2KT_MSGOUT);
|
||||||
NMEA2000.SendMsg(msg);
|
|
||||||
trySendActisense(msg);
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -683,16 +750,12 @@ void setup() {
|
||||||
usbStream=usbSerial->getStream(false);
|
usbStream=usbSerial->getStream(false);
|
||||||
actisenseReader->SetReadStream(usbStream);
|
actisenseReader->SetReadStream(usbStream);
|
||||||
actisenseReader->SetMsgHandler([](const tN2kMsg &msg){
|
actisenseReader->SetMsgHandler([](const tN2kMsg &msg){
|
||||||
countNMEA2KOut.add(msg.PGN);
|
|
||||||
NMEA2000.SendMsg(msg);
|
|
||||||
handleN2kMessage(msg);
|
|
||||||
countUSBIn.add(String(msg.PGN));
|
countUSBIn.add(String(msg.PGN));
|
||||||
|
handleN2kMessage(msg,N2KT_MSGACT);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
NMEA2000.SetMsgHandler([](const tN2kMsg &n2kMsg){
|
NMEA2000.SetMsgHandler([](const tN2kMsg &n2kMsg){
|
||||||
countNMEA2KIn.add(n2kMsg.PGN);
|
handleN2kMessage(n2kMsg,N2KT_MSGIN);
|
||||||
trySendActisense(n2kMsg);
|
|
||||||
handleN2kMessage(n2kMsg);
|
|
||||||
});
|
});
|
||||||
NMEA2000.Open();
|
NMEA2000.Open();
|
||||||
logger.logDebug(GwLog::LOG,"starting addon tasks");
|
logger.logDebug(GwLog::LOG,"starting addon tasks");
|
||||||
|
@ -700,58 +763,14 @@ void setup() {
|
||||||
userCodeHandler.startAddonTask(F("handleButtons"),handleButtons,100);
|
userCodeHandler.startAddonTask(F("handleButtons"),handleButtons,100);
|
||||||
setLedMode(LED_GREEN);
|
setLedMode(LED_GREEN);
|
||||||
userCodeHandler.startAddonTask(F("handleLeds"),handleLeds,101);
|
userCodeHandler.startAddonTask(F("handleLeds"),handleLeds,101);
|
||||||
userCodeHandler.startUserTasks(200);
|
{
|
||||||
|
GWSYNCHRONIZED(&mainLock);
|
||||||
|
userCodeHandler.startUserTasks(MIN_USER_TASK);
|
||||||
|
}
|
||||||
|
|
||||||
logger.logDebug(GwLog::LOG,"setup done");
|
logger.logDebug(GwLog::LOG,"setup done");
|
||||||
}
|
}
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void sendBufferToChannels(const char * buffer, int sourceId){
|
|
||||||
if (sendTCP->asBoolean() && checkFilter(buffer,MIN_TCP_CHANNEL_ID,false)){
|
|
||||||
socketServer.sendToClients(buffer,sourceId);
|
|
||||||
updateNMEACounter(MIN_TCP_CHANNEL_ID,buffer,false);
|
|
||||||
}
|
|
||||||
if (! actisenseReader && sendUsb->asBoolean() && checkFilter(buffer,USB_CHANNEL_ID,false)){
|
|
||||||
usbSerial->sendToClients(buffer,sourceId);
|
|
||||||
updateNMEACounter(USB_CHANNEL_ID,buffer,false);
|
|
||||||
}
|
|
||||||
if (serial1 && serCanWrite && checkFilter(buffer,SERIAL1_CHANNEL_ID,false)){
|
|
||||||
serial1->sendToClients(buffer,sourceId);
|
|
||||||
updateNMEACounter(SERIAL1_CHANNEL_ID,buffer,false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
void SendNMEA0183Message(const tNMEA0183Msg &NMEA0183Msg, int sourceId) {
|
|
||||||
if ( ! sendTCP->asBoolean() && ! sendUsb->asBoolean() ) return;
|
|
||||||
logger.logDebug(GwLog::DEBUG+2,"SendNMEA0183(1)");
|
|
||||||
char buf[MAX_NMEA0183_MESSAGE_SIZE+3];
|
|
||||||
if ( !NMEA0183Msg.GetMessage(buf, MAX_NMEA0183_MESSAGE_SIZE) ) return;
|
|
||||||
logger.logDebug(GwLog::DEBUG+2,"SendNMEA0183: %s",buf);
|
|
||||||
size_t len=strlen(buf);
|
|
||||||
buf[len]=0x0d;
|
|
||||||
buf[len+1]=0x0a;
|
|
||||||
buf[len+2]=0;
|
|
||||||
sendBufferToChannels(buf,sourceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleReceivedNmeaMessage(const char *buf, int sourceId){
|
|
||||||
if (! checkFilter(buf,sourceId,true)) return;
|
|
||||||
updateNMEACounter(sourceId,buf,true);
|
|
||||||
if ((sourceId == USB_CHANNEL_ID && n2kFromUSB->asBoolean())||
|
|
||||||
(sourceId >= MIN_TCP_CHANNEL_ID && n2kFromTCP->asBoolean())||
|
|
||||||
(sourceId == SERIAL1_CHANNEL_ID && n2kFromSerial->asBoolean())
|
|
||||||
)
|
|
||||||
toN2KConverter->parseAndSend(buf,sourceId);
|
|
||||||
sendBufferToChannels(buf,sourceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleSendAndRead(bool handleRead){
|
void handleSendAndRead(bool handleRead){
|
||||||
socketServer.loop(handleRead);
|
socketServer.loop(handleRead);
|
||||||
usbSerial->loop(handleRead);
|
usbSerial->loop(handleRead);
|
||||||
|
@ -800,6 +819,7 @@ class NMEAMessageReceiver : public GwBufferWriter{
|
||||||
NMEAMessageReceiver receiver;
|
NMEAMessageReceiver receiver;
|
||||||
unsigned long lastHeapReport=0;
|
unsigned long lastHeapReport=0;
|
||||||
void loop() {
|
void loop() {
|
||||||
|
GWSYNCHRONIZED(&mainLock);
|
||||||
logger.flush();
|
logger.flush();
|
||||||
gwWifi.loop();
|
gwWifi.loop();
|
||||||
unsigned long now=millis();
|
unsigned long now=millis();
|
||||||
|
|
Loading…
Reference in New Issue