Benutzer-Werkzeuge

Webseiten-Werkzeuge


contiki:simple-udp-workshop

Workshop: Erstellung eines einfachen UDP Service mit Contiki

1. Installation der Entwicklungsumgebung: Instant Contiki

  • Die Installation von Instant Contiki benötigt VMWare Player, oder Virtualbox
  • Anmeldung an Instant Contiki mit dem Passwort: user
  • Die folgende Beschreibung bezieht sich immer auf das Quellcode-Verzeichnis: /home/user/contiki-3.0/

2. Anpassungen des Quellcodes

Im Workshop werden Contiki-Anwendungen direkt in Instant Contiki auf dem Entwicklungsrechner ausgeführt. Dazu müssen einige Veränderungen an Quellcode-Dateien vorgenommen werden. Im ersten Schritt wird die Anwendung für IPv4 erstellt. Die Anpassung für IPv6, sowie die Kompilierung für weitere Hardwareplattformen (Mikrocontrollerboards) ist später möglich.

2.1 Erstellen eines neuen Projekt-Verzeichnisses

  1. Erstellen Sie das Verzeichnis: /home/user/contiki-3.0/examples/simpleUDP

2.2 Erstellen des Makefiles

Für das Projekt werden eine C-Datei und ein Makefile benötigt.

  1. Erstellen Sie folgendes Makefile im Verzeichnis (für IPv4):
CONTIKI_PROJECT = simpleUDP
all: $(CONTIKI_PROJECT)
 
WITH_UIP=1
 
CONTIKI = ../..
include $(CONTIKI)/Makefile.include

Für die Verwendung von IPv6 verwenden Sie das folgende Makefile:

CONTIKI_PROJECT = simpleUDP
all: $(CONTIKI_PROJECT)
 
UIP_CONF_IPV6=1
UIP_CONF_RPL=0
 
CFLAGS += -DUIP_CONF_IPV6=1
 
CONTIKI = ../..
include $(CONTIKI)/Makefile.include

2.3 Erstellen des Quellcodes

  1. Erstellen Sie die C-Datei simpleUDP.c:
/**
 * \file
 *         A very simple Contiki UDP application
 * \author
 *         Thomas Scheffler, Sven Zehl
 */
 
#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"
#include "net/ip/uip.h"
#include "net/netstack.h"
#include <stdio.h> /* For printf() */
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
 
#define UDP_IP_BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
 
/*---------------------------------------------------------------------------*/
PROCESS(simpleUDP_process, "Simple UDP process");
AUTOSTART_PROCESSES(&simpleUDP_process);
/*---------------------------------------------------------------------------*/
static struct uip_udp_conn *udpconn;
#define MAX_PAYLOAD_LEN 120
 
 
void bsp_udphandler(void)
{
  char buf[MAX_PAYLOAD_LEN];
  if(uip_newdata()) 
  {
    /*Zeige Benutzer den Inhalt der empfangenen Nachricht*/
    /*Setze letztes Byte zu Null, fuer String Ende*/
    ((char *)uip_appdata)[uip_datalen()] = 0;
    printf("Server received: %s\n", (char *)uip_appdata);
 
    /*Verwende die Quell- als Zieladresse fuer Antwort */
    uip_ipaddr_copy(&udpconn->ripaddr, &UDP_IP_BUF->srcipaddr);
    udpconn->rport = UDP_IP_BUF->srcport;
 
    /*Schreibe Antwort-Daten in Buffer*/
    sprintf(buf, "Hello from the server");
 
    /*Versende das Antwort-Packet*/
    uip_udp_packet_send(udpconn, buf, strlen(buf));
 
    /*Setze Adresse/Port in Verbindungsstruktur auf Null,*/
    /*um von jedem Absender Daten empfangen zu koennen*/
    memset(&udpconn->ripaddr, 0, sizeof(udpconn->ripaddr));
    udpconn->rport = 0;
  }
}
 
