Work in progress...

Dependencies:   ESC FreeIMU mbed-rtos mbed

Experiment - work in progress...

Committer:
MatteoT
Date:
Sat May 24 17:42:03 2014 +0000
Revision:
7:cda17cffec3c
Parent:
6:4ddd68260f76
experiments (going to first launch)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MatteoT 5:33abcc31b0aa 1 ////////////// Information about the frame format: //////////////
MatteoT 5:33abcc31b0aa 2 #define TXRX_BUFFER 600
MatteoT 5:33abcc31b0aa 3 //Ethernet:
MatteoT 5:33abcc31b0aa 4 #define ETH_PROTO_OFFSET (12)
MatteoT 5:33abcc31b0aa 5 #define ETH_PAYLOAD_OFFSET (14)
MatteoT 5:33abcc31b0aa 6 //IP/UDP:
MatteoT 5:33abcc31b0aa 7 #define MSG_LEN (TXRX_BUFFER-14-20-8-10)
MatteoT 5:33abcc31b0aa 8 #define IP_LEN_OFFSET (2)
MatteoT 5:33abcc31b0aa 9 #define IP_PROTO_OFFSET (9)
MatteoT 6:4ddd68260f76 10 #define IP_CKS_OFFSET (10)
MatteoT 5:33abcc31b0aa 11 #define IP_SRC_ADDR_OFFSET (12)
MatteoT 5:33abcc31b0aa 12 #define IP_DEST_ADDR_OFFSET (16)
MatteoT 5:33abcc31b0aa 13 #define IP_PAYLOAD_OFFSET (20)
MatteoT 5:33abcc31b0aa 14 #define IP_UDP_DESTPORT_OFFSET (20+2)
MatteoT 5:33abcc31b0aa 15 #define IP_UDP_LEN_OFFSET (20+2+2)
MatteoT 6:4ddd68260f76 16 #define IP_UDP_CKS_OFFSET (20+2+2+2)
MatteoT 5:33abcc31b0aa 17 #define IP_UDP_PAYLOAD_OFFSET (20+8)
MatteoT 5:33abcc31b0aa 18 //ARP:
MatteoT 5:33abcc31b0aa 19 #define ARP_SENDER_HW_ADDR_OFFSET (8)
MatteoT 5:33abcc31b0aa 20 #define ARP_TARGET_HW_ADDR_OFFSET (8+6+4)
MatteoT 5:33abcc31b0aa 21 #define ARP_LEN (28)
MatteoT 5:33abcc31b0aa 22
MatteoT 5:33abcc31b0aa 23 /////////////////////////////////////////////////////////////////
MatteoT 6:4ddd68260f76 24 struct QuadStateTXRXTimes{
MatteoT 6:4ddd68260f76 25 double target_tx_dt;
MatteoT 6:4ddd68260f76 26 double actual_tx_dt;
MatteoT 6:4ddd68260f76 27 double average_tx_dt;
MatteoT 6:4ddd68260f76 28 double average_tx_dt_k;
MatteoT 6:4ddd68260f76 29
MatteoT 6:4ddd68260f76 30 double target_rx_dt;
MatteoT 6:4ddd68260f76 31 double actual_rx_dt;
MatteoT 6:4ddd68260f76 32 double average_rx_dt;
MatteoT 6:4ddd68260f76 33 double average_rx_dt_k;
MatteoT 6:4ddd68260f76 34
MatteoT 6:4ddd68260f76 35 void reset(){
MatteoT 6:4ddd68260f76 36 target_tx_dt = TARGET_TX_DT;
MatteoT 6:4ddd68260f76 37 actual_tx_dt = TARGET_TX_DT;
MatteoT 6:4ddd68260f76 38 average_tx_dt = TARGET_TX_DT;
MatteoT 6:4ddd68260f76 39 average_tx_dt_k = AVERAGE_DT_K_GAIN;
MatteoT 6:4ddd68260f76 40
MatteoT 6:4ddd68260f76 41 target_rx_dt = TARGET_RX_DT;
MatteoT 6:4ddd68260f76 42 actual_rx_dt = TARGET_RX_DT;
MatteoT 6:4ddd68260f76 43 average_rx_dt = TARGET_RX_DT;
MatteoT 6:4ddd68260f76 44 average_rx_dt_k = AVERAGE_DT_K_GAIN;
MatteoT 6:4ddd68260f76 45 }
MatteoT 6:4ddd68260f76 46 };
MatteoT 6:4ddd68260f76 47 QuadStateTXRXTimes TXRX_times;
MatteoT 5:33abcc31b0aa 48 Mutex TXRX_mutex;
MatteoT 5:33abcc31b0aa 49 QuadState TXRX_txQuadState;
MatteoT 5:33abcc31b0aa 50 QuadState TXRX_rxQuadState;
MatteoT 5:33abcc31b0aa 51 Timer TXRX_tx_dt_timer;
MatteoT 5:33abcc31b0aa 52 Timer TXRX_rx_dt_timer;
MatteoT 5:33abcc31b0aa 53 char TXRX_buffer [TXRX_BUFFER];
MatteoT 5:33abcc31b0aa 54
MatteoT 5:33abcc31b0aa 55 //Addresses
MatteoT 5:33abcc31b0aa 56 #define DEST_MAC_ADDR 0xF8,0xD1,0x11,0xA0,0x51,0xD0 //MAC address of my TL-MR3020 router
MatteoT 5:33abcc31b0aa 57 #define MY_IP_ADDR 0xc0,0xa8,0x02,0x10
MatteoT 5:33abcc31b0aa 58 #define DEST_IP_ADDR 0xc0,0xa8,0x02,0x01
MatteoT 5:33abcc31b0aa 59 #define UDP_PORT 0x08,0xb1
MatteoT 5:33abcc31b0aa 60 const char dest_mac_addr [6] = {
MatteoT 5:33abcc31b0aa 61 DEST_MAC_ADDR
MatteoT 5:33abcc31b0aa 62 };
MatteoT 5:33abcc31b0aa 63
MatteoT 5:33abcc31b0aa 64 //dumped frames:
MatteoT 5:33abcc31b0aa 65 char ethernet_frame [14] = { //Ethernetv2 packet header
MatteoT 5:33abcc31b0aa 66 0xff,0xff,0xff,0xff,0xff,0xff, //DEST ADDR
MatteoT 5:33abcc31b0aa 67 0x00,0x02,0xf7,0xf1,0xa4,0xdb, //SRC ADDR
MatteoT 5:33abcc31b0aa 68 0x08,0x00 //PROTO
MatteoT 5:33abcc31b0aa 69 };
MatteoT 5:33abcc31b0aa 70 const char ethernet_frame_arp_proto [2] = {
MatteoT 5:33abcc31b0aa 71 0x08,0x06
MatteoT 5:33abcc31b0aa 72 };
MatteoT 5:33abcc31b0aa 73 char ipudp_frame [28] = { //IPv4/UDP packet header (message must be MSG_LEN bytes)
MatteoT 5:33abcc31b0aa 74 0x45, //IP: VER/HEADER LEN
MatteoT 5:33abcc31b0aa 75 0x00, //DIFFERENTIAL SERVICE
MatteoT 5:33abcc31b0aa 76 0x02,0x40, //TOTAL LEN
MatteoT 5:33abcc31b0aa 77 0x01,0xa0, //ID
MatteoT 5:33abcc31b0aa 78 0x00, //FLAGS
MatteoT 5:33abcc31b0aa 79 0x00, //FRAG OFFSET
MatteoT 5:33abcc31b0aa 80 0xff, //TTL
MatteoT 5:33abcc31b0aa 81 0x11, //PROTO=udp
MatteoT 5:33abcc31b0aa 82 0x32,0x99, //HEADER CKS
MatteoT 5:33abcc31b0aa 83 MY_IP_ADDR, //SOURCE ADDR
MatteoT 5:33abcc31b0aa 84 DEST_IP_ADDR, //DEST ADDR
MatteoT 5:33abcc31b0aa 85 //UDP:
MatteoT 5:33abcc31b0aa 86 UDP_PORT, //SOURCE PORT
MatteoT 5:33abcc31b0aa 87 UDP_PORT, //DEST PORT
MatteoT 5:33abcc31b0aa 88 0x02,0x2c, //TOTAL LEN
MatteoT 5:33abcc31b0aa 89 0x27,0xe2 //CKS
MatteoT 5:33abcc31b0aa 90 };
MatteoT 5:33abcc31b0aa 91 char arp_frame [28] = { //Address Resolution Protocol packet
MatteoT 5:33abcc31b0aa 92 0x00,0x01, //HTYPE ethernet
MatteoT 5:33abcc31b0aa 93 0x08,0x00, //PTYPE IP
MatteoT 5:33abcc31b0aa 94 0x06,0x04, //HLEN, PLEN
MatteoT 5:33abcc31b0aa 95 0x00,0x02, //OPER reply
MatteoT 5:33abcc31b0aa 96 0x00,0x02,0xf7,0xf1,0xa4,0xdb, //Sender hw addr
MatteoT 5:33abcc31b0aa 97 MY_IP_ADDR, //Sender proto addr
MatteoT 5:33abcc31b0aa 98 DEST_MAC_ADDR, //Target hw addr
MatteoT 5:33abcc31b0aa 99 DEST_IP_ADDR //Target proto addr
MatteoT 5:33abcc31b0aa 100 };
MatteoT 5:33abcc31b0aa 101
MatteoT 6:4ddd68260f76 102 #define htons(n) ( (((n) & 0xFF00) >> 8) | (((n) & 0x00FF) << 8) )
MatteoT 6:4ddd68260f76 103 uint16_t ip_checksum (const char * buf, size_t hdr_len);
MatteoT 6:4ddd68260f76 104 uint16_t udp_checksum(const char * buff, size_t len, const char * src_addr, const char * dest_addr);
MatteoT 6:4ddd68260f76 105
MatteoT 5:33abcc31b0aa 106 void TXRX_thread_routine (void const *args){ //New magic version
MatteoT 5:33abcc31b0aa 107 DigitalOut led_rx(LED_RX); led_rx = 0;
MatteoT 5:33abcc31b0aa 108
MatteoT 5:33abcc31b0aa 109 //Prepare state
MatteoT 6:4ddd68260f76 110 TXRX_times.reset();
MatteoT 5:33abcc31b0aa 111 TXRX_txQuadState.reset();
MatteoT 5:33abcc31b0aa 112 TXRX_rxQuadState.reset();
MatteoT 5:33abcc31b0aa 113
MatteoT 5:33abcc31b0aa 114 //Setup the magic networking
MatteoT 5:33abcc31b0aa 115 Thread::wait(2000);
MatteoT 5:33abcc31b0aa 116 FAST_FLASH_OFF(led_rx,2);
MatteoT 5:33abcc31b0aa 117 Ethernet eth0;
MatteoT 5:33abcc31b0aa 118 FAST_FLASH_OFF(led_rx,2);
MatteoT 5:33abcc31b0aa 119 eth0.address(ethernet_frame+6);
MatteoT 5:33abcc31b0aa 120 FAST_FLASH_OFF(led_rx,2);
MatteoT 5:33abcc31b0aa 121 Thread::wait(2000);
MatteoT 5:33abcc31b0aa 122
MatteoT 5:33abcc31b0aa 123 //infinite loop: if disconnected, reconnects.
MatteoT 5:33abcc31b0aa 124 while(1){
MatteoT 5:33abcc31b0aa 125
MatteoT 5:33abcc31b0aa 126 //Wait eth0 link
MatteoT 5:33abcc31b0aa 127 Thread::wait(10);
MatteoT 5:33abcc31b0aa 128 while(!eth0.link()){
MatteoT 5:33abcc31b0aa 129 SLOW_FLASH_ON(led_rx,1);
MatteoT 5:33abcc31b0aa 130 };
MatteoT 6:4ddd68260f76 131 Thread::wait(5);
MatteoT 5:33abcc31b0aa 132 FAST_FLASH_OFF(led_rx,2);
MatteoT 5:33abcc31b0aa 133
MatteoT 6:4ddd68260f76 134 //Perform 5 gratuitous ARP reply, with an interval of 10ms
MatteoT 5:33abcc31b0aa 135 memset(ethernet_frame, 0xff, 6); //ethernet broadcast
MatteoT 5:33abcc31b0aa 136 memcpy(arp_frame+ARP_SENDER_HW_ADDR_OFFSET, ethernet_frame+6, 6); //sender hw addr = my mac; sender ip addr predefined.
MatteoT 5:33abcc31b0aa 137 memcpy(arp_frame+ARP_TARGET_HW_ADDR_OFFSET, arp_frame+ARP_SENDER_HW_ADDR_OFFSET, 6+4); //target = sender (both hw and ip - gratuitous ARP reply as announcement).
MatteoT 5:33abcc31b0aa 138 for(int i=0;i<5;++i){
MatteoT 5:33abcc31b0aa 139 eth0.write(ethernet_frame,12); //ethernet dest and src addr
MatteoT 5:33abcc31b0aa 140 eth0.write(ethernet_frame_arp_proto,2); //ethernet proto field = arp
MatteoT 5:33abcc31b0aa 141 eth0.write(arp_frame,ARP_LEN); //arp packet
MatteoT 5:33abcc31b0aa 142 eth0.send();
MatteoT 5:33abcc31b0aa 143 Thread::wait(10);
MatteoT 5:33abcc31b0aa 144 }
MatteoT 5:33abcc31b0aa 145 FAST_FLASH_ON(led_rx,5);
MatteoT 5:33abcc31b0aa 146 Thread::wait(5);
MatteoT 5:33abcc31b0aa 147
MatteoT 5:33abcc31b0aa 148
MatteoT 5:33abcc31b0aa 149 //Prepare timers
MatteoT 5:33abcc31b0aa 150 TXRX_tx_dt_timer.reset(); TXRX_tx_dt_timer.start();
MatteoT 5:33abcc31b0aa 151 TXRX_rx_dt_timer.reset(); TXRX_rx_dt_timer.start();
MatteoT 5:33abcc31b0aa 152
MatteoT 5:33abcc31b0aa 153 unsigned int step=0;
MatteoT 5:33abcc31b0aa 154 bool accept=false, sent=false, connected=true;
MatteoT 5:33abcc31b0aa 155 while(connected){
MatteoT 5:33abcc31b0aa 156
MatteoT 6:4ddd68260f76 157 led_rx = (step % 40 < 35 ? 1 : (TXRX_times.actual_rx_dt < 1 ? 1 : 0)); //allways light on while receiving, blink 0.5Hz while not receiving.
MatteoT 5:33abcc31b0aa 158
MatteoT 5:33abcc31b0aa 159 { //RECEIVE
MatteoT 5:33abcc31b0aa 160 accept = false;
MatteoT 5:33abcc31b0aa 161 const int received = eth0.receive();
MatteoT 5:33abcc31b0aa 162 if(received > ETH_PAYLOAD_OFFSET && received < TXRX_BUFFER){ //check ethernet frame packet
MatteoT 5:33abcc31b0aa 163 //ACCEPTANCE
MatteoT 6:4ddd68260f76 164 accept = (eth0.read(TXRX_buffer,received) > ETH_PAYLOAD_OFFSET ? true : false);
MatteoT 5:33abcc31b0aa 165 //memcpy(ethernet_frame, TXRX_buffer+6, 6);//sent dest hw addr = received src hw addr
MatteoT 5:33abcc31b0aa 166 //CHECK ARP PACKET AND SEND REPLY
MatteoT 5:33abcc31b0aa 167 if(accept && 0 == memcmp(TXRX_buffer+ETH_PROTO_OFFSET,ethernet_frame_arp_proto,2)){
MatteoT 6:4ddd68260f76 168 accept = false; //consider arp packets as not accepted and reply now.
MatteoT 5:33abcc31b0aa 169 memcpy(arp_frame+ARP_SENDER_HW_ADDR_OFFSET, ethernet_frame+6, 6); //sender hw = my mac
MatteoT 5:33abcc31b0aa 170 memcpy(arp_frame+ARP_TARGET_HW_ADDR_OFFSET, TXRX_buffer+ETH_PAYLOAD_OFFSET+ARP_SENDER_HW_ADDR_OFFSET, 6+4); //target = sender (both hw and ip)
MatteoT 5:33abcc31b0aa 171 eth0.write(ethernet_frame,12);
MatteoT 5:33abcc31b0aa 172 eth0.write(ethernet_frame_arp_proto,2);
MatteoT 5:33abcc31b0aa 173 eth0.write(arp_frame,ARP_LEN);
MatteoT 5:33abcc31b0aa 174 eth0.send();
MatteoT 5:33abcc31b0aa 175 }
MatteoT 6:4ddd68260f76 176 else if(accept && 0 == memcmp(TXRX_buffer+ETH_PROTO_OFFSET, ethernet_frame+ETH_PROTO_OFFSET,2)
MatteoT 6:4ddd68260f76 177 && received > ETH_PAYLOAD_OFFSET + IP_UDP_PAYLOAD_OFFSET + 2){
MatteoT 5:33abcc31b0aa 178 //VALIDATE UDP PACKET
MatteoT 5:33abcc31b0aa 179 TXRX_buffer[received] = 0; //string termination
MatteoT 6:4ddd68260f76 180 accept = true;/*
MatteoT 5:33abcc31b0aa 181 if(0 != memcmp(TXRX_buffer+ETH_PROTO_OFFSET,ethernet_frame+ETH_PROTO_OFFSET, 2)) accept = false;
MatteoT 5:33abcc31b0aa 182 if(0 != memcmp(TXRX_buffer+ETH_PAYLOAD_OFFSET+IP_PROTO_OFFSET,ipudp_frame+IP_PROTO_OFFSET, 2)) accept = false;
MatteoT 6:4ddd68260f76 183 if(0 != memcmp(TXRX_buffer+ETH_PAYLOAD_OFFSET+IP_UDP_DESTPORT_OFFSET,ipudp_frame+IP_UDP_DESTPORT_OFFSET, 2)) accept = false;*/
MatteoT 5:33abcc31b0aa 184 }
MatteoT 5:33abcc31b0aa 185 else accept = false;
MatteoT 5:33abcc31b0aa 186 }
MatteoT 5:33abcc31b0aa 187 }
MatteoT 5:33abcc31b0aa 188 TXRX_mutex.lock();
MatteoT 5:33abcc31b0aa 189 //PRODUCE ACCEPTING DATA
MatteoT 6:4ddd68260f76 190 if(accept)
MatteoT 6:4ddd68260f76 191 accept = (QuadState::length() == TXRX_rxQuadState.setFromJSON(TXRX_buffer+ETH_PAYLOAD_OFFSET+IP_UDP_PAYLOAD_OFFSET));
MatteoT 6:4ddd68260f76 192
MatteoT 6:4ddd68260f76 193 //Import tx/rx times config from main thread
MatteoT 6:4ddd68260f76 194 TXRX_times.target_rx_dt = TXRX_txQuadState.target_rx_dt;
MatteoT 6:4ddd68260f76 195 TXRX_times.average_rx_dt_k = TXRX_txQuadState.average_rx_dt_k;
MatteoT 6:4ddd68260f76 196 TXRX_times.target_tx_dt = TXRX_txQuadState.target_tx_dt;
MatteoT 6:4ddd68260f76 197 TXRX_times.average_tx_dt_k = TXRX_txQuadState.average_tx_dt_k;
MatteoT 6:4ddd68260f76 198 //Export tx/rx times measured to remote and main thread
MatteoT 6:4ddd68260f76 199 TXRX_txQuadState.actual_rx_dt = (TXRX_rxQuadState.actual_rx_dt = TXRX_times.actual_rx_dt);
MatteoT 6:4ddd68260f76 200 TXRX_txQuadState.average_rx_dt = (TXRX_rxQuadState.average_rx_dt = TXRX_times.average_rx_dt);
MatteoT 6:4ddd68260f76 201 TXRX_txQuadState.actual_tx_dt = (TXRX_rxQuadState.actual_tx_dt = TXRX_times.actual_tx_dt);
MatteoT 6:4ddd68260f76 202 TXRX_txQuadState.average_tx_dt = (TXRX_rxQuadState.average_tx_dt = TXRX_times.average_tx_dt);
MatteoT 5:33abcc31b0aa 203
MatteoT 5:33abcc31b0aa 204 { //SEND
MatteoT 6:4ddd68260f76 205 //TXRX_buffer will contain: IP header, UDP header, json message. (no ethernet header).
MatteoT 6:4ddd68260f76 206 //Why? the function udp_checksum needs the udp payload to be next to the udp header.
MatteoT 6:4ddd68260f76 207 memset(TXRX_buffer+IP_UDP_PAYLOAD_OFFSET,' ',MSG_LEN);
MatteoT 6:4ddd68260f76 208 int setted = TXRX_txQuadState.getJSON(TXRX_buffer+IP_UDP_PAYLOAD_OFFSET);
MatteoT 5:33abcc31b0aa 209 TXRX_mutex.unlock();
MatteoT 6:4ddd68260f76 210 //CALC CHECKSUMs
MatteoT 6:4ddd68260f76 211 memcpy(TXRX_buffer,ipudp_frame,IP_UDP_PAYLOAD_OFFSET);
MatteoT 6:4ddd68260f76 212 memset(TXRX_buffer+IP_CKS_OFFSET,0,2);
MatteoT 6:4ddd68260f76 213 memset(TXRX_buffer+IP_UDP_CKS_OFFSET,0,2);
MatteoT 6:4ddd68260f76 214 uint16_t ip_cks = htons ( ip_checksum(TXRX_buffer,IP_PAYLOAD_OFFSET) );
MatteoT 6:4ddd68260f76 215 //uint16_t udp_cks = htons ( udp_checksum(TXRX_buffer+IP_PAYLOAD_OFFSET, 8+MSG_LEN, TXRX_buffer+IP_SRC_ADDR_OFFSET, TXRX_buffer+IP_DEST_ADDR_OFFSET) );
MatteoT 6:4ddd68260f76 216 memcpy(TXRX_buffer+IP_CKS_OFFSET,&ip_cks,2);
MatteoT 6:4ddd68260f76 217 //memcpy(TXRX_buffer+IP_UDP_CKS_OFFSET,&udp_cks,2);
MatteoT 6:4ddd68260f76 218 //WRITE PACKET AND SEND
MatteoT 6:4ddd68260f76 219 eth0.write(ethernet_frame,ETH_PAYLOAD_OFFSET);
MatteoT 6:4ddd68260f76 220 eth0.write(TXRX_buffer,IP_UDP_PAYLOAD_OFFSET+MSG_LEN);
MatteoT 6:4ddd68260f76 221 sent = (eth0.send() ? true : false);
MatteoT 5:33abcc31b0aa 222 }
MatteoT 5:33abcc31b0aa 223
MatteoT 6:4ddd68260f76 224 //check rx/tx dt time
MatteoT 6:4ddd68260f76 225 if(accept)
MatteoT 6:4ddd68260f76 226 QUAD_STATE_UPDATE_DT (TXRX_times, rx, TXRX_rx_dt_timer)
MatteoT 6:4ddd68260f76 227 else
MatteoT 6:4ddd68260f76 228 QUAD_STATE_READ_ACTUAL_DT (TXRX_times, rx, TXRX_rx_dt_timer)
MatteoT 6:4ddd68260f76 229 if(sent)
MatteoT 6:4ddd68260f76 230 QUAD_STATE_UPDATE_DT (TXRX_times, tx, TXRX_tx_dt_timer)
MatteoT 6:4ddd68260f76 231 else
MatteoT 6:4ddd68260f76 232 QUAD_STATE_READ_ACTUAL_DT (TXRX_times, tx, TXRX_tx_dt_timer)
MatteoT 6:4ddd68260f76 233
MatteoT 6:4ddd68260f76 234
MatteoT 6:4ddd68260f76 235 if(TXRX_times.actual_rx_dt > 10.0*TXRX_times.target_rx_dt)//disconnect when receiving nothing for a long time
MatteoT 6:4ddd68260f76 236 connected = false;
MatteoT 6:4ddd68260f76 237 if(TXRX_times.actual_rx_dt > 3.00*TXRX_times.target_rx_dt)//check link when receiving nothing for just a while
MatteoT 6:4ddd68260f76 238 connected = eth0.link();
MatteoT 6:4ddd68260f76 239
MatteoT 5:33abcc31b0aa 240 led_rx = 0;
MatteoT 5:33abcc31b0aa 241
MatteoT 6:4ddd68260f76 242 ///REALX TIMINGS (always sleep at least 48ms)
MatteoT 6:4ddd68260f76 243 double to_sleep = (TXRX_times.target_tx_dt - TXRX_times.actual_tx_dt) - 0.048;
MatteoT 6:4ddd68260f76 244 if(to_sleep < 0)
MatteoT 6:4ddd68260f76 245 to_sleep=0;
MatteoT 6:4ddd68260f76 246 QUAD_STATE_WAIT_DT_TARGET(0, to_sleep)
MatteoT 6:4ddd68260f76 247 Thread::wait(48);
MatteoT 5:33abcc31b0aa 248
MatteoT 5:33abcc31b0aa 249 ++step;
MatteoT 5:33abcc31b0aa 250 }
MatteoT 5:33abcc31b0aa 251 //end of while(connected)
MatteoT 5:33abcc31b0aa 252 }
MatteoT 5:33abcc31b0aa 253 }
MatteoT 5:33abcc31b0aa 254
MatteoT 5:33abcc31b0aa 255
MatteoT 5:33abcc31b0aa 256 //////////////////////////////////////////////////////
MatteoT 5:33abcc31b0aa 257
MatteoT 5:33abcc31b0aa 258
MatteoT 5:33abcc31b0aa 259 bool TXRX_stateExchange (QuadState & tx, QuadState & rx){
MatteoT 5:33abcc31b0aa 260 if(TXRX_mutex.trylock()){
MatteoT 5:33abcc31b0aa 261 rx = TXRX_rxQuadState;
MatteoT 5:33abcc31b0aa 262 TXRX_txQuadState = tx;
MatteoT 5:33abcc31b0aa 263 TXRX_mutex.unlock();
MatteoT 5:33abcc31b0aa 264 return true;
MatteoT 5:33abcc31b0aa 265 }
MatteoT 5:33abcc31b0aa 266 return false;
MatteoT 5:33abcc31b0aa 267 }
MatteoT 5:33abcc31b0aa 268
MatteoT 5:33abcc31b0aa 269
MatteoT 5:33abcc31b0aa 270 //////////////////////////////////////////////////////
MatteoT 5:33abcc31b0aa 271
MatteoT 5:33abcc31b0aa 272
MatteoT 5:33abcc31b0aa 273
MatteoT 5:33abcc31b0aa 274
MatteoT 6:4ddd68260f76 275 uint16_t ip_checksum (const char * buf, size_t hdr_len)
MatteoT 6:4ddd68260f76 276 {
MatteoT 6:4ddd68260f76 277 unsigned long sum = 0;
MatteoT 6:4ddd68260f76 278 const char *ip1 = buf;
MatteoT 6:4ddd68260f76 279 while (hdr_len > 1)
MatteoT 6:4ddd68260f76 280 {
MatteoT 6:4ddd68260f76 281 sum += (*ip1++)<<8; sum += (*ip1++);
MatteoT 6:4ddd68260f76 282 if (sum & 0x80000000)
MatteoT 6:4ddd68260f76 283 sum = (sum & 0xFFFF) + (sum >> 16);
MatteoT 6:4ddd68260f76 284 hdr_len -= 2;
MatteoT 6:4ddd68260f76 285 }
MatteoT 6:4ddd68260f76 286 while (sum >> 16)
MatteoT 6:4ddd68260f76 287 sum = (sum & 0xFFFF) + (sum >> 16);
MatteoT 6:4ddd68260f76 288 return(~sum);
MatteoT 6:4ddd68260f76 289 }
MatteoT 5:33abcc31b0aa 290
MatteoT 6:4ddd68260f76 291 uint16_t udp_checksum(const char * buff, size_t len, const char * src_addr, const char * dest_addr){
MatteoT 6:4ddd68260f76 292 const char *buf=buff;
MatteoT 6:4ddd68260f76 293 uint32_t sum;
MatteoT 6:4ddd68260f76 294 size_t length=len;
MatteoT 6:4ddd68260f76 295 sum = 0;
MatteoT 6:4ddd68260f76 296 while (len > 1){
MatteoT 6:4ddd68260f76 297 sum += (*buf++)<<8; sum += (*buf++);
MatteoT 6:4ddd68260f76 298 if (sum & 0x80000000)
MatteoT 6:4ddd68260f76 299 sum = (sum & 0xFFFF) + (sum >> 16);
MatteoT 6:4ddd68260f76 300 len -= 2;
MatteoT 5:33abcc31b0aa 301 }
MatteoT 6:4ddd68260f76 302 if ( len & 1 )
MatteoT 6:4ddd68260f76 303 sum += *((uint8_t *)buf);
MatteoT 6:4ddd68260f76 304 sum += (*src_addr++)<<8; sum += (*src_addr++);
MatteoT 6:4ddd68260f76 305 sum += (*src_addr++)<<8; sum += (*src_addr++);
MatteoT 6:4ddd68260f76 306 sum += (*dest_addr++)<<8; sum += (*dest_addr++);
MatteoT 6:4ddd68260f76 307 sum += (*dest_addr++)<<8; sum += (*dest_addr++);
MatteoT 6:4ddd68260f76 308 sum += htons(17); //IPPROTO_UDP
MatteoT 6:4ddd68260f76 309 sum += htons(length);
MatteoT 6:4ddd68260f76 310 while (sum >> 16)
MatteoT 6:4ddd68260f76 311 sum = (sum & 0xFFFF) + (sum >> 16);
MatteoT 6:4ddd68260f76 312 return ((uint16_t)(~sum));
MatteoT 6:4ddd68260f76 313 }