Solving "redeclared as different kind of symbol" error - websocket

I'm currently working on Arduino. I'm working for Lamp using Atmega1284. I saw an example code, ModbusIP_ENC28J60 -> Lamp. I first compiled it without adding anything, it compiled properly. Now, I'm adding WebSocketServer, since I want this to work on websocket too. I added few necessary lines, but I ended up with this error:
error: 'EthernetClass Ethernet' redeclared as different kind of symbol
I don't understand what's wrong with the code or what I should change. Can someone help me with this?
I'm pasting my code here for reference:
#include <EtherCard.h>
#include <Modbus.h>
#include <ModbusIP_ENC28J60.h>
#include <WebSocketsServer.h>
WebSocketsServer webSocketServer = WebSocketsServer(8080);
//Modbus Registers Offsets (0-9999)
const int LAMP1_COIL = 100;
//Used Pins
const int ledPin = 9;
//ModbusIP object
ModbusIP mb;
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) {
switch(type) {
case WStype_DISCONNECTED:
Serial.println("[%u] Disconnected!\n");
break;
case WStype_CONNECTED:
{
//IPAddress ip = webSocket.remoteIP(num);
Serial.println("[%u] Disconnected!\n");
// send message to client
//webSocket.sendTXT(num, "Connected");
}
break;
case WStype_TEXT:
Serial.println("[%u] got text!\n");
// send message to client
// webSocket.sendTXT(num, "message here");
// send data to all connected clients
// webSocket.broadcastTXT("message here");
break;
case WStype_BIN:
Serial.println("[%u] get binary ");
//hexdump(payload, lenght);
// send message to client
// webSocket.sendBIN(num, payload, lenght);
break;
}
}
void setup() {
// The media access control (ethernet hardware) address for the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// The IP address for the shield
byte ip[] = { 192, 168, 0, 120 };
//Config Modbus IP
mb.config(mac, ip);
//Set ledPin mode
pinMode(ledPin, OUTPUT);
// Add LAMP1_COIL register - Use addCoil() for digital outputs
mb.addCoil(LAMP1_COIL);
webSocketServer.begin();
webSocketServer.onEvent(webSocketEvent);
}
void loop() {
//Call once inside loop() - all magic here
mb.task();
//Attach ledPin to LAMP1_COIL register
digitalWrite(ledPin, mb.Coil(LAMP1_COIL));
webSocketServer.loop();
}
Help me to make it work.

You are declaring Ethernet twice. And they are different.
First is probably in the include file Ethercard.h
Second is Modbus.h
In the ModbusIP_ENC28J60 I found in github via Google they declare Ethernet as an array.
Either rename one declaration (e.g. ether vs Ethernet) or eliminate the use of one. Also, considering the include files in your source I would be surprised if there are only two conflicts.
C lesson: Declaring a variable for use by a function, very straightforward. When adding additional modules any name conflicts will cause problems. If you get two variables to agree but are still in the program you will suffer massive debugging headaches because one function will access its variable while the other will have its own, resulting in nothing actually working.
Go back and look at the source files (*.h). Search for "Ethernet" variables. See how they are declared and how they are used. The simplest solution is to pick the latest addition and change Ethernet to ether (as I suggested above).
Good Luck.

Related

Generate an RPC code for a client to remotely call the existing server functions?

