Arianna station communication peripherals.

Dependents:   AutonomousDAQ AutonomousDAQ

Committer:
uci1
Date:
Wed Aug 08 21:00:41 2018 +0000
Revision:
10:29301aaa8c33
Parent:
7:ba4bc9266f9c
Fixed EOL termination for SBD comms, replacing \r\n with \r (or something like that)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
uci1 0:26c9189e5924 1 #ifndef SN_SnCommSBD
uci1 0:26c9189e5924 2 #define SN_SnCommSBD
uci1 0:26c9189e5924 3
uci1 0:26c9189e5924 4 #include "SnCommPeripheral.h"
uci1 0:26c9189e5924 5
uci1 0:26c9189e5924 6 #ifdef ENABLE_SBD
uci1 0:26c9189e5924 7
uci1 0:26c9189e5924 8 #include "SnHeaderFrame.h"
uci1 0:26c9189e5924 9 #include "string"
uci1 0:26c9189e5924 10
uci1 0:26c9189e5924 11 #define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
uci1 0:26c9189e5924 12
uci1 0:26c9189e5924 13 class SnCommSBD : public SnCommPeripheral {
uci1 0:26c9189e5924 14 public:
uci1 0:26c9189e5924 15 static const uint16_t kMaxSend = 340-SnHeaderFrame::kMaxSizeOf; // max bytes sendable by SBD
uci1 0:26c9189e5924 16 static const uint16_t kMaxRecv = 270-SnHeaderFrame::kMaxSizeOf; // max bytes readable by SBD
uci1 3:a7f72492f19e 17 static const uint16_t kWaitOnGSS = 30; // seconds
uci1 3:a7f72492f19e 18 static const uint16_t kRxBufSz = 5*kMaxRecv; // size of read buffer in bytes
uci1 3:a7f72492f19e 19 static const uint16_t kTxBufSz = kMaxSend; // size of send buffer in bytes
uci1 0:26c9189e5924 20
uci1 0:26c9189e5924 21 //typedef int32_t (SnCommSBD::*SBDSendRecv)(char* const, const uint32_t, const uint32_t);
uci1 0:26c9189e5924 22 typedef bool (SnCommSBD::*SerialReadWriteable)();
uci1 0:26c9189e5924 23
uci1 0:26c9189e5924 24 private:
uci1 5:2ee6cbb948c0 25 COMM_SERIALTYPE* fSBD; // serial connection to the SBD modem. maybe a MODSERIAL (which inherits from Serial)
uci1 3:a7f72492f19e 26 char fRxBuf[kRxBufSz]; // store the incoming SBD msg in case it's not read all at once
uci1 3:a7f72492f19e 27 char fTxBuf[kTxBufSz]; // store the incoming SBD msg in case it's not read all at once
uci1 3:a7f72492f19e 28 uint16_t fTxPos; // current position in tx buffer
uci1 3:a7f72492f19e 29 uint16_t fRxPos; // position in rx buffer
uci1 3:a7f72492f19e 30 uint16_t fRxSiz; // size of message stored in rx buffer
uci1 0:26c9189e5924 31 uint16_t fRMsgNum; // recv SBD message number
uci1 0:26c9189e5924 32 uint16_t fRMsgTot; // recv total SBD messages
uci1 0:26c9189e5924 33 uint16_t fSMsgNum; // send SBD message number
uci1 0:26c9189e5924 34 uint16_t fSMsgTot; // send total SBD messages. separate from the read num/tot to allow (a) read 1/2, (b) send msg, (c) read 2/2
uci1 7:ba4bc9266f9c 35 // TODO: with outgoing buffering, the total number of messages to be sent cannot be known ahead of time!
uci1 0:26c9189e5924 36
uci1 0:26c9189e5924 37 template<class DATA, class SENDRECV>
uci1 0:26c9189e5924 38 int DoIO(DATA data,
uci1 0:26c9189e5924 39 const uint32_t length,
uci1 0:26c9189e5924 40 const uint32_t timeout_clock,
uci1 0:26c9189e5924 41 SENDRECV fcn,
uci1 0:26c9189e5924 42 SerialReadWriteable able=0) {
uci1 0:26c9189e5924 43 // TODO: if B64, must return number of bytes of raw (non encoded) message
uci1 0:26c9189e5924 44 int res=0;
uci1 0:26c9189e5924 45 uint32_t b=0;
uci1 0:26c9189e5924 46 while ( (length>b) ) {
uci1 0:26c9189e5924 47 if (IsTimedOut(timeout_clock)) {
uci1 0:26c9189e5924 48 break;
uci1 0:26c9189e5924 49 }
uci1 0:26c9189e5924 50 if ( (able==0) ||
uci1 0:26c9189e5924 51 ((able!=0) && (CALL_MEMBER_FN(*this, able)())) ) {
uci1 0:26c9189e5924 52 res = CALL_MEMBER_FN(*this, fcn)(data+b, length-b, timeout_clock);
uci1 0:26c9189e5924 53 if (res<0) {
uci1 0:26c9189e5924 54 return b;
uci1 0:26c9189e5924 55 } else {
uci1 0:26c9189e5924 56 b += res;
uci1 0:26c9189e5924 57 }
uci1 0:26c9189e5924 58 } else if (able!=0) {
uci1 4:8328c2972290 59 #ifdef USE_RTOS
uci1 4:8328c2972290 60 Thread::wait(10);
uci1 4:8328c2972290 61 #else
uci1 0:26c9189e5924 62 wait_ms(10); // wait for readable/writeable
uci1 4:8328c2972290 63 #endif
uci1 0:26c9189e5924 64 }
uci1 0:26c9189e5924 65 }
uci1 0:26c9189e5924 66 return b; // timeout
uci1 0:26c9189e5924 67 }
uci1 3:a7f72492f19e 68 /*
uci1 0:26c9189e5924 69 template<class DATA, class SENDRECV>
uci1 0:26c9189e5924 70 int32_t DoIOInChunks(DATA data, const uint32_t length,
uci1 0:26c9189e5924 71 const uint32_t timeout_clock,
uci1 0:26c9189e5924 72 const uint16_t maxBufLen,
uci1 0:26c9189e5924 73 SENDRECV fcn) {
uci1 0:26c9189e5924 74 // get/ship the data in chunks (since SBD limits incoming/outgoing messages)
uci1 0:26c9189e5924 75 int32_t b=0, cl=0;
uci1 0:26c9189e5924 76 while ( length>b ) {
uci1 0:26c9189e5924 77 if (IsTimedOut(timeout_clock)) {
uci1 0:26c9189e5924 78 break;
uci1 0:26c9189e5924 79 }
uci1 0:26c9189e5924 80 cl = (length-b);
uci1 0:26c9189e5924 81 if (cl>maxBufLen) {
uci1 0:26c9189e5924 82 cl = maxBufLen;
uci1 0:26c9189e5924 83 }
uci1 3:a7f72492f19e 84 #ifdef DEBUG
uci1 0:26c9189e5924 85 printf("DoIOInChunks: call DoIO with b=%d, cl=%d\r\n",b,cl);
uci1 3:a7f72492f19e 86 #endif
uci1 0:26c9189e5924 87 b += DoIO<DATA>(data+b, cl, timeout_clock, fcn);
uci1 3:a7f72492f19e 88 #ifdef DEBUG
uci1 0:26c9189e5924 89 printf("DoIOInChunks: b=%d, length=%u\r\n",b,length);
uci1 3:a7f72492f19e 90 #endif
uci1 0:26c9189e5924 91 }
uci1 3:a7f72492f19e 92 #ifdef DEBUG
uci1 0:26c9189e5924 93 printf("DoIOInChunks: return %d\r\n",b);
uci1 3:a7f72492f19e 94 #endif
uci1 0:26c9189e5924 95 return b;
uci1 0:26c9189e5924 96 }
uci1 0:26c9189e5924 97 */
uci1 0:26c9189e5924 98 bool SerialReadable();
uci1 0:26c9189e5924 99 bool SerialWriteable();
uci1 0:26c9189e5924 100 int32_t PutC(const char* const data, const uint32_t, const uint32_t);
uci1 0:26c9189e5924 101 int32_t GetC(char* const data, const uint32_t, const uint32_t);
uci1 3:a7f72492f19e 102 int32_t SendBufferedSBD(const char* const data,
uci1 3:a7f72492f19e 103 const uint32_t length,
uci1 3:a7f72492f19e 104 const uint32_t timeout_clock);
uci1 0:26c9189e5924 105 int32_t SendSBD(const char* const data, const uint32_t length,
uci1 0:26c9189e5924 106 const uint32_t timeout_clock);
uci1 0:26c9189e5924 107 int32_t RecvSBD(char* const data, const uint32_t length,
uci1 0:26c9189e5924 108 const uint32_t timeout_clock);
uci1 0:26c9189e5924 109 int32_t AtCmd(const char* const cmd,
uci1 0:26c9189e5924 110 const uint32_t timeout);
uci1 0:26c9189e5924 111 int32_t AtResp(char* const res, const uint32_t rlen,
uci1 0:26c9189e5924 112 const uint32_t timeout);
uci1 0:26c9189e5924 113 void AppendRespTxt(std::string& str,
uci1 0:26c9189e5924 114 const uint32_t timeout,
uci1 0:26c9189e5924 115 const uint32_t maxslen);
uci1 0:26c9189e5924 116 bool AtRespContainsTxt(const char* const desired,
uci1 0:26c9189e5924 117 const uint32_t timeout,
uci1 0:26c9189e5924 118 std::string& str,
uci1 0:26c9189e5924 119 const char* until="\r\n",
uci1 0:26c9189e5924 120 const uint32_t maxslen=1024);
uci1 0:26c9189e5924 121 bool WaitForAtResponse(const char* const desired,
uci1 0:26c9189e5924 122 const uint32_t timeout,
uci1 0:26c9189e5924 123 const char* until="\r\n");
uci1 0:26c9189e5924 124 bool WaitForAtResponse(const char* const desired,
uci1 0:26c9189e5924 125 const uint32_t timeout,
uci1 0:26c9189e5924 126 std::string& str,
uci1 0:26c9189e5924 127 const char* until="\r\n");
uci1 0:26c9189e5924 128 bool WaitForAtResponses(const char* const desired,
uci1 0:26c9189e5924 129 const uint32_t timeout,
uci1 0:26c9189e5924 130 const char* until="\r\n");
uci1 0:26c9189e5924 131 bool WaitForAtResponses(const char* const desired,
uci1 0:26c9189e5924 132 const uint32_t timeout,
uci1 0:26c9189e5924 133 std::string& str,
uci1 0:26c9189e5924 134 const char* until="\r\n");
uci1 0:26c9189e5924 135 void EmptyRxBuffer(const uint32_t timeout);
uci1 0:26c9189e5924 136 static
uci1 0:26c9189e5924 137 uint16_t GetMsgNumFromHeader(const uint32_t hlen) {
uci1 0:26c9189e5924 138 return (hlen>>16u);
uci1 0:26c9189e5924 139 }
uci1 0:26c9189e5924 140 static
uci1 0:26c9189e5924 141 uint16_t GetMsgTotFromHeader(const uint32_t hlen) {
uci1 0:26c9189e5924 142 return (hlen&0xFFFF);
uci1 0:26c9189e5924 143 }
uci1 0:26c9189e5924 144 static
uci1 0:26c9189e5924 145 void GetMsgNumTotFromHeader(const uint32_t hlen,
uci1 0:26c9189e5924 146 uint16_t& mnum,
uci1 0:26c9189e5924 147 uint16_t& mtot) {
uci1 0:26c9189e5924 148 mnum = GetMsgNumFromHeader(hlen);
uci1 0:26c9189e5924 149 mtot = GetMsgTotFromHeader(hlen);
uci1 0:26c9189e5924 150 }
uci1 0:26c9189e5924 151 uint32_t GetHeaderFromMsgNumTot(const bool isSending) const {
uci1 0:26c9189e5924 152 uint32_t h = (isSending ? fSMsgNum : fRMsgNum);
uci1 0:26c9189e5924 153 h <<= 16u;
uci1 0:26c9189e5924 154 h |= (isSending ? fSMsgTot : fRMsgTot);
uci1 0:26c9189e5924 155 return h;
uci1 0:26c9189e5924 156 }
uci1 0:26c9189e5924 157
uci1 0:26c9189e5924 158 protected:
uci1 0:26c9189e5924 159 virtual int32_t ReceiveAll(char* const buf, const uint32_t mlen,
uci1 0:26c9189e5924 160 const uint32_t timeout_clock);
uci1 0:26c9189e5924 161 virtual int32_t SendAll(const char* const data, const uint32_t length,
uci1 0:26c9189e5924 162 const uint32_t timeout_clock);
uci1 3:a7f72492f19e 163 virtual int32_t FinishSending(const uint32_t timeout_clock);
uci1 0:26c9189e5924 164
uci1 0:26c9189e5924 165 public:
uci1 5:2ee6cbb948c0 166 // Serial and MODSERIAL don't share virtual functions, so we MUST obtain
uci1 5:2ee6cbb948c0 167 // a pointer of type MODSERIAL if that's what we're using
uci1 5:2ee6cbb948c0 168 SnCommSBD(COMM_SERIALTYPE* sbdPort=0) :
uci1 3:a7f72492f19e 169 fSBD(sbdPort), fTxPos(0), fRxPos(0), fRxSiz(0),
uci1 0:26c9189e5924 170 fRMsgNum(0), fRMsgTot(0), // essential that these start at 0!
uci1 0:26c9189e5924 171 fSMsgNum(0), fSMsgTot(0) {
uci1 0:26c9189e5924 172
uci1 3:a7f72492f19e 173 memset(fRxBuf, 0, kRxBufSz*sizeof(char));
uci1 3:a7f72492f19e 174 memset(fTxBuf, 0, kTxBufSz*sizeof(char));
uci1 0:26c9189e5924 175 }
uci1 0:26c9189e5924 176 virtual ~SnCommSBD() {}
uci1 0:26c9189e5924 177
uci1 4:8328c2972290 178 virtual bool TrySetSysTimeUnix(const uint32_t timeout,
uci1 4:8328c2972290 179 uint32_t& prvTime,
uci1 4:8328c2972290 180 uint32_t& setTime);
uci1 0:26c9189e5924 181
uci1 5:2ee6cbb948c0 182 virtual bool CheckSignalStrength(const uint32_t timeout,
uci1 5:2ee6cbb948c0 183 float& sigstr);
uci1 5:2ee6cbb948c0 184
uci1 0:26c9189e5924 185 virtual bool Connect(const uint32_t timeout);
uci1 0:26c9189e5924 186
uci1 3:a7f72492f19e 187 virtual bool CloseConn(const uint32_t timeout) {
uci1 3:a7f72492f19e 188 ClearSendReceiveBuffers();
uci1 3:a7f72492f19e 189 return true;
uci1 3:a7f72492f19e 190 }
uci1 3:a7f72492f19e 191
uci1 3:a7f72492f19e 192 virtual bool PowerDown(const uint32_t);
uci1 0:26c9189e5924 193
uci1 3:a7f72492f19e 194 void ClearSendReceiveBuffers() {
uci1 3:a7f72492f19e 195 fRxPos=0;
uci1 3:a7f72492f19e 196 fRxSiz=0;
uci1 3:a7f72492f19e 197 fRMsgNum=0;
uci1 3:a7f72492f19e 198 fRMsgTot=0;
uci1 3:a7f72492f19e 199 fSMsgNum=0;
uci1 3:a7f72492f19e 200 fSMsgTot=0;
uci1 3:a7f72492f19e 201 memset(fRxBuf, 0, kMaxRecv*sizeof(char));
uci1 3:a7f72492f19e 202 }
uci1 0:26c9189e5924 203
uci1 0:26c9189e5924 204 static
uci1 0:26c9189e5924 205 bool ParseSBDSresp(const std::string& sr,
uci1 0:26c9189e5924 206 int32_t& mo, int32_t& momsn,
uci1 0:26c9189e5924 207 int32_t& mt, int32_t& mtmsn);
uci1 0:26c9189e5924 208
uci1 0:26c9189e5924 209 static
uci1 0:26c9189e5924 210 bool ParseSBDIXresp(const std::string& ixr,
uci1 0:26c9189e5924 211 int32_t& mo, int32_t& momsn,
uci1 0:26c9189e5924 212 int32_t& mt, int32_t& mtmsn,
uci1 0:26c9189e5924 213 int32_t& mtlen, int32_t& mtq);
uci1 0:26c9189e5924 214
uci1 0:26c9189e5924 215
uci1 0:26c9189e5924 216 };
uci1 0:26c9189e5924 217
uci1 0:26c9189e5924 218 #endif // ENABLE_SBD
uci1 0:26c9189e5924 219
uci1 0:26c9189e5924 220 #endif // SN_SnCommSBD