Skip to content

Commit

Permalink
can logging: working tcp client and server
Browse files Browse the repository at this point in the history
  • Loading branch information
markwj committed Jul 9, 2019
1 parent 5c5273e commit d988f20
Show file tree
Hide file tree
Showing 4 changed files with 258 additions and 17 deletions.
121 changes: 112 additions & 9 deletions vehicle/OVMS.V3/components/can/src/canlog_tcpclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ static const char *TAG = "canlog-tcpclient";
#include "ovms_config.h"
#include "ovms_peripherals.h"

canlog_tcpclient* MyCanLogTcpClient = NULL;

void can_log_tcpclient_start(int verbosity, OvmsWriter* writer, OvmsCommand* cmd, int argc, const char* const* argv)
{
std::string format(cmd->GetName());
Expand Down Expand Up @@ -85,36 +87,74 @@ OvmsCanLogTcpClientInit::OvmsCanLogTcpClientInit()
}
}

static void tcMongooseHandler(struct mg_connection *nc, int ev, void *p)
{
if (MyCanLogTcpClient)
MyCanLogTcpClient->MongooseHandler(nc, ev, p);
else if (ev == MG_EV_ACCEPT)
{
ESP_LOGI(TAG, "Log service connection rejected (logger not running)");
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
}
}

canlog_tcpclient::canlog_tcpclient(std::string path, std::string format)
: canlog("tcpclient", format)
{
MyCanLogTcpClient = this;
m_mgconn = NULL;
m_isopen = false;
m_path = path;
}

canlog_tcpclient::~canlog_tcpclient()
{
Close();
MyCanLogTcpClient = NULL;
}

bool canlog_tcpclient::Open()
{
//ESP_LOGI(TAG, "Now logging CAN messages as a tcp client to %s",m_path.c_str());
//std::string header = m_formatter->getheader();
//if (header.length()>0)
// { ESP_LOGD(TAG,"%s",header.c_str()); }

ESP_LOGE(TAG, "Not yet implemented");
return false;
struct mg_mgr* mgr = MyNetManager.GetMongooseMgr();
if (mgr != NULL)
{
ESP_LOGI(TAG, "Launching TCP client to %s",m_path.c_str());
struct mg_connect_opts opts;
const char* err;
memset(&opts, 0, sizeof(opts));
opts.error_string = &err;
if ((m_mgconn = mg_connect_opt(mgr, m_path.c_str(), tcMongooseHandler, opts)) != NULL)
{
m_isopen = true;
return true;
}
else
{
ESP_LOGE(TAG,"Could not connect to %s",m_path.c_str());
return false;
}
}
else
{
ESP_LOGE(TAG,"Network manager is not available");
return false;
}
}

void canlog_tcpclient::Close()
{
ESP_LOGI(TAG, "Closed TCP client log: %s", GetStats().c_str());
if ((m_isopen)&&(m_mgconn != NULL))
{
ESP_LOGI(TAG, "Closed TCP client log: %s", GetStats().c_str());
m_mgconn->flags |= MG_F_CLOSE_IMMEDIATELY;
m_mgconn = NULL;
m_isopen = false;
}
}

bool canlog_tcpclient::IsOpen()
{
return false;
return m_isopen;
}

std::string canlog_tcpclient::GetInfo()
Expand All @@ -128,4 +168,67 @@ std::string canlog_tcpclient::GetInfo()
void canlog_tcpclient::OutputMsg(CAN_log_message_t& msg)
{
if (m_formatter == NULL) return;

if ((m_mgconn != NULL)&&(m_isopen))
{
std::string result = m_formatter->get(&msg);
if (result.length()>0)
{
if (m_mgconn->send_mbuf.len < 4096)
{
mg_send(m_mgconn, (const char*)result.c_str(), result.length());
}
else
{
m_dropcount++;
}
}
}
}