Before I ask the main question, I have two existing client/server win32 projects based on sockets in which the client sends a string request for the server and receives the result as a string using socket functions i.e. send(), recv()
a part of the server code (currently still based on sockets)
struct client_ctx
{
int socket;
CHAR buf_recv[MAX_SEND_BUF_SIZE]; // receive buffer
CHAR buf_send[MAX_SEND_BUF_SIZE]; // send buffer
unsigned int sz_recv; // size of recv buffer
unsigned int sz_send_total; // size of send buffer
unsigned int sz_send; // size of data send
// OVERLAPPED structures for notifications of completition
OVERLAPPED overlap_recv;
OVERLAPPED overlap_send;
OVERLAPPED overlap_cancel;
DWORD flags_recv; // Flags for WSARecv
};
struct client_ctx g_ctxs[1 + MAX_CLIENTS];
void schedule_write(DWORD idx)
{
WSABUF buf; buf.buf = g_ctxs[idx].buf_send + g_ctxs[idx].sz_send;
buf.len = g_ctxs[idx].sz_send_total - g_ctxs[idx].sz_send;
memset(&g_ctxs[idx].overlap_send, 0, sizeof(OVERLAPPED));
WSASend(g_ctxs[idx].socket, &buf, 1, NULL, 0, &g_ctxs[idx].overlap_send, NULL);
}
And using the above functions I send the requested data to the client
The data I send from the server
static class SystemInfo{
public :
static std::string GetOSVersion();
static std::string GetCurrentTimeStr();
static std::string GetTimeSinceStartStr();
static std::string GetFreeMemoryStr();
static std::string GetFreeSpaceStr();
static std::string CheckAccess();
static std::string CheckKeyFileDirectoryAccessRights(wchar_t *char_path, wchar_t *char_buf);
static std::string UserNameFromSid(PSID userSid);
static BOOL FileOrDirectoryExists(LPCTSTR szPath);
};
And the question is: is there any guide on how can I use the midl compiler to be able to represent the methods from SystemInfo class as procedures that can be called remotely? I can't find any manual of How to connect the existing functions with the remote procedure calls (and use them from the client side in my case)
You aren't going to be able to hook the client calls directly to existing server functions. Even when implicit binding handles are used on the client side the actual server function gets a binding handle (otherwise the server wouldn't be able to handle multiple clients). Because of that the signatures simply aren't going to match.

Using AODV in a wired simulation

I am trying to use AODV in a wired simulation but I can't make it work, is it possible to link 2 AODVRouters by wire and use the AODV protocol?? or should I use 2 standardhost and modify the AODVrouting.cc??
EDIT:
I just simulate the AODV simpleRREQ example using standardhosts instead of AODVrouters and using the debug mode it crashes in this piece of code:
void AODVRouting::sendAODVPacket(AODVControlPacket *packet, const L3Address& destAddr, unsigned int timeToLive, double delay)
{INetworkProtocolControlInfo *networkProtocolControlInfo = addressType->createNetworkProtocolControlInfo();
networkProtocolControlInfo->setHopLimit(timeToLive);
networkProtocolControlInfo->setTransportProtocol(IP_PROT_MANET);
networkProtocolControlInfo->setDestinationAddress(destAddr);
networkProtocolControlInfo->setSourceAddress(getSelfIPAddress());
// TODO: Implement: support for multiple interfaces
InterfaceEntry *ifEntry = interfaceTable->getInterfaceByName("AODV");
networkProtocolControlInfo->setInterfaceId(ifEntry->getInterfaceId());
UDPPacket *udpPacket = new UDPPacket(packet->getName());
udpPacket->encapsulate(packet);
udpPacket->setSourcePort(aodvUDPPort);
udpPacket->setDestinationPort(aodvUDPPort);
udpPacket->setControlInfo(dynamic_cast<cObject *>(networkProtocolControlInfo));
if (destAddr.isBroadcast())
lastBroadcastTime = simTime();
if (delay == 0)
send(udpPacket, "ipOut");
else
sendDelayed(udpPacket, delay, "ipOut");
}
How can I send the AODV packet throw all the ethernet ports of the router?

Efficiently write log file on Windows

I want to write log files. My application could be run on Linux and Windows. I've pretty much figured out how to do it for the former, thanks to this example:
void SyslogMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
Q_UNUSED(context)
QByteArray localMsg = msg.toLocal8Bit();
switch (type)
{
case QtDebugMsg:
#ifdef __linux__
syslog(LOG_DEBUG, "Message (debug): %s", localMsg.constData());
#elif _WIN32
// WRITE INTO FILE
#else
#endif
break;
// etc.
}
}
int main()
{
// Install our message handler.
qInstallMessageHandler(SyslogMessageHandler);
// Send some messages, which should go to syslog.
qDebug("Debug log message from Qt test program");
}
source (2nd example)
However, I am wondering what would be the fastest way for Windows? Is using QFile or QTextStream an efficient way for writing this kind of information?
I was thinking about storing everything in a simple QString and then put everything in a file when the app closes or crashes (in the latter case, is that possible?).

