Tom Soulanille / snet
Committer:
altasoul
Date:
Thu Mar 05 00:18:25 2015 +0000
Revision:
1:9c211ac06a12
Parent:
0:6df0a6ed91d4
Child:
2:397316d97354
refactor Snet to have registered_udp_handler

Who changed what in which revision?

UserRevisionLine numberNew contents of line
altasoul 0:6df0a6ed91d4 1 #include "flyer.h"
altasoul 0:6df0a6ed91d4 2 #include "snet.h"
altasoul 0:6df0a6ed91d4 3
altasoul 0:6df0a6ed91d4 4 #if 0
altasoul 0:6df0a6ed91d4 5 extern Ethernet eth;
altasoul 0:6df0a6ed91d4 6
altasoul 0:6df0a6ed91d4 7 //-- from inet.cpp
altasoul 0:6df0a6ed91d4 8 extern uint16_t ones_complement_sum(const uint8_t *buf, int len, int sum);
altasoul 0:6df0a6ed91d4 9 extern uint16_t ip_checksum_of(const uint8_t *buf, const int len);
altasoul 0:6df0a6ed91d4 10 extern void turn_ip_packet_around(uint8_t *buf);
altasoul 0:6df0a6ed91d4 11 #endif
altasoul 0:6df0a6ed91d4 12
altasoul 0:6df0a6ed91d4 13 //-- from radio.cpp
altasoul 0:6df0a6ed91d4 14 extern void send_packet_to_radio(uint8_t const *, int);
altasoul 0:6df0a6ed91d4 15
altasoul 0:6df0a6ed91d4 16 //-- from util.cpp
altasoul 0:6df0a6ed91d4 17 extern void print_hex(const uint8_t *p, int len);
altasoul 0:6df0a6ed91d4 18
altasoul 0:6df0a6ed91d4 19 void Snet::turn_udp_packet_around(uint8_t *buf) {
altasoul 0:6df0a6ed91d4 20 uint8_t dh, dl;
altasoul 0:6df0a6ed91d4 21 turn_ip_packet_around(buf);
altasoul 0:6df0a6ed91d4 22 dh = buf[UDP_DST_PORT_O];
altasoul 0:6df0a6ed91d4 23 dl = buf[UDP_DST_PORT_O+1];
altasoul 0:6df0a6ed91d4 24 buf[UDP_DST_PORT_O] = buf[UDP_SRC_PORT_O];
altasoul 0:6df0a6ed91d4 25 buf[UDP_DST_PORT_O+1] = buf[UDP_SRC_PORT_O+1];
altasoul 0:6df0a6ed91d4 26 buf[UDP_SRC_PORT_O] = dh;
altasoul 0:6df0a6ed91d4 27 buf[UDP_SRC_PORT_O+1] = dl;
altasoul 0:6df0a6ed91d4 28 }
altasoul 0:6df0a6ed91d4 29
altasoul 0:6df0a6ed91d4 30 // Send a UDP packet addressed as in buf, with specified payload
altasoul 0:6df0a6ed91d4 31 void Snet::send_udp_packet(uint8_t *buf, const uint8_t *payload, int payload_len) {
altasoul 0:6df0a6ed91d4 32 int ip_total_length = UDP_PAYLOAD_O - IP_HEADER_O + payload_len;
altasoul 0:6df0a6ed91d4 33 int udp_length = UDP_HEADER_LEN + payload_len;
altasoul 0:6df0a6ed91d4 34 buf[IP_TOTAL_LENGTH_O] = ip_total_length >> 8;
altasoul 0:6df0a6ed91d4 35 buf[IP_TOTAL_LENGTH_O+1] = ip_total_length;
altasoul 0:6df0a6ed91d4 36
altasoul 0:6df0a6ed91d4 37 buf[UDP_LENGTH_O] = udp_length >> 8;
altasoul 0:6df0a6ed91d4 38 buf[UDP_LENGTH_O+1] = udp_length;
altasoul 0:6df0a6ed91d4 39 #if 0
altasoul 0:6df0a6ed91d4 40 // RFC1768: "An all zero transmitted
altasoul 0:6df0a6ed91d4 41 // checksum value means that the transmitter generated no checksum (for
altasoul 0:6df0a6ed91d4 42 // debugging or for higher level protocols that don't care)."
altasoul 0:6df0a6ed91d4 43 buf[UDP_CHECKSUM_O] = buf[UDP_CHECKSUM_O+1] = 0;
altasoul 0:6df0a6ed91d4 44 #else
altasoul 0:6df0a6ed91d4 45 // find the udp checksum for a given enet packet presumed to be udp
altasoul 0:6df0a6ed91d4 46 // From rfc768:
altasoul 0:6df0a6ed91d4 47 // The pseudo header conceptually prefixed to the UDP header contains the
altasoul 0:6df0a6ed91d4 48 // source address, the destination address, the protocol, and the UDP
altasoul 0:6df0a6ed91d4 49 // length. This information gives protection against misrouted datagrams.
altasoul 0:6df0a6ed91d4 50 // This checksum procedure is the same as is used in TCP.
altasoul 0:6df0a6ed91d4 51 //
altasoul 0:6df0a6ed91d4 52 // 0 7 8 15 16 23 24 31
altasoul 0:6df0a6ed91d4 53 // +--------+--------+--------+--------+
altasoul 0:6df0a6ed91d4 54 // | source address |
altasoul 0:6df0a6ed91d4 55 // +--------+--------+--------+--------+
altasoul 0:6df0a6ed91d4 56 // | destination address |
altasoul 0:6df0a6ed91d4 57 // +--------+--------+--------+--------+
altasoul 0:6df0a6ed91d4 58 // | zero |protocol| UDP length |
altasoul 0:6df0a6ed91d4 59 // +--------+--------+--------+--------+
altasoul 0:6df0a6ed91d4 60 //
altasoul 0:6df0a6ed91d4 61 // If the computed checksum is zero, it is transmitted as all ones (the
altasoul 0:6df0a6ed91d4 62 // equivalent in one's complement arithmetic). An all zero transmitted
altasoul 0:6df0a6ed91d4 63 // checksum value means that the transmitter generated no checksum (for
altasoul 0:6df0a6ed91d4 64 // debugging or for higher level protocols that don't care).
altasoul 0:6df0a6ed91d4 65
altasoul 0:6df0a6ed91d4 66 // This is the pseudo-header sum
altasoul 0:6df0a6ed91d4 67 int sum = ones_complement_sum(&buf[IP_SADDR_O], 4+4, 0);
altasoul 0:6df0a6ed91d4 68 sum += 0x11; // proto
altasoul 0:6df0a6ed91d4 69 sum += 8 + payload_len; // UDP length
altasoul 0:6df0a6ed91d4 70
altasoul 0:6df0a6ed91d4 71 // add the real UDP header, with zeroed-out checksum
altasoul 0:6df0a6ed91d4 72 buf[UDP_CHECKSUM_O] = buf[UDP_CHECKSUM_O+1] = 0;
altasoul 0:6df0a6ed91d4 73 sum = ones_complement_sum(&buf[UDP_HEADER_O],
altasoul 0:6df0a6ed91d4 74 UDP_PAYLOAD_O - UDP_HEADER_O,
altasoul 0:6df0a6ed91d4 75 sum);
altasoul 0:6df0a6ed91d4 76
altasoul 0:6df0a6ed91d4 77 // add the payload that will be included and take the result
altasoul 0:6df0a6ed91d4 78 int chksum = ~ones_complement_sum(payload, payload_len, sum);
altasoul 0:6df0a6ed91d4 79
altasoul 0:6df0a6ed91d4 80 chksum = chksum ? chksum : ~chksum; // send -0 for +0
altasoul 0:6df0a6ed91d4 81 buf[UDP_CHECKSUM_O] = chksum >> 8;
altasoul 0:6df0a6ed91d4 82 buf[UDP_CHECKSUM_O+1] = chksum;
altasoul 0:6df0a6ed91d4 83 #endif
altasoul 0:6df0a6ed91d4 84 buf[IP_CHKSUM_O] = buf[IP_CHKSUM_O+1] = 0;
altasoul 0:6df0a6ed91d4 85 int chk = ip_checksum_of(&buf[IP_HEADER_O], IP_HEADER_LEN);
altasoul 0:6df0a6ed91d4 86 buf[IP_CHKSUM_O] = chk >> 8;
altasoul 0:6df0a6ed91d4 87 buf[IP_CHKSUM_O+1] = chk;
altasoul 0:6df0a6ed91d4 88 eth.write((char *) buf, UDP_PAYLOAD_O);
altasoul 0:6df0a6ed91d4 89 eth.write((char *) payload, payload_len);
altasoul 0:6df0a6ed91d4 90 eth.send();
altasoul 0:6df0a6ed91d4 91 #if 0
altasoul 0:6df0a6ed91d4 92 printf("rup wrote:");
altasoul 0:6df0a6ed91d4 93 print_hex(buf, UDP_PAYLOAD_O);
altasoul 0:6df0a6ed91d4 94 printf("then wrote:");
altasoul 0:6df0a6ed91d4 95 print_hex((uint8_t *) payload, payload_len);
altasoul 0:6df0a6ed91d4 96 printf("udp chksum 0x%02x%02x\r\n", buf[UDP_CHECKSUM_O], buf[UDP_CHECKSUM_O+1]);
altasoul 0:6df0a6ed91d4 97 #endif
altasoul 0:6df0a6ed91d4 98 }
altasoul 0:6df0a6ed91d4 99
altasoul 0:6df0a6ed91d4 100 // Return a UDP packet to the sender of packet in buf, with new payload
altasoul 0:6df0a6ed91d4 101 void Snet::return_udp_packet(uint8_t *buf, const uint8_t *payload, int payload_len) {
altasoul 0:6df0a6ed91d4 102 turn_udp_packet_around(buf);
altasoul 0:6df0a6ed91d4 103 send_udp_packet(buf, payload, payload_len);
altasoul 0:6df0a6ed91d4 104 }
altasoul 0:6df0a6ed91d4 105
altasoul 0:6df0a6ed91d4 106
altasoul 0:6df0a6ed91d4 107
altasoul 0:6df0a6ed91d4 108 void Snet::send_to_correspondent(const uint8_t *what, int what_len) {
altasoul 0:6df0a6ed91d4 109 send_udp_packet(correspondent_facing_packet_header, what, what_len);
altasoul 0:6df0a6ed91d4 110 }
altasoul 0:6df0a6ed91d4 111
altasoul 0:6df0a6ed91d4 112 void Snet::tell_correspondent(char *s) {
altasoul 0:6df0a6ed91d4 113 send_to_correspondent((const uint8_t *) s, strlen(s));
altasoul 0:6df0a6ed91d4 114 }
altasoul 0:6df0a6ed91d4 115
altasoul 1:9c211ac06a12 116 void Snet::set_udp_correspondent(uint8_t *buf, int len) {
altasoul 0:6df0a6ed91d4 117 turn_udp_packet_around(buf);
altasoul 0:6df0a6ed91d4 118 memcpy(correspondent_facing_packet_header, buf, UDP_PAYLOAD_O);
altasoul 1:9c211ac06a12 119 }
altasoul 1:9c211ac06a12 120
altasoul 1:9c211ac06a12 121 void Snet::register_correspondent_for_updates(uint8_t *buf, int len, char updates) {
altasoul 1:9c211ac06a12 122 set_udp_correspondent(buf, len);
altasoul 0:6df0a6ed91d4 123 //printf("registered for updates: 0x%x\r\n", updates); //DEBUG
altasoul 0:6df0a6ed91d4 124 tell_correspondent("OK");
altasoul 0:6df0a6ed91d4 125 }
altasoul 0:6df0a6ed91d4 126
altasoul 0:6df0a6ed91d4 127
altasoul 0:6df0a6ed91d4 128
altasoul 0:6df0a6ed91d4 129 void Snet::handle_udp_packet(uint8_t *buf, int len) {
altasoul 0:6df0a6ed91d4 130 #if 0
altasoul 0:6df0a6ed91d4 131 printf("UDP:");
altasoul 0:6df0a6ed91d4 132 print_hex(&buf[UDP_HEADER_O], len-UDP_HEADER_O);
altasoul 0:6df0a6ed91d4 133 #endif
altasoul 1:9c211ac06a12 134 if (registered_udp_handler) (*registered_udp_handler)(buf, len);
altasoul 0:6df0a6ed91d4 135 };