void canlog_tcpclient::MongooseHandler(struct mg_connection *nc, int ev, void *p)
{
switch (ev)
{
case MG_EV_CONNECT:
{
int *success = (int*)p;
ESP_LOGV(TAG, "MongooseHandler(MG_EV_CONNECT=%d)",*success);
if (*success == 0)
{
// Successful connection
ESP_LOGI(TAG, "Connection successful to %s",m_path.c_str());
if (m_formatter != NULL)
{
std::string result = m_formatter->getheader();
if (result.length()>0)
{
mg_send(nc, (const char*)result.c_str(), result.length());
}
}
}
else
{
// Connection failed
ESP_LOGE(TAG, "Connection failed to %s",m_path.c_str());
m_mgconn = NULL;
m_isopen = false;
}
}
break;
case MG_EV_CLOSE:
ESP_LOGV(TAG, "MongooseHandler(MG_EV_CLOSE)");
if (m_isopen)
{
ESP_LOGE(TAG,"Disconnected from %s",m_path.c_str());
m_mgconn = NULL;
m_isopen = false;
}
break;
case MG_EV_RECV:
ESP_LOGV(TAG, "MongooseHandler(MG_EV_RECV)");
break;
default:
break;
}
}
8 changes: 8 additions & 0 deletions vehicle/OVMS.V3/components/can/src/canlog_tcpclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#define __CANLOG_TCP_CLIENT_H__

#include "canlog.h"
#include "ovms_netmanager.h"

class canlog_tcpclient : public canlog
{
Expand All @@ -45,6 +46,13 @@ class canlog_tcpclient : public canlog
public:
virtual void OutputMsg(CAN_log_message_t& msg);

public:
void MongooseHandler(struct mg_connection *nc, int ev, void *p);

public:
struct mg_connection *m_mgconn;
bool m_isopen;

public:
std::string m_path;
};
Expand Down
132 changes: 124 additions & 8 deletions vehicle/OVMS.V3/components/can/src/canlog_tcpserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
; THE SOFTWARE.
*/

#include <sdkconfig.h>
#ifdef CONFIG_OVMS_SC_GPL_MONGOOSE

#include "ovms_log.h"
static const char *TAG = "canlog-tcpserver";

Expand All @@ -33,6 +36,8 @@ static const char *TAG = "canlog-tcpserver";
#include "ovms_config.h"
#include "ovms_peripherals.h"

canlog_tcpserver* MyCanLogTcpServer = NULL;

void can_log_tcpserver_start(int verbosity, OvmsWriter* writer, OvmsCommand* cmd, int argc, const char* const* argv)
{
std::string format(cmd->GetName());
Expand Down Expand Up @@ -85,36 +90,81 @@ OvmsCanLogTcpServerInit::OvmsCanLogTcpServerInit()
}
}

static void tsMongooseHandler(struct mg_connection *nc, int ev, void *p)
{
if (MyCanLogTcpServer)
MyCanLogTcpServer->MongooseHandler(nc, ev, p);
else if (ev == MG_EV_ACCEPT)
{
ESP_LOGI(TAG, "Log service connection rejected (logger not running)");
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
}
}

canlog_tcpserver::canlog_tcpserver(std::string path, std::string format)
: canlog("tcpserver", format)
{
MyCanLogTcpServer = this;
m_path = path;
if (m_path.find(':') == std::string::npos)
{
m_path.append(":3000");
}
m_isopen = false;
}

canlog_tcpserver::~canlog_tcpserver()
{
Close();
MyCanLogTcpServer = NULL;
}

bool canlog_tcpserver::Open()
{
//ESP_LOGI(TAG, "Now logging CAN messages as a tcp server on %s",m_path.c_str());
//std::string header = m_formatter->getheader();
//if (header.length()>0)
// { ESP_LOGD(TAG,"%s",header.c_str()); }
if (m_isopen) return true;

ESP_LOGE(TAG, "Not yet implemented");
return false;
ESP_LOGI(TAG, "Launching TCP server at %s",m_path.c_str());
struct mg_mgr* mgr = MyNetManager.GetMongooseMgr();
if (mgr != NULL)
{
if (mg_bind(mgr, m_path.c_str(), tsMongooseHandler))
{
m_isopen = true;
return true;
}
else
{
ESP_LOGE(TAG,"Could not listen on %s",m_path.c_str());
return false;
}
}
else
{
ESP_LOGE(TAG,"Network manager is not available");
return false;
}
}

