Library for the Adafruit FONA. This is a port of the original Arduino library available at: https://github.com/adafruit/Adafruit_FONA_Library . - Modified by Marc PLOUHINEC 27/06/2015 for use in mbed - Modified by lionel VOIRIN 05/08/2018 for use Adafruit FONA 3

Dependents:   Adafruit_FONA_3G_Library_Test

Adafruit_FONA.h

Committer:
Nels885
Date:
2019-03-03
Revision:
12:7a6b5413b407
Parent:
10:7951d9691cb2

File content as of revision 12:7a6b5413b407:

/***************************************************
  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 Marc PLOUHINEC 27/06/2015 for use in mbed
 *  Modified by lionel VOIRIN 05/08/2018 for use Adafruit FONA 3G
 */

#ifndef ADAFRUIT_FONA_H
#define ADAFRUIT_FONA_H

#include "mbed.h"

//#define ADAFRUIT_FONA_DEBUG

#define FONA800L 1
#define FONA800H 6

#define FONA808_V1 2
#define FONA808_V2 3

#define FONA3G_A 4
#define FONA3G_E 5

// Set the preferred SMS storage.
//   Use "SM" for storage on the SIM.
//   Use "ME" for internal storage on the FONA chip
#define FONA_PREF_SMS_STORAGE "\"SM\""
//#define FONA_PREF_SMS_STORAGE "\"ME\""

#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

#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

class Adafruit_FONA : public Stream
{
public:
    /**
     * Listener for FONA events.
     */
    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:
    Adafruit_FONA(PinName tx, PinName rx, PinName rst, PinName key);
    bool begin(int baudrate);
    uint8_t type();
    void powerOn();
    void powerOff();
    void setEventListener(EventListener *eventListener);

    // Stream
    virtual int _putc(int value);
    virtual int _getc();
    int readable();

    // FONA 3G requirements
    bool getBaudrate(uint32_t *baud);
    bool setBaudrate(uint32_t baud);

    // RTC
    bool enableRTC(uint8_t i); // i = 0 <=> disable, i = 1 <=> enable

    // Battery and ADC
    bool getADCVoltage(uint16_t *v);
    bool getBattPercent(uint16_t *p);
    bool getBattVoltage(uint16_t *v);

    // SIM query
    uint8_t unlockSIM(char *pin);
    uint8_t getSIMCCID(char *ccid);
    uint8_t getNetworkStatus(void);
    uint8_t getRSSI(void);

    // IMEI
    uint8_t getIMEI(char *imei);

    // set Audio output
    bool setAudio(uint8_t a);
    bool setVolume(uint8_t i);
    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
    bool tuneFMradio(uint16_t station);
    bool FMradio(bool onoff, uint8_t a = FONA_HEADSETAUDIO);
    bool setFMVolume(uint8_t i);
    int8_t getFMVolume();
    int8_t getFMSignalLevel(uint16_t station);

    // SMS handling
    bool setSMSInterrupt(uint8_t i);
    uint8_t getSMSInterrupt(void);
    int8_t getNumSMS(void);
    bool readSMS(uint8_t i, char *smsbuff, uint16_t max, uint16_t *readsize);
    bool sendSMS(char *smsaddr, char *smsmsg);
    bool deleteSMS(uint8_t i);
    bool getSMSSender(uint8_t i, char *sender, int senderlen);

    // Time
    bool enableNetworkTimeSync(bool onoff);
    bool enableNTPTimeSync(bool onoff, const char* ntpserver=0);
    bool getTime(char* buff, uint16_t maxlen);

    // GPRS handling
    bool enableGPRS(bool onoff);
    int 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);
    uint8_t getIPADDR(char *ipaddr);
    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)
    bool setPWM(uint16_t period, uint8_t duty = 50);

    // Phone calls
    bool callPhone(char *phonenum);
    bool hangUp(void);
    bool pickUp(void);
    bool callerIdNotification(bool enable);
    bool incomingCallNumber(char* phonenum);

    // Helper functions to verify responses.
    bool expectReply(const char* reply, uint16_t timeout = 10000);

protected:
    DigitalOut _keypin;
    DigitalOut _rstpin;
    uint8_t _type;

    char replybuffer[255];
    char* apn;
    char* apnusername;
    char* apnpassword;
    bool httpsredirect;
    char* useragent;
    char* ok_reply;

    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, uint32_t *v, char divider = ',', uint8_t index=0);
    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, uint32_t *v, char divider = ',', uint8_t index = 0);
    bool sendParseReply(const char* tosend, const char* toreply, uint16_t *v, char divider = ',', uint8_t index = 0);

    void onIncomingCall();
};

class Adafruit_FONA_3G : public Adafruit_FONA
{
public:
    Adafruit_FONA_3G(PinName tx, PinName rx, PinName rst, PinName key) : Adafruit_FONA(tx, rx, rst, key) {
        _type = FONA3G_A;
    }

    bool getBattVoltage(uint16_t *v);
    bool hangUp(void);
    bool pickUp(void);
    bool enableGPS(bool onoff);
    
    // SIM query
    uint8_t unlockSIM(char *pin);
    
    // TCP raw connections
    uint8_t TCPinitialize(void);
    uint8_t sslTCPinitialize(void);
    uint8_t getTCPtimeout(char *tcptimeout);
    bool TCPconnect(char *server, uint16_t port);
    bool sslTCPconnect(char *server, uint16_t port);
    bool TCPclose(void);
    bool sslTCPclose(void);
    bool TCPsend(char *packet);
    bool sslTCPsend(char *packet);
    uint16_t sslTCPread(char *buff);

protected:
    bool sendParseReply(const char* tosend, const char* toreply, float *f, char divider, uint8_t index);
    bool parseReply(const char* toreply, uint16_t *v, char divider = ',', uint8_t index=0);
    bool parseReply(const char* toreply, float *f, char divider, uint8_t index=0);
};

#endif