Git Product home page Git Product logo

gsmsim's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gsmsim's Issues

No method to get the senders number

If we look into the SIM800L library by cristiansteib, there's a method that retrieves the SMS senders number. Which is a pretty handy feature.
Following is the code segment from cristiansteib's library.

String Sim800l::getNumberSms(uint8_t index){
  _buffer=readSms(index);
  Serial.println(_buffer.length());
  if (_buffer.length() > 10) //avoid empty sms
  {
    uint8_t _idx1=_buffer.indexOf("+CMGR:");
    _idx1=_buffer.indexOf("\",\"",_idx1+1);
    return _buffer.substring(_idx1+3,_buffer.indexOf("\",\"",_idx1+4));
  }else{
    return "";
  }
}

Adding a command that help us to reject an incoming call.

In some project, when we only want to send a sms or make a call, and we no need to answer any incoming call, which make module sim busy in a long period of time. So i think we should have a command that help us to reject an imcoming call positively.
Thank you for all your helps.

Arduino Mega 2560 not Support

hai.... i have project to make a controller relay with sms. and i tested this library on my arduino mega. its work with pin 9 and 10. but the pin comunication is useless if i using digital pin. i try change pin from 9 and 10 to pin 14 and 15 (TX3 and RX3), but not working. why is not working?. does the communication pin must to use serial?

About HttpPost

Hi Erdem,
Is there any method like HttpPost. In library i see only httpGet methot wish to have httpPost.
Teşekkürler.

time.get() hangs the sketch

The time.get(int *day, int *month, int *year, int *hour, int *minute, int *second) function won't return to the loop even after 1-2min. Is there something wrong with my stuff or can others reproduce the issue?
Thanks in advance...

GSMSim and Arduino Nano + SIM800C

Hallo Erdem,
I have tested with success your library "GSMSim" with Arduino UNO in every examples, but I cannot send Email ONLY with the Arduino Nano with the same hardware configuration.
I put a LIPO battery directly to VBAT and GND of my SIM800C (with Arduino UNO and NANO) and my Arduino Nano is powered by the USB cable (to have the debug).
I receive these messages:

GSMSim Library - Send Email Example
Connect to Internet: 1
Set gmail smtp configuration: 1
Write email to someone: ERROR:TITLE_NOT_SET
Send email... : SUCCESS:EMAIL_SEND
Close Internet: 1

But I receive the Email with the "title", but without the "body".
Thanks a lot if you have any suggestion.
Roberto
Graz - Austria

.

oops it's already implemented. sry. pls delete

library not working with sim7020e

Hi,
I have module sim7020e, i tried to test it with library called Adafruit FONA Library and it found the card and show me his info with no problem!

My next step was to try to work with you library, but the connection is in initial and your library cant find the modem device.

Please help me, what may be the problem??
Thanks.

Proposing a new version of this class, compatible with other architectures where you find preexistent instances of HardwareSerial instead of SoftwareSerial

Hi,

Here's an idea I hope you will like, to make this library also usable on other architectures where you don't have SoftwareSerial, you find preexistent instances of HardwareSerial instead.

NOTICE: The calls you are using to SoftwareSerial methods have equivalents of the same exact name in the HardwareSerial class, I didn't have to change any such calls. But I haven't checked that all methods actually behave the same way, I have only tested sending SMS messages so far [EDIT: and dialing a call to a landlilne or mobile phone, both things are working very fine now].

Very short story: I made a program on the STM32F103C8T6 board (very cheap yet much more capable than Uno/ProMini and Leonardo/ProMicro) which - apart other things - sends an SMS from a SIM800L GSM module.

Then, I wanted to give a look at your library and I liked it, you did a great job.

So, I spent a few hours seeing if it could be easily modified to work with a preexistent instance of HardwareSerial, instead of inheriting from SoftwareSerial.

I'm using the Roger Clark core for the STM32F103C8T6. In it, you find one pre-instantiated HardwareSerial object for each hardware serial interface on the board, there's no SoftwareSerial library available as far as I know (slash-dev's answer on this page corroborates that it would be nonsense to use SoftwareSerial on it).

Here's a quick mod of your example which sends an SMS + your GSMSim class. I started from the current official release ver 1.0.19. You don't have to take my work, apart for testing if you want, you can redo what I did rather quickly, starting from the next official GSMSim releaes which would integrate all current ongoing fixes/improvements.

In fact, the process was easy because you very diligently used "this->" every time you called a method inherited from SoftwareSerial.

So, the main modification is to define a member serialManager (or the name you like), which is a reference to an external preexistent instance of a HardwareSerial or SoftwareSerial object, and replace all occurrences of "this->" with "serialManager." occurrences.

Actually, I first modified it for HardwareSerial only and tested it, then I turned it into a template so the same source and maintanance/upgrade work would be usable with both HardwareSerial and SoftwareSerial classes (and possibly other method-to-method compatible classes).

IN CASE SOME PECULIAR PART OF THE SOURCE CODE WOULD HAVE TO BE DIFFERENT, THIS PAGE EXPLAINS HOW TO DO IT WITH "TEMPLATE SPECIALIZATION".

(Of course I had to touch a few other things, certain constructors become unnecessary because now you can initialize an external SerialSoftware object apart, before creating the GSMSim one, when you don't find a pre-instantiated HardwareSerial object of course, such as in the core I'm using with this STM32F103C8T6 boards.)

You'll see that I've also commented out the LED related lines, but you don't have to do the same of course.

I've seen on GitHub that a few minor problems have already been or are already being addressed, e.g. values which can't be represented with uint8_t, or lines with just "false" instead of "return false". The current version of the Arduino IDE was warning on them all.

Finally, I would advise to keep - as I was taught long ago - one single exit point from functions: instead of many return ... lines, you can have many lines like returnValue = ... and then one single return returnValue line at the end.
But your source is so tidy that this is not a real issue.


Here's file GSMSim_TemplateSerial___SMS___v01.001.ino, quick mod of your SMS example:

#include <GSMSim_TemplateSerial.h>
/*  Orig lib GSMSim, let's see if we can also use it with a preexistent instance of HardwareSerial instead of inheriting from SoftwareSerial.
    Quick mod by Nicola "JazzTp" Bernardelli
    STM32F103C8T6 board with Roger Clark's core https://github.com/rogerclarkmelbourne/Arduino_STM32
    NOTICE: only tested sending SMS and dialing a number, so far.
*/


#ifdef BOARD_generic_stm32f103c
  #define DEFAULT_PIN_RESET PB0
#else
  #define DEFAULT_PIN_RESET 2
#endif

#define BAUD 9600

GSMSim_TemplateSerial<HardwareSerial> gsm(Serial2, DEFAULT_PIN_RESET);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  Serial.println("GSMSim_HWserial Library - SMS Example");
  Serial.println("");
  delay(1000);

  gsm.start(); // baud default 9600
  // gsm.start(BAUD);

  Serial.println("Changing to text mode.");
  gsm.smsTextMode(true); // TEXT or PDU mode. TEXT is readable :)

  const char* number = "+905123456789";
  char* message = "Hi my friend. How are you?"; // message lenght must be <= 160. Only english characters.

  Serial.println("Sending Message --->");
  Serial.println(gsm.smsSend(number, message)); // if success it returns true (1) else false (0)
  delay(2000);

  Serial.println("Listing unread message(s).");
  Serial.println(gsm.smsListUnread()); // if not unread messages have it returns "NO_SMS"

  Serial.println("Read SMS on index no = 1");
  Serial.println(gsm.smsRead(1)); // if no message in that index, it returns INDEX_NO_ERROR
  
}

void loop() {
  // put your main code here, to run repeatedly:
}


And here's file GSMSim_TemplateSerial.h quick mod of your class, you might simply call it GSMSim2 instead of GSMSim_TemplateSerial (it also contains what was in the .cpp file, but please see the note I left where that part begins).

Again: this class does not inherit from SoftwareSerial, this breaks compatibility, you would have to put all ongoing minor fixes into GSMSim, make one final official release, and then leave it and create the new GSMSim2 library, other developers did that with their libraries, leaving both the old and the new one available).

Please just let me know if you want me to e-mail you both files.

