Arianna station communication peripherals.
Dependents: AutonomousDAQ AutonomousDAQ
SnCommAfarNetIf.cpp
- Committer:
- uci1
- Date:
- 2018-08-08
- Revision:
- 10:29301aaa8c33
- Parent:
- 4:8328c2972290
File content as of revision 10:29301aaa8c33:
#include "SnCommAfarNetIf.h" #ifdef ENABLE_AFAR #include "lwip/inet.h" //#define DEBUG SnCommAfarNetIf::SnCommAfarNetIf(const char* rserv, const uint16_t rport, const char* ip, const char* mask, const char* gate) : fUseB64(false), fRserv(rserv), fRport(rport), fMyIp(ip), fMyMask(mask), fMyGate(gate), fEth(0), fSock(0), fEthConnected(false), fSockReading(false), fEthWriteable(false), fConnAborted(false), fEthSetup(false), fRxRd(fRxBuf), fRxWt(fRxBuf), fRxEnd(fRxBuf+RX_BUF_LEN), fRxBufWriteable(true) { #ifdef DEBUG printf("SnCommAfarNetIf ctor ip=%s, mas=%s, gate=%s\r\n", fMyIp.c_str(), fMyMask.c_str(), fMyGate.c_str()); printf("rserv=%s, rport=%hu\r\n", fRserv.c_str(), fRport); printf("calling NewEthAndSocket\r\n"); #endif NewEthAndSocket(); #ifdef DEBUG printf("ctor done\r\n"); #endif } SnCommAfarNetIf::~SnCommAfarNetIf() { delete fEth; delete fSock; } void SnCommAfarNetIf::Set(const char* remote, const uint16_t rport) { fRserv = remote; fRport = rport; /* #ifdef DEBUG printf("closing socket\r\n"); #endif fSock->close(); */ #ifdef DEBUG printf("disconnect eth\r\n"); #endif #ifdef DEBUG printf("init %s, %s, %s\r\n",fMyIp.c_str(), fMyMask.c_str(), fMyGate.c_str()); #endif NewEthAndSocket(); #ifdef DEBUG printf("Set done\r\n"); #endif } void SnCommAfarNetIf::Set(const char* remote, const uint16_t rport, const char* myip, const char* mask, const char* gate, const bool useb64) { fUseB64 = useb64; fMyIp = myip; fMyMask = mask; fMyGate = gate; Set(remote, rport); } void SnCommAfarNetIf::NewEthAndSocket() { #ifdef DEBUG printf("deleting fEth(%p)\r\n",(void*)fEth); #endif delete fEth; fEthSetup = false; #ifdef DEBUG printf("making ip_addr_t's\r\n"); #endif ip_addr_t ip_n, mask_n, gateway_n, dns_n; inet_aton(fMyIp.c_str(), &ip_n); inet_aton(fMyMask.c_str(), &mask_n); inet_aton(fMyGate.c_str(), &gateway_n); //inet_aton("0.0.0.0", &dns_n); //inet_aton("128.200.1.201", &dns_n); inet_aton("157.132.107.58", &dns_n); #ifdef DEBUG printf("new ethernet\r\n"); #endif fEth = new EthernetNetIf( IpAddr(&ip_n), IpAddr(&mask_n), IpAddr(&gateway_n), IpAddr(&dns_n) ); NewSocket(); } void SnCommAfarNetIf::NewSocket() { #ifdef DEBUG printf("deleting fSock(%p)\r\n",(void*)fSock); #endif delete fSock; #ifdef DEBUG printf("new socket\r\n"); #endif fSock = new TCPSocket; #ifdef DEBUG printf("clearing rx buffer\r\n"); #endif memset(fRxBuf, 0, RX_BUF_LEN*sizeof(char)); #ifdef DEBUG printf("setOnEvent\r\n"); #endif // catch events fSock->setOnEvent(this, &SnCommAfarNetIf::onTCPSocketEvent); fEthConnected = false; fEthWriteable = false; } int32_t SnCommAfarNetIf::PullFromBuffTo(char* const buf, const uint32_t len) { // pull 'len' bytes out of the Rx buffer and copy them to buf // no check on the length of 'buf' is performed! // no check on 'len' is performed! memcpy(buf, fRxRd, len); fRxRd += len; if (fRxWt > fRxRd) { // there's still data in the buffer fRxBufWriteable = false; const int32_t nb = fRxWt - fRxRd; memmove(fRxBuf, fRxRd, nb); // move it to the beginning (overlap ok in memmove) fRxRd = fRxBuf; fRxWt -= nb; fRxBufWriteable = true; } else { // nothing in buffer fRxBufWriteable = false; fRxRd = fRxWt = fRxBuf; fRxBufWriteable = true; } return len; } int32_t SnCommAfarNetIf::ReceiveAll(char* const buf, const uint32_t mlen, const uint32_t timeout_clock) { // TODO: if B64, must return number of bytes of raw (non encoded) message //return DoIO(buf, mlen, timeout_clock, &TCPSocketConnection::receive_all); // use regular recv; DoIO will do a receive_all but use our timeout Net::poll(); // first get out of buffer int32_t br = 0; while ( (br<mlen) && (fRxRd<fRxWt) ) { int32_t bl = fRxWt - fRxRd; if (mlen<bl) { bl = mlen; } br += PullFromBuffTo(buf+br, bl); } // get the rest from the socket if (br<mlen) { fSockReading = true; br += DoIO(buf, mlen, timeout_clock, &TCPSocket::recv, fRxBufWriteable); fSockReading = false; } return br; } int32_t SnCommAfarNetIf::SendAll(const char* const data, const uint32_t length, const uint32_t timeout_clock) { // TODO: if B64, must return number of bytes of raw (non encoded) message //return DoIO(data, length, timeout_clock, &TCPSocketConnection::send_all); // use regular send; DoIO will do a send_all but use our timeout Net::poll(); const char* const buf = data; #ifdef DEBUG const int32_t br = #else return #endif DoIO(buf, length, timeout_clock, &TCPSocket::send, fEthWriteable); #ifdef DEBUG printf("SendAll: DoIO returned %d bytes\r\n",br); return br; #endif } bool SnCommAfarNetIf::Connect(const uint32_t timeout) { #ifdef DEBUG printf("SnCommAfarNetIf::Connect : setup\r\n"); printf("fEthConnected=%s\r\n",fEthConnected?"true":"false"); #endif if (fEthConnected==false) { #ifdef DEBUG printf("fEthSetup=%s\r\n",fEthSetup?"true":"false"); #endif if (fEthSetup==false) { EthernetErr ethErr = fEth->setup(); while ( (ethErr!=ETH_OK) && (IsTimedOut(timeout)==false) ) { wait_ms(250); ethErr = fEth->setup(); } if (ethErr==ETH_OK) { fEthSetup = true; } #ifdef DEBUG printf("fEthSetup=%s\r\n",fEthSetup?"true":"false"); #endif // why were these waits here?? -- test in comms lab at McMurdo! //wait(10); //wait(40); // for use with switch in comms @ McMurdo } if (fEthSetup) { #ifdef DEBUG printf("SnCommAfarNetIf::Connect : bind\r\n"); #endif ip_addr_t rserv_n; inet_aton(fRserv.c_str(), &rserv_n); Host server( IpAddr(&rserv_n), fRport ); //Host server( IpAddr(128,195,204,151), 6655 ); #ifdef DEBUG printf("SnCommAfarNetIf::Connect : fRserv=%s, fRport=%hu\r\n", fRserv.c_str(), fRport); #endif SockConnect(server, timeout); /* // catch events fSock->setOnEvent(this, &SnCommAfarNetIf::onTCPSocketEvent); */ #ifdef DEBUG printf("SnCommAfarNetIf::Connect : tcp connect\r\n"); #endif //fEthConnected = false; while ( (fEthConnected==false) && (IsTimedOut(timeout)==false) ) { Net::poll(); if (fConnAborted) { #ifdef DEBUG printf("SnCommAfarNetIf::Connect : conn aborted. new socket, sockconnect...\r\n"); #endif fConnAborted = false; NewSocket(); SockConnect(server, timeout); } } fEthWriteable = fEthConnected; } } return fEthConnected; } bool SnCommAfarNetIf::SockConnect(const Host& server, const uint32_t timeout) { #ifdef DEBUG printf("SnCommAfarNetIf::SockConnect\r\n"); #endif TCPSocketErr bindErr = fSock->connect(server); while ( (bindErr!=TCPSOCKET_OK) && (IsTimedOut(timeout)==false) ) { wait_ms(250); bindErr = fSock->connect(server); } #ifdef DEBUG printf("SnCommAfarNetIf::SockConnect: %s\r\n", (bindErr==TCPSOCKET_OK) ? "true" : "false"); #endif return (bindErr==TCPSOCKET_OK); } bool SnCommAfarNetIf::CloseConn(const uint32_t) { fEthConnected = false; fEthSetup = false; // new addition -- why was this not here before? return (fSock->close() == TCPSOCKET_OK); } void SnCommAfarNetIf::onTCPSocketEvent(TCPSocketEvent e) { #ifdef DEBUG printf("TCPSocketEvent is (%d) ",static_cast<int>(e)); #endif if (e == TCPSOCKET_CONNECTED) { fEthConnected = true; #ifdef DEBUG printf("TCPSOCKET_CONNECTED\r\n"); #endif } else if (e == TCPSOCKET_WRITEABLE) { #ifdef DEBUG printf("TCPSOCKET_WRITEABLE\r\n"); fEthWriteable=true; #endif //TODO: does this event ever occur? } else if (e == TCPSOCKET_READABLE) { #ifdef DEBUG printf("TCPSOCKET_READABLE\r\n"); #endif fEthConnected = true; // read & buffer the data immediately (if there's room) if (fSockReading==false) { fSockReading = true; fRxWt += DoIO(fRxWt, fRxEnd-fRxWt, time(0)+RX_TIMEOUT, &TCPSocket::recv, fRxBufWriteable); fSockReading = false; #ifdef DEBUG printf("fRxBuf now contains:\r\n"); dispStrBytes(fRxBuf, fRxWt-fRxBuf); #endif } } else if (e == TCPSOCKET_CONABRT) { #ifdef DEBUG printf("TCPSOCKET_CONABRT\r\n"); #endif fConnAborted = true; } #ifdef DEBUG else { printf(" %d\r\n",(int)e); } #endif } #endif // ENABLE_AFAR