Library for Adafruit FONA breakout board

Revision:
0:52654f3080d9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_FONA.h	Wed Mar 30 17:18:50 2016 +0000
@@ -0,0 +1,542 @@
+/***************************************************
+  This is a library for our Adafruit FONA Cellular Module
+
+  Designed specifically to work with the Adafruit FONA
+  ----> http://www.adafruit.com/products/1946
+  ----> http://www.adafruit.com/products/1963
+
+  These displays use TTL Serial to communicate, 2 pins are required to
+  interface
+  Adafruit invests time and resources providing this open source code,
+  please support Adafruit and open-source hardware by purchasing
+  products from Adafruit!
+
+  Written by Limor Fried/Ladyada for Adafruit Industries.
+  BSD license, all text above must be included in any redistribution
+ ****************************************************/
+ 
+ /*
+  *  Modified by George Tzintzarov & Jesse Baker 03/14/2016 for use in mbed LPC1768
+  */
+ 
+#ifndef ADAFRUIT_FONA_H
+#define ADAFRUIT_FONA_H
+
+#include "mbed.h"
+
+//#define ADAFRUIT_FONA_DEBUG
+
+#define FONA_HEADSETAUDIO 0
+#define FONA_EXTAUDIO 1
+
+#define FONA_STTONE_DIALTONE 1
+#define FONA_STTONE_BUSY 2
+#define FONA_STTONE_CONGESTION 3
+#define FONA_STTONE_PATHACK 4
+#define FONA_STTONE_DROPPED 5
+#define FONA_STTONE_ERROR 6
+#define FONA_STTONE_CALLWAIT 7
+#define FONA_STTONE_RINGING 8
+#define FONA_STTONE_BEEP 16
+#define FONA_STTONE_POSTONE 17
+#define FONA_STTONE_ERRTONE 18
+#define FONA_STTONE_INDIANDIALTONE 19
+#define FONA_STTONE_USADIALTONE 20
+
+#define FONA_DEFAULT_TIMEOUT_MS 500 //timeout between send AT and reply from FONA
+
+#define FONA_HTTP_GET   0
+#define FONA_HTTP_POST  1
+#define FONA_HTTP_HEAD  2 
+
+#define RX_BUFFER_SIZE  255
+
+/** Adafruit FONA 800H Class
+*  Modified by George Tzintzarov & Jesse Baker 03/14/2016 for use in mbed LPC1768
+*/
+
+class Adafruit_FONA : public Stream {
+    public:
+/**
+Listener for FONA events. Inherit this class to customize.
+@code
+#define FONA_RST p12
+#define FONA_TX p13
+#define FONA_RX p14
+#define FONA_RI p11
+
+Adafruit_FONA my_fona(FONA_TX, FONA_RX, FONA_RST, FONA_RI);
+DigitalOut led1(LED1); 
+class FonaEventListener : public Adafruit_FONA::EventListener {
+    virtual void onRing() {
+        led1 = 1;
+}
+
+    virtual void onNoCarrier() {
+        led1 = 0; 
+    }
+};
+FonaEventListener fonaEventListener;
+my_fona.setEventListener(&fonaEventListener);
+@endcode
+*/
+        
+        class EventListener {
+            public:
+                /**
+                 * Method called when somebody call the FONA.
+                 */
+                virtual void onRing() = 0;
+                
+                /**
+                 * Method called when the calling person stop his call.
+                 */
+                virtual void onNoCarrier() = 0;
+        };
+    
+    public:
+        /** Create instance of the Adafruit_FONA
+        @param tx Set mbed TX 
+        @param rx Set mbed RX
+        @param rst Set reset pin
+        @param ringIndicator Set ring indicator pin. This is to let mbed know if there is an incoming call
+        */
+        
+        Adafruit_FONA(PinName tx, PinName rx, PinName rst, PinName ringIndicator) :
+            _rstpin(rst, false), _ringIndicatorInterruptIn(ringIndicator),
+            apn("FONAnet"), apnusername(NULL), apnpassword(NULL), httpsredirect(false), useragent("FONA"),
+            _incomingCall(false), eventListener(NULL), mySerial(tx, rx), rxBufferInIndex(0), rxBufferOutIndex(0), 
+            currentReceivedLineSize(0) {}
+            
+        /** Built-in Test to see if FONA is connected
+        @param baudrate test and set at baudrate
+        @return true upon success
+        @return false upon failure. Most likely something is not hooked up.
+        
+EXAMPLE CODE:
+        @code
+// See if the FONA is responding
+// fona is an instance of Adafruit_FONA
+if (! fona.begin(9600)) {
+    printf("Couldn't find FONA\r\n");
+    while (1);
+}
+        @endcode
+        */
+        bool begin(int baudrate);
+        
+        /** Set the event listener for incoming calls
+        @param eventListener A pointer to the event listener
+        @see Adafruit_FONA::EventListener for specific example
+        */
+        
+        void setEventListener(EventListener *eventListener);
+        
+        // Stream----------------------------------------------------------------------
+        virtual int _putc(int value);
+        virtual int _getc();
+        
+        /** Check if FONA has anything in its output buffer
+        @return 0 if nothing
+        */
+        int readable(void);
+        
+        // RTC----------------------------------------------------------------------
+        bool enableRTC(uint8_t i); // i = 0 <=> disable, i = 1 <=> enable
+        
+        // Battery and ADC----------------------------------------------------------------------
+        /** Get ADC voltage from external pin
+        @param v uint16_t pointer to insert ADC voltage data
+        @return TRUE if successful
+        
+EXAMPLE CODE:
+        @code
+// read the ADC
+// fona is an instance of Adafruit_FONA
+uint16_t adc;
+if (! fona.getADCVoltage(&adc)) {
+    printf("Failed to read ADC\r\n");
+} 
+else {
+    printf("ADC = %d mV\r\n", adc);
+}
+        @endcode
+        */
+        bool getADCVoltage(uint16_t *v);
+        
+        /** Get battery percentage level
+        @param p uint16_t pointer to insert battery percent data
+        @return TRUE if successful
+        
+EXAMPLE CODE:
+        @code
+// read the battery percent level
+// fona is an instance of Adafruit_FONA
+uint16_t vbatPer;
+if (! fona.getBattPercent(&vbatPer)) {
+    printf("Failed to read Batt\r\n");
+} 
+else {
+    printf("VPct = %d%%\r\n", vbatPer);
+}
+        @endcode
+        */
+        
+        bool getBattPercent(uint16_t *p);
+        
+        /** Get battery voltage level
+        @param v uint16_t pointer to insert battery voltage data
+        @return TRUE if successful
+        
+EXAMPLE CODE:
+        @code
+// read the battery voltage
+// fona is an instance of Adafruit_FONA
+uint16_t vbat;
+if (! fona.getBattPercent(&vbat)) {
+    printf("Failed to read Batt\r\n");
+} 
+else {
+    printf("Vbat = %d%%\r\n", vbat);
+}
+        @endcode
+        */
+        bool getBattVoltage(uint16_t *v);
+        
+        // SIM query----------------------------------------------------------------------
+        /** Unlock SIM if needed
+        @param pin 4 digit char arrary
+        @return TRUE if successful
+        */        
+        bool unlockSIM(char *pin);
+        /** Get the SIM chip card interface device (CCID)
+        @param ccid make sure it is at least 21 bytes long
+        @return length of CCID
+        */
+        
+        uint8_t getSIMCCID(char *ccid);
+        /** Get the Network Status of FONA
+        @return Code 0-5 
+        @see https://www.adafruit.com/datasheets/sim800_series_at_command_manual_v1.01.pdf page 80
+        */
+        uint8_t getNetworkStatus(void);
+        
+        /** Get the RSSI of the network signal
+        @return RSSI value in dBm per below reference
+        
+        EXAMPLE
+        @code
+// read the RSSI
+uint8_t n = fona.getRSSI();
+int8_t r = 0;
+
+pcSerial.printf("RSSI = %d: ", n);
+if (n == 0) r = -115;
+if (n == 1) r = -111;
+if (n == 31) r = -52;
+if ((n >= 2) && (n <= 30)) {
+    r = map(n, 2, 30, -110, -54);
+}
+printf("%d dBm\r\n", r);
+
+// helper function MAP to do calculations
+long MAP(long x, long in_min, long in_max, long out_min, long out_max)
+{
+    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
+}
+        @endcode
+        @see https://www.adafruit.com/datasheets/sim800_series_at_command_manual_v1.01.pdf page 82
+        */
+        uint8_t getRSSI(void);
+        
+        // IMEI----------------------------------------------------------------------
+        /** Get the International Mobile Station Equipment Identity (IMEI)
+        @param imei A char array with minimum length 16
+        @return The IMEI of the device
+        
+EXAMPLE CODE:
+        @code
+// Print SIM card IMEI number.
+char imei[15] = {0}; // MUST use a 16 character buffer for IMEI!
+uint8_t imeiLen = fona.getIMEI(imei); //fona is an instance of Adafruit_FONA
+if (imeiLen > 0) {
+    pcSerial.printf("SIM card IMEI: %s\r\n", imei);
+}
+        @endcode
+        */
+        uint8_t getIMEI(char *imei);
+        
+        // set Audio output----------------------------------------------------------------------
+        /** Set the Audio Output interface
+        @param a 0 is headset, 1 is external audio
+        @return TRUE if successful
+        */
+        bool setAudio(uint8_t a);
+
+        /** Set the Audio Volume
+        @param i a unit8_t volume number
+        @return TRUE if successful
+        */
+        bool setVolume(uint8_t i);
+
+        /** Get the Audio Volume
+        @return the current volume
+        */
+        uint8_t getVolume(void);
+        bool playToolkitTone(uint8_t t, uint16_t len);
+        bool setMicVolume(uint8_t a, uint8_t level);
+        bool playDTMF(char tone);
+        
+        // FM radio functions----------------------------------------------------------------------
+        /** Tune the FM radio
+        @param station frequency, for example 107.9 MHz -> 1079 
+        @return TRUE if successful
+        */
+        bool tuneFMradio(uint16_t station);
+
+        /** FM radio set output
+        @param onoff bool to turn on if TRUE
+        @param a 0 (default) is headset, 1 is external audio
+        @return TRUE if successful
+        */
+        bool FMradio(bool onoff, uint8_t a = FONA_HEADSETAUDIO);
+
+        /** Set the FM Radio Volume
+        @param i a unit8_t volume number
+        @return TRUE if successful
+        */
+        bool setFMVolume(uint8_t i);
+
+        /** Get the FM Volume
+        @return the current FM volume
+        */
+        int8_t getFMVolume();
+
+        /** Get the FM signal strength
+        @param station a unit8_t volume number
+        @return TRUE if successful
+        */
+        int8_t getFMSignalLevel(uint16_t station);
+        
+        // SMS handling----------------------------------------------------------------------
+        /** Set the SMS Interrupt
+        @param i 0 = OFF, 1 = ON with TCPIP, FTP, and URC control Ring Indicator Pin, 2 = ON with only TCPIP control
+        @return TRUE if successful
+        @see https://www.adafruit.com/datasheets/sim800_series_at_command_manual_v1.01.pdf page 152
+        */
+        bool setSMSInterrupt(uint8_t i);
+
+        /** Get SMS Interrupt Setting
+        @return setting
+        @see https://www.adafruit.com/datasheets/sim800_series_at_command_manual_v1.01.pdf page 152
+        */
+        uint8_t getSMSInterrupt(void);
+
+        /** Set the SMS Interrupt
+        @return number of SMS messages in inbox
+        */
+        int8_t getNumSMS(void);
+
+        /** Read SMS
+        @param i sms number in memory
+        @param smsbuff char pointer to char array
+        @param max Maximum length of smsbuff
+        @param readsize the size in bytes of the SMS
+        @return TRUE if successful
+        */
+        bool readSMS(uint8_t i, char *smsbuff, uint16_t max, uint16_t *readsize);
+
+        /** Send SMS
+        @param smsaddr Phone number to send out
+        @param smsmsg Char array containing message
+        @return TRUE if successful
+        */
+        bool sendSMS(char *smsaddr, char *smsmsg);
+
+        /** Delete SMS
+        @param i number of SMS in memory
+        @return TRUE if successful
+        */
+        bool deleteSMS(uint8_t i);
+
+        /** Send SMS
+        @param i Number of SMS in memory
+        @param sender Char array to store the sender number
+        @param senderlen length of sender
+        @return TRUE if successful
+        */
+        bool getSMSSender(uint8_t i, char *sender, int senderlen);
+        
+        // Time----------------------------------------------------------------------
+        /** Enable FONA to sync time with the cellular network
+        @param onoff on = true, off = false
+        @return TRUE if successful
+        */
+        bool enableNetworkTimeSync(bool onoff);
+
+        /** Enable FONA to sync time with the time server
+        @param onoff true = on, false = off
+        @return TRUE if successful
+        */
+        bool enableNTPTimeSync(bool onoff, const char* ntpserver=0);
+
+        /** Retrieve the current time from the enabled server
+        @param buff char array to store time value. Given as "yy/MM/dd,hh:mm:ss+zz"
+        @param maxlen Maximum length of the char array
+        @return TRUE if successful
+        */
+        bool getTime(char* buff, uint16_t maxlen);
+
+        // GPRS handling----------------------------------------------------------------------
+        bool enableGPRS(bool onoff);
+        uint8_t GPRSstate(void);
+        bool getGSMLoc(uint16_t *replycode, char *buff, uint16_t maxlen);
+        bool getGSMLoc(float *lat, float *lon);
+        void setGPRSNetworkSettings(const char* apn, const char* username=0, const char* password=0);
+
+        // GPS handling----------------------------------------------------------------------
+        bool enableGPS(bool onoff);
+        int8_t GPSstatus(void);
+        uint8_t getGPS(uint8_t arg, char *buffer, uint8_t maxbuff);
+        bool getGPS(float *lat, float *lon, float *speed_kph=0, float *heading=0, float *altitude=0);
+        bool enableGPSNMEA(uint8_t nmea);
+
+        // TCP raw connections----------------------------------------------------------------------
+        bool TCPconnect(char *server, uint16_t port);
+        bool TCPclose(void);
+        bool TCPconnected(void);
+        bool TCPsend(char *packet, uint8_t len);
+        uint16_t TCPavailable(void);
+        uint16_t TCPread(uint8_t *buff, uint8_t len);
+
+        // HTTP low level interface (maps directly to SIM800 commands).----------------------------------------------------------------------
+        bool HTTP_init();
+        bool HTTP_term();
+        void HTTP_para_start(const char* parameter, bool quoted = true);
+        bool HTTP_para_end(bool quoted = true);
+        bool HTTP_para(const char* parameter, const char *value);
+        bool HTTP_para(const char* parameter, int32_t value);
+        bool HTTP_data(uint32_t size, uint32_t maxTime=10000);
+        bool HTTP_action(uint8_t method, uint16_t *status, uint16_t *datalen, int32_t timeout = 10000);
+        bool HTTP_readall(uint16_t *datalen);
+        bool HTTP_ssl(bool onoff);
+
+        // HTTP high level interface (easier to use, less flexible).----------------------------------------------------------------------
+        bool HTTP_GET_start(char *url, uint16_t *status, uint16_t *datalen);
+        void HTTP_GET_end(void);
+        bool HTTP_POST_start(char *url, const char* contenttype, const uint8_t *postdata, uint16_t postdatalen, uint16_t *status, uint16_t *datalen);
+        void HTTP_POST_end(void);
+        void setUserAgent(const char* useragent);
+
+        // HTTPS----------------------------------------------------------------------
+        void setHTTPSRedirect(bool onoff);
+
+        // PWM (buzzer)----------------------------------------------------------------------
+        /** Control the buzzer capability of the PWM out on the FONA
+        @param period of the buzzing cycle (max 2000)
+        @param duty the duty cycle of the buzzer (0 to 100)
+        @return TRUE if successful
+        */
+        bool setPWM(uint16_t period, uint8_t duty = 50);
+
+        // Phone calls----------------------------------------------------------------------
+        /** Call a phone
+        @param phonenum a character array of the phone number
+        @return TRUE if successful
+        */
+        bool callPhone(char *phonenum);
+
+        /** Hang up a phone call
+        */
+        bool hangUp(void);
+
+        /** Answer a phone call
+        */
+        bool pickUp(void);
+
+        /** Enable/disable caller ID
+        @param enable true to enable, false to disable
+        @return TRUE if successful
+        */
+        bool callerIdNotification(bool enable);
+
+        /** Retrieve the incoming call number
+        @param phonenum a character array of the phone number calling
+        @return TRUE if successful
+        */
+        bool incomingCallNumber(char* phonenum);
+
+        // Helper functions to verify responses.
+        bool expectReply(const char* reply, uint16_t timeout = 10000);
+
+    private:
+        DigitalOut _rstpin;
+        InterruptIn _ringIndicatorInterruptIn;
+
+        char replybuffer[255]; // the output of getreply(), readline() is the function that changes the replybuffer
+        char* apn;
+        char* apnusername;
+        char* apnpassword;
+        bool httpsredirect;
+        char* useragent;
+
+        volatile bool _incomingCall;
+        EventListener *eventListener;
+        Serial mySerial;
+
+        // Circular buffer used to receive serial data from an interruption
+        int rxBuffer[RX_BUFFER_SIZE + 1];
+        volatile int rxBufferInIndex; // Index where new data is added to the buffer
+        volatile int rxBufferOutIndex; // Index where data is removed from the buffer
+        char currentReceivedLine[RX_BUFFER_SIZE]; // Array containing the current received line
+        int currentReceivedLineSize;
+
+        inline bool isRxBufferFull() {
+            return ((rxBufferInIndex + 1) % RX_BUFFER_SIZE) == rxBufferOutIndex;
+        }
+
+        inline bool isRxBufferEmpty() {
+            return rxBufferInIndex == rxBufferOutIndex;
+        }
+
+        inline void incrementRxBufferInIndex() {
+            rxBufferInIndex = (rxBufferInIndex + 1) % RX_BUFFER_SIZE;
+        }
+
+        inline void incrementRxBufferOutIndex() {
+            rxBufferOutIndex = (rxBufferOutIndex + 1) % RX_BUFFER_SIZE;
+        }
+
+        /**
+         * Method called when Serial data is received (interrupt routine).
+         */
+        void onSerialDataReceived();
+
+        // HTTP helpers
+        bool HTTP_setup(char *url);
+
+        void flushInput();
+        uint16_t readRaw(uint16_t b);
+        uint8_t readline(uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS, bool multiline = false);
+        uint8_t getReply(const char* send, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
+        uint8_t getReply(const char* prefix, char *suffix, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
+        uint8_t getReply(const char* prefix, int32_t suffix, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
+        uint8_t getReply(const char* prefix, int32_t suffix1, int32_t suffix2, uint16_t timeout); // Don't set default value or else function call is ambiguous.
+        uint8_t getReplyQuoted(const char* prefix, const char* suffix, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
+
+        bool sendCheckReply(const char* send, const char* reply, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
+        bool sendCheckReply(const char* prefix, char *suffix, const char* reply, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
+        bool sendCheckReply(const char* prefix, int32_t suffix, const char* reply, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
+        bool sendCheckReply(const char* prefix, int32_t suffix, int32_t suffix2, const char* reply, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
+        bool sendCheckReplyQuoted(const char* prefix, const char* suffix, const char* reply, uint16_t timeout = FONA_DEFAULT_TIMEOUT_MS);
+
+        bool parseReply(const char* toreply, uint16_t *v, char divider  = ',', uint8_t index=0);
+        bool parseReply(const char* toreply, char *v, char divider  = ',', uint8_t index=0);
+        bool parseReplyQuoted(const char* toreply, char* v, int maxlen, char divider, uint8_t index);
+
+        bool sendParseReply(const char* tosend, const char* toreply, uint16_t *v, char divider = ',', uint8_t index = 0);
+
+        void onIncomingCall();
+};
+
+#endif
\ No newline at end of file