[EDIT: sorry I see that here some indent problems appear, I'm seeing it differently in GEdit.]

/*  Orig lib GSMSim, let's see if we can also use it with a preexistent instance of HardwareSerial instead of inheriting from SoftwareSerial.
    Quick mod by Nicola "JazzTp" Bernardelli
    STM32F103C8T6 board with Roger Clark's core https://github.com/rogerclarkmelbourne/Arduino_STM32
    NOTICE: only tested sending SMS and dialing a number, so far.
*/

/*
	GSMSim_TemplateSerial Library

	This library written for SIMCOM Sim800L module. Library may worked on any SIMCOM modules
	and GSM Shields.

	Created 11.05.2017
	By Erdem ARSLAN
	Modified 25.08.2017

	Erdem ARSLAN
	Science and Technology Teacher, an Arduino Lover =)
	[email protected]
	https://www.erdemarslan.com/
	http://www.robothane.net/
	http://www.eralabs.net/

*/


#ifndef GSMSim_TemplateSerial_h
#define GSMSim_TemplateSerial_h
// #include <SoftwareSerial.h>
#include "Arduino.h"



// DEFAULT PIN DEFINATIONS IN HERE
// #define DEFAULT_RX_PIN 7
// #define DEFAULT_TX_PIN 8
// #define DEFAULT_RST_PIN 2

// #define DEFAULT_LED_FLAG true
// #define DEFAULT_LED_PIN 13
// #define DEFAULT_LED_PIN 32

#define DEFAULT_BAUD_RATE 9600
#define BUFFER_RESERVE_MEMORY	255
#define TIME_OUT_READ_SERIAL	5000


// PIN (PERSONAL IDENTIFICATION NUMBER) STATUS
#define PIN_READY 0
#define SIM_PIN 1
#define SIM_PUK 2
#define PH_SIM_PIN 3
#define PH_SIM_PUK 4
#define SIM_PIN2 5
#define SIM_PUK2 6
#define PIN_STATUS_UNKNOWN 7

// CALL STATUS
#define READY 0
#define UNKNOWN 2
#define RINGING 3
#define IN_CALL 4
#define NOT_READ 99


// CLASS BEGIN IN HERE
template <class HWorSW_Serial> class GSMSim_TemplateSerial /* : public SoftwareSerial nope, we want to be able to work with pre-instantiated objects */
{
	private:  /* consider changing to protected! */
    HWorSW_Serial& serialManager;

		uint32_t _baud;
		uint8_t _timeout;
		String _buffer;
		String _readSerial();
		String _readSerial(uint32_t timeout);

		uint8_t RESET_PIN;

	public:
    /*
		uint8_t	RX_PIN;
		uint8_t TX_PIN;
		uint8_t RESET_PIN;
		uint8_t LED_PIN;
		bool	LED_FLAG;
		uint32_t BAUDRATE;
    */


		GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t _RESET_PIN);
    /*
		GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t _RESET_PIN, uint8_t rx, uint8_t tx);
		GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t _RESET_PIN, uint8_t rx, uint8_t tx, uint8_t rst);
		GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t _RESET_PIN, uint8_t rx, uint8_t tx, uint8_t rst, uint8_t led);
		GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t _RESET_PIN, uint8_t rx, uint8_t tx, uint8_t rst, uint8_t led, bool ledflag);
    */

		// Başlatıcı Fonksiyon
		void start();
		void start(uint32_t baud);
		// Reset Fonksiyonu
		void reset();

		// Kontrol Metotları

		// Telefon Fonksiyonunu ayarlar
		bool setPhoneFunc(uint8_t level);
		// Sinyal kalitesi
		uint8_t signalQuality();
		// Operatöre bağlı mı?
		bool isRegistered();
		// Sim kart takılımı
		bool isSimInserted();
		// pin durumu
		uint8_t pinStatus();
		// operatör adı
		String operatorName();
		// sim karttaki operatör adı
		String operatorNameFromSim();
		// telefon durumu
		uint8_t phoneStatus();
		// echo kapalı
		bool echoOff();
		// echo açıkı
		bool echoOn();
		// modül üreticisi
		String moduleManufacturer();
		// modül modeli
		String moduleModel();
		// modül revizyon
		String moduleRevision();
		// modül imei
		String moduleIMEI();
		// modül imei değiştirme
		bool moduleIMEIChange(const char* imeino);
		// modül sim no
		String moduleIMSI();
		// modül sim operatör no
		String moduleICCID();
		// zil volümü
		uint8_t ringerVolume();
		// zil seviyesini ayarlar
		bool setRingerVolume(uint8_t level);
		// speaker düzeyi
		uint8_t speakerVolume();
		// speaker düzeyini ayarla
		bool setSpeakerVolume(uint8_t level);
		// debug modu - verbose mode
		String moduleDebug();





		// Arama Fonksiyonları
		// arama yapar
		bool call(const char* phone_number);
		// arama cevaplar
		bool callAnswer();
		// aramayı sonlandırır
		bool callHangoff();
		// arama durumu
		uint8_t callStatus();
		// COLP u aktif veya pasif yapar
		bool callSetCOLP(bool active);
		// COLP aktif mi?
		bool callIsCOLPActive();
		// Arayanı söyleme aktif mi değil mi?
		bool callActivateListCurrent(bool active);
		// şimdi arayanı söyle
		String callReadCurrentCall(String serialRaw);


		// SMS Fonksiyonları
		// sms i text yada pdu moda döndürür
		bool smsTextMode(bool textModeON);
		// sms gönderir
		bool smsSend(const char* number, const char* message);
		// okunmamış mesaj listesi
		String smsListUnread();
		// indexi verilen mesajı oku
		String smsRead(uint8_t index);
		// indexi verilen mesajı oku
		String smsRead(uint8_t index, bool markRead);
		// serialden direk mesajı oku -> serialden gelen veri verilmeli
		String smsReadFromSerial(String serialRaw);
		// serialden gelen sms bilgisinin indexini ver
		uint8_t smsIndexFromSerial(String serialRaw);
		// mesaj merkezini öğren
		String smsReadMessageCenter();
		// mesaj merkezini değiştir
		bool smsChangeMessageCenter(const char* messageCenter);
		// mesajı sil
		bool smsDeleteOne(uint8_t index);
		// tüm okunmuşları sil
		bool smsDeleteAllRead();
		// tüm mesajları sil
		bool smsDeleteAll();


		// DTMF Fonksiyonları
		// DTMF yi ayarlar
		bool dtmfSet(bool active, uint8_t interval, bool reportTime, bool soundDetect);
		// DTMF yi serialden okur!
		String dtmfRead(String serialRaw);


		// USSD Kodları
		// USSD kodu gönderir
		bool ussdSend(const char* code);
		// Raw datadan cevabı okur!
		String ussdRead(String serialRaw);

		// Radyo Kodları
		bool fmOpen();
		bool fmOpen(bool mainChannel);
		bool fmOpen(bool mainChannel, int freq);
		bool fmIsOpened();
		bool fmClose();
		uint8_t fmGetFreq();
		bool fmSetFreq(int freq);
		uint8_t fmGetVolume();
		bool fmSetVolume(int volume);

		// GPRS Kodları
		// Connect to Bearer
		bool gprsConnectBearer();
		//String gprsConnectBearerT();
		bool gprsConnectBearer(String apn);
		bool gprsConnectBearer(String apn, String user, String password);

		// Check connection
		bool gprsIsConnected();
		// get ip address
		String gprsGetIP();
		// close gprs bearer connection
		bool gprsCloseConn();
		String gprsHTTPGet(String url);
		String gprsHTTPGet(String url, bool read);


		// NTP Komutları
		bool timeSetServer(int timezone);
		bool timeSetServer(int timezone, String server);
		String timeSyncFromServer();
		String timeGetRaw();
		void timeGet(int *day, int *month, int *year, int *hour, int *minute, int *second);

		// Email Komutları
		bool emailSMTPConf(String server, String port, bool useSSL);
		bool emailSMTPAuth(String username, String password);
		bool emailSMTPAuth(String username, String password, bool requireAuth);
		bool emailSMTPGmail(String username, String password);
		String emailSMTPWrite(String from, String to, String title, String message);
		String emailSMTPWrite(String from, String to, String title, String message, String fromName, String toName);
		String emailSMTPSend();

};

//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================


/* What follows was inside "GSMSim_TemplateSerial.cpp" before changing this class into a template.
   If you really want to keep it in a .cpp file, this web page mentions a few possibilities:
   https://www.codeproject.com/Articles/48575/How-to-define-a-template-class-in-a-h-file-and-imp
*/


/*
	GSMSim_TemplateSerial Library

	This library written for SIMCOM Sim800L module. Library may worked on any SIMCOM modules
	and GSM Shields.

	Created 11.05.2017
	By Erdem ARSLAN
	Modified 30.08.2017

	Erdem ARSLAN
	Science and Technology Teacher, an Arduino Lover =)
	[email protected]
	https://www.erdemarslan.com/
	http://www.robothane.net/
	http://www.eralabs.net/

*/


#include "Arduino.h"
// #include "GSMSim_TemplateSerial.h"  the header includes this file

// #include <SoftwareSerial.h>

template <class HWorSW_Serial>
GSMSim_TemplateSerial<HWorSW_Serial>::GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t _RESET_PIN) /* : SoftwareSerial(DEFAULT_RX_PIN, DEFAULT_TX_PIN) */
  : serialManager(_serialManager), RESET_PIN(_RESET_PIN)
{
  /*
	RX_PIN = DEFAULT_RX_PIN;
	TX_PIN = DEFAULT_TX_PIN;
	RESET_PIN = DEFAULT_RST_PIN;
	LED_PIN = DEFAULT_LED_PIN;
	LED_FLAG = DEFAULT_LED_FLAG;
  */
}

/* ===================================================================

GSMSim_TemplateSerial<HWorSW_Serial>::GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t rx, uint8_t tx) /^ : SoftwareSerial(rx, tx) ^/
  : serialManager(_serialManager)
{
  /^
	RX_PIN = rx;
	TX_PIN = tx;
	RESET_PIN = DEFAULT_RST_PIN;
	LED_PIN = DEFAULT_LED_PIN;
	LED_FLAG = DEFAULT_LED_FLAG;
  ^/
}


GSMSim_TemplateSerial<HWorSW_Serial>::GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t rx, uint8_t tx, uint8_t rst) /^ : SoftwareSerial(rx, tx) ^/
  : serialManager(_serialManager)
{
  /^
	RX_PIN = rx;
	TX_PIN = tx;
	RESET_PIN = rst;
	LED_PIN = DEFAULT_LED_PIN;
	LED_FLAG = DEFAULT_LED_FLAG;
  ^/
}


GSMSim_TemplateSerial<HWorSW_Serial>::GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t rx, uint8_t tx, uint8_t rst, uint8_t led) /^ : SoftwareSerial(rx, tx) ^/
  : serialManager(_serialManager)
{
  /^
	RX_PIN = rx;
	TX_PIN = tx;
	RESET_PIN = rst;
	LED_PIN = led;
	LED_FLAG = DEFAULT_LED_FLAG;
  ^/
}


GSMSim_TemplateSerial<HWorSW_Serial>::GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t rx, uint8_t tx, uint8_t rst, uint8_t led, bool ledflag) /^ : SoftwareSerial(rx, tx) ^/
  : serialManager(_serialManager)
{
  /^
	RX_PIN = rx;
	TX_PIN = tx;
	RESET_PIN = rst;
	LED_PIN = led;
	LED_FLAG = ledflag;
  ^/
}
=================================================================== */



// Start GSMSim_TemplateSerial
template <class HWorSW_Serial>
void GSMSim_TemplateSerial<HWorSW_Serial>::start() {
	pinMode(RESET_PIN, OUTPUT);
	digitalWrite(RESET_PIN, HIGH);

	_baud = DEFAULT_BAUD_RATE;

	serialManager.begin(_baud);

  /*
	if (LED_FLAG) {
		pinMode(LED_PIN, OUTPUT);
	}
  */

	_buffer.reserve(BUFFER_RESERVE_MEMORY);
}


template <class HWorSW_Serial>
void GSMSim_TemplateSerial<HWorSW_Serial>::start(uint32_t baud) {
	pinMode(RESET_PIN, OUTPUT);
	digitalWrite(RESET_PIN, HIGH);

	_baud = baud;

	serialManager.begin(_baud);

  /*
	if (LED_FLAG) {
		pinMode(LED_PIN, OUTPUT);
	}
  */

	_buffer.reserve(BUFFER_RESERVE_MEMORY);
}


// Reset GMS Module
template <class HWorSW_Serial>
void GSMSim_TemplateSerial<HWorSW_Serial>::reset() {
  /*
	if (LED_FLAG) {
		digitalWrite(LED_PIN, HIGH);
	}
  */

	digitalWrite(RESET_PIN, LOW);
	delay(1000);
	digitalWrite(RESET_PIN, HIGH);
	delay(1000);

	// Modul kendine geldi mi onu bekle
	serialManager.print(F("AT\r"));
	while (_readSerial().indexOf("OK") == -1) {
		serialManager.print(F("AT\r"));
	}
  /*
	if (LED_FLAG) {
		digitalWrite(LED_PIN, LOW);
	}
  */
}


// SET PHONE FUNC
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::setPhoneFunc(uint8_t level = 1) {
	if(level != 0 || level != 1 || level != 4) {
		return false;
	}
	else {
		serialManager.print(F("AT+CFUN="));
		serialManager.print(String(level));
		serialManager.print(F("\r"));

		_buffer = _readSerial();
		if( (_buffer.indexOf("OK") ) != -1)  {
			return true;
		}
		else {
			return false;
		}
	}
}


// SIGNAL QUALTY - 0-31 | 0-> poor | 31 - Full | 99 -> Unknown
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::signalQuality() {
	serialManager.print(F("AT+CSQ\r"));
	_buffer = _readSerial();

	if((_buffer.indexOf("+CSQ:")) != -1) {
		return _buffer.substring(_buffer.indexOf("+CSQ: ")+6, _buffer.indexOf(",")).toInt();
	} else {
		return 99;
	}
}


// IS Module connected to the operator?
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::isRegistered() {
	serialManager.print(F("AT+CREG?\r"));
	_buffer = _readSerial();

	if( (_buffer.indexOf("+CREG: 0,1")) != -1 || (_buffer.indexOf("+CREG: 0,5")) != -1 || (_buffer.indexOf("+CREG: 1,1")) != -1 || (_buffer.indexOf("+CREG: 1,5")) != -1) {
		return true;
	} else {
		return false;
	}
}


