Linux userspace code to communicate between Linux board and each node running contiki udp sender example code

蹲街弑〆低调 提交于 2019-12-11 13:39:06

问题


I am using Contiki to create an IoT product involving multiple STM32L152 based nodes and a Linux board. I have one embedded Linux board (based on iMX6) that receives data from nodes, sends to the internet using cellular and 10 nodes that sense the different environmental parameter and deliver to Linux board. Linux board has a coprocessor that running border/edge router code, UART2 lines of that coprocessor is connected to Linux board. I use Contiki tool tunslip6 to create tun0 interface, I am able to ping each node. To make the question more understandable, I will explain the hardware setup and step that I performed.

  1. I am running UDP sender example code (STM32CubeExpansion_SUBG1_V3.0.0/Projects/Multi/Applications/Contiki/Udp-sender) on STM32L152RE-NUCLEO board that has x-nucleo-ids01a5 (SPSGRF-915 module) board sitting on top.

  2. On second similar hardware setup, I am running Border-router example code. USB cable is attached to my Linux box.

after doing this; sudo ./tunslip6 –s /dev/ttyACM0 aaaa::1/64, I am able to see all neighbor node on the webpage, I am able to ping6 each node too. I want to write application code on Linux to receive and send data to each node, I am stuck at this point.

sudo ./tunslip6 -s /dev/ttyACM0 aaaa::1/64
********SLIP started on ``/dev/ttyACM0''
opened tun device ``/dev/tun0''
ifconfig tun0 inet `hostname` mtu 1500 up
ifconfig tun0 add aaaa::1/64
ifconfig tun0 add fe80::0:0:0:1/64
ifconfig tun0

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00- 
00-00-00-00-00  
          inet addr:127.0.1.1  P-t-P:127.0.1.1  Mask:255.255.255.255
          inet6 addr: fe80::1/64 Scope:Link
          inet6 addr: aaaa::1/64 Scope:Global
          inet6 addr: fe80::8fad:d1a:c8d0:b76f/64 Scope:Link
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

*** Address:aaaa::1 => aaaa:0000:0000:0000
Got configuration message of type P
Setting prefix aaaa::
Server IPv6 addresses:
 aaaa::900:f4ff:c3a:f3c5
 fe80::900:f4ff:c3a:f3c5

ifconfig
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:127.0.1.1  P-t-P:127.0.1.1  Mask:255.255.255.255
          inet6 addr: fe80::1/64 Scope:Link
          inet6 addr: aaaa::1/64 Scope:Global
          inet6 addr: fe80::8fad:d1a:c8d0:b76f/64 Scope:Link
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:37 errors:0 dropped:0 overruns:0 frame:0
          TX packets:67 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500 
          RX bytes:3422 (3.4 KB)  TX bytes:5653 (5.6 KB)

ip addr show tun0
3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none 
    inet 127.0.1.1/32 scope host tun0
       valid_lft forever preferred_lft forever
    inet6 aaaa::1/64 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::1/64 scope link 
       valid_lft forever preferred_lft forever
    inet6 fe80::8fad:d1a:c8d0:b76f/64 scope link flags 800 
       valid_lft forever preferred_lft forever

sudo ip -6 route
aaaa::/64 dev tun0  proto kernel  metric 256  pref medium
fe80::/64 dev tun0  proto kernel  metric 256  pref medium

This is what I am seeing on the webpage, I have one neighbor node I am able to ping this.

ping6 aaaa::fdff:d2fa:2d05
PING aaaa::fdff:d2fa:2d05(aaaa::fdff:d2fa:2d05) 56 data bytes
64 bytes from aaaa::fdff:d2fa:2d05: icmp_seq=1 ttl=63 time=130 ms
64 bytes from aaaa::fdff:d2fa:2d05: icmp_seq=2 ttl=63 time=131 ms
64 bytes from aaaa::fdff:d2fa:2d05: icmp_seq=3 ttl=63 time=130 ms
64 bytes from aaaa::fdff:d2fa:2d05: icmp_seq=4 ttl=63 time=130 ms
64 bytes from aaaa::fdff:d2fa:2d05: icmp_seq=6 ttl=63 time=130 ms
64 bytes from aaaa::fdff:d2fa:2d05: icmp_seq=7 ttl=63 time=130 ms
64 bytes from aaaa::fdff:d2fa:2d05: icmp_seq=8 ttl=63 time=131 ms
^C
--- aaaa::fdff:d2fa:2d05 ping statistics ---
8 packets transmitted, 7 received, 12% packet loss, time 7040ms
rtt min/avg/max/mdev = 130.681/131.068/131.863/0.555 ms

