@ -187,7 +187,7 @@ public:
}
bool autoBaud ( unsigned long timeout = 10000L ) {
streamWrite ( GF ( " AAAAAAAAAAAA " ) ) ; / / some extra A ' s to help detect the baud rate
streamWrite ( GF ( " AAAAAAAAAAAAA " ) ) ; / / extra A ' s to help detect the baud rate
for ( unsigned long start = millis ( ) ; millis ( ) - start < timeout ; ) {
sendAT ( GF ( " " ) ) ;
if ( waitResponse ( 200 ) = = 1 ) {
@ -279,79 +279,11 @@ public:
return res ;
}
String getGsmLocation ( ) {
sendAT ( GF ( " +CIPGSMLOC=1,1 " ) ) ;
if ( waitResponse ( GF ( GSM_NL " +CIPGSMLOC: " ) ) ! = 1 ) {
return " " ;
}
String res = streamReadUntil ( ' \n ' ) ;
waitResponse ( ) ;
return res ;
}
bool setGsmBusy ( bool busy = true ) {
sendAT ( GF ( " +GSMBUSY= " ) , busy ? 1 : 0 ) ;
return waitResponse ( ) = = 1 ;
}
bool callAnswer ( ) {
sendAT ( GF ( " A " ) ) ;
return waitResponse ( ) = = 1 ;
}
bool callNumber ( const String & number ) {
sendAT ( GF ( " D " ) , number ) ;
return waitResponse ( ) = = 1 ;
}
bool callHangup ( const String & number ) {
sendAT ( GF ( " H " ) , number ) ;
return waitResponse ( ) = = 1 ;
}
bool sendSMS ( const String & number , const String & text ) {
sendAT ( GF ( " +CMGF=1 " ) ) ;
waitResponse ( ) ;
sendAT ( GF ( " +CMGS= \" " ) , number , GF ( " \" " ) ) ;
if ( waitResponse ( GF ( " > " ) ) ! = 1 ) {
return false ;
}
stream . print ( text ) ;
stream . write ( ( char ) 0x1A ) ;
return waitResponse ( 60000L ) = = 1 ;
}
bool sendSMS_UTF16 ( const String & number , const void * text , size_t len ) {
sendAT ( GF ( " +CMGF=1 " ) ) ;
waitResponse ( ) ;
sendAT ( GF ( " +CSCS= \" HEX \" " ) ) ;
waitResponse ( ) ;
sendAT ( GF ( " +CSMP=17,167,0,8 " ) ) ;
waitResponse ( ) ;
sendAT ( GF ( " +CMGS= \" " ) , number , GF ( " \" " ) ) ;
if ( waitResponse ( GF ( " > " ) ) ! = 1 ) {
return false ;
}
uint16_t * t = ( uint16_t * ) text ;
for ( size_t i = 0 ; i < len ; i + + ) {
uint8_t c = t [ i ] > > 8 ;
if ( c < 0x10 ) { stream . print ( ' 0 ' ) ; }
stream . print ( c , HEX ) ;
c = t [ i ] & 0xFF ;
if ( c < 0x10 ) { stream . print ( ' 0 ' ) ; }
stream . print ( c , HEX ) ;
}
stream . write ( ( char ) 0x1A ) ;
return waitResponse ( 60000L ) = = 1 ;
}
SimStatus getSimStatus ( unsigned long timeout = 10000L ) {
for ( unsigned long start = millis ( ) ; millis ( ) - start < timeout ; ) {
sendAT ( GF ( " +CPIN? " ) ) ;
if ( waitResponse ( GF ( GSM_NL " +CPIN: " ) ) ! = 1 ) {
delay ( 25 0) ;
delay ( 1000 ) ;
continue ;
}
int status = waitResponse ( GF ( " READY " ) , GF ( " SIM PIN " ) , GF ( " SIM PUK " ) , GF ( " NOT INSERTED " ) ) ;
@ -389,16 +321,14 @@ public:
}
bool waitForNetwork ( unsigned long timeout = 60000L ) {
unsigned long start = millis ( ) ;
bool is_registered = false ;
while ( millis ( ) - start < timeout & & is_registered = = false ) {
for ( unsigned long start = millis ( ) ; millis ( ) - start < timeout ; ) {
RegStatus s = getRegistrationStatus ( ) ;
if ( s = = REG_OK_HOME | | s = = REG_OK_ROAMING ) {
is_registered = true ;
return true ;
}
delay ( 1000 ) ;
}
return is_registered ;
return false ;
}
/*
@ -491,6 +421,26 @@ public:
* Phone Call functions
*/
bool setGsmBusy ( bool busy = true ) {
sendAT ( GF ( " +GSMBUSY= " ) , busy ? 1 : 0 ) ;
return waitResponse ( ) = = 1 ;
}
bool callAnswer ( ) {
sendAT ( GF ( " A " ) ) ;
return waitResponse ( ) = = 1 ;
}
bool callNumber ( const String & number ) {
sendAT ( GF ( " D " ) , number ) ;
return waitResponse ( ) = = 1 ;
}
bool callHangup ( const String & number ) {
sendAT ( GF ( " H " ) , number ) ;
return waitResponse ( ) = = 1 ;
}
/*
* Messaging functions
*/
@ -501,12 +451,61 @@ public:
void sendSMS ( ) {
}
bool sendSMS ( const String & number , const String & text ) {
sendAT ( GF ( " +CMGF=1 " ) ) ;
waitResponse ( ) ;
sendAT ( GF ( " +CMGS= \" " ) , number , GF ( " \" " ) ) ;
if ( waitResponse ( GF ( " > " ) ) ! = 1 ) {
return false ;
}
stream . print ( text ) ;
stream . write ( ( char ) 0x1A ) ;
return waitResponse ( 60000L ) = = 1 ;
}
bool sendSMS_UTF16 ( const String & number , const void * text , size_t len ) {
sendAT ( GF ( " +CMGF=1 " ) ) ;
waitResponse ( ) ;
sendAT ( GF ( " +CSCS= \" HEX \" " ) ) ;
waitResponse ( ) ;
sendAT ( GF ( " +CSMP=17,167,0,8 " ) ) ;
waitResponse ( ) ;
sendAT ( GF ( " +CMGS= \" " ) , number , GF ( " \" " ) ) ;
if ( waitResponse ( GF ( " > " ) ) ! = 1 ) {
return false ;
}
uint16_t * t = ( uint16_t * ) text ;
for ( size_t i = 0 ; i < len ; i + + ) {
uint8_t c = t [ i ] > > 8 ;
if ( c < 0x10 ) { stream . print ( ' 0 ' ) ; }
stream . print ( c , HEX ) ;
c = t [ i ] & 0xFF ;
if ( c < 0x10 ) { stream . print ( ' 0 ' ) ; }
stream . print ( c , HEX ) ;
}
stream . write ( ( char ) 0x1A ) ;
return waitResponse ( 60000L ) = = 1 ;
}
/*
* Location functions
*/
void getLocation ( ) {
}
String getGsmLocation ( ) {
sendAT ( GF ( " +CIPGSMLOC=1,1 " ) ) ;
if ( waitResponse ( GF ( GSM_NL " +CIPGSMLOC: " ) ) ! = 1 ) {
return " " ;
}
String res = streamReadUntil ( ' \n ' ) ;
waitResponse ( ) ;
return res ;
}
/*
* Battery functions
*/
@ -524,6 +523,109 @@ public:
return res ;
}
/* Public Utilities */
template < typename . . . Args >
void sendAT ( Args . . . cmd ) {
streamWrite ( " AT " , cmd . . . , GSM_NL ) ;
stream . flush ( ) ;
TINY_GSM_YIELD ( ) ;
DBG ( GSM_NL , " >>> AT: " , cmd . . . ) ;
}
/ / TODO : Optimize this !
uint8_t waitResponse ( uint32_t timeout , String & data ,
GsmConstStr r1 = GFP ( GSM_OK ) , GsmConstStr r2 = GFP ( GSM_ERROR ) ,
GsmConstStr r3 = NULL , GsmConstStr r4 = NULL , GsmConstStr r5 = NULL )
{
/*String r1s(r1); r1s.trim();
String r2s ( r2 ) ; r2s . trim ( ) ;
String r3s ( r3 ) ; r3s . trim ( ) ;
String r4s ( r4 ) ; r4s . trim ( ) ;
String r5s ( r5 ) ; r5s . trim ( ) ;
DBG ( " ### ..: " , r1s , " , " , r2s , " , " , r3s , " , " , r4s , " , " , r5s ) ; */
data . reserve ( 64 ) ;
bool gotData = false ;
int mux = - 1 ;
int index = 0 ;
unsigned long startMillis = millis ( ) ;
do {
TINY_GSM_YIELD ( ) ;
while ( stream . available ( ) > 0 ) {
int a = streamRead ( ) ;
if ( a < = 0 ) continue ; / / Skip 0x00 bytes , just in case
data + = ( char ) a ;
if ( r1 & & data . endsWith ( r1 ) ) {
index = 1 ;
goto finish ;
} else if ( r2 & & data . endsWith ( r2 ) ) {
index = 2 ;
goto finish ;
} else if ( r3 & & data . endsWith ( r3 ) ) {
index = 3 ;
goto finish ;
} else if ( r4 & & data . endsWith ( r4 ) ) {
index = 4 ;
goto finish ;
} else if ( r5 & & data . endsWith ( r5 ) ) {
index = 5 ;
goto finish ;
} else if ( data . endsWith ( GF ( GSM_NL " +CIPRXGET: " ) ) ) {
String mode = streamReadUntil ( ' , ' ) ;
if ( mode . toInt ( ) = = 1 ) {
mux = streamReadUntil ( ' \n ' ) . toInt ( ) ;
gotData = true ;
data = " " ;
} else {
data + = mode ;
}
} else if ( data . endsWith ( GF ( " CLOSED " GSM_NL ) ) ) {
int nl = data . lastIndexOf ( GSM_NL , data . length ( ) - 8 ) ;
int coma = data . indexOf ( ' , ' , nl + 2 ) ;
mux = data . substring ( nl + 2 , coma ) . toInt ( ) ;
if ( mux ) {
sockets [ mux ] - > sock_connected = false ;
data = " " ;
}
}
}
} while ( millis ( ) - startMillis < timeout ) ;
finish :
if ( ! index ) {
data . trim ( ) ;
if ( data . length ( ) ) {
DBG ( " ### Unhandled: " , data ) ;
}
data = " " ;
}
else {
data . trim ( ) ;
data . replace ( GSM_NL GSM_NL , GSM_NL ) ;
data . replace ( GSM_NL , GSM_NL " " ) ;
if ( data . length ( ) ) {
DBG ( GSM_NL , " <<< " , data ) ;
}
data = " " ;
}
if ( gotData ) {
sockets [ mux ] - > sock_available = modemGetAvailable ( mux ) ;
}
return index ;
}
uint8_t waitResponse ( uint32_t timeout ,
GsmConstStr r1 = GFP ( GSM_OK ) , GsmConstStr r2 = GFP ( GSM_ERROR ) ,
GsmConstStr r3 = NULL , GsmConstStr r4 = NULL , GsmConstStr r5 = NULL )
{
String data ;
return waitResponse ( timeout , data , r1 , r2 , r3 , r4 , r5 ) ;
}
uint8_t waitResponse ( GsmConstStr r1 = GFP ( GSM_OK ) , GsmConstStr r2 = GFP ( GSM_ERROR ) ,
GsmConstStr r3 = NULL , GsmConstStr r4 = NULL , GsmConstStr r5 = NULL )
{
return waitResponse ( 1000 , r1 , r2 , r3 , r4 , r5 ) ;
}
private :
int modemConnect ( const char * host , uint16_t port , uint8_t mux ) {
sendAT ( GF ( " +CIPSTART= " ) , mux , ' , ' , GF ( " \" TCP " ) , GF ( " \" , \" " ) , host , GF ( " \" , " ) , port ) ;
@ -604,7 +706,7 @@ private:
return 1 = = res ;
}
/* Utilities */
/* Private Utilities */
template < typename T >
void streamWrite ( T last ) {
stream . print ( last ) ;
@ -638,108 +740,6 @@ private:
} else return false ;
}
template < typename . . . Args >
void sendAT ( Args . . . cmd ) {
streamWrite ( " AT " , cmd . . . , GSM_NL ) ;
stream . flush ( ) ;
TINY_GSM_YIELD ( ) ;
DBG ( GSM_NL , " >>> AT: " , cmd . . . ) ;
}
/ / TODO : Optimize this !
uint8_t waitResponse ( uint32_t timeout , String & data ,
GsmConstStr r1 = GFP ( GSM_OK ) , GsmConstStr r2 = GFP ( GSM_ERROR ) ,
GsmConstStr r3 = NULL , GsmConstStr r4 = NULL , GsmConstStr r5 = NULL )
{
/*String r1s(r1); r1s.trim();
String r2s ( r2 ) ; r2s . trim ( ) ;
String r3s ( r3 ) ; r3s . trim ( ) ;
String r4s ( r4 ) ; r4s . trim ( ) ;
String r5s ( r5 ) ; r5s . trim ( ) ;
DBG ( " ### ..: " , r1s , " , " , r2s , " , " , r3s , " , " , r4s , " , " , r5s ) ; */
data . reserve ( 64 ) ;
bool gotData = false ;
int mux = - 1 ;
int index = 0 ;
unsigned long startMillis = millis ( ) ;
do {
TINY_GSM_YIELD ( ) ;
while ( stream . available ( ) > 0 ) {
int a = streamRead ( ) ;
if ( a < = 0 ) continue ; / / Skip 0x00 bytes , just in case
data + = ( char ) a ;
if ( r1 & & data . endsWith ( r1 ) ) {
index = 1 ;
goto finish ;
} else if ( r2 & & data . endsWith ( r2 ) ) {
index = 2 ;
goto finish ;
} else if ( r3 & & data . endsWith ( r3 ) ) {
index = 3 ;
goto finish ;
} else if ( r4 & & data . endsWith ( r4 ) ) {
index = 4 ;
goto finish ;
} else if ( r5 & & data . endsWith ( r5 ) ) {
index = 5 ;
goto finish ;
} else if ( data . endsWith ( GF ( GSM_NL " +CIPRXGET: " ) ) ) {
String mode = streamReadUntil ( ' , ' ) ;
if ( mode . toInt ( ) = = 1 ) {
mux = streamReadUntil ( ' \n ' ) . toInt ( ) ;
gotData = true ;
data = " " ;
} else {
data + = mode ;
}
} else if ( data . endsWith ( GF ( " CLOSED " GSM_NL ) ) ) {
int nl = data . lastIndexOf ( GSM_NL , data . length ( ) - 8 ) ;
int coma = data . indexOf ( ' , ' , nl + 2 ) ;
mux = data . substring ( nl + 2 , coma ) . toInt ( ) ;
if ( mux ) {
sockets [ mux ] - > sock_connected = false ;
data = " " ;
}
}
}
} while ( millis ( ) - startMillis < timeout ) ;
finish :
if ( ! index ) {
data . trim ( ) ;
if ( data . length ( ) ) {
DBG ( " ### Unhandled: " , data ) ;
}
data = " " ;
}
else {
data . trim ( ) ;
data . replace ( GSM_NL GSM_NL , GSM_NL ) ;
data . replace ( GSM_NL , GSM_NL " " ) ;
if ( data . length ( ) ) {
DBG ( GSM_NL , " <<< " , data ) ;
}
data = " " ;
}
if ( gotData ) {
sockets [ mux ] - > sock_available = modemGetAvailable ( mux ) ;
}
return index ;
}
uint8_t waitResponse ( uint32_t timeout ,
GsmConstStr r1 = GFP ( GSM_OK ) , GsmConstStr r2 = GFP ( GSM_ERROR ) ,
GsmConstStr r3 = NULL , GsmConstStr r4 = NULL , GsmConstStr r5 = NULL )
{
String data ;
return waitResponse ( timeout , data , r1 , r2 , r3 , r4 , r5 ) ;
}
uint8_t waitResponse ( GsmConstStr r1 = GFP ( GSM_OK ) , GsmConstStr r2 = GFP ( GSM_ERROR ) ,
GsmConstStr r3 = NULL , GsmConstStr r4 = NULL , GsmConstStr r5 = NULL )
{
return waitResponse ( 1000 , r1 , r2 , r3 , r4 , r5 ) ;
}
private :
Stream & stream ;
GsmClient * sockets [ 5 ] ;