Update to work with latest mBed

Dependencies:   mbed-dev

Fork of FONA_CellPhone by Dream Team

Adafruit_FONA.h

Committer:
michaelVisimid
Date:
2017-01-27
Revision:
19:06dd156420a5
Parent:
18:d52017f1d087

File content as of revision 19:06dd156420a5:

/***************************************************
  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 FONA_CALL_READY 0
#define FONA_CALL_FAILED 1
#define FONA_CALL_UNKNOWN 2
#define FONA_CALL_RINGING 3
#define FONA_CALL_INPROGRESS 4

#define RX_BUFFER_SIZE  255

#define CIPSHUT_DELAY   (uint16_t)65000
#define CGATT_DELAY     (uint16_t)10000
#define SAPBR_DELAY     (uint16_t)85000
#define CIICR_DELAY     (uint16_t)85000
#define CGATT_DELAY     (uint16_t)10000
#define CIPGSMLOC_DELAY (uint16_t)60000
#define CPIMUX_DELAY    (uint16_t)160000

/** Adafruit FONA 800H Class
*  Modified by George Tzintzarov & Jesse Baker 03/14/2016 for use in mbed LPC1768
*/

class Adafruit_FONA : public Stream {
    public:
        
        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:
                Serial mySerial;
        
        Adafruit_FONA(PinName tx, PinName rx, PinName rst, PinName ringIndicator) :
             mySerial(tx, rx),_rstpin(rst, false), _ringIndicatorInterruptIn(ringIndicator),
            apn("FONAnet"), apnusername(NULL), apnpassword(NULL), httpsredirect(false), useragent("FONA"),
            _incomingCall(false), eventListener(NULL), rxBufferInIndex(0), rxBufferOutIndex(0), 
            currentReceivedLineSize(0) {}
            

        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);
                bool setBaudrate(uint16_t baud);   
                bool readRTC(uint8_t *year, uint8_t *month, uint8_t *date, uint8_t *hr, uint8_t *min, uint8_t *sec);
        // 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
        

        bool getADCVoltage(uint16_t *v);

        
        bool getBattPercent(uint16_t *p);

        bool getBattVoltage(uint16_t *v);
        
       
        bool unlockSIM(char *pin);

        uint8_t getSIMCCID(char *ccid);

        uint8_t getNetworkStatus(void);

        uint8_t getRSSI(void);

        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 = 30000);
        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);
            uint8_t getCallStatus(void);
        /** 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);
        bool sendUSSD(char *ussdmsg, char *ussdbuff, uint16_t maxlen, uint16_t *readlen);
    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;
        

        // 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