void canlog_tcpserver::Close()
{
ESP_LOGI(TAG, "Closed TCP server log: %s", GetStats().c_str());
if (m_isopen)
{
if (m_smap.size() > 0)
{
for (ts_map_t::iterator it=m_smap.begin(); it!=m_smap.end(); ++it)
{
it->first->flags |= MG_F_CLOSE_IMMEDIATELY;
}
m_smap.clear();
}
ESP_LOGI(TAG, "Closed TCP server log: %s", GetStats().c_str());
m_isopen = false;
}
}

bool canlog_tcpserver::IsOpen()
{
return false;
return m_isopen;
}

std::string canlog_tcpserver::GetInfo()
Expand All @@ -128,4 +178,70 @@ std::string canlog_tcpserver::GetInfo()
void canlog_tcpserver::OutputMsg(CAN_log_message_t& msg)
{
if (m_formatter == NULL) return;

std::string result = m_formatter->get(&msg);
if (result.length()>0)
{
for (ts_map_t::iterator it=m_smap.begin(); it!=m_smap.end(); ++it)
{
if (it->first->send_mbuf.len < 4096)
{
// Limit to 4KB queue on output buffer
mg_send(it->first, (const char*)result.c_str(), result.length());
}
else
{
m_dropcount++;
}
}
}
}

void canlog_tcpserver::MongooseHandler(struct mg_connection *nc, int ev, void *p)
{
char addr[32];

switch (ev)
{
case MG_EV_ACCEPT:
{
// New network connection has arrived
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP);
ESP_LOGI(TAG, "Log service connection from %s",addr);
m_smap[nc] = 1;
if (m_formatter != NULL)
{
std::string result = m_formatter->getheader();
if (result.length()>0)
{
mg_send(nc, (const char*)result.c_str(), result.length());
}
}
break;
}

case MG_EV_CLOSE:
{
// Network connection has gone
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP);
ESP_LOGI(TAG, "Log service disconnection from %s",addr);
auto k = m_smap.find(nc);
if (k != m_smap.end())
m_smap.erase(k);
break;
}

case MG_EV_RECV:
{
// Receive data on the network connection
size_t bl = nc->recv_mbuf.len;
mbuf_remove(&nc->recv_mbuf, bl);
break;
}

default:
break;
}
}

#endif // #ifdef CONFIG_OVMS_SC_GPL_MONGOOSE
14 changes: 14 additions & 0 deletions vehicle/OVMS.V3/components/can/src/canlog_tcpserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@
#ifndef __CANLOG_TCP_SERVER_H__
#define __CANLOG_TCP_SERVER_H__

#include <sdkconfig.h>
#ifdef CONFIG_OVMS_SC_GPL_MONGOOSE

#include "canlog.h"
#include "canlog_tcpserver.h"
#include "ovms_netmanager.h"

class canlog_tcpserver : public canlog
{
Expand All @@ -45,8 +50,17 @@ class canlog_tcpserver : public canlog
public:
virtual void OutputMsg(CAN_log_message_t& msg);

public:
void MongooseHandler(struct mg_connection *nc, int ev, void *p);

public:
typedef std::map<mg_connection*, uint8_t> ts_map_t;
ts_map_t m_smap;
bool m_isopen;

public:
std::string m_path;
};

#endif // #ifdef CONFIG_OVMS_SC_GPL_MONGOOSE
#endif // __CANLOG_TCP_SERVER_H__

0 comments on commit d988f20

Please sign in to comment.