UDP server send packet not over multicast ip with boost asio - boost

I'm beginner with boost::asio and udp networking system.
I'm trying to receive many of packet from multicast(239.255.255.251:5353) and I want to send packet multicast(239.255.255.251:5353) for specific device.
I referenced this example from boost
http://www.boost.org/doc/libs/1_37_0/doc/html/boost_asio/example/multicast/receiver.cpp
and I modified that
void handle_receive_from(const boost::system::error_code& error,
size_t bytes_recvd)
{
if (!error)
{
if(mdns_validate_name(data_, bytes_recvd))
{
std::cout.write(data_, bytes_recvd);
std::cout << std::endl;
/** make packet for send **/
socket_.async_send_to(
boost::asio::buffer(data_, length), multi_endpoint_,
boost::bind(&receiver::handle_send, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
socket_.async_receive_from(
boost::asio::buffer(data_, max_length), multi_endpoint_,
boost::bind(&receiver::handle_receive_from, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
}
}
my problem is packet not over multicast(239.255.255.251:5353). it just sent specific ip(192.168.0.168). I checked wire shark.
I want to send packet again over multicast (239.255.255.251:5353).
please comment!

Unfortunately UDP multicast sending and receiving are completely different.
A receiver uses a local address to select the receiving device: usually set to any. Whilst a sender requires a remote address, i.e. the multicast address. In your case that would be 239.255.255.251.
E.g. from the boost::asio sender example:
class sender
{
public:
sender(boost::asio::io_service& io_service,
const boost::asio::ip::address& multicast_address)
: endpoint_(multicast_address, multicast_port),
socket_(io_service, endpoint_.protocol())
{}
.
.
.
private:
boost::asio::ip::udp::endpoint endpoint_;
boost::asio::ip::udp::socket socket_;
};
BTW the boost::asio UDP example that you reference is very old and for a receiver!
The latest boost::asio UDP sender example is here. However, for your purposes the echo server would be a better starting point.
If you want to see complete example of IPv4 and IPv6 UDP asio comms then have a look at udp_adaptor.hpp here.

Related

Comunicazione NDEF

I'm working on a mobile app and my intent is to make the Arduino communicate with the smartphone. so far I can only read the first message sent by the arduino, when the application is not active.
I'm using this function of react-native-nfc-manager library:
getLaunchTagEvent ()
After this event I can no longer read other NDEF messages. how can i solve?
The code is as follows:
componentDidMount(){
NfcManager.isSupported()
.then(supported => {
this.setState({ supported });
if (supported) {
this._startNfc();
}
})
}
_startNfc() {
if (Platform.OS === 'android') {
NfcManager.getLaunchTagEvent()
.then(tag => {
console.log('launch tag', tag);
if (tag) {
this.setState({ tag });
}
})
.catch(err => {
console.log(err);
})
}
}
Also i am trying to read the tag with the application open, but the action fails on the arduino. solutions?
The code is as follows:
readData = async () => {
NfcManager.registerTagEvent(
tag => {
console.log('Tag Discovered', tag);
},
'Hold your device over the tag',
{
readerModeFlags:
NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK,
readerModeDelay: 2,
},
);
}
The Arduino code is as follows:
#include "SPI.h"
#include "PN532_SPI.h"
#include "snep.h"
#include "NdefMessage.h"
PN532_SPI pn532spi(SPI, 10);
SNEP nfc(pn532spi);
uint8_t ndefBuf[128];
void setup() {
Serial.begin(9600);
Serial.println("NFC Peer to Peer-Send Message");
}
void loop() {
Serial.println("Send a message to Peer");
NdefMessage message = NdefMessage();
message.addTextRecord("Hello");
int messageSize = message.getEncodedSize();
if (messageSize > sizeof(ndefBuf)) {
Serial.println("ndefBuf is too small");
while (1) {
}
}
message.encode(ndefBuf);
if (0 >= nfc.write(ndefBuf, messageSize)) {
Serial.println("Failed");
} else {
Serial.println("Success");
}
delay(3000);
}
The uses of SNEP (and LLCP) complicates things as this is a peer to peer protocol and peer to peer has been deprecated in Android 10 and not supported in iOS and I'm not so familiar with it.
I'm not sure it is possible read SNEP messages using enableReaderMode (this is what you have asked react-native-nfc-manager library to use).
This is because SNEP and (LLCP) is not a TYPE A technology type
If you look at the NFC standards diagram at https://pdfslide.net/documents/divnfc0804-250-nfc-standards-v18.html
It might be a TYPE F technology type so I would try instead of NfcAdapter.FLAG_READER_NFC_A I would use NfcAdapter.FLAG_READER_NFC_F or enable all of the technologies to be on the safe side (though I think this might not work as well)
But if this does not work, normally with Android Peer to Peer it expects only to be sent NDEF messages and you have disabled the System NFC App from processing NDEF messages with NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK so I would try removing that and work with the Ndef tag technology type.
But I don't think any of that will help, the next thing I would try is to not use enableReaderMode with react-native-nfc-manager but use the underlying enableForgroundDispatch methods by just by specifying NfcManager.registerTagEvent();.
As this interacts with the Android System NFC App at a later point in the chain of events where the Android System NFC App is creating Intents to share with other Apps either to Launch an App to handle the Intent or pass it to a running App that has asked to be sent NFC Intents.
As this looks to be a common point between how the Android System NFC App handles real NFC Tags and Peer to Peer SNEP messages as a SNEP message can launch your App.
But going forward I would not use SNEP (peer to peer) as this is deprecated but get the Arduino to do Host Card Emulation to send the data (Then you could use Reader Mode)

Solving "redeclared as different kind of symbol" error

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.

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?

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?

Processing: open UDP socket for reading?

Here's an example of opening and reading data from a TCP socket. Is there a way to create a UDP socket as well?
void setup() {
c = new Client(this, "127.0.0.1", 12345); // Replace with your server's IP and port
}
void draw() {
if (c.available() > 0) {
input = c.readString();
http://www.processing.org/learning/libraries/sharedcanvasclient.html
You can use the UDP library for processing (http://ubaa.net/shared/processing/udp/). Some examples are provided, so you can start experimenting with UDP easily.
I have used UDP communication in processing a lot for many projects. The implementation is really good and ready for real world applications.

Resources