26void SIM900::sendCommand(String message) {
27 this->sim900.println(message);
30String SIM900::getResponse() {
33 if(this->sim900.available() > 0) {
34 String response = this->sim900.readString();
43String SIM900::getReturnedMode() {
44 String response = this->getResponse();
45 return response.substring(response.lastIndexOf(
'\n') + 1);
48bool SIM900::isSuccessCommand() {
49 return this->getReturnedMode() == F(
"OK");
52String SIM900::rawQueryOnLine(uint16_t line) {
53 String response = this->getResponse();
56 uint16_t currentLine = 0;
57 for(
int i = 0; i < response.length(); i++)
58 if(currentLine == line && response[i] !=
'\n')
59 result += response[i];
60 else if(response[i] ==
'\n') {
63 if(currentLine > line)
70String SIM900::queryResult() {
71 String response = this->getResponse();
72 String result = F(
"");
74 int idx = response.indexOf(
": ");
76 result = response.substring(
78 response.indexOf(
'\n', idx)
87 this->sendCommand(F(
"AT"));
88 return this->isSuccessCommand();
92 this->sendCommand(F(
"AT+CPIN?"));
93 return this->isSuccessCommand();
100 this->sendCommand(
"AT+CPIN=\"" + String(pin) +
"\"");
101 return this->isSuccessCommand();
107 this->sendCommand(
"AT+CSQ");
109 String response = this->queryResult();
110 uint8_t delim = response.indexOf(
',');
115 signal.rssi = (uint8_t) response.substring(0, delim).toInt();
116 signal.bit_error_rate = (uint8_t) response.substring(delim + 1).toInt();
126 this->sendCommand(
"ATD+ " + number +
";");
128 SIM900DialResult result = SIM900_DIAL_RESULT_ERROR;
129 String mode = this->getReturnedMode();
131 if(mode == F(
"NO DIALTONE"))
132 result = SIM900_DIAL_RESULT_NO_DIALTONE;
133 else if(mode == F(
"BUSY"))
134 result = SIM900_DIAL_RESULT_BUSY;
135 else if(mode == F(
"NO CARRIER"))
136 result = SIM900_DIAL_RESULT_NO_CARRIER;
137 else if(mode == F(
"NO ANSWER"))
138 result = SIM900_DIAL_RESULT_NO_ANSWER;
139 else if(mode == F(
"OK"))
140 result = SIM900_DIAL_RESULT_OK;
146 this->sendCommand(F(
"ATDL"));
148 SIM900DialResult result = SIM900_DIAL_RESULT_ERROR;
149 String mode = this->getReturnedMode();
151 if(mode == F(
"NO DIALTONE"))
152 result = SIM900_DIAL_RESULT_NO_DIALTONE;
153 else if(mode == F(
"BUSY"))
154 result = SIM900_DIAL_RESULT_BUSY;
155 else if(mode == F(
"NO CARRIER"))
156 result = SIM900_DIAL_RESULT_NO_CARRIER;
157 else if(mode == F(
"NO ANSWER"))
158 result = SIM900_DIAL_RESULT_NO_ANSWER;
159 else if(mode == F(
"OK"))
160 result = SIM900_DIAL_RESULT_OK;
166 this->sendCommand(F(
"ATA"));
168 SIM900DialResult result = SIM900_DIAL_RESULT_ERROR;
169 String mode = this->getReturnedMode();
171 if(mode == F(
"NO CARRIER"))
172 result = SIM900_DIAL_RESULT_NO_CARRIER;
173 else if(mode == F(
"OK"))
174 result = SIM900_DIAL_RESULT_OK;
180 this->sendCommand(F(
"ATH"));
181 return this->isSuccessCommand();
187 this->sendCommand(F(
"AT+CMGF=1"));
189 this->sendCommand(
"AT+CMGS=\"" + number +
"\"");
191 this->sendCommand(message);
193 this->sim900.write(0x1a);
195 return this->getReturnedMode().startsWith(
">");
200 simOperator.mode =
static_cast<SIM900OperatorMode
>(0);
201 simOperator.format =
static_cast<SIM900OperatorFormat
>(0);
202 simOperator.name =
"";
204 this->sendCommand(F(
"AT+COPS?"));
206 String response = this->queryResult();
207 uint8_t delim1 = response.indexOf(
','),
208 delim2 = response.indexOf(
',', delim1 + 1);
210 simOperator.mode = intToSIM900OperatorMode((uint8_t) response.substring(0, delim1).toInt());
211 simOperator.format = intToSIM900OperatorFormat((uint8_t) response.substring(delim1 + 1, delim2).toInt());
212 simOperator.name = response.substring(delim2 + 2, response.length() - 2);
218 this->sendCommand(F(
"AT+CMGF=1"));
219 if(!this->isSuccessCommand())
222 this->sendCommand(F(
"AT+CGATT=1"));
223 if(!this->isSuccessCommand())
227 "AT+CSTT=\"" + apn.apn +
228 "\",\"" + apn.username +
229 "\",\"" + apn.password +
"\""
232 return (this->hasAPN = this->isSuccessCommand());
239 this->sendCommand(F(
"AT+CIICR"));
242 return this->isSuccessCommand();
247 response.status = -1;
253 "AT+CIPSTART=\"TCP\",\"" +
request.domain +
257 String resp = this->getResponse();
261 if(!resp.endsWith(F(
"CONNECT OK")))
264 String requestStr =
request.method +
" " +
265 request.resource +
" HTTP/1.0\r\nHost: " +
268 for(
int i = 0; i <
request.header_count; i++)
269 requestStr +=
request.headers[i].key +
": " +
270 request.headers[i].value +
"\r\n";
273 requestStr +=
request.data +
"\r\n";
275 requestStr += F(
"\r\n");
276 this->sendCommand(requestStr);
284 "AT+CCLK=\"" + String(config.year <= 9 ?
"0" :
"") + String(config.year) +
285 "/" + String(config.month <= 9 ?
"0" :
"") + String(config.month) +
286 "/" + String(config.day <= 9 ?
"0" :
"") + String(config.day) +
287 "," + String(config.hour <= 9 ?
"0" :
"") + String(config.hour) +
288 ":" + String(config.minute <= 9 ?
"0" :
"") + String(config.minute) +
289 ":" + String(config.second <= 9 ?
"0" :
"") + String(config.second) +
290 "+" + String(config.gmt <= 9 ?
"0" :
"") + String(config.gmt) +
"\""
293 return this->isSuccessCommand();
302 this->sendCommand(F(
"AT+CMGF=1"));
303 if(!this->isSuccessCommand())
306 this->sendCommand(F(
"AT+CENG=3"));
307 if(!this->isSuccessCommand())
309 this->sendCommand(F(
"AT+CCLK?"));
311 String time = this->queryResult();
312 time = time.substring(1, time.length() - 2);
314 uint8_t delim1 = time.indexOf(
'/'),
315 delim2 = time.indexOf(
'/', delim1 + 1),
316 delim3 = time.indexOf(
',', delim2),
317 delim4 = time.indexOf(
':', delim3),
318 delim5 = time.indexOf(
':', delim4 + 1),
319 delim6 = time.indexOf(
'+', delim5);
321 rtc.year = (uint8_t) time.substring(0, delim1).toInt();
322 rtc.month = (uint8_t) time.substring(delim1 + 1, delim2).toInt();
323 rtc.day = (uint8_t) time.substring(delim2 + 1, delim3).toInt();
324 rtc.hour = (uint8_t) time.substring(delim3 + 1, delim4).toInt();
325 rtc.minute = (uint8_t) time.substring(delim4 + 1, delim5).toInt();
326 rtc.second = (uint8_t) time.substring(delim5 + 1, delim6).toInt();
327 rtc.gmt = (uint8_t) time.substring(delim6 + 1).toInt();
334 "AT+CPBW=" + String(index) +
335 ",\"" + account.number +
336 "\"," + account.numberType +
337 ",\"" + account.name +
"\""
339 return this->isSuccessCommand();
343 this->sendCommand(
"AT+CPBR=" + String(index));
346 accountInfo.numberType =
static_cast<SIM900PhonebookType
>(0);
348 String response = this->queryResult();
349 response = response.substring(response.indexOf(
',') + 1);
351 uint8_t delim1 = response.indexOf(
','),
352 delim2 = response.indexOf(
',', delim1 + 1);
354 accountInfo.number = response.substring(1, delim1 - 1);
356 uint8_t type = (uint8_t) response.substring(delim1 + 1, delim2).toInt();
357 if(type == 129 || type == 145)
358 accountInfo.numberType =
static_cast<SIM900PhonebookType
>(type);
359 else accountInfo.numberType =
static_cast<SIM900PhonebookType
>(0);
361 accountInfo.name = response.substring(delim2 + 2, response.length() - 2);
366 this->sendCommand(
"AT+CPBW=" + String(index));
367 return this->isSuccessCommand();
372 capacity.used = capacity.max = 0;
373 capacity.memoryType = F(
"");
375 this->sendCommand(
"AT+CPBS?");
377 String response = this->queryResult();
378 uint8_t delim1 = response.indexOf(
','),
379 delim2 = response.indexOf(
',', delim1 + 1);
381 capacity.memoryType = response.substring(1, delim1 - 1);
382 capacity.used = (uint8_t) response.substring(delim1 + 1, delim2).toInt();
383 capacity.max = (uint8_t) response.substring(delim2 + 1).toInt();
389 this->sendCommand(F(
"AT+CNUM"));
392 account.name = F(
"");
394 String response = this->queryResult();
395 if(response == F(
""))
398 uint8_t delim1 = response.indexOf(
','),
399 delim2 = response.indexOf(
',', delim1 + 1),
400 delim3 = response.indexOf(
',', delim2 + 1),
401 delim4 = response.indexOf(
',', delim3 + 1);
403 account.name = response.substring(1, delim1 - 1);
404 account.number = response.substring(delim1 + 2, delim2 - 1);
405 account.type = (uint8_t) response.substring(delim2 + 1, delim3).toInt();
406 account.speed = (uint8_t) response.substring(delim3 + 1, delim4).toInt();
407 account.service = intToSIM900CardService((uint8_t) response.substring(delim4 + 1).toInt());
408 account.numberType =
static_cast<SIM900PhonebookType
>(0);
414 this->sendCommand(F(
"AT+GMI"));
415 return this->rawQueryOnLine(2);
419 this->sendCommand(F(
"AT+GMR"));
421 String result = this->rawQueryOnLine(2);
422 result = result.substring(result.lastIndexOf(F(
":")) + 1);
428 this->sendCommand(F(
"AT+GSN"));
429 return this->rawQueryOnLine(2);
433 this->sendCommand(F(
"AT+GMM"));
434 return this->rawQueryOnLine(2);
438 this->sendCommand(F(
"AT+GOI"));
439 return this->rawQueryOnLine(2);
443 this->sendCommand(F(
"AT+CIFSR"));
444 return this->rawQueryOnLine(2);
bool savePhonebook(uint8_t index, SIM900CardAccount account)
Save a contact in the SIM card's phonebook.
String manufacturer()
Get the manufacturer name of the SIM900 module.
SIM900DialResult redialUp()
Redial the last outgoing call.
String chipName()
Get the chip name of the SIM900 module.
SIM900PhonebookCapacity phonebookCapacity()
Get information about the capacity of the SIM card's phonebook.
SIM900DialResult acceptIncomingCall()
Accept an incoming call.
SIM900DialResult dialUp(String number)
Initiate an outgoing call to a phone number.
bool enableGPRS()
Enable the General Packet Radio Service (GPRS) for data communication.
String ipAddress()
Get the IP address assigned to the SIM900 module.
SIM900CardAccount cardNumber()
Get the SIM card number.
String chipModel()
Get the chip model of the SIM900 module.
bool deletePhonebook(uint8_t index)
Delete a contact from the SIM card's phonebook.
SIM900Operator networkOperator()
Get information about the current network operator.
bool sendSMS(String number, String message)
Send an SMS (Short Message Service).
bool updateRtc(SIM900RTC config)
Update the SIM900 module's real-time clock (RTC).
String softwareRelease()
Get the software release version of the SIM900 module.
bool hangUp()
Hang up an active call.
bool connectAPN(SIM900APN apn)
Connect to an Access Point Name (APN) for mobile data.
bool changeCardPin(uint8_t pin)
Change the PIN code of the SIM card.
SIM900(Stream &_sim900)
Constructor for the SIM900 class.
SIM900RTC rtc()
Get the real-time clock (RTC) information.
bool handshake()
Initialize communication with the SIM900 module and perform a handshake.
bool isCardReady()
Check if the SIM card is ready.
String imei()
Get the International Mobile Equipment Identity (IMEI) number of the SIM900 module.
SIM900CardAccount retrievePhonebook(uint8_t index)
Retrieve a contact from the SIM card's phonebook.
SIM900Signal signal()
Get the signal strength and bit error rate of the network connection.
SIM900HTTPResponse request(SIM900HTTPRequest request)
Send an HTTP request to a remote server.
A structure representing Access Point Name (APN) configuration for mobile data.
A structure representing a card account, including name, number, type, and service information.
A structure representing an HTTP request.
A structure representing an HTTP response.
A structure representing mobile network operator information.
A structure representing the capacity of a phonebook memory type.
A structure representing real-time clock (RTC) information.
A structure representing signal strength and bit error rate information.