ATtiny85 serial communication with multiple inputs

In a project, we try to set up a communication network between three ATtinys, where the first must receive messages from the other two. Those other two tinys are connected to two different pins of the first tiny. The first tiny must then receive two strings from the other tinys, one from each, and send it to an Arduino. For the communication we used SoftwareSerial. We managed to receive and send the input from one tiny, but not from both of them, because we could not find a way to read the input from only one specific pin at a time.
This is the code we used:
#include <SoftwareSerial.h>
const int rx=4;
const int rx2=1;
const int tx=3;
const int tx2=3;
SoftwareSerial mySerial(rx,tx);
SoftwareSerial mySerial2(rx2,tx2);
void setup()
{
pinMode(rx,INPUT);
pinMode(rx2,INPUT);
pinMode(tx,OUTPUT);
mySerial.begin(9600);
mySerial2.begin(9600);
}
void loop()
{
mySerial.listen();
if (mySerial.isListening()) {
mySerial.println("Port One is listening!");
mySerial.println(mySerial.read());
}
else{
mySerial.println("Port One is not listening!");
}
mySerial2.listen();
if (mySerial2.isListening()) {
mySerial2.println("Port Two is listening!");
mySerial2.println(mySerial2.read());
}
else{
mySerial2.println("Port Two is not listening!");
}
delay(500);
}
The code above worked without the part after mySerial2.listen();. Maybe the listen-function of SoftwareSerial does not work on the tinys, but if that is the case, is there another way to listen to a specific input pin?
Or do you have any advice what to do?

How to create a simple server/client application using boost.asio?

I was going over the examples of boost.asio and I am wondering why there isn't an example of a simple server/client example that prints a string on the server and then returns a response to the client.
I tried to modify the echo server but I can't really figure out what I'm doing at all.
Can anyone find me a template of a client and a template of a server?
I would like to eventually create a server/client application that receives binary data and just returns an acknowledgment back to the client that the data is received.
EDIT:
void handle_read(const boost::system::error_code& error,
size_t bytes_transferred) // from the server
{
if (!error)
{
boost::asio::async_write(socket_,
boost::asio::buffer("ACK", bytes_transferred),
boost::bind(&session::handle_write, this,
boost::asio::placeholders::error));
}
else
{
delete this;
}
}
This returns to the client only 'A'.
Also in data_ I get a lot of weird symbols after the response itself.
Those are my problems.
EDIT 2:
Ok so the main problem is with the client.
size_t reply_length = boost::asio::read(s,
boost::asio::buffer(reply, request_length));
Since it's an echo server the 'ACK' will only appear whenever the request length is more then 3 characters.
How do I overcome this?
I tried changing request_length to 4 but that only makes the client wait and not do anything at all.
Eventually I found out that the problem resides in this bit of code in the server:
void handle_read(const boost::system::error_code& error,
size_t bytes_transferred) // from the server
{
if (!error)
{
boost::asio::async_write(socket_,
boost::asio::buffer("ACK", 4), // replaced bytes_transferred with the length of my message
boost::bind(&session::handle_write, this,
boost::asio::placeholders::error));
}
else
{
delete this;
}
}
And in the client:
size_t reply_length = boost::asio::read(s,
boost::asio::buffer(reply, 4)); // replaced request_length with the length of the custom message.
The echo client/server is the simple example. What areas are you having trouble with? The client should be fairly straightforward since it uses the blocking APIs. The server is slightly more complex since it uses the asynchronous APIs with callbacks. When you boil it down to the core concepts (session, server, io_service) it's fairly easy to understand.

Resources