diff --git a/RF24Client.cpp b/RF24Client.cpp index 9deb901..101ec2f 100644 --- a/RF24Client.cpp +++ b/RF24Client.cpp @@ -9,42 +9,39 @@ extern "C" #include "RF24Ethernet.h" #include "RF24Client.h" +#include "RF24Network.h" #define UIP_TCP_PHYH_LEN UIP_LLH_LEN+UIP_IPTCPH_LEN uip_userdata_t RF24Client::all_data[UIP_CONNS]; +/*************************************************************/ + RF24Client::RF24Client(): data(NULL) {} -//RF24Client::RF24Client(uint16_t dataSize): _dataLen(dataSize){} - -//EthernetClient::EthernetClient(uint8_t sock) : _sock(sock) { -//} - +/*************************************************************/ RF24Client::RF24Client(uip_userdata_t* conn_data) : data(conn_data) { } +/*************************************************************/ + uint8_t RF24Client::connected(){ - return 1;//(uip_connected()); + return (data && (data->packets_in[0] != 0 || (data->state & UIP_CLIENT_CONNECTED))) ? 1 : 0; } -/* -int RF24Client::available(){ - return RF24Ethernet.dataCnt; -}*/ - - +/*************************************************************/ int RF24Client::connect(IPAddress ip, uint16_t port) { - //stop(); - /*uip_ipaddr_t ipaddr; + + stop(); + uip_ipaddr_t ipaddr; uip_ip_addr(ipaddr, ip); struct uip_conn* conn = uip_connect(&ipaddr, htons(port)); if (conn) @@ -74,10 +71,12 @@ int RF24Client::connect(IPAddress ip, uint16_t port) } #endif } - }*/ - return 1; + } + return 0; } +/*************************************************************/ + int RF24Client::connect(const char *host, uint16_t port) { @@ -96,14 +95,17 @@ RF24Client::connect(const char *host, uint16_t port) return ret; } +/*************************************************************/ + void RF24Client::stop() { if (data && data->state) { -#ifdef UIPETHERNET_DEBUG_CLIENT +#ifdef RF24ETHERNET_DEBUG_CLIENT Serial.println(F("before stop(), with data")); - _dumpAllData(); + //_dumpAllData(); #endif + data->packets_in[0] = 0; //_flushBlocks(&data->packets_in[0]); if (data->state & UIP_CLIENT_REMOTECLOSED) { @@ -113,12 +115,12 @@ void RF24Client::stop() { data->state |= UIP_CLIENT_CLOSE; } -#ifdef UIPETHERNET_DEBUG_CLIENT +#ifdef RF24ETHERNET_DEBUG_CLIENT Serial.println(F("after stop()")); //_dumpAllData(); #endif } -#ifdef UIPETHERNET_DEBUG_CLIENT +#ifdef RF24ETHERNET_DEBUG_CLIENT else { Serial.println(F("stop(), data: NULL")); @@ -127,22 +129,18 @@ void RF24Client::stop() data = NULL; RF24Ethernet.tick(); } -/* -uint8_t RF24Client::connected() -{ - //return (data && (data->packets_in[0] != NOBLOCK || (data->state & UIP_CLIENT_CONNECTED))) ? 1 : 0; - return 0; -}*/ + +/*************************************************************/ // the next function allows us to use the client returned by // EthernetServer::available() as the condition in an if-statement. bool RF24Client::operator==(const RF24Client& rhs) { - //return 0;//!RF24Ethernet.dataCnt; return data && rhs.data && (data = rhs.data); - //return 0; } +/*************************************************************/ + RF24Client::operator bool() { Ethernet.tick(); @@ -150,125 +148,272 @@ RF24Client::operator bool() return data && (!(data->state & UIP_CLIENT_REMOTECLOSED) || data->packets_in[0] != 0); } +/*************************************************************/ + size_t RF24Client::write(uint8_t c) { - //return _write(data, &c, 1); - return 0; + return _write(data, &c, 1); + //return 0; } +/*************************************************************/ + size_t RF24Client::write(const uint8_t *buf, size_t size) { - return 0;//_write(data, buf, size); + return _write(data, buf, size); } +/*************************************************************/ -void serialip_appcall(void) +size_t RF24Client::_write(uip_userdata_t* u, const uint8_t *buf, size_t size) { +test: + RF24EthernetClass::tick(); + if(u->packets_out[0] == 1){ + //delay(50); + goto test; + } + RF24NetworkHeader headerOut(00,EXTERNAL_DATA_TYPE); + int remain = size; + uint16_t written; +#if UIP_ATTEMPTS_ON_WRITE > 0 + uint16_t attempts = UIP_ATTEMPTS_ON_WRITE; +#endif + repeat: + + RF24EthernetClass::tick(); + if (u && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))) + { + + +#ifdef RF24ETHERNET_DEBUG_CLIENT + Serial.print(F("UIPClient.write: writePacket(")); + Serial.print(u->packets_out[p]); + Serial.print(F(") pos: ")); + Serial.print(u->out_pos); + Serial.print(F(", buf[")); + Serial.print(size-remain); + Serial.print(F("-")); + Serial.print(remain); + Serial.print(F("]: '")); + Serial.write((uint8_t*)buf+size-remain,remain); + Serial.println(F("'")); +#endif + + memcpy(&u->myDataOut[0],buf,size); + u->packets_out[0] = 1; + remain -= size;//written; + u->out_pos=size; + //Serial.print(F(") pos: ")); + //Serial.println(u->out_pos); +/* +test2: + RF24EthernetClass::tick(); + if(u->packets_out[0] == 1){ + goto test2; + }*/ + //u->packets_out[0] = 1; + /*if (remain > 0) + { + if (p == UIP_SOCKET_NUMPACKETS-1) + { +#if UIP_ATTEMPTS_ON_WRITE > 0 + if ((--attempts)>0) +#endif +#if UIP_ATTEMPTS_ON_WRITE != 0 + goto repeat; +#endif + goto ready; + } + p++; + goto newpacket; + }*/ +ready: +/*#if UIP_CLIENT_TIMER >= 0 + u->timer = millis()+UIP_CLIENT_TIMER; +#endif*/ + return size;//-remain; + } + return -1; +} + +/*************************************************************/ + +void serialip_appcall(void) +{ uint16_t send_len = 0; uip_userdata_t *u = (uip_userdata_t*)uip_conn->appstate; if (!u && uip_connected()){ -//#ifdef RF24ETHERNET_DEBUG_CLIENT +#ifdef RF24ETHERNET_DEBUG_CLIENT Serial.println(F("UIPClient uip_connected")); // RF24Client::_dumpAllData(); -//#endif +#endif u = (uip_userdata_t*) EthernetClient::_allocateData(); if (u) { uip_conn->appstate = u; -//#ifdef UIPETHERNET_DEBUG_CLIENT +#ifdef RF24ETHERNET_DEBUG_CLIENT Serial.print(F("UIPClient allocated state: ")); Serial.println(u->state,BIN); -//#endif +#endif } -//#ifdef UIPETHERNET_DEBUG_CLIENT +#ifdef RF24ETHERNET_DEBUG_CLIENT else Serial.println(F("UIPClient allocation failed")); -//#endif +#endif } if(u){ if (uip_newdata()){ -//#ifdef UIPETHERNET_DEBUG_CLIENT +#ifdef RF24ETHERNET_DEBUG_CLIENT Serial.print(F("UIPClient uip_newdata, uip_len:")); Serial.println(uip_len); -//#endif - +#endif + u->restarted = 0; if (uip_len && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))){ - // for (uint8_t i=0; i < UIP_SOCKET_NUMPACKETS; i++){ - // if (u->packets_in[i] == NOBLOCK){ - // u->packets_in[i] = !NOBLOCK;//Enc28J60Network::allocBlock(uip_len); - // if (u->packets_in[i] != NOBLOCK){ - Serial.println("Data buffered"); - RF24Ethernet.dataCnt = min(UIP_BUFSIZE-42,uip_datalen()); + uip_stop(); + RF24Ethernet.dataCnt = uip_datalen(); memcpy(&RF24Ethernet.myData,uip_appdata,RF24Ethernet.dataCnt); u->packets_in[0] = 1; - //RF24EthernetClass::packetstate &= ~UIPETHERNET_FREEPACKET; - } + } } } + +finish_newdata: + if (u->state & UIP_CLIENT_RESTART ) + { + + + u->state &= ~UIP_CLIENT_RESTART; + if( !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))){ + uip_restart(); + //Serial.print("rst"); + // Workaround to prevent the connection from stalling when a restart packet fails to get through + // If data has not been received by the next time round, call restart again + u->restarted = 1; + u->restartTime = millis(); + } + + }else + if(u->restarted && millis() - u->restartTime > 5000){ + if( !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))){ + uip_restart(); + u->restarted = 1; + u->restartTime = millis(); + Serial.print("man rst"); + } + } + + + + // If the connection has been closed, save received but unread data. + if (uip_closed() || uip_timedout() || uip_aborted()) + { +#ifdef UIPETHERNET_DEBUG_CLIENT + Serial.println(F("UIPClient uip_closed")); + RF24Client::_dumpAllData(); +#endif + // drop outgoing packets not sent yet: + //UIPClient::_flushBlocks(&u->packets_out[0]); + if (u->packets_in[0] != 0) + { + ((uip_userdata_closed_t *)u)->lport = uip_conn->lport; + u->state |= UIP_CLIENT_REMOTECLOSED; + } + else{ + u->state = 0; + } +#ifdef UIPETHERNET_DEBUG_CLIENT + Serial.println(F("after UIPClient uip_closed")); + //RF24Client::_dumpAllData(); +#endif + uip_conn->appstate = NULL; + goto finish; + } + + if (uip_acked()) + { +#ifdef RF24ETHERNET_DEBUG_CLIENT + Serial.println(F("UIPClient uip_acked")); +#endif + u->packets_out[0] = 0; + u->out_pos=0; + // UIPClient::_eatBlock(&u->packets_out[0]); + + } + if (uip_poll() ) + { +#ifdef RF24ETHERNET_DEBUG_CLIENT + Serial.println(F("UIPClient uip_poll")); +#endif + if (u->packets_out[0] != 0 ) + { + send_len = u->out_pos; + + if (send_len > 0) + { + RF24Ethernet.uip_hdrlen = ((uint8_t*)uip_appdata)-uip_buf; + uip_len = send_len; + uip_send(&u->myDataOut[0],send_len); + + RF24Ethernet.packetstate |= UIPETHERNET_SENDPACKET; + } + goto finish; + } + } + if( uip_rexmit()){ + //Serial.println("REXMIT"); + if (u->packets_out[0] != 0 ) + { + send_len = u->out_pos; + + if (send_len > 0) + { + RF24Ethernet.uip_hdrlen = ((uint8_t*)uip_appdata)-uip_buf; + uip_len = send_len; + uip_send(&u->myDataOut[0],send_len); + RF24Ethernet.packetstate |= UIPETHERNET_SENDPACKET; + } + goto finish; + } + } + + + if (u->state & UIP_CLIENT_CLOSE) { -//#ifdef UIPETHERNET_DEBUG_CLIENT +#ifdef RF24ETHERNET_DEBUG_CLIENT Serial.println(F("UIPClient state UIP_CLIENT_CLOSE")); //UIPClient::_dumpAllData(); -//#endif - //if (u->packets_out[0] == 0) +#endif if (u->packets_out[0] == 0) { u->state = 0; uip_conn->appstate = NULL; uip_close(); -//#ifdef UIPETHERNET_DEBUG_CLIENT +#ifdef RF24ETHERNET_DEBUG_CLIENT Serial.println(F("no blocks out -> free userdata")); //UIPClient::_dumpAllData(); -//#endif +#endif } else { uip_stop(); -//#ifdef UIPETHERNET_DEBUG_CLIENT - Serial.println(F("blocks outstanding transfer -> uip_stop()")); -//#endif +#ifdef RF24ETHERNET_DEBUG_CLIENT + Serial.println(F("blocks outstanding transfer -> uip_stop()")); +#endif } - } - + } + + finish:; + //uip_send(uip_appdata,send_len); + //uip_len = send_len; + //u->packets_out[0]=0; + -/* struct serialip_state *s = &(uip_conn->appstate); - //uip_listen(HTONS(port)); - //struct serialip_state *t = &(uip_conn->appstate); - - //uip_userdata_t *u = (uip_userdata_t*)uip_conn->appstate; - if (uip_connected()) { - //Serial.print("Conn on port: "); - //Serial.println(HTONS(uip_conn->lport)); - s->connected = 1; - //PSOCK_INIT(&s->p, s->inputBuffer, sizeof(s->inputBuffer)); - } - - if(uip_newdata()){ - RF24Ethernet.dataCnt = min(UIP_BUFSIZE-42,uip_datalen()); - memcpy(&RF24Ethernet.myData,uip_appdata,RF24Ethernet.dataCnt); - s->packets_in[0] = 1; - //if(PSOCK_NEWDATA(&s->p)) { - //If data is available, put it into the input buffer - //PSOCK_READTO(&s->p, '\n'); - //memcpy(s->outputBuffer,s->inputBuffer,PSOCK_DATALEN(s)); - // } - } - - if (uip_closed() || uip_aborted() || uip_timedout() || uip_rexmit() ) { - uip_close(); - #if defined (ETH_DEBUG_L1) - Serial.println("*****CLOSE *********"); - #endif - //PSOCK_CLOSE(&s->p); - //PSOCK_END(&s->p); - } - - RF24Client::handle_connection(s);*/ } /*******************************************************/ @@ -305,28 +450,26 @@ uip_userdata_t *RF24Client::_allocateData() if (!data->state) { data->state = sock | UIP_CLIENT_CONNECTED; - memset(&data->packets_in[0],0,sizeof(uip_userdata_t)-sizeof(data->state)); + //memset(&data->packets_in[0],0,sizeof(uip_userdata_t)-sizeof(data->state)); + data->packets_in[0]=0; return data; } } return NULL; } -/* -size_t RF24Client::_write(uip_userdata_t* u, const uint8_t *buf, size_t size) -{ - return 0; -}*/ - +/*************************************************************/ int RF24Client::available() { if (*this) - //return RF24Ethernet.dataCnt; + RF24Ethernet.tick(); return _available(data); return 0; } +/*************************************************************/ + int RF24Client::_available(uip_userdata_t *u) { int len = 0; @@ -335,18 +478,7 @@ int RF24Client::_available(uip_userdata_t *u) //len += Enc28J60Network::blockSize(u->packets_in[i]); //} - //if(UIPEthernet.network.update() == EXTERNAL_DATA_TYPE){ - // RF24NetworkFrame *frame = UIPEthernet.network.frag_ptr; - // len = frame->message_size; - // } - - len = RF24Ethernet.dataCnt; -// if(UIPEthernet.inPos > 0){ -// len=UIPEthernet.inPos; -// } - //len=UIPEthernet.dataSize; - //Serial.print("av len"); - //Serial.println(len); + len = RF24Ethernet.dataCnt; return len; } @@ -363,38 +495,30 @@ int RF24Client::read(uint8_t *buf, size_t size) //do // { //read = Enc28J60Network::readPacket(data->packets_in[0],0,buf+size-remain,remain); -/* Serial.println("1"); - RF24NetworkFrame *frame = UIPEthernet.network.frag_ptr; - read = frame->message_size; - //Serial.println("got ext"); - memcpy(&buf,&frame->message_buffer,size);*/ - //read = UIPEthernet.inPos; - //memcpy(&buf,&UIPEthernet.myPackets_In,remain); size = min(RF24Ethernet.dataCnt,size); memcpy(buf,&RF24Ethernet.myData,size); RF24Ethernet.dataCnt -= size; - memmove(RF24Ethernet.myData,RF24Ethernet.myData+size,RF24Ethernet.dataCnt); - - - - //memcpy(&buf,UIPEthernet.packetDataIn,size); + memmove(RF24Ethernet.myData,RF24Ethernet.myData+size,RF24Ethernet.dataCnt); + //Serial.println("got ext"); + read = size; if(!RF24Ethernet.dataCnt)// read == Enc28J60Network::blockSize(data->packets_in[0])) { - remain -= read; + // remain -= read; + remain = 0; data->packets_in[0] = 0; //_eatBlock(&data->packets_in[0]); if (uip_stopped(&uip_conns[data->state & UIP_CLIENT_SOCKETS]) && !(data->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_REMOTECLOSED))) data->state |= UIP_CLIENT_RESTART; - // if (data->packets_in[0] == NOBLOCK) - // { + if (data->packets_in[0] == 0) + { if (data->state & UIP_CLIENT_REMOTECLOSED) { data->state = 0; data = NULL; } return size-remain; - // } + } } /*else { @@ -408,20 +532,19 @@ int RF24Client::read(uint8_t *buf, size_t size) return -1; } -int -RF24Client::read() +/*************************************************************/ + +int RF24Client::read() { - //memcpy(buf,&RF24Ethernet.myData,size); - //RF24Ethernet.dataCnt -= size; - uint8_t c; if (read(&c,1) < 0) return -1; return c; } -int -RF24Client::peek() +/*************************************************************/ + +int RF24Client::peek() { if (*this) { @@ -435,10 +558,14 @@ RF24Client::peek() return -1; } +/*************************************************************/ + void RF24Client::flush() { if (*this) { //_flushBlocks(&data->packets_in[0]); } -} \ No newline at end of file +} + +/*************************************************************/ diff --git a/RF24Client.h b/RF24Client.h index b884c9a..09ca3e6 100644 --- a/RF24Client.h +++ b/RF24Client.h @@ -56,6 +56,9 @@ typedef struct { unsigned long timer; #endif uint8_t connected; + bool restarted; + uint32_t restartTime; + uint8_t myDataOut[64]; } uip_userdata_t; @@ -65,8 +68,6 @@ class RF24Client : public Client { public: RF24Client(); - //RF24Client(int len); - //RF24Client(uint8_t sock); int connect(IPAddress ip, uint16_t port); int connect(const char *host, uint16_t port); int read(uint8_t *buf, size_t size); @@ -74,39 +75,25 @@ class RF24Client : public Client { uint8_t connected(); - //int available(); - size_t write(uint8_t); - size_t write(const uint8_t *buf, size_t size); - int available(); - int read(); - int peek(); - void flush(); - - using Print::write; + size_t write(uint8_t); + size_t write(const uint8_t *buf, size_t size); + int available(); + int read(); + int peek(); + void flush(); + + using Print::write; - operator bool(); - virtual bool operator==(const EthernetClient&); - virtual bool operator!=(const EthernetClient& rhs) { return !this->operator==(rhs); }; - + operator bool(); + virtual bool operator==(const EthernetClient&); + virtual bool operator!=(const EthernetClient& rhs) { return !this->operator==(rhs); }; private: - uint8_t _sock; - uint16_t _dataLen; - - static bool isConnected; - static bool clientClose; - static bool readData; static int handle_connection(uip_tcp_appstate_t *s); - //This is referenced by UIPServer.cpp in available() - //RF24Client(serialip_state* conn_data); - //RF24Client(uint8_t sock); - //RF24Client(size_t tmp); RF24Client(struct uip_conn *_conn); RF24Client(uip_userdata_t* conn_data); - //RF24Client(serialip_state* conn_data); - uip_userdata_t* data; @@ -114,11 +101,12 @@ class RF24Client : public Client { static uip_userdata_t all_data[UIP_CONNS]; static uip_userdata_t* _allocateData(); - + static size_t _write(uip_userdata_t *,const uint8_t *buf, size_t size); + friend class RF24EthernetClass; friend class RF24Server; - friend void uipclient_appcall(void); + //friend void uipclient_appcall(void); friend void serialip_appcall(void); }; diff --git a/RF24Ethernet.cpp b/RF24Ethernet.cpp index 801c31e..0c659e6 100644 --- a/RF24Ethernet.cpp +++ b/RF24Ethernet.cpp @@ -34,19 +34,19 @@ extern "C" { #include #include -//RF24EthernetClass::RF24EthernetClass(){}//:fn_uip_cb(NULL){} +/*************************************************************/ RF24EthernetClass::RF24EthernetClass(RF24& _radio, RF24Network& _network): radio(_radio),network(_network) //fn_uip_cb(NULL) { - } +/*************************************************************/ + void RF24EthernetClass::use_device() { radio.begin(); RF24_Channel = RF24_Channel ? RF24_Channel : 97; - //network.begin(Ethernet.RF24_Channel,04444); } /*******************************************************/ @@ -56,7 +56,7 @@ void RF24EthernetClass::setMac(uint16_t address){ uint8_t mac[6] = {0x00,0x00,0x52,0x46,0x32,0x34}; mac[0] = address; mac[1] = address >> 8; - printf("MAC: %o %d\n",address,mac[0]); + //printf("MAC: %o %d\n",address,mac[0]); uip_seteth_addr(mac); RF24_Channel = RF24_Channel ? RF24_Channel : 97; @@ -77,8 +77,8 @@ void RF24EthernetClass::begin(IP_ADDR myIP, IP_ADDR subnet) { uip_ipaddr_t ipaddr; + timer_set(&this->periodic_timer, CLOCK_SECOND / 4); //timer_set(&this->periodic_timer, CLOCK_SECOND / 4); - timer_set(&this->periodic_timer, CLOCK_SECOND / 8); #if defined (TAP) timer_set(&this->arp_timer, CLOCK_SECOND * 10); @@ -95,8 +95,6 @@ void RF24EthernetClass::begin(IP_ADDR myIP, IP_ADDR subnet) #endif //slipdev_init(); - - uip_ipaddr(ipaddr, myIP.a, myIP.b, myIP.c, myIP.d); uip_sethostaddr(ipaddr); uip_ipaddr(ipaddr, subnet.a, subnet.b, subnet.c, subnet.d); @@ -111,6 +109,12 @@ void RF24EthernetClass::set_gateway(IP_ADDR myIP) uip_ipaddr_t ipaddr; uip_ipaddr(ipaddr, myIP.a, myIP.b, myIP.c, myIP.d); uip_setdraddr(ipaddr); +/* uip_getdraddr(ipaddr); + Serial.println(uip_ipaddr1(&ipaddr)); + Serial.println(uip_ipaddr2(&ipaddr)); + Serial.println(uip_ipaddr3(&ipaddr)); + Serial.println(uip_ipaddr4(&ipaddr));*/ + } /*******************************************************/ @@ -119,166 +123,112 @@ void RF24EthernetClass::listen(uint16_t port) { uip_listen(HTONS(port)); } - /*hwsend(&uip_buf[0], UIP_LLH_LEN); - if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) { - hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN); - } else { - hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN); - hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN); - - */ - + /*******************************************************/ -void RF24EthernetClass::tick() -{ +void RF24EthernetClass::tick() { if(RF24Ethernet.network.update() == EXTERNAL_DATA_TYPE){ - - RF24NetworkFrame *frame = RF24Ethernet.network.frag_ptr; - memcpy(&uip_buf,frame->message_buffer,frame->message_size); - #if defined (ETH_DEBUG_L1) - Serial.print("got len"); - Serial.println(frame->message_size); - for(int i=0; imessage_size; i++){ - Serial.print(uip_buf[i],HEX); - } - Serial.println(""); - #endif + RF24NetworkFrame *frame = RF24Ethernet.network.frag_ptr; uip_len = frame->message_size; + memcpy(&uip_buf,frame->message_buffer,frame->message_size); + }else{ + uip_len = 0; } - if(uip_len > 0) { - //Serial.println("data in"); - #if defined (TAP) - if(BUF->type == htons(UIP_ETHTYPE_IP)) { - uip_arp_ipin(); - //Serial.println("TAP"); - #endif - uip_input(); - // If the above function invocation resulted in data that - // should be sent out on the network, the global variable - // uip_len is set to a value > 0. - if (uip_len > 0){ - uip_arp_out(); - size_t totalSize = 0; - //uint8_t buffer[uip_len + UIP_LLH_LEN + UIP_TCPIP_HLEN]; - /*memcpy(&buffer, &uip_buf,UIP_LLH_LEN); - totalSize += UIP_LLH_LEN; - if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) { - memcpy(&buffer+totalSize,&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN); - totalSize += uip_len - UIP_LLH_LEN; - }else{ - memcpy(&buffer+totalSize,&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN); - totalSize += UIP_TCPIP_HLEN; - memcpy(&buffer+totalSize,uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN); - totalSize += uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN; - - - }*/ - //memcpy(&buffer, &uip_buf,uip_len); - //delay(5); - bool ook = 0; - //while(!ook){ - RF24NetworkHeader headerOut(00,EXTERNAL_DATA_TYPE); - ook = RF24Ethernet.network.write(headerOut,&uip_buf,uip_len); - //} - #if defined (ETH_DEBUG_L1) - printf("data out %d\n",ook); - #endif - //network.write(headerOut,&buffer,totalSize); - } - - - - #if defined (TAP) - }else if(BUF->type == htons(UIP_ETHTYPE_ARP)) { - uip_arp_arpin(); - #if defined (ETH_DEBUG_L1) - Serial.println("ARp"); - #endif - // If the above function invocation resulted in data that - // should be sent out on the network, the global variable - // uip_len is set to a value > 0. - if(uip_len > 0) { - //network_device_send(); - //uint8_t buffer[uip_len + UIP_LLH_LEN + UIP_TCPIP_HLEN]; - //memcpy(&buffer, &uip_buf,uip_len); - //delay(5); - bool ook = 0; - //while(!ook){ - RF24NetworkHeader headerOut(00,EXTERNAL_DATA_TYPE); - ook = RF24Ethernet.network.write(headerOut,&uip_buf,uip_len); - //} - #if defined (ETH_DEBUG_L1) - printf("data out %d\n",ook); - #endif - } - } - - #endif - - - }else if (timer_expired(&RF24Ethernet.periodic_timer)) { - timer_reset(&RF24Ethernet.periodic_timer); - for (int i = 0; i < UIP_CONNS; i++) { - uip_periodic(i); - // If the above function invocation resulted in data that - // should be sent out on the network, the global variable - // uip_len is set to a value > 0. - if (uip_len > 0) { - uip_arp_out(); - //uint8_t buffer[uip_len + UIP_LLH_LEN + UIP_TCPIP_HLEN]; - //memcpy(&buffer, &uip_buf,uip_len); - //delay(5); - bool ook = 0; - //while(!ook){ - RF24NetworkHeader headerOut(00,EXTERNAL_DATA_TYPE); - ook = RF24Ethernet.network.write(headerOut,&uip_buf,uip_len); - //} - #if defined (ETH_DEBUG_L1) - printf("data out %d\n",ook); - #endif - } - } - + if(uip_len > 0) { + if(BUF->type == htons(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_input(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + uip_arp_out(); + network_send(); + } + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + network_send(); + } + } + + } else if(timer_expired(&Ethernet.periodic_timer)) { + timer_reset(&Ethernet.periodic_timer); + for(int i = 0; i < UIP_CONNS; i++) { + uip_periodic(i); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + uip_arp_out(); + network_send(); + } + } #if UIP_UDP - for (int i = 0; i < UIP_UDP_CONNS; i++) { - uip_udp_periodic(i); - // If the above function invocation resulted in data that - // should be sent out on the network, the global variable - // uip_len is set to a value > 0. */ - if (uip_len > 0){ - //uint8_t buffer[uip_len + UIP_LLH_LEN + UIP_TCPIP_HLEN]; - //memcpy(&buffer, &uip_buf,uip_len); - //delay(5); - bool ook = 0; - while(!ook){ - RF24NetworkHeader headerOut(00,EXTERNAL_DATA_TYPE); - ook = RF24Ethernet.network.write(headerOut,&uip_buf,uip_len); - } - //printf("data out %d",ook); - } - } -#endif /* UIP_UDP */ - /* Call the ARP timer function every 10 seconds. */ - if(timer_expired(&RF24Ethernet.arp_timer)) { - timer_reset(&RF24Ethernet.arp_timer); - uip_arp_timer(); - } + for(i = 0; i < UIP_UDP_CONNS; i++) { + uip_udp_periodic(i); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + uip_arp_out(); + network_send(); } - + } +#endif /* UIP_UDP */ + + /* Call the ARP timer function every 10 seconds. */ + if(timer_expired(&Ethernet.arp_timer)) { + timer_reset(&Ethernet.arp_timer); + uip_arp_timer(); + } + } } -/* -void RF24EthernetClass::set_uip_callback(fn_uip_cb_t fn) + + +boolean RF24EthernetClass::network_send() { - this->fn_uip_cb = fn; + RF24NetworkHeader headerOut(00,EXTERNAL_DATA_TYPE); + + bool ok = 0; + if(RF24Ethernet.packetstate == UIPETHERNET_SENDPACKET){ + + uint8_t buf[uip_len + UIP_TCPIP_HLEN + UIP_LLH_LEN]; + size_t pSize = 0; + //RF24Ethernet.network.write(headerOut,&uip_buf[0], UIP_LLH_LEN); + memcpy(&buf[0],&uip_buf[0],UIP_LLH_LEN); + pSize += UIP_LLH_LEN; + if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) { + //RF24Ethernet.network.write(headerOut,&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN); + memcpy(&buf[UIP_LLH_LEN],&uip_buf[UIP_LLH_LEN],uip_len-UIP_LLH_LEN); + pSize += uip_len-UIP_LLH_LEN; + } else { + //RF24Ethernet.network.write(headerOut,&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN); + //RF24Ethernet.network.write(headerOut,uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN); + memcpy(&buf[UIP_LLH_LEN],&uip_buf[UIP_LLH_LEN],UIP_TCPIP_HLEN); + pSize += UIP_TCPIP_HLEN; + memcpy(&buf[UIP_LLH_LEN+UIP_TCPIP_HLEN],uip_appdata,uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN); + pSize += uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN; + } + ok = RF24Ethernet.network.write(headerOut,&buf[0],pSize); + }else{ + + + ok = RF24Ethernet.network.write(headerOut,&uip_buf,uip_len); + } + if(ok){ + RF24Ethernet.packetstate &= ~UIPETHERNET_SENDPACKET; + } } -*/ /*******************************************************/ @@ -288,126 +238,3 @@ void uipudp_appcall(){ /*******************************************************/ - - - - //RF24Ethernet.cur_conn = s; - //if (this->fn_uip_cb) { - // The sketch wants to handle all uIP events itself, using uIP functions. - // this->fn_uip_cb(s);//->p, &s->user); - //} else { - // The sketch wants to use our simplified interface. - // This is still in the planning stage :-) - /* struct serialip_state *s = &(uip_conn->appstate); - - SerialIP.cur_conn = s; - - if (uip_connected()) { - s->obpos = 0; - handle_ip_event(IP_INCOMING_CONNECTION, &s->user); - } - - if (uip_rexmit() && s->obpos) { - // Send the same buffer again - SerialIP.queue(); - //uip_send(this->send_buffer, this->bufpos); - return; - } - - if ( - uip_closed() || - uip_aborted() || - uip_timedout() - ) { - handle_ip_event(IP_CONNECTION_CLOSED, &s->user); - return; - } - - if (uip_acked()) { - s->obpos = 0; - handle_ip_event(IP_PACKET_ACKED, &s->user); - } - - if (uip_newdata()) { - handle_ip_event(IP_INCOMING_DATA, &s->user); - } - - if ( - uip_newdata() || - uip_acked() || - uip_connected() || - uip_poll() - ) { - // We've got space to send another packet if the user wants - handle_ip_event(IP_SEND_PACKET, &s->user); - }*/ - //} - - -//RF24Network net = RF24EthernetClass::network; -//RF24EthernetClass RF24Ethernet; -/* typedef struct connDataStruct{ - char input_buffer[16]; - char name[20]; - } connection_data; - - */ - -// uIP callback function -//void serialip_appcall(void) -//{ -// RF24Ethernet.uip_callback(); - //uip_callback(); -/* if (uip_connected()) { - - // We want to store some data in our connections, so allocate some space - // for it. The connection_data struct is defined in a separate .h file, - // due to the way the Arduino IDE works. (typedefs come after function - // definitions.) - connection_data *d = (connection_data *)malloc(sizeof(connection_data)); - - // Save it as RF24Ethernet user data so we can get to it later. - s->user = d; - - // The protosocket's read functions need a per-connection buffer to store - // data they read. We've got some space for this in our connection_data - // structure, so we'll tell uIP to use that. - PSOCK_INIT(&s->p, d->input_buffer, sizeof(d->input_buffer)); - - } - - // Call/resume our protosocket handler. - handle_connection(s, (connection_data *)s->user); - - // If the connection has been closed, release the data we allocated earlier. - if (uip_closed()) { - if (s->user) free(s->user); - s->user = NULL; - }*/ -//} - - - -/* - * Code to interface the serial port with the SLIP handler. - * - * See slipdev.h for further explanation. - */ -/* -extern SerialDevice *slip_device; - -// Put a character on the serial device. -void slipdev_char_put(u8_t c) -{ - ::slip_device->write((char)c); -} - -// Poll the serial device for a character. -u8_t slipdev_char_poll(u8_t *c) -{ - if (::slip_device->available()) { - *c = ::slip_device->read(); - return 1; - } - return 0; -}*/ diff --git a/RF24Ethernet.h b/RF24Ethernet.h index 4be18ab..ed15eb2 100644 --- a/RF24Ethernet.h +++ b/RF24Ethernet.h @@ -36,6 +36,10 @@ extern "C" { #include "utility/uip.h" } + +#define UIPETHERNET_FREEPACKET 1 +#define UIPETHERNET_SENDPACKET 2 + //#define TUN // Use only the tcp protocol, no ethernet headers or arps #define TAP // Include ethernet headers @@ -149,26 +153,29 @@ class RF24EthernetClass {//: public Print { //virtual void write(uint8_t ch); /*virtual void write(const char *str); virtual void write(const uint8_t *buffer, size_t size);*/ - uint8_t myData[UIP_BUFSIZE]; + uint8_t myData[UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN]; + size_t dataCnt; int available(); + uint8_t packetstate; + uint8_t uip_hdrlen; + + private: - //RF24& radio; - //RF24Network& network; - + + uint8_t in_packet; // tick() must be called at regular intervals to process the incoming serial // data and issue IP events to the sketch. It does not return until all IP // events have been processed. static void tick(); + static boolean network_send(); uint8_t RF24_Channel; int handle_connection(uip_tcp_appstate_t *s); struct timer periodic_timer; + struct timer arp_timer; - //, arp_timer; - struct serialip_state *cur_conn; // current connection (for print etc.) - //fn_uip_cb_t fn_uip_cb; void uip_callback(); //friend void serialip_appcall(void); diff --git a/RF24Ethernet_config.h b/RF24Ethernet_config.h index 9d3cbca..6ffa8b0 100644 --- a/RF24Ethernet_config.h +++ b/RF24Ethernet_config.h @@ -1,6 +1,7 @@ /*********** USER CONFIGURATION *********/ -#define ETH_DEBUG_L1 +//#define RF24ETHERNET_DEBUG_CLIENT +//#define ETH_DEBUG_L1 //#define ETH_DEBUG_L2 /****************************************/ \ No newline at end of file diff --git a/examples/Getting_Started_SimpleClient/Getting_Started_SimpleClient.ino b/examples/Getting_Started_SimpleClient/Getting_Started_SimpleClient.ino new file mode 100644 index 0000000..be8dcff --- /dev/null +++ b/examples/Getting_Started_SimpleClient/Getting_Started_SimpleClient.ino @@ -0,0 +1,179 @@ +/* + * RF24Ethernet Hello World example, lib initially based on SerialIP + * + * SerialIP is a TCP/IP stack that can be used over a serial port (a bit + * like a dial-up Internet connection, but without the modem.) It works with + * stock Arduinos (no shields required.) When attached to a PC supporting + * SLIP, the Arduino can host network servers and access the Internet (if the + * PC is configured to share its Internet connection of course!) + * + * RF24Ethernet uses the fine uIP stack by Adam Dunkels + * + * For more information see the SerialIP page on the Arduino wiki: + * + * + * ----------------- + * + * This Hello World example sets up a server at 192.168.5.2 on port 1000. + * Telnet here to access the service. The uIP stack will also respond to + * pings to test. + * + * This version also can be easily configured to send out an HTTP response to a browser + * + * + * This example was based upon uIP hello-world by Adam Dunkels + * Ported to the Arduino IDE by Adam Nielsen + */ + + +#include +#include +#include +//#include + #include + + +/**** NOTE: Radio CE,CS pins must be configured in RF24Ethernet.cpp */ +// This code is experimental, so not user friendly +//This sketch will communicate with an RF24Network master node (00) + +// The connection_data struct needs to be defined in an external file. +//#include "HelloWorldData.h" + +RF24 radio(7,8); +RF24Network network(radio); +RF24EthernetClass RF24Ethernet(radio,network); + + +//EthernetServer server = EthernetServer(1000); +//EthernetServer server2 = EthernetServer(80); + +EthernetClient client; + +void setup() { + + Serial.begin(115200); + //printf_begin(); + // This initializes the radio with basic settings. + // Needs to be called at the beginning of every sketch + Ethernet.use_device(); + + // Tell RF24Ethernet which channel to use. This step is not that important, but it + // is important to set the channel this way, not directly via the radio + //Ethernet.setChannel(97); + + // This step is very important. The address of the node needs to be set both + // on the radio and in the UIP layer + // This is the RF24Network address and needs to be configured accordingly if + // using more than 4 nodes with the master node. Otherwise, 01-04 can be used. + uint16_t myRF24NetworkAddress = 04; + Ethernet.setMac(myRF24NetworkAddress); + + //Optional + radio.setPALevel(RF24_PA_HIGH); + //radio.printDetails(); + + // Set the IP address we'll be using. Make sure this doesn't conflict with + // any IP addresses or subnets on your LAN or you won't be able to connect to + // either the Arduino or your LAN... + IP_ADDR myIP = {10,10,2,3}; + IP_ADDR subnet = {255,255,255,0}; + Ethernet.begin(myIP, subnet); + + // If you'll be making outgoing connections from the Arduino to the rest of + // the world, you'll need a gateway set up. + IP_ADDR gwIP = {10,10,2,2}; + Ethernet.set_gateway(gwIP); +} + +uint32_t testTimer = 0; +uint32_t counter = 0; +uint32_t reqTimer = 0; +uint32_t restartTimer = 0; +bool first = 1; +void loop() { + +// if(millis() - testTimer > 5000){ +// testTimer = millis(); +// Serial.println(F("alive")); +// } + uint8_t c=0; + size_t size; + +if(size = client.available() > 0){ + //char c = client.read(); + //Serial.print(c); + uint8_t buf[size]; + client.read(buf,size); + Serial.write(buf,size); + if(counter > 100){ /*Serial.println("");*/ counter=0;} + counter++; + //delay(4); + restartTimer = millis(); +}else{ + if(millis()-restartTimer > 1000){ + restartTimer = millis(); + //uip_restart(); + //Serial.println("restart manual"); + } +} + + // if the server's disconnected, stop the client: + if (!client.connected()) { + Serial.println(); + Serial.println(F("Disconnect. Waiting for serial input")); + client.stop(); + + // Wait for serial input to begin + //while (!Serial.available() && !client.connected()){} + //Serial.read(); + reqTimer = millis(); + while(millis() - reqTimer < 5000 && !client.available() ){ } + connect(); + + } + // We can do other things in the loop, but be aware that the loop will + // briefly pause while IP data is being processed. +} + +void connect(){ + Serial.println(F("connecting")); + IPAddress goog(74,125,224,72); + IPAddress purp(83,227,225,7); + IPAddress loc(10,10,1,49); + IPAddress art(80,237,132,189); + IPAddress pizza(94,199,58,243); + //IPAddress reddit(198,41,209,137); + if (client.connect(purp, 80)) { + Serial.println(F("connected")); + // Make a HTTP request: + //client.println(F("GET /search?q=arduino HTTP/1.1")); + //delay(100); + //client.println(F("GET / HTTP/1.1")); + //client.println(F("Host: www.google.ca")); + //client.println(F("Connection: close")); + + //uint8_t buffr[39] = {"GET / HTTP/1.1\n"}; + //uint8_t buffr[39] = {"GET /asciiart/pizza.txt HTTP/1.1\n"}; //Length is 15 bytes + //uint8_t buffr[32] = {"GET /ascii/c/cat.txt HTTP/1.1\n"}; //Length is 30 bytes + uint8_t buffr[33] = {"GET /taiji/ascii.txt HTTP/1.1\n"}; + + client.write(buffr,30); + //memcpy(buffr,"Host: www.google.ca\n",20); + memcpy(buffr,"Host: hakank.org\n",17); + //memcpy(buffr,"Host: fiikus.net\n",17); + //client.println(F("GET /r/funny/.rss HTTP/1.1")); + client.write(buffr,17); + memcpy(buffr,"Connection: close\n",18); + //buffr = "Connection: close\n"; + client.write(buffr,18); + client.println(); + //delay(100); + + }else{ + // if you didn't get a connection to the server: + Serial.println(F("connection failed")); + } +} + + diff --git a/examples/Getting_Started_SimpleServer/Getting_Started_SimpleServer.ino b/examples/Getting_Started_SimpleServer/Getting_Started_SimpleServer.ino index 936410b..dd00af9 100644 --- a/examples/Getting_Started_SimpleServer/Getting_Started_SimpleServer.ino +++ b/examples/Getting_Started_SimpleServer/Getting_Started_SimpleServer.ino @@ -40,7 +40,7 @@ // The connection_data struct needs to be defined in an external file. //#include "HelloWorldData.h" -RF24 radio(48,49); +RF24 radio(7,8); RF24Network network(radio); RF24EthernetClass RF24Ethernet(radio,network); @@ -76,13 +76,13 @@ void setup() { // any IP addresses or subnets on your LAN or you won't be able to connect to // either the Arduino or your LAN... IP_ADDR myIP = {10,10,2,3}; - IP_ADDR subnet = {255,255,0,0}; + IP_ADDR subnet = {255,255,255,0}; Ethernet.begin(myIP, subnet); // If you'll be making outgoing connections from the Arduino to the rest of // the world, you'll need a gateway set up. - //IP_ADDR gwIP = {192,168,1,1}; - //Ethernet.set_gateway(gwIP); + IP_ADDR gwIP = {10,10,2,2}; + Ethernet.set_gateway(gwIP); // Listen for incoming connections on TCP port 1000. Each incoming // connection will result in the uip_callback() function being called. @@ -111,6 +111,16 @@ void loop() { Serial.println(""); //Serial.write(msg,size); } + client.write( "HTTP/1.1 200 OK\n"); + client.write( "Content-Type: text/html\n"); + client.write( "Connection: close\n"); + client.write( "Refresh: 5\n"); + client.write( "\n"); + client.write( "\n"); + client.write( "\n"); + client.write( "HELLO FROM ARDUINO!\n"); + client.write( "\n"); + testTimer = millis(); client.stop(); Serial.println("********"); diff --git a/uip-conf.h b/uip-conf.h index feedeb3..a4b7999 100644 --- a/uip-conf.h +++ b/uip-conf.h @@ -74,7 +74,7 @@ typedef unsigned short uip_stats_t; - +//********** TMRh20: These options are mostly invalid and should be configured elsewhere **********// /* for TCP */ #define UIP_SOCKET_NUMPACKETS 1 //#define UIP_CONF_MAX_CONNECTIONS 2 @@ -87,20 +87,22 @@ typedef unsigned short uip_stats_t; /* number of attempts on write before returning number of bytes sent so far * set to -1 to block until connection is closed by timeout */ -#define UIP_ATTEMPTS_ON_WRITE -1 +//#define UIP_ATTEMPTS_ON_WRITE -1 /* timeout after which UIPClient::connect gives up. The timeout is specified in seconds. * if set to a number <= 0 connect will timeout when uIP does (which might be longer than you expect...) */ -#define UIP_CONNECT_TIMEOUT -1 +//#define UIP_CONNECT_TIMEOUT -1 /* periodic timer for uip (in ms) */ -#define UIP_PERIODIC_TIMER 250 +//#define UIP_PERIODIC_TIMER 250 /* timer to poll client for data after last write (in ms) * set to -1 to disable fast polling and rely on periodic only (saves 100 bytes flash) */ -#define UIP_CLIENT_TIMER 10 +//#define UIP_CLIENT_TIMER 10 + +/************* TMRh20: User Configuration *******************/ /** @@ -110,7 +112,7 @@ typedef unsigned short uip_stats_t; */ //#define UIP_CONF_MAX_CONNECTIONS 40 //#define UIP_CONF_MAX_CONNECTIONS 12 -#define UIP_CONF_MAX_CONNECTIONS 2 +#define UIP_CONF_MAX_CONNECTIONS 1 /** * Maximum number of listening TCP ports. @@ -119,7 +121,7 @@ typedef unsigned short uip_stats_t; */ //#define UIP_CONF_MAX_LISTENPORTS 40 //#define UIP_CONF_MAX_LISTENPORTS 4 -#define UIP_CONF_MAX_LISTENPORTS 2 +#define UIP_CONF_MAX_LISTENPORTS 1 /** * uIP buffer size. @@ -128,9 +130,9 @@ typedef unsigned short uip_stats_t; */ //#define UIP_CONF_BUFFER_SIZE 420 // ORIG #define UIP_CONF_BUFFER_SIZE 128 -#define UIP_CONF_BUFFER_SIZE 128 +#define UIP_CONF_BUFFER_SIZE 120 -#define UIP_REASSEMBLY +//#define UIP_REASSEMBLY /** * The TCP maximum segment size. @@ -138,7 +140,7 @@ typedef unsigned short uip_stats_t; * This is should not be to set to more than * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN. */ -#define UIP_CONF_TCP_MSS 170 +//#define UIP_CONF_RECEIVE_WINDOW 60 /** * CPU byte order. * @@ -184,8 +186,8 @@ typedef unsigned short uip_stats_t; //#define IP_INPUT_BUFFER_LENGTH 16 //#define IP_OUTPUT_BUFFER_LENGTH 16 -#define IP_INPUT_BUFFER_LENGTH 16 -#define IP_OUTPUT_BUFFER_LENGTH 16 +//#define IP_INPUT_BUFFER_LENGTH 16 +//#define IP_OUTPUT_BUFFER_LENGTH 16 typedef void* uip_tcp_appstate_t; diff --git a/utility/psock.c b/utility/psock.c index f284cb9..90229be 100644 --- a/utility/psock.c +++ b/utility/psock.c @@ -308,7 +308,7 @@ PT_THREAD(psock_readbuf(register struct psock *psock)) do { if(psock->readlen == 0) { PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); - printf("Waited for newdata\n"); + //printf("Waited for newdata\n"); psock->state = STATE_READ; psock->readptr = (u8_t *)uip_appdata; psock->readlen = uip_datalen(); diff --git a/utility/uip.c b/utility/uip.c index ee88514..84ea8c3 100644 --- a/utility/uip.c +++ b/utility/uip.c @@ -1887,8 +1887,8 @@ htons(u16_t val) void uip_send(const void *data, int len) { + uip_slen = len; if(len > 0) { - uip_slen = len; if(data != uip_sappdata) { memcpy(uip_sappdata, (data), uip_slen); } diff --git a/utility/uip_arp.c b/utility/uip_arp.c index 75ade64..44ca7c4 100644 --- a/utility/uip_arp.c +++ b/utility/uip_arp.c @@ -230,7 +230,7 @@ uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr) * variable uip_len. */ /*-----------------------------------------------------------------------------------*/ -#if 0 +//#if 0 void uip_arp_ipin(void) { @@ -250,7 +250,7 @@ uip_arp_ipin(void) return; } -#endif /* 0 */ +//#endif /* 0 */ /*-----------------------------------------------------------------------------------*/ /** * ARP processing for incoming ARP packets. diff --git a/utility/uip_arp.h b/utility/uip_arp.h index e32594d..ef93054 100644 --- a/utility/uip_arp.h +++ b/utility/uip_arp.h @@ -80,8 +80,8 @@ void uip_arp_init(void); inserts a new mapping if none exists. The function assumes that an IP packet with an Ethernet header is present in the uip_buf buffer and that the length of the packet is in the uip_len variable. */ -/*void uip_arp_ipin(void);*/ -#define uip_arp_ipin() +void uip_arp_ipin(void); +//#define uip_arp_ipin() /* The uip_arp_arpin() should be called when an ARP packet is received by the Ethernet driver. This function also assumes that the diff --git a/utility/uip_clock.h b/utility/uip_clock.h new file mode 100644 index 0000000..6dd72be --- /dev/null +++ b/utility/uip_clock.h @@ -0,0 +1,88 @@ +/** + * \defgroup clock Clock interface + * + * The clock interface is the interface between the \ref timer "timer library" + * and the platform specific clock functionality. The clock + * interface must be implemented for each platform that uses the \ref + * timer "timer library". + * + * The clock interface does only one this: it measures time. The clock + * interface provides a macro, CLOCK_SECOND, which corresponds to one + * second of system time. + * + * \sa \ref timer "Timer library" + * + * @{ + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: clock.h,v 1.3 2006/06/11 21:46:39 adam Exp $ + */ +#ifndef __UIP_CLOCK_H__ +#define __UIP_CLOCK_H__ + +#include "clock-arch.h" + +/** + * Initialize the clock library. + * + * This function initializes the clock library and should be called + * from the main() function of the system. + * + */ +void uip_clock_init(void); + +/** + * Get the current clock time. + * + * This function returns the current system clock time. + * + * \return The current clock time, measured in system ticks. + */ +clock_time_t clock_time(void); + +/** + * A second, measured in system clock time. + * + * \hideinitializer + */ +#ifdef CLOCK_CONF_SECOND +#define CLOCK_SECOND CLOCK_CONF_SECOND +#else +#define CLOCK_SECOND (clock_time_t)32 +#endif + +#endif /* __CLOCK_H__ */ + +/** @} */ diff --git a/utility/uip_debug.cpp b/utility/uip_debug.cpp new file mode 100644 index 0000000..444bd0e --- /dev/null +++ b/utility/uip_debug.cpp @@ -0,0 +1,170 @@ +#include +#include +#include +#include +extern "C" { + #import "utility/uip.h" +} + +struct uip_conn con[UIP_CONNS]; + +void +UIPDebug::uip_debug_printconns() +{ + for(uint8_t i=0;iripaddr,rhs->ripaddr)) + { + Serial.print(" ripaddr: "); + uip_debug_printbytes((const uint8_t *)lhs->ripaddr,4); + Serial.print(" -> "); + uip_debug_printbytes((const uint8_t *)rhs->ripaddr,4); + Serial.println(); + uip_ipaddr_copy(lhs->ripaddr,rhs->ripaddr); + changed = true; + } + if (lhs->lport != rhs->lport) + { + Serial.print(" lport: "); + Serial.print(htons(lhs->lport)); + Serial.print(" -> "); + Serial.println(htons(rhs->lport)); + lhs->lport = rhs->lport; + changed = true; + } + if (lhs->rport != rhs->rport) + { + Serial.print(" rport: "); + Serial.print(htons(lhs->rport)); + Serial.print(" -> "); + Serial.println(htons(rhs->rport)); + lhs->rport = rhs->rport; + changed = true; + } + if ((uint32_t)lhs->rcv_nxt[0] != (uint32_t)rhs->rcv_nxt[0]) + { + Serial.print(" rcv_nxt: "); + uip_debug_printbytes(lhs->rcv_nxt,4); + Serial.print(" -> "); + uip_debug_printbytes(rhs->rcv_nxt,4); + *((uint32_t *)&lhs->rcv_nxt[0]) = (uint32_t)rhs->rcv_nxt[0]; + Serial.println(); + changed = true; + } + if ((uint32_t)lhs->snd_nxt[0] != (uint32_t)rhs->snd_nxt[0]) + { + Serial.print(" snd_nxt: "); + uip_debug_printbytes(lhs->snd_nxt,4); + Serial.print(" -> "); + uip_debug_printbytes(rhs->snd_nxt,4); + *((uint32_t *)&lhs->snd_nxt[0]) = (uint32_t)rhs->snd_nxt[0]; + Serial.println(); + changed = true; + } + if (lhs->len != rhs->len) + { + Serial.print(" len: "); + Serial.print(lhs->len); + Serial.print(" -> "); + Serial.println(rhs->len); + lhs->len = rhs->len; + changed = true; + } + if (lhs->mss != rhs->mss) + { + Serial.print(" mss: "); + Serial.print(lhs->mss); + Serial.print(" -> "); + Serial.println(rhs->mss); + lhs->mss = rhs->mss; + changed = true; + } + if (lhs->initialmss != rhs->initialmss) + { + Serial.print(" initialmss: "); + Serial.print(lhs->initialmss); + Serial.print(" -> "); + Serial.println(rhs->initialmss); + lhs->initialmss = rhs->initialmss; + changed = true; + } + if (lhs->sa != rhs->sa) + { + Serial.print(" sa: "); + Serial.print(lhs->sa); + Serial.print(" -> "); + Serial.println(rhs->sa); + lhs->sa = rhs->sa; + changed = true; + } + if (lhs->sv != rhs->sv) + { + Serial.print(" sv: "); + Serial.print(lhs->sv); + Serial.print(" -> "); + Serial.println(rhs->sv); + lhs->sv = rhs->sv; + changed = true; + } + if (lhs->rto != rhs->rto) + { + Serial.print(" rto: "); + Serial.print(lhs->rto); + Serial.print(" -> "); + Serial.println(rhs->rto); + lhs->rto = rhs->rto; + changed = true; + } + if (lhs->tcpstateflags != rhs->tcpstateflags) + { + Serial.print(" tcpstateflags: "); + Serial.print(lhs->tcpstateflags); + Serial.print(" -> "); + Serial.println(rhs->tcpstateflags); + lhs->tcpstateflags = rhs->tcpstateflags; + changed = true; + } + if (lhs->timer != rhs->timer) + { + Serial.print(" timer: "); + Serial.print(lhs->timer); + Serial.print(" -> "); + Serial.println(rhs->timer); + lhs->timer = rhs->timer; + changed = true; + } + if (lhs->nrtx != rhs->nrtx) + { + Serial.print(" nrtx: "); + Serial.print(lhs->nrtx); + Serial.print(" -> "); + Serial.println(rhs->nrtx); + lhs->nrtx = rhs->nrtx; + changed = true; + } + return changed; +} + +void +UIPDebug::uip_debug_printbytes(const uint8_t *data, uint8_t len) +{ + for(uint8_t i=0;i + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: timer.c,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +#include "uip_clock.h" +#include "uip_timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function is used to set a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * \param t A pointer to the timer + * \param interval The interval before the timer expires. + * + */ +void +uip_timer_set(struct uip_timer *t, clock_time_t interval) +{ + t->interval = interval; + t->start = clock_time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_rester() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +uip_timer_reset(struct uip_timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +uip_timer_restart(struct uip_timer *t) +{ + t->start = clock_time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +uip_timer_expired(struct uip_timer *t) +{ + return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval; +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/utility/uip_timer.h b/utility/uip_timer.h new file mode 100644 index 0000000..f260349 --- /dev/null +++ b/utility/uip_timer.h @@ -0,0 +1,86 @@ +/** + * \defgroup timer Timer library + * + * The timer library provides functions for setting, resetting and + * restarting timers, and for checking if a timer has expired. An + * application must "manually" check if its timers have expired; this + * is not done automatically. + * + * A timer is declared as a \c struct \c timer and all access to the + * timer is made by a pointer to the declared timer. + * + * \note The timer library uses the \ref clock "Clock library" to + * measure time. Intervals should be specified in the format used by + * the clock library. + * + * @{ + */ + + +/** + * \file + * Timer library header file. + * \author + * Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: timer.h,v 1.3 2006/06/11 21:46:39 adam Exp $ + */ +#ifndef __UIP_TIMER_H__ +#define __UIP_TIMER_H__ + +#include "uip_clock.h" + +/** + * A timer. + * + * This structure is used for declaring a timer. The timer must be set + * with timer_set() before it can be used. + * + * \hideinitializer + */ +struct uip_timer { + clock_time_t start; + clock_time_t interval; +}; + +void uip_timer_set(struct uip_timer *t, clock_time_t interval); +void uip_timer_reset(struct uip_timer *t); +void uip_timer_restart(struct uip_timer *t); +int uip_timer_expired(struct uip_timer *t); + +#endif /* __UIP_TIMER_H__ */ + +/** @} */ diff --git a/utility/uipopt.h b/utility/uipopt.h index b1ef8e5..42badf8 100644 --- a/utility/uipopt.h +++ b/utility/uipopt.h @@ -302,7 +302,11 @@ * This is should not be to set to more than * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN. */ +#ifndef UIP_CONF_TCP_MSS #define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) +#else +#define UIP_TCP_MSS UIP_CONF_TCP_MSS +#endif /** * The size of the advertised receiver's window. @@ -419,10 +423,10 @@ * \hideinitializer * */ -#ifndef UIP_CONF_BROADCAST -#define UIP_BROADCAST 0 -#else /* UIP_CONF_BROADCAST */ +#if UIP_UDP && UIP_CONF_BROADCAST #define UIP_BROADCAST UIP_CONF_BROADCAST +#else /* UIP_CONF_BROADCAST */ +#define UIP_BROADCAST 0 #endif /* UIP_CONF_BROADCAST */ /** diff --git a/utility/util.h b/utility/util.h new file mode 100644 index 0000000..5042e82 --- /dev/null +++ b/utility/util.h @@ -0,0 +1,13 @@ +#ifndef UTIL_H +#define UTIL_H + +#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) ) +#define ntohs(x) htons(x) + +#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \ + ((x)<< 8 & 0x00FF0000UL) | \ + ((x)>> 8 & 0x0000FF00UL) | \ + ((x)>>24 & 0x000000FFUL) ) +#define ntohl(x) htonl(x) + +#endif