/* * ThreadedGSM.h * * Author: Neta Yahav, Pavel Brychta */ #pragma once #include "DTE.h" //#include #include // Defaults #define THREADEDGSM_DEF_DTE_BUF_SIZ 512 #define THREADEDGSM_DEF_AT_TIMEOUT 2000 #define THREADEDGSM_DEF_STA_PON 15000 #define THREADEDGSM_DEF_STA_POF 1000 // Use custom values or default ones #ifndef THREADEDGSM_DTE_BUFFER_SIZE #define THREADEDGSM_DTE_BUFFER_SIZE THREADEDGSM_DEF_DTE_BUF_SIZ #endif #ifndef THREADEDGSM_AT_TIMEOUT #define THREADEDGSM_AT_TIMEOUT THREADEDGSM_DEF_AT_TIMEOUT #endif #ifndef THREADEDGSM_STARTUP_DELAY #define THREADEDGSM_STARTUP_DELAY THREADEDGSM_DEF_STA_PON #endif #ifndef THREADEDGSM_STARTUP_POWER_OFF_DELAY #define THREADEDGSM_STARTUP_POWER_OFF_DELAY THREADEDGSM_DEF_STA_POF #endif #define THREADEDGSM_INTERVAL_COUNT 3 class ThreadedGSM : public Executable { // variables public: struct NetworkTime { int year; int month; int day; int hour; int minute; int second; }; enum ReadMessagesListTypeE { READ_TYPE_UNREAD = 0, READ_TYPE_READ = 1, READ_TYPE_UNSENT = 2, READ_TYPE_SENT = 3, READ_TYPE_ALL = 4 }; enum IntervalSourceE { INTERVAL_CLOCK, INTERVAL_INBOX, INTERVAL_SIGNAL, INTERVAL_BATTERY }; struct SignalLevel { int Dbm; int Value; }; struct BatteryInfo { int Percent; int Voltage; }; struct SMSInfo { String Number; String Text; }; typedef void (*ThreadedGSMCallbackSignal)(ThreadedGSM &, SignalLevel &); typedef void (*ThreadedGSMCallbackClock)(ThreadedGSM &, NetworkTime &); typedef void (*ThreadedGSMCallbackBattery)(ThreadedGSM &, BatteryInfo &); typedef void (*ThreadedGSMCallbackIncomingSMS)(ThreadedGSM &, SMSInfo &); typedef void (*ThreadedGSMCallbackBool)(ThreadedGSM &, bool); typedef void (*ThreadedGSMCallback)(ThreadedGSM &); typedef void (*ThreadedGSMCallbackRing)(ThreadedGSM &, String &); struct conf { ThreadedGSMCallbackSignal signal; ThreadedGSMCallbackClock clock; ThreadedGSMCallbackIncomingSMS incoming; ThreadedGSMCallback ready; ThreadedGSMCallback outgoing; ThreadedGSMCallbackBool power; ThreadedGSMCallbackBattery battery; ThreadedGSMCallbackRing ring; }; protected: enum StatesStartup { STARTUP_POWER_OFF, STARTUP_POWER_OFF_DELAY, STARTUP_POWER_ON, STARTUP_DELAY, STARTUP_ENTER_AT, STARTUP_CHK_CPIN, STARTUP_CHK_CREG, STARTUP_CHK_CLTS, STARTUP_CHK_CENG, STARTUP_CHK_CLIP }; enum StatesClock { CLOCK_REQ, CLOCK_VERIFY }; enum StatesSignal { SIGNAL_REQ, SIGNAL_VERIFY }; enum StatesBattry { BATTERY_REQ, BATTERY_VERIFY }; enum StatesInbox { READ_REQ, READ_CHK_CMGF, READ_CHK_CPMS, READ_CHK_CMGL, READ_DELAY_CLEAR_BUFF, READ_TEXT_CMGR, READ_CHK_CMGR, READ_CHK_CMGD }; enum StatesOutbox { SEND_REQ, SEND_CHK_CMGF, SEND_CHK_RDY, SEND_CHK_OK }; enum StateHangup { HANGUP_REQ, HANGUP_CHK }; enum StatesCheckRing { RING_WAIT, RING_CHK, }; unsigned long mTick = 0; struct { int Index; // Index of read message } Message{}; SMSInfo mSMSi{}; // Inbox SMS (incoming) SMSInfo mSMSo{}; // Outbox SMS (outgoing) Stream & mStream; DTE mDte; unsigned long tickSync[THREADEDGSM_INTERVAL_COUNT]{}; unsigned long Intervals[THREADEDGSM_INTERVAL_COUNT]{}; // callbacks // conf mConfiguration = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; conf mConfiguration{}; enum ReqTypes { REQ_CLOCK = 1, REQ_SIG = 2, REQ_INBOX = 4, REQ_OUTBOX = 8, REQ_STARTUP = 16, REQ_BATTERY = 32, REQ_HANGUP = 64, }; int mRequests = 0; int mState = 0; int mJob = 0; int mRingState; // functions public: explicit ThreadedGSM(Stream & stream); ~ThreadedGSM() override = default; void nextJob(); void setHandlers(conf config); void setInterval(IntervalSourceE source, unsigned long interval); // Initialization void begin(); // Call this function for executing thread void exec() override; // Requests void sendSMS(String & Number, String & Text); void sendSMS(String & Number, const char * Text); void hangup(); void restartModem(); protected: void startupDone(); // States void Startup(); // Threads void Clock(); void Signal(); void Battery(); void clearReq(int req); void Inbox(); void Outbox(); void Hangup(); void CheckRing(); }; // ThreadedGSM