pfodParser  3.61.0
The pfodParser library is handles commands sent from the Android pfodApp, pfodApp supports WiFi, BLE, Bluetooth and SMS connections
pfodSMS_SIM900.h
Go to the documentation of this file.
1 #ifndef pfodSMS_SIM900_h
2 #define pfodSMS_SIM900_h
3 /*
4  * (c)2014-2017 Forward Computing and Control Pty. Ltd.
5  * NSW Australia, www.forward.com.au
6  * This code is not warranted to be fit for any purpose. You may only use it at your own risk.
7  * This code may be freely used for both private and commercial use
8  * Provide this copyright is maintained.
9  */
10  /*
11  This library uses about 17K of ROM (program space) and 3200 bytes of RAM
12  and so is NOT suitable for use on an UNO
13  Use a Mega2560 or similar with more then 4K of RAM
14  */
15 
16 #include "Arduino.h"
17 
18 #include "pfodStream.h"
19 #include "pfod_Base.h"
20 #include "pfod_rawOutput.h"
21 
22 #define SMS_MAX_SIZE 160
23 #define SMS_RX_BUFFER_SIZE 267
24 // max msg size after decode 256 + + 8(hash) + 2(extra) +null
25 // max pfod msg size
26 #define SMS_TX_MSG_SIZE 1026
27 // 1024 + 2
28 #define SMS_TX_BUFFER_SIZE (SMS_TX_MSG_SIZE+8+2)
29 // add a little 1026 + 8(hash) + 2(extra) + null
30 
31 class pfodSMS_SIM900: public pfod_Base {
32 
33  public:
35  void init(Stream *_gprs, int powerOnOffPin); // use -1 for powerOnOffPin if not used
36  void setDebugStream(Stream* out);
37  unsigned long getDefaultTimeOut();
38  Print* getRawDataOutput();
39  int available(void);
40  int peek(void);
41  int read(void);
42  void flush(void);
43  size_t write(uint8_t);
44  size_t writeRawData(uint8_t c);
45  Stream* getPfodAppStream(); // use pfodSecurity.getPfodAppStream() instead get the command response stream we are reading from and writing to
47 
48  private:
49  int powerResetPin;
50  const static int MAX_PHNO_LEN = 20;
51  const static int MAX_PHNO_CHECK = 6; // from end
52  struct connection {
53  int connectionNo; // = 0; is valid
54  int msgNo_rx; // = 0; // first expected
55  int msgNo_tx; // = 0; // next msgNo for next SMS being sent
56  int msgNo_tx_newMsg; // = 0; next msgNo for start of new response
57  // the msgNo_tx is set to this on a new msg
58  int msgNo_tx_resend; // = 0; // starting msgNo for last response
59  // the msgNo_tx is set to this on resend
60  boolean timedOut;
61  //knownConnection conPtr*;
62  char returnPhNo[MAX_PHNO_LEN + 1]; // plus null idx runs from 0 to MAX_PHNO_LEN
63  };
64 
65  struct knownConnection {
66  int connectionNo; // = 0; is valid
67  char returnPhNo[MAX_PHNO_LEN + 1]; // plus null idx runs from 0 to MAX_PHNO_LEN
68  };
69 
70  static const int MAX_KNOWN_CONNECTION = 10;
71  struct knownConnection knownConnectionsArray[MAX_KNOWN_CONNECTION]; // this allocate space for structs as well
72  struct knownConnection* knownArrayPtrs[MAX_KNOWN_CONNECTION]; // allocate space for ptrs
73 
74  void init();
75  int findEmptyKnownConnection();
76  void updateMsgNoForStartNewCommand();
77  void updateMsgNoForStartResend();
78 
79  void stopResponseSends();
80  void stopAllSends();
81 
82  void clearKnownConnection(knownConnection *kCon);
83  void clearKnownConnection(int idx);
84  void printKnownConnections();
85  void printKnownConnection(knownConnection *kCon);
86  void swapKnownConnections();
87  void setTopKnownConnectionFromCurrent();
88  void moveKnownConnectionToTop(int idx);
89  void updateKnownConnectionNo(connection *con); // always succeeds
90  void updateKnownConnectionNoAndMoveToTop(connection *con); // always succeeds
91  void setNextExpectedConnectionMsgNo(connection *con, boolean foundEndParens);
92 
93  typedef enum decode_sms_return_t {
94  IGNORE, // invalid msg, wrong msgNo etc
95  RESEND_LAST_RESPONSE, // ignore msg and resend last response
96  CLOSE_CONNECTION, // close current connection no change in connectionNo
97  START_NEW_COMMAND, // start a new command no new connection
98  PROCESS_NEXT_PART_OF_COMMAND, // process continuation SMS of a command for connection expectedMsgNo has been updated
99  CLOSE_CONNECTION_AND_UPDATE_CONNECTION, // close current and update for new connectionNo
100  NEW_CONNECTION_SAME_PHONE_NO, // new connect but with same phoneNo
101  IGNORE_CONNECTION, // ignore connection attempt as current connection not timed out but let pfodApp retry
102  START_NEW_CONNECTION, // start a new connection from a different phone no
103  START_NEW_CONNECTION_AND_CLOSE // start new connection but msg is {!} so no reply but send alert to current and process msg
104  } decode_sms_return_t;
105 
106  decode_sms_return_t decodeSMS(connection *current, connection *next, const char* smsChars, byte* decodedSMS,
107  size_t* currentDecodedLen);
108 
109 
110  void clearParser();
111  void clearResponseSet();
112  boolean decodeSMScmd(const char*smsChars, byte*decodedSMS, size_t* currentDecodedLen);
113  int checkSMSmsgForValidNewConnection(int connectionNo, int msgNo, const char* decodedSMS, boolean foundCmdClose);
114  size_t encodeSMS(int connectionNo, int msgNo, const byte* msgBytes, size_t msgBytesIdx, char* encodedSMS);
115  //boolean isResendStoredSMS();
116 
117  const char* findStr(const char* msg, const __FlashStringHelper *ifsh);
118  const char *findStr(const char* str, const char* target);
119 
120  const static size_t MAX_BYTES_TO_CONVERT = 117;
121 
122  const static int MAX_MSG_NO_LEN = 3;
123  const static int MAX_MSG_LEN = 256; // max msg len then null
124  char gprsMsg[MAX_MSG_LEN + 1]; // plus null idx runs from 0 to MAX_MSG_LEN
125  int gprsMsgIdx; // = 0;
126  unsigned char gprsLastChar; // = '\0';
127  // keep track of the next 10 incoming SMS sim card msg numbers are reported by +CMTI:
128  const static int MAX_INCOMING_MSG_NOS = 10; // = 10+1 for head != tail
129 
130  uint8_t incomingMsgNos_head; // from 0 to MAX_INCOMING_MSG_NOS;
131  uint8_t incomingMsgNos_tail; // from 0 to MAX_INCOMING_MSG_NOS;
132  // add to head take from tail
133  // stop adding when head+1%MAX_INCOMING_MSG_NOS+1 == tail
134  // stop taking when tail == head
135  // start tail==head == 0;
136  // take (tail == head) so empty
137  // add test (head+1%MAX_INCOMING_MSG_NOS != tail) add to [head] and head++
138  // take tail!= head take[tail++] now tail == head
139  // add 3 [0],[1]
140  char incomingMsgNos[MAX_INCOMING_MSG_NOS + 1][MAX_MSG_NO_LEN + 1];
141  void requestIncomingSmsMsg(const char *msgNo);
142 
143  size_t rxBufferLen; // runs from 0 to SMS_RX_BUFFER_SIZE
144  size_t txBufferLen; // runs from 0 to SMS_TX_BUFFER_SIZE
145  size_t rxBufferIdx; // runs from 0 to rxBufferLen
146  size_t txBufferIdx; // runs from 0 to txBufferLen
147  byte rxBuffer[SMS_RX_BUFFER_SIZE + 1]; // allow for terminating null
148  byte txBuffer[SMS_TX_BUFFER_SIZE + 1]; // allow for terminating null
149  char responseSMSbuffer[SMS_MAX_SIZE + 1]; // only 160 + 1
150  static const int SMS_RAWDATA_TX_BUFFER_SIZE = MAX_BYTES_TO_CONVERT - 1; //117
151  byte rawdataTxBuffer[SMS_RAWDATA_TX_BUFFER_SIZE + 1]; // allow for terminating null and force null at end
152  size_t rawdataTxBufferLen; // runs from 0 to SMS_RAWDATA_TX_BUFFER_SIZE
153  size_t rawdataTxBufferIdx; // runs from 0 to rawdataTxBufferLen
154  char rawdataSMSbuffer[SMS_MAX_SIZE + 1]; // only 160 + 1
155  void flushRawData();
156  void clearRawdataTxBuffer();
157  boolean isSendingResponse();
158  boolean haveRequestedIncomingMsg;
159  void requestNextIncomingMsg();
160 
161  boolean expectingMessageLines; // note msg from pfodApp may have embedded new line
162  boolean sendingRawdata; // true if processing and sending SMS response to command
163  boolean sendingResponse; // true if processing and sending SMS response to command
164  boolean sendingResend; // true if processing and sending SMS resend of previous response to command
165  boolean resendLastResponse; // true if should start resend of last response
166  // if sendingResponse then canSendRawData() return false and any write is just dropped
167  boolean responseSet; // true if tx_buffer holds respons upto } and no new cmd recieved
168  boolean deleteReadSmsMsgs; // true if should delete read msgs
169  boolean foundOK; // true when OK was last gprs msg
170 
171  struct connection connection_A;
172  struct connection connection_B;
173  struct connection *currentConnection;
174  struct connection *nextConnection;
175  void pollSMSboard();
176  void sendSMSrawData();
177 
178  const char* collectGprsMsgs();
179  void clearGprsLine();
180  void processGprsLine(const char* line);
181  // maxLen includes null at end
182  // void getProgStr(const __FlashStringHelper *ifsh, char*str, int maxLen);
183  int decodeInt(const char*smsChars, size_t idx);
184  size_t encodeInt(int number, char*rtn, size_t idx);
185  size_t convertThree8Bytes(long three8Bytes, char*rtn, size_t idx);
186  byte decodeSMSChar(byte encodedChar);
187  byte encodeSMSChar(byte encodedChar);
188  //Stream *console;
189  Stream *gprs; // sms shield serial connection
190  const static byte invalidSMSCharReturn = 0xff; // == 255,
191  byte bytesToConvert[MAX_BYTES_TO_CONVERT + 1]; // max bytes to convert + null
192 
193  void closeConnection(connection* con);
194  void clearConnection(connection* con);
195 
196  boolean newConnectionNumberGreater(int current, int next);
197  boolean validSMSmsgLen(const char* smsChars);
198  void printIgnoreOutOfSequence();
199  unsigned long timedOutTimer;
200  unsigned long start_mS;
201  int findMatchingKnownPhoneNo(const char *phNo);
202  boolean phoneNoMatchesCurrent(const char*newPhNo);
203  boolean phoneNoMatches(const char*oldPhNo, const char*newPhNo);
204  boolean phoneNoHas6Digits(const char *phNo);
205  void checkGPRSpoweredUp();
206  void setupSMS();
207  boolean gprsReady;
208  boolean powerUpGPRS();
209  void clearTxBuffer();
210 
211  void printConnection(connection* con);
212  void swapConnections();
213  void setPhoneNo(connection *con, const char* phNo);
214 
215  void printCurrentConnection();
216  void printNextConnection();
217 
218  void startSMS(const char* phoneNo);
219  void sendNextSMS(); // send next part of txbuffer
220  void clearReadSmsMsgs();
221  void clearAllSmsMsgs();
222  void emptyIncomingMsgNo();
223 
224  void gprsPrint(const char* str);
225  void gprsPrint(char c);
226  void gprsPrint(const __FlashStringHelper *ifsh);
227 
228  boolean haveIncomingMsgNo();
229  boolean addIncomingMsgNo(const char* msgNo);
230  const char* getIncomingMsgNo();
231  void deleteIncomingMsg(const char *newMsgNo);
232 
233  pfod_rawOutput raw_io;
234  pfod_rawOutput* raw_io_ptr;
235 
236 
237  private:
238  Stream* debugOut;
239 
240 };
241 
242 #endif // pfodSMS_SIM900_h
243 
pfod_Base for Arduino Base class for all pfod_Base_xxxx classes The subclasses pfod_Base_xxx must ove...
Definition: pfod_Base.h:18
size_t writeRawData(uint8_t c)
size_t write(uint8_t)
unsigned long getDefaultTimeOut()
int read(void)
void init(Stream *_gprs, int powerOnOffPin)
void _closeCurrentConnection()
int available(void)
void setDebugStream(Stream *out)
Stream * getPfodAppStream()
int peek(void)
void flush(void)
Print * getRawDataOutput()
#define SMS_TX_BUFFER_SIZE
#define SMS_MAX_SIZE
#define SMS_RX_BUFFER_SIZE