I am not an expert in networking and socket programming, I wrote some code that I found on the internet and tried. I tried something like this;

import socket
UDP_IP = "aaaa::fdff:d2fa:2d05"  
UDP_PORT = 1234
print "UDP target IP:", UDP_IP
print "UDP target port:", UDP_PORT
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) # UDP
sock.connect((UDP_IP, UDP_PORT))
while True:
   data = sock.recv(1024)
   print 'Received', repr(data)

Question: In Linux userspace, my colleague wants to write an application code that can read and write each node (in this case aaaa::fdff:d2fa:2d05), how can we achieve that? On microcontroller board I am able to read and write with two nodes, but not in Linux space. Please help me, how can I read and write data from Linux userspace to each node? If possible please share some example code. Thanks!

Update - I tried to communicate between Linux host and node with the different Contiki example, contiki/examples/ipv6/rpl-udp/udp-client.c and had success, I was able to receive data from node. My python code is;

import socket, struct

UDP_LOCAL_IP = 'aaaa::1'
UDP_LOCAL_PORT = 5678


UDP_REMOTE_IP = 'fe80::fdff:d2fa:2d05'
UDP_REMOTE_PORT = 8765


try:
    socket_rx = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
    socket_rx.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    socket_rx.bind((UDP_LOCAL_IP, UDP_LOCAL_PORT))
except Exception:
    print "ERROR: Server Port Binding Failed"

print 'UDP server ready: %s'% UDP_LOCAL_PORT
print

while True:
    data, addr = socket_rx.recvfrom(1024)
    print "address : ", addr
    print "received message: ", data
    print "\n"
    socket_rx.sendto("Hello from serevr\n", (UDP_REMOTE_IP, UDP_REMOTE_PORT))

Above python code is working.


回答1:


The border router has a hard-coded IPv6 address, according to https://anrg.usc.edu/contiki/index.php/RPL_Border_Router this address is fe80:0000:0000:0000:0212:7401:0001:0101 ( possibly run ip addr show tun0 -> your edit shows that the assigned address is fe80:0000:0000:0000:8fad:d1a:c8d0:b76f ). To this address you bind the socket of your application, have no code for this in python. Because you use tunslip you can possibly also bind to localhost with accurate port and ipv4 protocol

For testing you can use netcat to send UDP packets directly to the nodes ( http://www.tutorialspoint.com/unix_commands/nc.htm )

To get rid of the error ( comment ) you have to apply inet_pton for converting the IPv6 address ( http://man7.org/linux/man-pages/man3/inet_pton.3.html )

in the following is working C code that you can translate to python. was written for using a Raven USB stick as border router ( search for Contiki Jackdaw, no tunslip used )

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <net/if.h>

 int fd = 0;   //socket file descriptor
 struct sockaddr_in6 server;


/* ipv6 address to in6_addr structure */

const char *ip6str = "fe80::8fad:d1a:c8d0:b76f";
struct in6_addr ravenipv6;

if (inet_pton(AF_INET6, ip6str, &ravenipv6) == 1) // successful
{
   printf("%s \n", "ipv6 address ...");
}


/* Create an empty IPv6 socket interface specification */
memset(&server, 0, sizeof(server));


server.sin6_family = AF_INET6;
server.sin6_flowinfo = 0;
server.sin6_port = htons(1234);  // port
server.sin6_addr = ravenipv6;  <- here the address converted with inet_ptons is inserted
server.sin6_scope_id = if_nametoindex("tun0");  // if your border router is on tun0

/*create socket*/
if ((fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1)
  {
    printf("%s \n", "failed to create socket");
  }

 /*bind to socket*/

if(bind(fd, (struct sockaddr_in6*)&server, sizeof(server)) == -1)

{
    printf("%s \n", "no binding ! ");
}


来源:https://stackoverflow.com/questions/52900177/linux-userspace-code-to-communicate-between-linux-board-and-each-node-running-co

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!