// IS SIM Inserted?
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::isSimInserted() {
	serialManager.print(F("AT+CSMINS?\r"));
	_buffer = _readSerial();
	if(_buffer.indexOf(",") != -1) {
		// bölelim
		String veri = _buffer.substring(_buffer.indexOf(","), _buffer.indexOf("OK"));
		veri.trim();
		if(veri == "1") {
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
}


// Pin statüsü - AT+CPIN?
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::pinStatus() {
	serialManager.print(F("AT+CPIN?\r"));
	_buffer = _readSerial();

	if(_buffer.indexOf("READY") != -1)
	{
		return 0;
	}
	else if(_buffer.indexOf("SIM PIN") != -1)
	{
		return 1;
	}
	else if(_buffer.indexOf("SIM PUK") != -1)
	{
		return 2;
	}
	else if(_buffer.indexOf("PH_SIM PIN") != -1)
	{
		return 3;
	}
	else if(_buffer.indexOf("PH_SIM PUK") != -1)
	{
		return 4;
	}
	else if(_buffer.indexOf("SIM PIN2") != -1)
	{
		return 5;
	}
	else if(_buffer.indexOf("SIM PUK2") != -1)
	{
		return 6;
	}
	else {
		return 7;
	}
}


// OPERATOR NAME
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::operatorName() {
	serialManager.print(F("AT+COPS?\r"));
	_buffer = _readSerial();

	if(_buffer.indexOf(",") == -1) {
		return "NOT CONNECTED";
	}
	else {
		 return _buffer.substring(_buffer.indexOf(",\"")+2, _buffer.lastIndexOf("\""));
	}
}


// OPERATOR NAME FROM SIM
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::operatorNameFromSim() {
	serialManager.flush();
	serialManager.print(F("AT+CSPN?\r"));
	_buffer = _readSerial();
	delay(250);
	_buffer = _readSerial();
	/*
	return _buffer;
	*/
	if(_buffer.indexOf("OK") != -1) {
		return _buffer.substring(_buffer.indexOf(" \"") + 2, _buffer.lastIndexOf("\""));
	}
	else {
		return "NOT CONNECTED";
	}

}


// PHONE STATUS
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::phoneStatus() {
	serialManager.print(F("AT+CPAS\r"));
	_buffer = _readSerial();

	if((_buffer.indexOf("+CPAS: ")) != -1)
	{
		return _buffer.substring(_buffer.indexOf("+CPAS: ")+7,_buffer.indexOf("+CPAS: ")+9).toInt();
	}
	else {
		return 99; // not read from module
	}
}


// ECHO OFF
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::echoOff() {
	serialManager.print(F("ATE0\r"));
	_buffer = _readSerial();
	if ( (_buffer.indexOf("OK") )!=-1 ) {
   		return true;
   }
   else {
   	return false;
   }
}


// ECHO ON
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::echoOn() {
	serialManager.print(F("ATE1\r"));
	_buffer = _readSerial();
	if ( (_buffer.indexOf("OK") )!=-1 ) {
   		return true;
   }
   else {
   	return false;
   }
}


// Modül Üreticisi
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::moduleManufacturer() {
	serialManager.print(F("AT+CGMI\r"));
	_buffer = _readSerial();
	String veri = _buffer.substring(8, _buffer.indexOf("OK"));
	veri.trim();
	veri.replace("_", " ");
	return veri;
}


// Modül Modeli
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::moduleModel() {
	serialManager.print(F("AT+CGMM\r"));
	_buffer = _readSerial();

	String veri = _buffer.substring(8, _buffer.indexOf("OK"));
	veri.trim();
	veri.replace("_", " ");
	return veri;
}


// Modül Revizyonu
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::moduleRevision() {
	serialManager.print(F("AT+CGMR\r"));
	_buffer = _readSerial();

	String veri = _buffer.substring(_buffer.indexOf(":")+1 , _buffer.indexOf("OK"));
	veri.trim();
	return veri;
}


// Modülün IMEI numarası
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::moduleIMEI() {
	serialManager.print(F("AT+CGSN\r"));
	_buffer = _readSerial();

	String veri = _buffer.substring(8, _buffer.indexOf("OK"));
	veri.trim();
	return veri;
}


// Modülün IMEI Numarasını değiştirir.
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::moduleIMEIChange(const char* imeino) {
	return true;
}


// Modülün SIM Numarası
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::moduleIMSI() {
	serialManager.print(F("AT+CIMI\r"));
	_buffer = _readSerial();

	String veri = _buffer.substring(8, _buffer.indexOf("OK"));
	veri.trim();
	return veri;
}


// Sim Kart Seri Numarası
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::moduleICCID() {
	serialManager.print(F("AT+CCID\r"));
	_buffer = _readSerial();

	String veri = _buffer.substring(8, _buffer.indexOf("OK"));
	veri.trim();

	return veri;
}


// Çalma Sesi
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::ringerVolume() {
	serialManager.print(F("AT+CRSL?\r"));
	_buffer = _readSerial();

	String veri = _buffer.substring(7, _buffer.indexOf("OK"));
	veri.trim();

	return veri.toInt();
}


// Çalma sesini ayarla
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::setRingerVolume(uint8_t level) {
	if(level > 100) {
		level = 100;
	}

	serialManager.print(F("AT+CRSL="));
	serialManager.print(level);
	serialManager.print(F("\r"));
	_buffer = _readSerial();

	if(_buffer.indexOf("OK") != -1) {
		return true;
	} else {
		return false;
	}
}


// Hoparlör sesi
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::speakerVolume() {
	serialManager.print(F("AT+CLVL?\r"));
	_buffer = _readSerial();

	String veri = _buffer.substring(7, _buffer.indexOf("OK"));
	veri.trim();

	return veri.toInt();
}


// Hoparlör sesini ayarla
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::setSpeakerVolume(uint8_t level) {
	if(level > 100) {
		level = 100;
	}

	serialManager.print(F("AT+CLVL="));
	serialManager.print(level);
	serialManager.print(F("\r"));

	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {
		return true;
	}
	else {
		return false;
	}
}


template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::moduleDebug() {
	serialManager.print(F("AT&V\r"));

	return _readSerial();
}


//////////////////////////////////////
//			CALL	SECTION			//
//////////////////////////////////////

// Arama Yapar
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::call(const char* phone_number) {

	bool sorgulamaYapma = callIsCOLPActive();
	_buffer = _readSerial();
	delay(100);

	serialManager.print(F("ATD+ "));  /* ATDnumber; => NO DIALTONE, ATD+ works, for instance ATD+ +541198765432; seen here https://lastminuteengineers.com/sim800l-gsm-module-arduino-tutorial/ NOTICE that it is not mentioned in SIM800_Series_AT_Command_Manual_V1.09.pdf */
	serialManager.print(phone_number);
	serialManager.print(";\r");

	if (sorgulamaYapma) {
		return true;
	}
	else {
		_buffer = _readSerial();

		if (_buffer.indexOf("OK") != -1)
		{
			return true;
		}
		else {
			return false;
		}
	}
}


// Gelen aramayı cevaplar
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::callAnswer() {
	serialManager.print(F("ATA\r"));

	_buffer = _readSerial();

  return (_buffer.indexOf("OK") != -1);
  /*
	if (_buffer.indexOf("OK") != -1)
	{
		return true;
	}
	else {
		return false;
	}
  */
}


// Aramayı reddeder veya görüşmeyi sonlandırır!
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::callHangoff() {
	serialManager.print(F("ATH\r"));
	_buffer = _readSerial();

  return (_buffer.indexOf("OK") != -1);
  /*
	if (_buffer.indexOf("OK") != -1)
	{
		return true;
	} else {
		return false;
	}
  */
}


// Arama durumunu belirtir
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::callStatus() {
	/*
		values of return:
		0 Ready (MT allows commands from TA/TE)
		2 Unknown (MT is not guaranteed to respond to tructions)
		3 Ringing (MT is ready for commands from TA/TE, but the ringer is active)
		4 Call in progress
	*/
	serialManager.print(F("AT+CPAS\r"));
	_buffer = _readSerial();
	return _buffer.substring(_buffer.indexOf("+CPAS: ") + 7, _buffer.indexOf("+CPAS: ") + 9).toInt();
}


// Connected Line Identification aktif veya kapalı
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::callSetCOLP(bool active) {
	int durum = active == true ? 1 : 0;
	serialManager.print(F("AT+COLP="));
	serialManager.print(durum);
	serialManager.print("\r");

	_buffer = _readSerial();

  return (_buffer.indexOf("OK") != -1);
}


// COLP Aktif mi değil mi?
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::callIsCOLPActive() {
	serialManager.print("AT+COLP?\r");
	_buffer = _readSerial();

	return (_buffer.indexOf("+COLP: 1") != -1);
}


// Arayanı söyleme aktif mi değil mi?
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::callActivateListCurrent(bool active) {
	int durum = active == true ? 1 : 0;
	serialManager.print(F("AT+CLCC="));
	serialManager.print(durum);
	serialManager.print("\r");

	_buffer = _readSerial();

	return (_buffer.indexOf("OK") != -1);
}


// şimdi arayanı söyle
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::callReadCurrentCall(String serialRaw) {

	String sonuc = "";
	if (serialRaw.indexOf("+CLCC:") != -1) {
		String durum = serialRaw.substring(11,13);
		String numara = serialRaw.substring(18, serialRaw.indexOf("\","));

		if (durum == "0") {
			durum = "STATUS:ACTIVE"; // Görüşme var
		}
		else if (durum == "1") {
			durum = "STATUS:HELD";
		}
		else if (durum == "2") {
			durum = "STATUS:DIALING"; // Çevriliyor
		}
		else if (durum == "3") {
			durum = "STATUS:ALERTING"; // Çalıyor
		}
		else if (durum == "4") {
			durum = "STATUS:INCOMING"; // Gelen arama
		}
		else if (durum == "5") {
			durum = "STATUS:WAITING"; // gelen arama bekliyor
		}
		else if (durum == "6") {
			durum = "STATUS:DISCONNECT"; // görüşme bitti
		}

		sonuc = durum + "|NUMBER:" + numara;
	}

	return sonuc;
}


//////////////////////////////////////
//			MESAJ BÖLÜMÜ			//
//////////////////////////////////////

// SMS i TEXT ya da PDU moduna alır.
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::smsTextMode(bool textModeON) {
	if (textModeON == true) {
		serialManager.print(F("AT+CMGF=1\r"));
	}
	else {
		serialManager.print(F("AT+CMGF=0\r"));
	}
	bool sonuc = false;
	_buffer = _readSerial();
	if (_buffer.indexOf("OK") != -1) {
		sonuc = true;
	}

	return sonuc;
}


// verilen numara ve mesajı gönderir!
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::smsSend(const char* number, const char* message) {
	serialManager.print(F("AT+CMGS=\""));  // command to send sms
	serialManager.print(number);
	serialManager.print(F("\"\r"));
	_buffer = _readSerial();
	serialManager.print(message);
	serialManager.print("\r");
	//change delay 100 to readserial
	_buffer += _readSerial();
	serialManager.print((char)26);

	_buffer += _readSerial();
	//expect CMGS:xxx   , where xxx is a number,for the sending sms.
	/*
	return _buffer;
	*/
	if (((_buffer.indexOf("AT+CMGS")) != -1)) {
		return true;
	}
	else {
		return false;
	}
}


// Belirtilen klasördeki smslerin indexlerini listeler!
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::smsListUnread() {

	serialManager.print(F("AT+CMGL=\"REC UNREAD\",1\r"));

	_buffer = _readSerial();

	String donus = "";

	if (_buffer.indexOf("ERROR") != -1) {
		donus = "ERROR";
	}


	if (_buffer.indexOf("+CMGL:") != -1) {

		String veri = _buffer;
		bool islem = false;
		donus = "";

		while (!islem) {
			if (veri.indexOf("+CMGL:") == -1) {
				islem = true;
				continue;
			}

			veri = veri.substring(veri.indexOf("+CMGL: ") + 7);
			String metin = veri.substring(0, veri.indexOf(","));
			metin.trim();

			if (donus == "") {
				donus += "SMSIndexNo:";
				donus += metin;
			}
			else {
				donus += ",";
				donus += metin;
			}

		}

	}
	else {
		if (donus != "ERROR") {
			donus = "NO_SMS";
		}
	}

	return donus;
}


// Indexi verilen mesajı okur. Anlaşılır hale getirir!
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::smsRead(uint8_t index) {
	serialManager.print("AT+CMGR=");
	serialManager.print(index);
	serialManager.print(",0\r");

	_buffer = _readSerial();

	String durum = "INDEX_NO_ERROR";

	if (_buffer.indexOf("+CMGR:") != -1) {

		String klasor, okundumu, telno, zaman, mesaj;

		klasor = "UNKNOWN";
		okundumu = "UNKNOWN";

		if (_buffer.indexOf("REC UNREAD") != -1) {
			klasor = "INCOMING";
			okundumu = "UNREAD";
		}
		if (_buffer.indexOf("REC READ") != -1) {
			klasor = "INCOMING";
			okundumu = "READ";
		}
		if (_buffer.indexOf("STO UNSENT") != -1) {
			klasor = "OUTGOING";
			okundumu = "UNSENT";
		}
		if (_buffer.indexOf("STO SENT") != -1) {
			klasor = "OUTGOING";
			okundumu = "SENT";
		}

		String telno_bol1 = _buffer.substring(_buffer.indexOf("\",\"") + 3);
		telno = telno_bol1.substring(0, telno_bol1.indexOf("\",\"")); // telefon numarası tamam

		String tarih_bol = telno_bol1.substring(telno_bol1.lastIndexOf("\",\"") + 3);

		zaman = tarih_bol.substring(0, tarih_bol.indexOf("\"")); // zamanı da aldık. Bir tek mesaj kaldı!

		mesaj = tarih_bol.substring(tarih_bol.indexOf("\"") + 1, tarih_bol.lastIndexOf("OK"));

		mesaj.trim();

		durum = "FOLDER:";
		durum += klasor;
		durum += "|STATUS:";
		durum += okundumu;
		durum += "|PHONENO:";
		durum += telno;
		durum += "|DATETIME:";
		durum += zaman;
		durum += "|MESSAGE:";
		durum += mesaj;
	}

	return durum;
}


// Indexi verilen mesajı okur. Anlaşılır hale getirir!
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::smsRead(uint8_t index, bool markRead) {
	serialManager.print("AT+CMGR=");
	serialManager.print(index);
	serialManager.print(",");
	if (markRead == true) {
		serialManager.print("0");
	}
	else {
		serialManager.print("1");
	}
	serialManager.print("\r");

	_buffer = _readSerial();

	String durum = "INDEX_NO_ERROR";

	if (_buffer.indexOf("+CMGR:") != -1) {

		String klasor, okundumu, telno, zaman, mesaj;

		klasor = "UNKNOWN";
		okundumu = "UNKNOWN";

		if (_buffer.indexOf("REC UNREAD") != -1) {
			klasor = "INCOMING";
			okundumu = "UNREAD";
		}
		if (_buffer.indexOf("REC READ") != -1) {
			klasor = "INCOMING";
			okundumu = "READ";
		}
		if (_buffer.indexOf("STO UNSENT") != -1) {
			klasor = "OUTGOING";
			okundumu = "UNSENT";
		}
		if (_buffer.indexOf("STO SENT") != -1) {
			klasor = "OUTGOING";
			okundumu = "SENT";
		}

		String telno_bol1 = _buffer.substring(_buffer.indexOf("\",\"") + 3);
		telno = telno_bol1.substring(0, telno_bol1.indexOf("\",\"")); // telefon numarası tamam

		String tarih_bol = telno_bol1.substring(telno_bol1.lastIndexOf("\",\"") + 3);

		zaman = tarih_bol.substring(0, tarih_bol.indexOf("\"")); // zamanı da aldık. Bir tek mesaj kaldı!

		mesaj = tarih_bol.substring(tarih_bol.indexOf("\"")+1, tarih_bol.lastIndexOf("OK"));

		mesaj.trim();

		durum = "FOLDER:";
		durum += klasor;
		durum += "|STATUS:";
		durum += okundumu;
		durum += "|PHONENO:";
		durum += telno;
		durum += "|DATETIME:";
		durum += zaman;
		durum += "|MESSAGE:";
		durum += mesaj;
	}

	return durum;
}


// Serialden Mesajı okur
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::smsReadFromSerial(String serialRaw) {
	if (serialRaw.indexOf("+CMTI:") != -1) {
		String numara = serialRaw.substring(serialRaw.indexOf("\",") + 2);
		int no = numara.toInt();

		return smsRead(no, true);
	}
	else {
		return "RAW_DATA_NOT_READ";
	}
}


// serialden mesajın indexini alır
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::smsIndexFromSerial(String serialRaw) {
	if (serialRaw.indexOf("+CMTI:") != -1) {
		String numara = serialRaw.substring(serialRaw.indexOf("\",") + 2);
		int no = numara.toInt();

		return no;
	}
	else {
		return -1;
	}
}


// mesaj merkez numasını getirir
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::smsReadMessageCenter() {
	serialManager.print("AT+CSCA?\r");
	_buffer = _readSerial();

	String sonuc = "";

	if (_buffer.indexOf("+CSCA:") != -1)
	{
		sonuc = _buffer.substring(_buffer.indexOf("+CSCA:")+8, _buffer.indexOf("\","));
	}

	return sonuc;
}


// mesaj merkez numarasını değiştirir
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::smsChangeMessageCenter(const char* messageCenter) {
	serialManager.print("AT+CSCA=\"");
	serialManager.print(messageCenter);
	serialManager.print("\"\r");

	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {
		return true;
	}
	else {
		return false;
	}
}


// tek bir mesajı siler
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::smsDeleteOne(uint8_t index) {
	serialManager.print(F("AT+CMGD="));
	serialManager.print(index);
	serialManager.print(F(",0\r"));

	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {
		return true;
	}
	else {
		return false;
	}

}


// Tüm okunmuş mesajlaarı siler. Fakat gidene dokunmaz
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::smsDeleteAllRead() {
	serialManager.print(F("AT+CMGD=1,1\r"));

	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {
		return true;
	}
	else {
		return false;
	}
}


// okunmuş okunmamış ne varsa siler
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::smsDeleteAll() {
	serialManager.print(F("AT+CMGD=1,4\r"));

	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {
		return true;
	}
	else {
		return false;
	}
}


//////////////////////////////////////
//			DTMF BÖLÜMÜ				//
//////////////////////////////////////

// DTMF yi ayarlar
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::dtmfSet(bool active, uint8_t interval, bool reportTime, bool soundDetect) {
	int mode = active == true ? 1 : 0;
	int rtime = reportTime == true ? 1 : 0;
	int ssdet = soundDetect == true ? 1 : 0;

	serialManager.print(F("AT+DDET="));
	serialManager.print(mode);
	serialManager.print(F(","));
	serialManager.print(interval);
	serialManager.print(F(","));
	serialManager.print(rtime);
	serialManager.print(F(","));
	serialManager.print(ssdet);
	serialManager.print(F("\r"));

	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {
		return true;
	}
	else {
		return false;
	}
}


// Serialden DTMF Yi okur ve karakter olarak geri döner!
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::dtmfRead(String serialRaw) {

	if (serialRaw.indexOf("+DTMF:") != -1) {
		//  var mı yok mu?
		String metin;
		if (serialRaw.indexOf(",") != -1) {
			metin = serialRaw.substring(7, serialRaw.indexOf(","));
		}
		else {
			metin = serialRaw.substring(7);
		}

		return metin;
	}
	else {
		return "?";
	}

}


//////////////////////////////////////
//			USSD SECTION			//
//////////////////////////////////////
// USSD kodu gönderir
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::ussdSend(const char* code) {
	serialManager.print(F("AT+CUSD=1,\""));
	serialManager.print(code);
	serialManager.print(F("\"\r"));

	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {
		return true;
	}
	else {
		return false;
	}
}
// Raw datadan cevabı okur!
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::ussdRead(String serialRaw) {
	if (serialRaw.indexOf("+CUSD:") != -1) {
		String metin = serialRaw.substring(serialRaw.indexOf(",\"") + 2, serialRaw.indexOf("\","));
		return metin;
	}
	else {
		return "NOT_USSD_RAW";
	}
}


//////////////////////////////////////
//			FM RADIO SECTION		//
//////////////////////////////////////

// SIM800L & SIM800H only

// FM RADIO Open
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::fmOpen() {
	serialManager.print(F("AT+FMOPEN=0\r"));
	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {
		return true;
	}
	else {
		return false;
	}
}


template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::fmOpen(bool mainChannel) {
	uint8_t channel = mainChannel == true ? 1 : 0;
	serialManager.print(F("AT+FMOPEN="));
	serialManager.print(channel);
	serialManager.print(F("\r"));

	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {
		return true;
	}
	else {
		return false;
	}
}


template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::fmOpen(bool mainChannel, int freq) {
	uint8_t channel = mainChannel == true ? 1 : 0;
  int frekans = 875;

	if (freq < 875) {
		frekans = 875;
	}
	else if (freq > 1080) {
		frekans = 1080;
	}


	serialManager.print(F("AT+FMOPEN="));
	serialManager.print(channel);
	serialManager.print(",");
	serialManager.print(frekans);
	serialManager.print(F("\r"));

	_buffer = _readSerial();

	return (_buffer.indexOf("OK") != -1);
}


// IS FM OPENED?
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::fmIsOpened() {
	serialManager.print(F("AT+FMOPEN?\r"));
	_buffer = _readSerial();

	return (_buffer.indexOf("+FMOPEN: 1") != -1);
}

// FM RADIO CLOSE
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::fmClose() {
	serialManager.print(F("AT+FMCLOSE\r"));
	_buffer = _readSerial();

	return (_buffer.indexOf("OK") != -1);
}


// GET FM RADIO FREQ
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::fmGetFreq() {
	serialManager.print(F("AT+FMFREQ?\r"));
	_buffer = _readSerial();

	if (_buffer.indexOf("+FMFREQ:") != -1) {
		String sonuc = _buffer.substring(_buffer.indexOf("+FMFREQ:")+8);
		sonuc.trim();
		return sonuc.toInt();
	}
	else {
		return 0;
	}
}

// SET FM RADIO FREQ
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::fmSetFreq(int freq) {
	serialManager.print(F("AT+FMFREQ="));
	int frekans = 875;
	if (freq < 875) {
		frekans = 875;
	}
	if (freq > 1080) {
		frekans = 1080;
	}
	serialManager.print(frekans);
	serialManager.print(F("\r"));

	_buffer = _readSerial();

	return (_buffer.indexOf("OK") != -1);
}

// GET FM RADIO FREQ
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::fmGetVolume() {
	serialManager.print(F("AT+FMVOLUME?\r"));
	_buffer = _readSerial();

	if (_buffer.indexOf("+FMVOLUME:") != -1) {
		String sonuc = _buffer.substring(_buffer.indexOf("+FMVOLUME:")+10);
		sonuc.trim();
		return sonuc.toInt();
	}
	else {
		return 0;
	}
}

// SET FM RADIO FREQ
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::fmSetVolume(int volume) {
	serialManager.print(F("AT+FMVOLUME="));
	uint8_t vol = 0;
	if (volume < 0) {
		vol = 0;
	}
	if (volume > 6) {
		vol = 6;
	}
	serialManager.print(vol);
	serialManager.print(F("\r"));

	_buffer = _readSerial();

	return (_buffer.indexOf("OK") != -1);
}


//////////////////////////////////////
//			GPRS METHODS			//
//////////////////////////////////////
// Connect to GPRS Bearer


template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::gprsConnectBearer() {
	serialManager.print(F("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"\r"));
	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {

		delay(100);
		serialManager.print(F("AT+SAPBR=3,1,\"APN\",\"internet\"\r"));
		_buffer = _readSerial();

		if (_buffer.indexOf("OK") != -1) {
			delay(100);

			serialManager.print(F("AT+SAPBR=3,1,\"USER\",\"\"\r"));
			_buffer = _readSerial();

			if (_buffer.indexOf("OK") != -1) {

				delay(100);

				serialManager.print(F("AT+SAPBR=3,1,\"PWD\",\"\"\r"));
				_buffer = _readSerial();

				if (_buffer.indexOf("OK") != -1) {

					delay(100);
					serialManager.print("AT+SAPBR=1,1\r");
					_buffer = _readSerial();
					delay(50);
					_buffer += _readSerial();
					if (_buffer.indexOf("OK") != -1) {

						serialManager.print("AT+SAPBR=2,1\r");
						_buffer = _readSerial();

						if (_buffer.indexOf("\"0.0.0.0\"") != -1 || _buffer.indexOf("ERR") != -1) {
							return false;
						}
						else {
							return true;
						}
					}
					else {
						return false;
					}

				}
				else {
					return false;
				}
			}
			else {
				return false;
			}
		}
		else {
			return false;
		}
	}
	else {
		return false;
	}
}


template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::gprsConnectBearer(String apn) {
	serialManager.print(F("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"\r"));
	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {

		delay(100);
		serialManager.print(F("AT+SAPBR=3,1,\"APN\",\""));
		serialManager.print(apn);
		serialManager.print(F("\"\r"));
		_buffer = _readSerial();

		if (_buffer.indexOf("OK") != -1) {
			delay(100);

			serialManager.print(F("AT+SAPBR=3,1,\"USER\",\"\"\r"));
			_buffer = _readSerial();

			if (_buffer.indexOf("OK") != -1) {

				delay(100);

				serialManager.print(F("AT+SAPBR=3,1,\"PWD\",\"\"\r"));
				_buffer = _readSerial();

				if (_buffer.indexOf("OK") != -1) {

					delay(100);
					serialManager.print("AT+SAPBR=1,1\r");
					_buffer = _readSerial();
					delay(50);
					_buffer += _readSerial();
					if (_buffer.indexOf("OK") != -1) {

						serialManager.print("AT+SAPBR=2,1\r");
						_buffer = _readSerial();

						if (_buffer.indexOf("\"0.0.0.0\"") != -1 || _buffer.indexOf("ERR") != -1) {
							return false;
						}
						else {
							return true;
						}
					}
					else {
						return false;
					}

				}
				else {
					return false;
				}
			}
			else {
				return false;
			}
		}
		else {
			return false;
		}
	}
	else {
		return false;
	}
}


template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::gprsConnectBearer(String apn, String user, String password) {
	serialManager.print(F("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"\r"));
	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {

		delay(100);
		serialManager.print(F("AT+SAPBR=3,1,\"APN\",\""));
		serialManager.print(apn);
		serialManager.print(F("\"\r"));
		_buffer = _readSerial();

		if (_buffer.indexOf("OK") != -1) {
			delay(100);

			serialManager.print(F("AT+SAPBR=3,1,\"USER\",\""));
			serialManager.print(user);
			serialManager.print(F("\"\r"));
			_buffer = _readSerial();

			if (_buffer.indexOf("OK") != -1) {

				delay(100);

				serialManager.print(F("AT+SAPBR=3,1,\"PWD\",\""));
				serialManager.print(password);
				serialManager.print(F("\"\r"));
				_buffer = _readSerial();

				if (_buffer.indexOf("OK") != -1) {

					delay(100);
					serialManager.print("AT+SAPBR=1,1\r");
					_buffer = _readSerial();
					delay(50);
					_buffer += _readSerial();
					if (_buffer.indexOf("OK") != -1) {

						serialManager.print("AT+SAPBR=2,1\r");
						_buffer = _readSerial();

						if (_buffer.indexOf("\"0.0.0.0\"") != -1 || _buffer.indexOf("ERR") != -1) {
							return false;
						}
						else {
							return true;
						}
					}
					else {
						return false;
					}

				}
				else {
					return false;
				}
			}
			else {
				return false;
			}
		}
		else {
			return false;
		}
	}
	else {
		return false;
	}
}


// Check is GPRS connected?
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::gprsIsConnected() {
	serialManager.print(F("AT+SAPBR=2,1\r"));
	_buffer = _readSerial();
	delay(50);
	_buffer += _readSerial();

	if (_buffer.indexOf("ERR") != -1 || _buffer.indexOf("\"0.0.0.0\"") != -1) {
		return false;
	}
	else {
		return true;
	}
}


// GET IP Address
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::gprsGetIP() {
	serialManager.print(F("AT+SAPBR=2,1\r\n"));
	_buffer = _readSerial();
	delay(50);
	_buffer += _readSerial();

	//return _buffer;

	if (_buffer.indexOf("ERR") != -1 || _buffer.indexOf("\"0.0.0.0\"") != -1) {
		return "ERROR:NO_IP";
	}
	else {
		if (_buffer.indexOf("+SAPBR:") != -1) {
			String veri = _buffer.substring(_buffer.indexOf(",\"")+2, _buffer.lastIndexOf("\""));
			veri.trim();
			return veri;
		}
		else {
			return "ERROR:NO_IP_FETCH";
		}
	}
}


template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::gprsCloseConn() {
	serialManager.print(F("AT+SAPBR=0,1\r"));
	_buffer = _readSerial();
	delay(50);
	_buffer = _readSerial();

	return (_buffer.indexOf("OK") != -1);
}

template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::gprsHTTPGet(String url) {
	if (gprsIsConnected()) {
		// Terminate http connection, if it opened before!
		serialManager.print(F("AT+HTTPTERM\r"));
		_buffer = _readSerial();

		serialManager.print(F("AT+HTTPINIT\r"));
		_buffer = _readSerial();
		if (_buffer.indexOf("OK") != -1) {
			serialManager.print(F("AT+HTTPPARA=\"CID\",1\r"));
			_buffer = _readSerial();
			if (_buffer.indexOf("OK") != -1) {
				serialManager.print(F("AT+HTTPPARA=\"URL\",\""));
				serialManager.print(url);
				serialManager.print("\"\r");
				_buffer = _readSerial();

				if (_buffer.indexOf("OK") != -1) {
					serialManager.print(F("AT+HTTPACTION=0\r"));
					_buffer = _readSerial();
					if (_buffer.indexOf("OK") != -1) {
						delay(100);
						_buffer = _readSerial(10000);
						if (_buffer.indexOf("+HTTPACTION: 0,") != -1) {
							String kod = _buffer.substring(_buffer.indexOf(",")+1, _buffer.lastIndexOf(","));
							String uzunluk = _buffer.substring(_buffer.lastIndexOf(",")+1);

							String sonuc = "METHOD:GET|HTTPCODE:";
							sonuc += kod;
							sonuc += "|LENGTH:";
							sonuc += uzunluk;

							// Bağlantıyı kapat!
							serialManager.print(F("AT+HTTPTERM\r"));
							_buffer = _readSerial();

							sonuc.trim();

							return sonuc;
						}
						else {
							return "HTTP_ACTION_READ_ERROR";
						}
					}
					else {
						return "HTTP_ACTION_ERROR";
					}
				}
				else {
					return "HTTP_PARAMETER_ERROR";
				}

			}
			else {
				return "HTTP_PARAMETER_ERROR";
			}
		}
		else {
			return "HTTP_INIT_ERROR";
		}
	}
	else {
		return "GPRS_NOT_CONNECTED";
	}
}


template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::gprsHTTPGet(String url, bool read) {
	if (gprsIsConnected()) {
		// Terminate http connection, if it opened before!
		serialManager.print(F("AT+HTTPTERM\r"));
		_buffer = _readSerial();

		serialManager.print(F("AT+HTTPINIT\r\n"));
		_buffer = _readSerial();

		//return _buffer;
		if (_buffer.indexOf("OK") != -1) {
			serialManager.print(F("AT+HTTPPARA=\"CID\",1\r"));
			_buffer = _readSerial();
			if (_buffer.indexOf("OK") != -1) {
				serialManager.print(F("AT+HTTPPARA=\"URL\",\""));
				serialManager.print(url);
				serialManager.print(F("\"\r"));
				_buffer = _readSerial();

				if (_buffer.indexOf("OK") != -1) {
					serialManager.print(F("AT+HTTPACTION=0\r"));
					_buffer = _readSerial();
					if (_buffer.indexOf("OK") != -1) {
						delay(100);
						_buffer = _readSerial(10000);
						if (_buffer.indexOf("+HTTPACTION: 0,") != -1) {
							String kod = _buffer.substring(_buffer.indexOf(",") + 1, _buffer.lastIndexOf(","));
							String uzunluk = _buffer.substring(_buffer.lastIndexOf(",") + 1);
							kod.trim();
							uzunluk.trim();

							serialManager.print(F("AT+HTTPREAD\r"));
							_buffer = _readSerial(10000);

							String okuma = "";

							if (_buffer.indexOf("+HTTPREAD:") != -1) {

								String kriter = "+HTTPREAD: " + uzunluk;
								String veri = _buffer.substring(_buffer.indexOf(kriter) + kriter.length(), _buffer.lastIndexOf("OK"));
								okuma = veri;
							}
							else {
								return "ERROR:HTTP_READ_ERROR";
							}

							String sonuc = "METHOD:GET|HTTPCODE:";
							sonuc += kod;
							sonuc += "|LENGTH:";
							sonuc += uzunluk;
							sonuc += "|DATA:";
							okuma.trim();
							sonuc += okuma;

							serialManager.print(F("AT+HTTPTERM\r"));
							_buffer = _readSerial();

							sonuc.trim();

							return sonuc;
						}
						else {
							return "ERROR:HTTP_ACTION_READ_ERROR";
						}
					}
					else {
						return "ERROR:HTTP_ACTION_ERROR";
					}
				}
				else {
					return "ERROR:HTTP_PARAMETER_ERROR";
				}

			}
			else {
				return "ERROR:HTTP_PARAMETER_ERROR";
			}
		}
		else {
			return "ERROR:HTTP_INIT_ERROR";
		}
	}
	else {
		return "ERROR:GPRS_NOT_CONNECTED";
	}
}


//////////////////////////////////////
//			TIME METHODS			//
//////////////////////////////////////

template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::timeSetServer(int timezone) {
	serialManager.print("AT+CNTPCID=1\r");
	_buffer = _readSerial();

	int zaman = 0;
	if (timezone <= -12) {
		zaman = -47;
	}
	if (timezone > 12) {
		zaman = 48;
	}
	if (timezone > -12 || timezone <= 12) {
		zaman = timezone * 4;
	}

	serialManager.print(F("AT+CNTP=\"202.120.2.101\","));
	serialManager.print(zaman);
	serialManager.print(F("\r"));

	_buffer = _readSerial();

	return (_buffer.indexOf("OK") != -1);
}


template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::timeSetServer(int timezone, String server) {
	serialManager.print("AT+CNTPCID=1\r");
	_buffer = _readSerial();

	int zaman = 0;
	if (timezone <= -12) {
		zaman = -47;
	}
	if (timezone > 12) {
		zaman = 48;
	}
	if (timezone > -12 || timezone <= 12) {
		zaman = timezone * 4;
	}

	serialManager.print(F("AT+CNTP=\""));
	serialManager.print(server);
	serialManager.print(F("\","));
	serialManager.print(zaman);
	serialManager.print(F("\r"));

	_buffer = _readSerial();

	return (_buffer.indexOf("OK") != -1);
}


template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::timeSyncFromServer() {

	serialManager.print(F("AT+CNTP\r"));
	_buffer = _readSerial();
	//delay(50);
	_buffer = _readSerial(20000);


	if (_buffer.indexOf("+CNTP:") != -1) {
		String kod = _buffer.substring(8);
		kod.trim();

		if (kod == "1") {
			return "TIME_SYNCHRONIZED_SUCCESS";
		}
		else if (kod == "61") {
			return "NETWORK_ERROR";
		}
		else if (kod == "62") {
			return "DNS_ERROR";
		}
		else if (kod == "63") {
			return "CONNECTION_ERROR";
		}
		else if (kod == "64") {
			return "SERVICE_RESPONSE_ERROR";
		}
		else if (kod == "65") {
			return "SERVICE_RESPONSE_TIMEOUT";
		}
		else {
			return "UNKNOWN_ERROR_" + kod;
		}
	}
	else {
		return "AT_COMMAND_ERROR";
		//return _buffer;
	}
}


template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::timeGetRaw() {
	serialManager.print("AT+CCLK?\r");
	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {
		String zaman = _buffer.substring(_buffer.indexOf("\"") + 1, _buffer.lastIndexOf("\""));
		return zaman;
	}
	else {
		return "ERROR:NOT_GET_DATETIME";
	}
}


template <class HWorSW_Serial>
void GSMSim_TemplateSerial<HWorSW_Serial>::timeGet(int *day, int *month, int *year, int *hour, int *minute, int *second) {
	serialManager.print("AT+CCLK?\r");
	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {
		_buffer = _buffer.substring(_buffer.indexOf("\"") + 1, _buffer.lastIndexOf("\"") - 1);
		*year = (_buffer.substring(0, 2).toInt()) + 2000;
		*month = _buffer.substring(3, 5).toInt();
		*day = _buffer.substring(6, 8).toInt();
		*hour = _buffer.substring(9, 11).toInt();
		*minute = _buffer.substring(12, 14).toInt();
		*second = _buffer.substring(15, 17).toInt();
	}
}


//////////////////////////////////////
//			EMAIL METHODS			//
//////////////////////////////////////

template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::emailSMTPConf(String server, String port, bool useSSL) {
	int ssl = useSSL == true ? 1 : 0;

	serialManager.print(F("AT+EMAILSSL="));
	serialManager.print(ssl);
	serialManager.print(F("\r"));
	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {

		serialManager.print(F("AT+EMAILCID=1\r"));
		_buffer = _readSerial();

		if (_buffer.indexOf("OK") != -1) {
			serialManager.print(F("AT+EMAILTO=30\r"));
			_buffer = _readSerial();

			if (_buffer.indexOf("OK") != -1) {
				serialManager.print(F("AT+SMTPSRV=\""));
				serialManager.print(server);
				serialManager.print(F("\",\""));
				serialManager.print(port);
				serialManager.print("\"\r");

				_buffer = _readSerial();

				if (_buffer.indexOf("OK") != -1) {
					return true;
				}
				else {
					return false;
				}
			}
			else {
				return false;
			}
		}
		else {
			return false;
		}
	}
	else {
		return false;
	}
}


template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::emailSMTPAuth(String username, String password) {
	serialManager.print(F("AT+SMTPAUTH=1,\""));
	serialManager.print(username);
	serialManager.print(F("\",\""));
	serialManager.print(password);
	serialManager.print(F("\"\r"));

	_buffer = _readSerial();
	if (_buffer.indexOf("OK") != -1) {
		return true;
	}
	else {
		return false;
	}
}


template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::emailSMTPAuth(String username, String password, bool requireAuth) {
	int auth = requireAuth == true ? 1 : 0;
	serialManager.print(F("AT+SMTPAUTH="));
	serialManager.print(auth);
	serialManager.print(F(",\""));
	serialManager.print(username);
	serialManager.print(F("\",\""));
	serialManager.print(password);
	serialManager.print(F("\"\r"));

	_buffer = _readSerial();
	return (_buffer.indexOf("OK") != -1);
}


template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::emailSMTPGmail(String username, String password) {
	bool conf = emailSMTPConf("smtp.gmail.com", "465", true);
	if (conf) {
		return emailSMTPAuth(username, password);
	}
	else {
		return false;
	}
}


template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::emailSMTPWrite(String from, String to, String title, String message) {

	serialManager.print(F("AT+SMTPFROM=\""));
	serialManager.print(from);
	serialManager.print("\"\r");
	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {

		serialManager.print("AT+SMTPRCPT=0\r");
		_buffer = _readSerial();
		delay(50);
		serialManager.print(F("AT+SMTPRCPT=0,1,\""));
		serialManager.print(to);
		serialManager.print("\"\r");
		_buffer = _readSerial();

		if (_buffer.indexOf("OK") != -1) {

			serialManager.print(F("AT+SMTPSUB=\""));
			serialManager.print(title);
			serialManager.print("\"\r");
			_buffer = _readSerial();

			if (_buffer.indexOf("OK") != -1) {

				uint8_t uzunluk = message.length();
				serialManager.print(F("AT+SMTPBODY="));
				serialManager.print(uzunluk);
				serialManager.print("\r");

				delay(50);

				serialManager.print(message);
				serialManager.print(F("\""));
				_buffer += _readSerial();

				if (_buffer.indexOf("OK") != -1) {

					return "OK";
				}
				else {
					return "ERROR:BODY_NOT_SET";
				}

			}
			else {
				return "ERROR:TITLE_NOT_SET";
			}
		}
		else {
			return "ERROR:TO_NOT_SET";
		}
	}
	else {
		return "ERROR:FROM_NOT_SET";
	}
}


template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::emailSMTPWrite(String from, String to, String title, String message, String fromName, String toName) {
	serialManager.print(F("AT+SMTPFROM=\""));
	serialManager.print(from);
	serialManager.print("\",\"");
	serialManager.print(fromName);
	serialManager.print("\"\r");
	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {

		serialManager.print("AT+SMTPRCPT=0\r");
		_buffer = _readSerial();
		delay(50);
		serialManager.print(F("AT+SMTPRCPT=0,1,\""));
		serialManager.print(to);
		serialManager.print("\",\"");
		serialManager.print(toName);
		serialManager.print("\"\r");
		_buffer = _readSerial();

		if (_buffer.indexOf("OK") != -1) {

			serialManager.print(F("AT+SMTPSUB=\""));
			serialManager.print(title);
			serialManager.print("\"\r");
			_buffer = _readSerial();

			if (_buffer.indexOf("OK") != -1) {

				uint8_t uzunluk = message.length();
				serialManager.print(F("AT+SMTPBODY="));
				serialManager.print(uzunluk);
				serialManager.print("\r");

				delay(50);

				serialManager.print(message);
				serialManager.print(F("\""));
				_buffer += _readSerial();

				if (_buffer.indexOf("OK") != -1) {

					return "OK";
				}
				else {
					return "ERROR:BODY_NOT_SET";
				}

			}
			else {
				return "ERROR:TITLE_NOT_SET";
			}
		}
		else {
			return "ERROR:TO_NOT_SET";
		}
	}
	else {
		return "ERROR:FROM_NOT_SET";
	}
}


template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::emailSMTPSend() {

	serialManager.print("AT+SMTPSEND\r");
	_buffer = _readSerial();

	if (_buffer.indexOf("OK") != -1) {
		delay(50);
		_buffer = _readSerial(30000);
		if (_buffer.indexOf("+SMTPSEND:") != -1) {
			String kod = _buffer.substring(12);
			kod.trim();

			if (kod == "1") {
				return "SUCCESS:EMAIL_SEND";
			}
			else if (kod == "61") {
				return "ERROR:NETWORK_ERROR";
			}
			else if (kod == "62") {
				return "ERROR:DNS_RESOLVE_ERROR";
			}
			else if (kod == "63") {
				return "ERROR:TCP_CONNECTION_ERROR";
			}
			else if (kod == "64") {
				return "ERROR:TIMEOUT_SMTP_RESPONSE";
			}
			else if (kod == "65") {
				return "ERROR:SMTP_RESPONSE_ERROR";
			}
			else if (kod == "66") {
				return "ERROR:NOT_AUTH";
			}
			else if (kod == "67") {
				return "ERROR:AUTH_FAILED";
			}
			else if (kod == "68") {
				return "ERROR:BAD_RECIPIENT";
			}
			else {
				return "ERROR:ERROR_NO_" + kod;
			}
		}
		else {
			delay(50);
			_buffer = _readSerial(30000);

			if (_buffer.indexOf("+SMTPSEND:") != -1) {
				String kod = _buffer.substring(12);
				kod.trim();

				if (kod == "1") {
					return "SUCCESS:EMAIL_SEND";
				}
				else if (kod == "61") {
					return "ERROR:NETWORK_ERROR";
				}
				else if (kod == "62") {
					return "ERROR:DNS_RESOLVE_ERROR";
				}
				else if (kod == "63") {
					return "ERROR:TCP_CONNECTION_ERROR";
				}
				else if (kod == "64") {
					return "ERROR:TIMEOUT_SMTP_RESPONSE";
				}
				else if (kod == "65") {
					return "ERROR:SMTP_RESPONSE_ERROR";
				}
				else if (kod == "66") {
					return "ERROR:NOT_AUTH";
				}
				else if (kod == "67") {
					return "ERROR:AUTH_FAILED";
				}
				else if (kod == "68") {
					return "ERROR:BAD_RECIPIENT";
				}
				else {
					return "ERROR:ERROR_NO_" + kod;
				}
			}
			else {
				return "ERROR:EMAIL_TIMEOUT_ERROR";
			}
		}
	}
	else {
		return "ERROR:EMAIL_SENDING_ERROR";
	}
}


//////////////////////////////////////
//			PRIVATE METHODS			//
//////////////////////////////////////

// READ FROM SERIAL
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::_readSerial() {

	uint64_t timeOld = millis();

	while (!serialManager.available() && !(millis() > timeOld + TIME_OUT_READ_SERIAL))
	{
		delay(13);
	}

	String str = "";

	while (serialManager.available())
	{
		if (serialManager.available())
		{
			str += (char) serialManager.read();
      /*     ^^^^^^ might be unnecessary    */
		}
	}

	return str;
}


template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::_readSerial(uint32_t timeout) {

	uint64_t timeOld = millis();

	while (!serialManager.available() && !(millis() > timeOld + timeout))
	{
		delay(13);
	}

	String str = "";

	while (serialManager.available())
	{
		if (serialManager.available())
		{
			str += (char) serialManager.read();
      /*     ^^^^^^ might be unnecessary    */
		}
	}

	return str;
}

#endif

All the best,
Nicola

Manually send AT commands

Hi,

I have tested some SIM800L EVB module (with blue PCB), if I use the library not work correctly, because it does not catch the signal by the carrier.

But if I use the AT command for manually catching the signal:

AT+COPS=?
+COPS: (2,"vodafone","voda IT","22210"),(1,"Wind Telecom SpA","I WIND","22288"),,(0-4),(0-2)

for listing all cell operator available and I manually set the operator:

AT+COPS=0,0,"I WIND"
OK

after this operations, I can send correctly SMS, or a call number, etc...

In your library exist some method for send manually AT+COPS commands?

Is this still being worked on ?

Hi, just wondering if this library is still being worked on ?

I would love to use this with the SIM7000G ( currently using the LiliyGo SIM7000G board ) but it crashes the board when I load it.
This might be something to do with the board but I thought I would ask if the SIM7000 was supported.

Thanks for your time and great work.

smsREAD not working

Hi,

I have been trying to use the SMSread function.
It always returns back index no error, however manual executing the +CMGR is working fine.
Is there any update

How to make a call to join a Zoom meeting

Hello,
Thanks for the library for the SIM900.
But I have a question and I hope you can help me.
I want to join a meeting at Zoom (https://zoom.us/) via the SIM900.
To do this I have to enter (paste) the following (in Android phone) to automatically call:

Phone Number+Pause(2 seconds)+MeetingID+#+Pause(4 seconds)+HostID+#+Pause(4 seconds)+Password+#
(MeetingID and Password as an example)
+31207946519,,83411719839#,,,,#,,,,*999999#

call(PHONE_NUMBER) does not connect.
Only accepts a phone number.

Any idea how I get that to work?
Thank you very much for the effort.
Sincerely,
Arie van den Berg

sms.deleteAll() and sms.deleteAllRead() not working, index not starting at 1 and SMS missing?

It seems both functions don't work or I'm doing it wrong:

Serial.println(sms.deleteAll()); and I see a 0 in the serial monitor.
If I delete an SMS using sms.deleteOne(idx); I get a 1 if the SMS with index exists.

While testing this lib I had received 2 SMS but their index was 21 and 22.
What about 0 to 20?
Before switching to this lib I was using just serial communication to do some tests with the SIM800L.
I already had received 2 more SMS before switching, but I don't see them with this lib.
Could it be that the lib uses a different memory location on the module compared to using a new module with just serial com?

Best regards,
Robert

Add function sim800

I want you to add a function to display the number of the incoming call.

"IncomingCall(char *number)"

Examples do not work

Hello there,
I noticed when using the examples - no matter which one I used, in every example I get the Error " 'Serial1' was not declared in this scope" and I'm quite new to Android, so I do not know, what that means.

However, I see nowhere a "Serial1" is defined in the whole class.
The error always points me to the Serial1 in the loop(). When removing Serial1 in the loop, it points me to the one in setup().

Kind Regards,
Kit

dtmf

Detection of DTMF tones - SIM800L module.

I get "OK" when I send 'AT+DDET=1,1000,1,1* ' over uart .
But it doesnt seem to detect anything afterwards.
Perhaps I am doing something wrong.
Would appreciate some feedback.

regards
Atul
ref : *SIM800 Series_AT Command Manual_V1.09

Can the library be used with pubsub or another mqtt client ?

Hello, great job for this library, it's the only one i play with which answer easily my basic needs: handle incoming call (get phone number), handle incoming sms (getting senderNo and message) and make https post.

But i want to add an mqtt features to my project and can't find a way to achieve it only with this library.

I use it with TinyGSM and Pubsub but since then i'm facing accidental complexity. I no longer systematically enter Serial1.available() in the loop() to process incoming calls or received messages. Sometimes TinyGSM handles it. For example, instead of +CLCC, I get RING or nothing. Other times, nothing happens.

The same goes for SMS. I think it's because i initialise both on the same rx and tx pinout

So does someone achieve to use gsmsim with an mqtt client please ? or perhaps ways to do it ?

Or rewrite if (Serial1.available()) part another way to manage this ?
Im using the lilygo tcall (sim800l and esp32 board)

questions: How To use string as sms message?

How can you use a string variable as sms message?

For example:

#define SMSNUMBER "+3xxxxxxxxxx"
String MESSAGE = "";   // depending on the reason is this filled with different text by the program/sketch/code

void loop() {
sms.send(SMSNUMBER, MESSAGE);
}

Tthis gives the fault message:

In function 'void SMSSend()': [Sketch]:[Line:Char]: error: no matching function for call to 
'GSMSimSMS::send(const char [13], String&)' sms.send(SMSNUMBER, MESSAGE);

When i remove the variable as message does the code compile correctly:

sms.send(SMSNUMBER, "Test Message");

This code also doesn't work:
sms.send(SMSNUMBER, "\""MESSAGE"\"");
fault message:

In function 'void SMSSend()': error: unable to find string literal operator 'operator""MESSAGE' with 'const char [3]', 'unsigned int' arguments
     sms.send(SMSNUMBER, "\""MESSAGE"\"");```

Code is quite hard to read.

I am currently trying to add functionality to parts of you library. Doing that, i constantly run into endles if-else chains big enough for the code to go off the right side of my screen...
These almost always are just checking if something succeeded, and if not exiting the function with an error. This can be written more cleanly like this: if (notFoundOK()) return "ERROR";. If you are just planning to return an error, this has the same effect. As soon as a return is executed, the function exits and code following it will not be executed.

Here is an example:

GSMSimHTTP.cpp get(String) - original

String GSMSimHTTP::get(String url) {

	if (isConnected()) {
		// Terminate http connection, if it opened before! Otherwise method not run correctly.
		gsm.print(F("AT+HTTPTERM\r"));
		_readSerial();

		gsm.print(F("AT+HTTPINIT\r"));
		_readSerial();
		if (_buffer.indexOf(F("OK")) != -1) {
			gsm.print(F("AT+HTTPPARA=\"CID\",1\r"));
			_readSerial();
			if (_buffer.indexOf(F("OK")) != -1) {
				gsm.print(F("AT+HTTPPARA=\"URL\",\""));
				gsm.print(url);
				gsm.print("\"\r");
				_readSerial();

				if (_buffer.indexOf(F("OK")) != -1) {
					gsm.print(F("AT+HTTPACTION=0\r"));
					_readSerial();
					if (_buffer.indexOf(F("OK")) != -1) {
						_readSerial(10000);
						if (_buffer.indexOf(F("+HTTPACTION: 0,")) != -1) {
							String kod = _buffer.substring(_buffer.indexOf(F(","))+1, _buffer.lastIndexOf(F(",")));
							String uzunluk = _buffer.substring(_buffer.lastIndexOf(F(","))+1);

							String sonuc = "METHOD:GET|HTTPCODE:";
							sonuc += kod;
							sonuc += "|LENGTH:";
							sonuc += uzunluk;

							// Bağlantıyı kapat!
							gsm.print(F("AT+HTTPTERM\r"));
							_readSerial();

							sonuc.trim();

							return sonuc;
						}
						else {
							return "HTTP_ACTION_READ_ERROR";
						}
					}
					else {
						return "HTTP_ACTION_ERROR";
					}
				}
				else {
					return "HTTP_PARAMETER_ERROR";
				}

			}
			else {
				return "HTTP_PARAMETER_ERROR";
			}
		}
		else {
			return "HTTP_INIT_ERROR";
		}
	}
	else {
		return "GPRS_NOT_CONNECTED";
	}
}

GSMSimHTTP.cpp get(String) - modified

String GSMSimHTTP::get(String url) {
	if (!isConnected()) return "GPRS_NOT_CONNECTED";
	// Terminate http connection, if it opened before! Otherwise method not run correctly.
	gsm.print(F("AT+HTTPTERM\r"));
	_readSerial();

	gsm.print(F("AT+HTTPINIT\r"));
	_readSerial();

	if (_buffer.indexOf(F("OK")) != -1) return "HTTP_INIT_ERROR";
	gsm.print(F("AT+HTTPPARA=\"CID\",1\r"));
	_readSerial();
	if (_buffer.indexOf(F("OK")) == -1) return "HTTP_PARAMETER_ERROR";

	gsm.print(F("AT+HTTPPARA=\"URL\",\""));
	gsm.print(url);
	gsm.print("\"\r");
	_readSerial();
	if (_buffer.indexOf(F("OK")) == -1) return "HTTP_PARAMETER_ERROR";
	
	gsm.print(F("AT+HTTPACTION=0\r"));
	_readSerial();
	if (_buffer.indexOf(F("OK")) == -1) return "HTTP_ACTION_ERROR";
	
	_readSerial(30000);
	if (_buffer.indexOf(F("+HTTPACTION: 0,")) == -1) return "HTTP_ACTION_READ_ERROR";
	
	String kod = _buffer.substring(_buffer.indexOf(F(","))+1, _buffer.lastIndexOf(F(",")));
	String uzunluk = _buffer.substring(_buffer.lastIndexOf(F(","))+1);
	kod.trim();
	uzunluk.trim();
	
	String sonuc = "METHOD:GET|HTTPCODE:";
	sonuc += kod;
	sonuc += "|LENGTH:";
	sonuc += uzunluk;

	// Bağlantıyı kapat!
	gsm.print(F("AT+HTTPTERM\r"));
	_readSerial();

	sonuc.trim();

	return sonuc;
}

At least in my opinion, the modified version is much easier to understand. The error message follows right after the condition that could cause it.

You could also replace all checks for OK in the buffer with one global checkOKinBuffer() defined in GSMSim.h

All that does not seem too hard to automate. A python script could probably rearrange the code automatically.

Another thing: having multiple functions with nearly-identical code and (even worse) identical strings affects the code size quite significantly. see #52

How to set a APN

I am trying to set the APN but I get an error.

Serial.println(http.gprsInit("www.vodafone.net.nz","",""));

But I get the error

GSMSim_HTTP:91:58: error: invalid use of void expression Serial.println(http.gprsInit("www.vodafone.net.nz","",""));

With a chevron pointing to the bracket before the ;.

Seems like the syntax is correct?

Help. No way to send sms.

Hi! I tried to use your library but there is no way to send an sms

Here my code

`/*

Example Serial Output

Set Phone Function... 1
is Module Registered to Network?... 1
Signal Quality... 15
Operator Name... Turk Telekom
Init SMS... 1
List Unread SMS... SMSIndexNo:35,36
SMS to any number... 1
Begin to listen incoming messages...

  1. SMS Index No... 38
    Who send the message?...xxxxxxxxxxxx
    Read the message... FOLDER:INCOMING|STATUS:UNREAD|PHONENO:xxxxxxxxxxxx|DATETIME:20/05/07,16:00:21+12|MESSAGE:Ne olsun. Yazisiyoruz kendimizle ;)
    */

#include <GSMSimSMS.h>
#include <SoftwareSerial.h>

SoftwareSerial Serial1(8, 7); // RX, TX

// You can use any Serial interface. I recommended HardwareSerial. Please use the library with highiest baudrate.
// In examples, i used HardwareSerial. You can change it anymore.

#define RESET_PIN 10 // you can use any pin.

static volatile int num = 0;

GSMSimSMS sms(Serial1, RESET_PIN); // GSMSimSMS inherit from GSMSim. You can use GSMSim methods with it.

void setup() {
Serial1.begin(9600); // If you dont change module baudrate, it comes with auto baudrate.

while(!Serial1) {
; // wait for module for connect.
}

Serial.begin(9600); // Serial for debug...

// Init module...
sms.init(); // use for init module. Use it if you dont have any valid reason.

Serial.print("Set Phone Function... ");
Serial.println(sms.setPhoneFunc(1));
delay(1000);

Serial.print("is Module Registered to Network?... ");
Serial.println(sms.isRegistered());
delay(1000);

Serial.print("Signal Quality... ");
Serial.println(sms.signalQuality());
delay(1000);

Serial.print("Operator Name... ");
Serial.println(sms.operatorNameFromSim());
delay(1000);

Serial.print("Init SMS... ");
Serial.println(sms.initSMS()); // Its optional but highly recommended. Some function work with this function.
delay(1000);

Serial.print("List Unread SMS... ");
Serial.println(sms.list(true)); // Its optional but highly recommended. Some function work with this function.
delay(1000);

Serial.print("SMS to any number... ");
Serial.println(sms.send("+393661789628", "Selam kardesim, naber?")); // only use ascii chars please
delay(1000);

// For other methods please look at readme.txt file.

//Serial.println("Begin to listen incoming messages...");

}

void loop() {

// Use your Serial interface...
// if(Serial1.available()) {
// String buffer = "";
// buffer = Serial1.readString();
// num = num + 1;
// Serial.print(num);
// Serial.print(". ");
// //Serial.println(buffer);
//
// /**/
// // This example for how you catch incoming calls.
// if(buffer.indexOf("+CMTI:") != -1) {
//
// Serial.print("SMS Index No... ");
// int indexno = sms.indexFromSerial(buffer);
// Serial.println(indexno);
//
// Serial.print("Who send the message?...");
// Serial.println(sms.getSenderNo(indexno));
//
// Serial.print("Read the message... ");
// Serial.println(sms.readFromSerial(buffer));
// } else {
// Serial.println(buffer);
// }
//
// }

// put your main code here, to run repeatedly:
}`

Any help is pleased. Thanks

2 litte correction that worked for me

Hi, Im using the library at the moment, and I like it a lot but some commands didint work for me. Im using a SIM800L and a arduino pro min. I edited the library a bit and now the two funtions are working (isSimInserted() and setPhoneFunc(uint8_t level)).

Here are the two codes working, hope it helps some one else!

bool GSMSim::setPhoneFunc(uint8_t level) {
if(level == 0 || level == 1 || level == 4) {
this->print(F("AT+CFUN="));
this->print(String(level));
this->print(F("\r"));

	_buffer = _readSerial();
	if( (_buffer.indexOf("OK") ) != -1)  {
		return true;
	}
	else {
		return false;
	}
}
else {
	return false;
}

}

and

bool GSMSim::isSimInserted() {
this->print(F("AT+CSMINS?\r"));
_buffer = _readSerial();
if(_buffer.indexOf(",") != -1) {
// bölelim
if(_buffer.substring(_buffer.indexOf(",") + 1, _buffer.indexOf(",") + 2)) {
return true;
} else {
return false;
}
} else {
return false;
}
}

Why not POST request?

I want to have a post request to send some data. my question is why is "post" request not in the library. is it not supported on GSM?

Repeat calling

If I use more numbers to call, only first number is active.
Serial.println("Calling the number " + String(phone_no));
Serial.println(gsm.call(phone_no));
delay(10000);
Serial.println("Call hang off");
gsm.callHangoff();
delay(10000);

Serial.println("Calling the number " + String(phone_no));
Serial.println(gsm.call(phone_no));
delay(10000);
Serial.println("Call hang off");
gsm.callHangoff();

No posible to second call

_readSerial does not catch a reply

I'm running the SMS example on a sim800l from Amazon. Although it sends the SMS, something seems wrong with receiving the replies from the sent AT-commands.
(I modified the first 3 functions to return the _buffer instead, and it seems like the sim module is just echoing the commands?)

22:10:27.293 -> Set Phone Function... AT+CFUN=1
22:10:29.299 -> is Module Registered to Network?... AT+CREG?
22:10:31.306 -> Signal Quality... AT+CSQ
22:10:33.313 -> Operator Name... NOT CONNECTED
22:10:35.320 -> Init SMS... 0
22:10:37.321 -> List Unread SMS... NO_SMS
22:10:39.368 -> SMS to any number... 1
22:10:42.404 -> Begin to listen incoming messages...

I work with an Arduino Nano. It only has 1 serial connection so I tried different softwareserial, and outputting to a display. Always the same result. The slightly modified code (with softserial):

#include <AltSoftSerial.h>
#include <GSMSimSMS.h>

// You can use any Serial interface. I recommended HardwareSerial. Please use the library with highiest baudrate.
// In examples, i used HardwareSerial. You can change it anymore.

#define RESET_PIN 10 // you can use any pin.

static volatile int num = 0;

AltSoftSerial mySerial;
GSMSimSMS sms(mySerial, RESET_PIN); // GSMSimSMS inherit from GSMSim. You can use GSMSim methods with it.



void initSIM() {
  mySerial.begin(9600); // If you dont change module baudrate, it comes with auto baudrate.
  delay(1000);
/*
  while(!mySerial.available()) {
    ; // wait for module for connect.
  }
*/
  Serial.begin(9600); // Serial for debug...

  // Init module...
  sms.init(); // use for init module. Use it if you dont have any valid reason.

  Serial.print("Set Phone Function... ");
  Serial.println(sms.setPhoneFunc(1));
  delay(1000);

  Serial.print("is Module Registered to Network?... ");
  Serial.println(sms.isRegistered());
  delay(1000);

  Serial.print("Signal Quality... ");
  Serial.println(sms.signalQuality());
  delay(1000);

  Serial.print("Operator Name... ");
  Serial.println(sms.operatorNameFromSim());
  delay(1000);



  Serial.print("Init SMS... ");
  Serial.println(sms.initSMS()); // Its optional but highly recommended. Some function work with this function.
  delay(1000);

  Serial.print("List Unread SMS... ");
  Serial.println(sms.list(true)); // Its optional but highly recommended. Some function work with this function.
  delay(1000);

  
  Serial.print("SMS to any number... ");
  Serial.println(sms.send("0032123456789", "Selam kardesim, naber?")); // only use ascii chars please
  //delay(1000);

  // For other methods please look at readme.txt file.

  Serial.println("Begin to listen incoming messages...");

}
void loop() {
  char c;

  if (Serial.available()) {
    c = Serial.read();
    mySerial.print(c);
  }
  if (mySerial.available()) {
    c = mySerial.read();
    Serial.print(c);
  }
}

Wrong return value in send method

Hi Erdem,

first let me thank you for developing this lib. I want to use it to realize my sms gateway using the SIM800L on an ESP8266 arduino board.

I get a compile error on line 148:

GSMSim/src/GSMSimSMS.cpp

Lines 127 to 156 in 337a9c8

bool GSMSimSMS::send(char* number, char* message) {
String str = "";
gsm.print(F("AT+CMGS=\"")); // command to send sms
gsm.print(number);
gsm.print(F("\"\r"));
_readSerial();
str += _buffer;
gsm.print(message);
gsm.print("\r");
//change delay 100 to readserial
//_buffer += _readSerial();
_readSerial();
str += _buffer;
gsm.print((char)26);
//_buffer += _readSerial();
_readSerial();
str += _buffer;
//expect CMGS:xxx , where xxx is a number,for the sending sms.
return str;
/**/
if (str.indexOf("+CMGS:") != -1) {
return true;
}
else {
return false;
}
}

The defined return type of the send method is boolean. But you try to return a string. It looks like a unwanted copypaste...

best regards

Syntax command get by GSMSimTime

When i write
DateTime.get(int *day, int *month, int *year, int *hour, int *minute, int *second);
Become the Error
expected'(' for function-style cast ot type construction

Signal Strength

Show 99 only. Sim800c connect to operator. I think cmd not work.

Code-size could be reduced.

Many functions have largely identical code and even worse, identical strings.
See for example this: https://github.com/H3wastooshort/GSMSim/blob/76da58a0c74fd5ce6e5e3692303a7a767dd6e5c5/src/GSMSimHTTP.cpp#L42

Using enums instead of strings for return codes would be better because
a) it would be easier to code error checks (no comparing strings) and
b) it would save valuable space in flash
You could one std::map (not supported in plain arduino) or errorToString function (just a switch-case with all codes and corresponding strings) to convert error-codes back into strings if needed. I think there is even a way to make enums printable using Arduino's Printable class.

Gmail function not working

I have tried using the gmail function but i think there is a problem with the "AT+SMTPFROM" part because when i enter the correct email in the .ino example even then it quits out the loop and tells me :
GSMSim Library - Send Email Example

Connect to Internet: 0
Set gmail smtp configuration: 0
Write email to someone: ERROR:FROM_NOT_SET
Send email... : ERROR:EMAIL_SENDING_ERROR
Close Internet: 0

Irregular use of F() macro.

The F() macro is used only sometimes. The RAM load would be decreased if it were to be used more regularly.

Example:

String GSMSimTime::syncFromServer() {
	gsm.print("AT+CNTPCID=1\r"); //Bad
	_readSerial();

	gsm.print(F("AT+CNTP\r")); //Good
	_readSerial();
	//delay(50);
	_readSerial(30000);

Was it just forgotten, or is there something preventing it's use?

problem reading sms

I tried to use your library with the following code to read sms

Serial.println("Unread sms");
String list = "NO_SMS";
while (list == "NO_SMS") {
list = gsm.smsListUnread();
Serial.println("No sms");
delay(2000);
}
uint8_t index = list.substring(11).toInt();
Serial.print("Reading sms n. ");
Serial.println(index);
String sms = gsm.smsRead(index, true);
Serial.println(sms);

It receive sms but, when it read, the answer is always INDEX_NO_ERROR

thanks for your help

gprsIsConnected() always return true

I have some problems with gprsIsConnected at v1.xx.
After the connection request, I have some bad characters at the beginning of the _buffer like:
Send: AT+SAPBR=2,1
Answer: ⸮+ATSAPBR.....
indexOf returns always -1, I think there is an issue at indexOf()..

Now I debugged the _buffer and the first char is 0xE0 = 224 = à

if (_buffer.indexOf("ERR") != -1 || _buffer.indexOf(""0.0.0.0"") != -1 || _buffer.substring(4).indexOf(""0.0.0.0"") != -1) {

Module is not connected to gsm operator

Hi, Please help me with my problem.
I'm using s800l module with arduino uno. I tried to send and sms using the library but i don't received any text from my module to my phone. I tried to run GSMSim_Module_Info and i got the following details:

GSMSim Library - Module Information

Manufacturer: SIMCOM Ltd
Model: SIMCOM SIM800L
Revision: 1418B04SIM800L24

O
IMEI:
IMSI: 864764036478012
ICCID: 515020210958145
Is Connected?: 0
Signal Quality: 99
Operator: T+CSQ

+CSQ: 27,0

OK

Operator From Sim: GLOBE

Is there something wrong with the output? It says not connected? What does exactly it mean?
I'm from Philippines.

Thank you for making this library.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.