From 9febc5dc0635f17a8e58ebfdcdfd49914388a083 Mon Sep 17 00:00:00 2001 From: giomba Date: Sun, 26 Dec 2021 18:24:23 +0100 Subject: [PATCH] udp: client --- examples/simple-udp-client/.gitignore | 1 + examples/simple-udp-client/Makefile | 15 ++++++ .../simple-udp-client/simple-udp-client.ino | 47 +++++++++++++++++++ src/udp.cpp | 28 +++++++++++ src/udp.h | 46 ++++++++++++------ 5 files changed, 122 insertions(+), 15 deletions(-) create mode 100644 examples/simple-udp-client/.gitignore create mode 100644 examples/simple-udp-client/Makefile create mode 100644 examples/simple-udp-client/simple-udp-client.ino diff --git a/examples/simple-udp-client/.gitignore b/examples/simple-udp-client/.gitignore new file mode 100644 index 0000000..84c048a --- /dev/null +++ b/examples/simple-udp-client/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/examples/simple-udp-client/Makefile b/examples/simple-udp-client/Makefile new file mode 100644 index 0000000..0ad6677 --- /dev/null +++ b/examples/simple-udp-client/Makefile @@ -0,0 +1,15 @@ +BOARD ?= arduino:avr:diecimila +PORT ?= /dev/ttyUSB0 + +CCFLAGS += -Icfg + +.PHONY: build flash + +build: + arduino-cli compile -v -e --libraries coppino -b $(BOARD) + +flash: + arduino-cli -b $(BOARD) -p $(PORT) -v upload + +clean: + rm -r build diff --git a/examples/simple-udp-client/simple-udp-client.ino b/examples/simple-udp-client/simple-udp-client.ino new file mode 100644 index 0000000..7d5c0b5 --- /dev/null +++ b/examples/simple-udp-client/simple-udp-client.ino @@ -0,0 +1,47 @@ +#include "coppino.h" +#include "ipv6.h" +#include "slip.h" +#include "udp.h" + +const char MY_ADDRESS[] = "\x20\x01\x04\x70\xc8\x44\x00\x31\x00\x00\x00\x00\x00\x00\xca\xfe"; + +void setup() +{ + /* Customize coppino library configuration settings by editing settings.h */ + + /* setup serial for Internet connectivity + * attach a SLIP daemon on the other endpoint; a good one is `tunslip6` by Contiki + * $ tunslip6 -s /dev/ttyUSB0 -L -v5 -B 19200 2001:db8:1324::1/64 + * Note: the address given is the one on the host it is running on + */ + Serial.begin(19200); + + /* set unique identifier of network hardware. It MUST be unique! + * For example, this could be your microcontroller serial number + * Note: pay attention to enter exactly 64 bits / 8 bytes + */ + ipv6::setEUI("\xde\xad\xbe\xef\x12\x34\x56\x78"); + /* set global address -- will be overwritten if SLAAC is enabled and a Router Advertisement is received */ + ipv6::setGlobalAddress(MY_ADDRESS); +} + +void loop() +{ + char message[16]; + ipv6::IPv6Addr srcaddr = ipv6::IPv6Addr(MY_ADDRESS); + ipv6::IPv6Addr dstaddr = ipv6::IPv6Addr("\x20\x01\x04\x70\xc8\x44\x00\x31\x00\x00\x00\x00\x00\x00\x00\x01"); + uint16_t srcport = 1337; + uint16_t dstport = 1234; + udp::UDPClient udpclient = udp::UDPClient(srcaddr, dstaddr, srcport, dstport); + + while (true) + { + for (int i = 0; i < 32; ++i) + { + sprintf(message, "iteration #%d\r\n", i); + + udpclient.send_datagram((const uint8_t *)message, strlen(message)); + delay(1000); + } + } +} diff --git a/src/udp.cpp b/src/udp.cpp index f459a93..4228fe1 100644 --- a/src/udp.cpp +++ b/src/udp.cpp @@ -87,4 +87,32 @@ namespace udp return -1; } + UDPClient::UDPClient( + const ipv6::IPv6Addr &_srcaddr, + ipv6::IPv6Addr &_dstaddr, + const uint16_t _srcport, + const uint16_t _dstport) : srcaddr(_srcaddr), + dstaddr(_dstaddr), + srcport(_srcport), + dstport(_dstport) + { + ; + } + + void UDPClient::send_datagram(const uint8_t *obuffer, size_t len) + { + UDPPacket *outgoing_packet = (UDPPacket *)(((uint8_t *)&ipv6::packetout) + 40); + outgoing_packet->setSrcPort(srcport); + outgoing_packet->setDstPort(dstport); + outgoing_packet->setPayload((const char *)obuffer, len); + outgoing_packet->computeChecksum(&srcaddr, &dstaddr, len + 8); + + ipv6::packetout.setLen(len + 8); + ipv6::packetout.setFlow("\x26\x12\x21"); + ipv6::packetout.setSrcAddress(&srcaddr); + ipv6::packetout.setDstAddress(&dstaddr); + ipv6::packetout.setNextHeader(ipv6::NH_UDP); + ipv6::packetout.send(); + } + } diff --git a/src/udp.h b/src/udp.h index 75dde1f..e5f69c2 100644 --- a/src/udp.h +++ b/src/udp.h @@ -4,27 +4,43 @@ #include "Arduino.h" #include "ipv6.h" -namespace udp { - class UDPPacket { - private: - char packet[ipv6::LEN - 40]; - public: - void setSrcPort(uint16_t port); - uint16_t getSrcPort(); - void setDstPort(uint16_t port); - uint16_t getDstPort(); - const char* UDPPacket::getPayload(); - void setPayload(const char* payload, int len); /* also sets proper length */ - void computeChecksum(const ipv6::IPv6Addr* src_addr, const ipv6::IPv6Addr* dst_addr, int len); /* computes and updates checksum in the packet */ +namespace udp +{ + class UDPPacket + { + private: + char packet[ipv6::LEN - 40]; + + public: + void setSrcPort(uint16_t port); + uint16_t getSrcPort(); + void setDstPort(uint16_t port); + uint16_t getDstPort(); + const char *UDPPacket::getPayload(); + void setPayload(const char *payload, int len); /* also sets proper length */ + void computeChecksum(const ipv6::IPv6Addr *src_addr, const ipv6::IPv6Addr *dst_addr, int len); /* computes and updates checksum in the packet */ + }; + + class UDPClient + { + private: + const ipv6::IPv6Addr &srcaddr; + const ipv6::IPv6Addr &dstaddr; + const uint16_t srcport; + const uint16_t dstport; + + public: + UDPClient(const ipv6::IPv6Addr &srcaddr, ipv6::IPv6Addr &dstaddr, const uint16_t srcport, const uint16_t dstport); + void send_datagram(const uint8_t *payload, size_t len); }; /* UDP handler for lower layer protocol */ - int handleUDP(char* output_buffer, const char* input_buffer, int len); + int handleUDP(char *output_buffer, const char *input_buffer, int len); /* pointer to server handler function */ - extern int(*server_handler) (char* output_buffer, const char* buffer, int size); + extern int (*server_handler)(char *output_buffer, const char *buffer, int size); extern uint16_t server_port; - void set_handler(uint16_t port, int(* handler) (char* output_buffer, const char* input_buffer, int size)); + void set_handler(uint16_t port, int (*handler)(char *output_buffer, const char *input_buffer, int size)); } #endif