PROCESS_THREAD(simpleUDP_process, ev, data)
{
  PROCESS_BEGIN();
 
  printf("UDP Echo Server\n");
 
  /*Starte neue UDP Verbindung mit IP 0.0.0.0 und Port 0, */
  /* d.h. akzeptiere jede ankommende Verbindung*/
  udpconn = udp_new(NULL, UIP_HTONS(0), NULL); 
 
  /*Setze den Port auf dem gelauscht wird auf 49999*/
  /*HTONS() uebersetzt zur Network Byte Order*/
  udp_bind(udpconn, UIP_HTONS(49999)); 
  printf("listening on UDP port %u\n", UIP_HTONS(udpconn->lport));
  while(1) {
    /* Warte bis ein TCP/IP Event eintrifft */
    PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);
 
    /*Rufe die Handler-Funktion auf*/
    bsp_udphandler();
  }
 
  PROCESS_END();
}

3. Übersetzen des UDP Services

Im Anschluss kann der UDP Service mit Hilfe des Makefiles übersetzt werden:

make TARGET=minimal-net

Sollte es notwenig sein nachträglich Änderungen am Makefile durchzuführen (zum Beispiel um zwischen IPv4 und IPv6 zu wechseln), sollte das Projekt vor der erneuten Übersetzung zurückgesetzt werden:

make TARGET=minimal-net clean

4. Ausführung des UDP-Service

Nach der erfolgreichen Übersetzung kann die Anwendung gestartet werden. Das muss mit dem Befehl sudo erfolgen. Dazu muss evtl. das Passwort user erneut eingegeben werden:

sudo ./simpleUDP.minimal-net

Contiki richtet jetzt ein neues Netzwerkinterface tap0 ein und startet den UDP-Service. Dabei werden die verwendeten Netzwerkeinstellungen angezeigt.

Anschließend kann über ein zweites Terminalfenster des Entwicklungssystems auf den Contiki-Service zugegriffen werden.

5. Interaktion mit dem UDP-Service

Starten Sie ein zweites Terminalfenster und testen Sie den Service

  1. Pingen Sie den Contiki UDP-Service:
    ping 172.18.0.2
  2. Senden Sie mit dem Programm netcat Daten an den Contiki UDP-Service:
    netcat -u 172.18.0.2 49999

    Beobachten Sie die Ausgabe des Services, sowie die vom Service gesendete Antwort. Sie sollten mit dem Service kommunizieren können.

6. Contiki UDP-Client

/**
 * \file
 *         A very simple Contiki UDP Client
 * \author
 *         Thomas Scheffler
 */
 
#include "contiki.h"
#include "sys/ctimer.h"
#include "sys/etimer.h"
#include "net/ip/uip.h"
#include "net/ipv6/uip-ds6.h"
#include <stdio.h>
#include <string.h>
 
#include "simple-udp.h"
#define UDP_PORT 40000
#define SEND_INTERVAL           (10 * CLOCK_SECOND)
 
static struct simple_udp_connection client_connection;
 
/*---------------------------------------------------------------------------*/
PROCESS(client_example_process, "UDP client example process");
AUTOSTART_PROCESSES(&client_example_process);
/*---------------------------------------------------------------------------*/
static void
receiver(struct simple_udp_connection *c,
         const uip_ipaddr_t *sender_addr,
         uint16_t sender_port,
         const uip_ipaddr_t *receiver_addr,
         uint16_t receiver_port,
         const uint8_t *data,
         uint16_t datalen)
{
  printf("Data received on port %d from port %d with length %d\n",
         receiver_port, sender_port, datalen);
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(client_example_process, ev, data)
{
  static struct etimer periodic_timer;
  uip_ipaddr_t addr;
 
  PROCESS_BEGIN();
  //ohne simple_udp_register funktioniert das Senden nicht!
  simple_udp_register(&client_connection, UDP_PORT,
                      NULL, UDP_PORT, receiver);
 
  etimer_set(&periodic_timer, SEND_INTERVAL);
  while(1) 
  {
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&periodic_timer));
    etimer_reset(&periodic_timer);
 
    printf("Sending UDP-Packet\n");
 
    // senden auf die eigene Adresse 172.18.0.2 funktioniert bei
    // Instant-Contiki nicht: arp auf tun0-Interface?
    //uip_ipaddr(&addr, 172,18,0,1);
    uip_ipaddr(&addr, 127,0,0,1);
    simple_udp_sendto(&client_connection, "Test", 4, &addr);
  }
  PROCESS_END();
}
contiki/simple-udp-workshop.txt · Zuletzt geändert: 2018/12/03 14:53 von admin