/********************************************************** Method update signal level return: OK ret val: ----------- 1 - Signal Level updated 0 - Signal level not updated ERROR ret. val: --------------- -1 - comm. line to the GSM module is not free -2 - GSM module didn't answer in timeout **********************************************************/ char GSM::UpdateSignalLevel() { char ret_val = -1; char sig=0; char *p_char; char *p_char1; if (CLS_FREE != GetCommLineStatus()) return (ret_val); SetCommLineStatus(CLS_ATCMD); ret_val = 0; // not found yet Serial.print(F("AT+CSQ\r")); switch (WaitResp(1000, 20, "+CSQ")) { case RX_TMOUT_ERR: // response was not received in specific time ret_val = -2; break; case RX_FINISHED_STR_RECV: p_char = strchr((char *)(comm_buf),':'); if (p_char != NULL) { p_char++; // we are on the first battery level character // find out ',' as finish character of battery level string p_char1 = strchr((char *)(p_char),','); if (p_char1 != NULL) { *p_char1 = 0; // end of string sig= atoi(p_char); //Convert string to integer 0-100% } } if((sig==0) || (sig==99)) signalLevel=0; else if((sig>0) && (sig<=5)) signalLevel=1; else if((sig>5) && (sig<=12)) signalLevel=2; else if((sig>12) && (sig<=17)) signalLevel=3; else if((sig>17) && (sig<=22)) signalLevel=4; else if((sig>22) && (sig<=32)) signalLevel=5; else signalLevel=0; ret_val =1; break; case RX_FINISHED_STR_NOT_RECV: ret_val = 0; break; } SetCommLineStatus(CLS_FREE); return (ret_val); }
/********************************************************** Method sets GPIO pin according required value it doesn't check if the pin was previously set as OUTPUT so INPUT pin is automatically switch as the output pin by using this function gpio_pin: 10..13 value: 0 - "0" as LOW 1 - "1" as HIGH return: ERROR ret. val: --------------- -1 - comm. line to the GSM module is not free -2 - GSM module didn't answer in timeout -3 - GSM module has answered "ERROR" string OK ret val: ----------- 0 - set to the "0" - LOW 1 - set to the "1" - HIGH **********************************************************/ char GSM::SetGPIOVal(byte GPIO_pin, byte value) { char ret_val = -1; if (CLS_FREE != GetCommLineStatus()) return (ret_val); SetCommLineStatus(CLS_ATCMD); // e.g. AT#GPIO=9,0,1 - set to "0" - LOW // or AT#GPIO=9,1,1 - set to "1" - HIGH Serial.print("AT#GPIO="); // pin number Serial.print((int)GPIO_pin); Serial.print(","); if (value > 1) value = 1; Serial.print((int)value); Serial.print(",1\r"); // pin is always set as output // 100 msec. for initial comm tmout // 20 msec. for inter character timeout if (RX_TMOUT_ERR == WaitResp(100, 20)) { ret_val = -2; // ERROR } else { if(IsStringReceived("OK")) { ret_val = value; // OK } else ret_val = -3; // ERROR } SetCommLineStatus(CLS_FREE); return (ret_val); }
/********************************************************** Sends parameters for initialization of GSM module group: 0 - parameters of group 0 - not necessary to be registered in the GSM 1 - parameters of group 1 - it is necessary to be registered **********************************************************/ void GSM::InitParam(byte group) { switch (group) { case PARAM_SET_0: // check comm line if (CLS_FREE != GetCommLineStatus()) return; SetCommLineStatus(CLS_ATCMD); // Reset to the factory settings SendATCmdWaitResp("AT&F0", 1000, 20, "OK", 5); // switch off echo SendATCmdWaitResp("ATE0", 500, 20, "OK", 5); // setup auto baud rate SendATCmdWaitResp("AT+IPR=0", 500, 20, "OK", 5); SetCommLineStatus(CLS_FREE); break; case PARAM_SET_1: // check comm line if (CLS_FREE != GetCommLineStatus()) return; SetCommLineStatus(CLS_ATCMD); // set the SMS mode to text SendATCmdWaitResp("AT+CMGF=1", 500, 20, "OK", 5); // init SMS storage InitSMSMemory(); // select phonebook memory storage SendATCmdWaitResp("AT+CPBS=\"SM\"", 1000, 20, "OK", 5); break; } }
/********************************************************** Method picks up an incoming call return: **********************************************************/ void GSM::PickUp(void) { if (CLS_FREE != GetCommLineStatus()) return; SetCommLineStatus(CLS_ATCMD); Serial.println("ATA"); SetCommLineStatus(CLS_FREE); }
/********************************************************** Method sets direction for GPIO pins GPIO10, GPIO11, GPIO12, GPIO13 gpio_pin: 10..13 direction: 0 - input 1 - output return: ERROR ret. val: --------------- -1 - comm. line to the GSM module is not free -2 - GSM module didn't answer in timeout -3 - GSM module has answered "ERROR" string OK ret val: ----------- 0 - set as INPUT 1 - set as OUTPUT **********************************************************/ char GSM::SetGPIODir(byte GPIO_pin, byte direction) { char ret_val = -1; if (CLS_FREE != GetCommLineStatus()) return (ret_val); SetCommLineStatus(CLS_ATCMD); // e.g. AT#GPIO=9,0,0 - sets as INPUT // e.g. AT#GPIO=9,0,1 - sets as OUTPUT and value is "0" - LOW Serial.print("AT#GPIO="); // pin number Serial.print((int)GPIO_pin); Serial.print(",0,"); // if case pin will be OUTPUT - // first value after initialization will be 0 if (direction > 1) direction = 1; Serial.print((int)direction); // 0-INPUT, 1-OUTPUT Serial.print("\r"); // finish command = send<CR> // 100 msec. for initial comm tmout // 20 msec. for inter character timeout if (RX_TMOUT_ERR == WaitResp(100, 20)) { ret_val = -2; // ERROR } else { if(IsStringReceived("OK")) { ret_val = direction; // OK } else ret_val = -3; // ERROR } SetCommLineStatus(CLS_FREE); return (ret_val); }
/********************************************************** Method sets speaker volume speaker_volume: volume in range 0..14 return: ERROR ret. val: --------------- -1 - comm. line to the GSM module is not free -2 - GSM module did not answer in timeout -3 - GSM module has answered "ERROR" string OK ret val: ----------- 0..100 current speaker volume **********************************************************/ char GSM::SetSpeakerVolume(byte speaker_volume) { char ret_val = -1; if (CLS_FREE != GetCommLineStatus()) return (ret_val); SetCommLineStatus(CLS_ATCMD); // remember set value as last value if (speaker_volume > 100) speaker_volume = 100; // select speaker volume (0 to 100) // AT+CLVL=X<CR> X<0..100> Serial.print(F("AT+CLVL=")); Serial.print((int)speaker_volume); Serial.print(F("\r")); // send <CR> // 10 sec. for initial comm tmout // 20 msec. for inter character timeout if (RX_TMOUT_ERR == WaitResp(10000, 20)) { ret_val = -2; // ERROR } else { if(IsStringReceived("OK")) { last_speaker_volume = speaker_volume; ret_val = last_speaker_volume; // OK } else ret_val = -3; // ERROR } SetCommLineStatus(CLS_FREE); return (ret_val); }
/********************************************************** Method del phone number from the specified SIM position position: SMS position <1..20> return: ERROR ret. val: --------------- -1 - comm. line to the GSM module is not free -2 - GSM module didn't answer in timeout -3 - position must be > 0 OK ret val: ----------- 0 - phone number was not deleted 1 - phone number was deleted **********************************************************/ char GSM::DelPhoneNumber(byte position) { char ret_val = -1; if (position == 0) return (-3); if (CLS_FREE != GetCommLineStatus()) return (ret_val); SetCommLineStatus(CLS_ATCMD); ret_val = 0; // phone number was not written yet //send: AT+CPBW=XY // where XY = position _cell.print(F("AT+CPBW=")); _cell.print((int)position); _cell.print(F("\r")); // 5000 msec. for initial comm tmout // 50 msec. for inter character timeout switch (WaitResp(5000, 50, "OK")) { case RX_TMOUT_ERR: // response was not received in specific time break; case RX_FINISHED_STR_RECV: // response is OK = has been written ret_val = 1; break; case RX_FINISHED_STR_NOT_RECV: // other response: e.g. ERROR break; } SetCommLineStatus(CLS_FREE); return (ret_val); }
/********************************************************** Checks if the GSM module is responding to the AT command - if YES nothing is made - if NO switch on sequence is repeated until there is a response from GSM module **********************************************************/ void GSM::TurnOn(void) { SetCommLineStatus(CLS_ATCMD); while (AT_RESP_ERR_NO_RESP == SendATCmdWaitResp("AT", 500, 20, "OK", 5)) { // there is no response => turn on the module #ifdef DEBUG_PRINT // parameter 0 - because module is off so it is not necessary // to send finish AT<CR> here DebugPrint("DEBUG: GSM module is off\r\n", 0); #endif // generate switch on pulse digitalWrite(GSM_ON, HIGH); delay(1200); digitalWrite(GSM_ON, LOW); delay(1200); delay(1500); // wait before next try } SetCommLineStatus(CLS_FREE); // send collection of first initialization parameters for the GSM module InitParam(PARAM_SET_0); }
/********************************************************** Method initializes GPRS apn: APN string login: user id string password: password string return: ERROR ret. val: --------------- -1 - comm. line is not free OK ret val: ----------- 0 - GPRS was not initialized 1 - GPRS was initialized an example of usage: APN si called internet user id and password are not used GSM gsm; gsm.InitGPRS("internet", "", ""); **********************************************************/ char GSM::InitGPRS(char* apn, char* login, char* password) { char ret_val = -1; char cmd[100]; if (CLS_FREE != GetCommLineStatus()) return (ret_val); SetCommLineStatus(CLS_ATCMD); // prepare command: AT+CGDCONT=1,"IP","apn" strcpy(cmd, "AT+CGDCONT=1,\"IP\",\""); strcat(cmd, apn); strcat(cmd, "\""); // add character " ret_val = SendATCmdWaitResp(cmd, 1000, 100, "OK", 2); if (ret_val == AT_RESP_OK) { // prepare command: AT#USERID="login" strcpy(cmd, "AT#USERID=\""); strcat(cmd, login); strcat(cmd, "\""); // add character " ret_val = SendATCmdWaitResp(cmd, 1000, 100, "OK", 2); if (ret_val == AT_RESP_OK) { // prepare command: AT#PASSW="password" strcpy(cmd, "AT#PASSW=\""); strcat(cmd, password); strcat(cmd, "\""); // add character " ret_val = SendATCmdWaitResp(cmd, 1000, 100, "OK", 2); if (ret_val == AT_RESP_OK) ret_val = 1; else ret_val = 0; } else ret_val = 0; } else ret_val = 0; SetCommLineStatus(CLS_FREE); return (ret_val); }
/********************************************************** Method hangs up incoming or active call return: **********************************************************/ void GSM::HangUp(void) { if (CLS_FREE != GetCommLineStatus()) return; SetCommLineStatus(CLS_ATCMD); Serial.println(F("ATH0\r")); SetCommLineStatus(CLS_FREE); }
/********************************************************** Method sends DTMF signal This function only works when call is in progress dtmf_tone: tone to send 0..15 return: ERROR ret. val: --------------- -1 - comm. line to the GSM module is not free -2 - GSM module didn't answer in timeout -3 - GSM module has answered "ERROR" string OK ret val: ----------- 0.. tone **********************************************************/ char GSM::SendDTMFSignal(byte dtmf_tone) { char ret_val = -1; if (CLS_FREE != GetCommLineStatus()) return (ret_val); SetCommLineStatus(CLS_ATCMD); // e.g. AT+VTS=5<CR> Serial.print(F("AT+VTS=")); Serial.print((int)dtmf_tone); Serial.print(F("\r")); // 1 sec. for initial comm tmout // 20 msec. for inter character timeout if (RX_TMOUT_ERR == WaitResp(1000, 20)) { ret_val = -2; // ERROR } else { if(IsStringReceived("OK")) { ret_val = dtmf_tone; // OK } else ret_val = -3; // ERROR } SetCommLineStatus(CLS_FREE); return (ret_val); }
/********************************************************** Turns off the user LED **********************************************************/ void GSM::TurnOffLED(void) { if (CLS_FREE != GetCommLineStatus()) return; SetCommLineStatus(CLS_ATCMD); // response here is not important SendATCmdWaitResp("AT#GPIO=8,0,1", 500, 20, "#GPIO:", 1); SetCommLineStatus(CLS_FREE); }
char GSM::GetPhoneNumber(byte position, char *phone_number) { char ret_val = -1; char *p_char; char *p_char1; if (position == 0) return (-3); if (CLS_FREE != GetCommLineStatus()) return (ret_val); SetCommLineStatus(CLS_ATCMD); ret_val = 0; // not found yet phone_number[0] = 0; // phone number not found yet => empty string //send "AT+CPBR=XY" - where XY = position _cell.print(F("AT+CPBR=")); _cell.print((int)position); _cell.print("\r"); // 5000 msec. for initial comm tmout // 50 msec. for inter character timeout switch (WaitResp(5000, 50, "+CPBR")) { case RX_TMOUT_ERR: // response was not received in specific time ret_val = -2; break; case RX_FINISHED_STR_RECV: // response in case valid phone number stored: // <CR><LF>+CPBR: <index>,<number>,<type>,<text><CR><LF> // <CR><LF>OK<CR><LF> // response in case there is not phone number: // <CR><LF>OK<CR><LF> p_char = strstr((char *)(comm_buf),",\""); if (p_char != NULL) { p_char++; p_char++; // we are on the first phone number character // find out '"' as finish character of phone number string p_char1 = strchr((char *)(p_char),'"'); if (p_char1 != NULL) { *p_char1 = 0; // end of string } // extract phone number string strcpy(phone_number, (char *)(p_char)); // output value = we have found out phone number string ret_val = 1; } break; case RX_FINISHED_STR_NOT_RECV: // only OK or ERROR => no phone number ret_val = 0; break; } SetCommLineStatus(CLS_FREE); return (ret_val); }
/********************************************************** Method enables GPRS context open_mode: 0 (= CHECK_AND_OPEN) - checks the current state of context and in case context has been already activated nothing else in made 1 (= CLOSE_AND_REOPEN) - context is deactivated anyway and then activated again it was found during testing, that you may need to reset the module etc., and in these cases, you may not be able to activate the GPRS context unless you deactivate it first return: ERROR ret. val: --------------- -1 - comm. line is not free OK ret val: ----------- 0 - GPRS context was disabled 1 - GPRS context was enabled an example of usage: GSM gsm; if (gsm.EnableGPRS(CHECK_AND_OPEN) == 1) { // GPRS context was enabled, so we have IP address // and we can communicate if necessary } **********************************************************/ char GSM::EnableGPRS(byte open_mode) { char ret_val = -1; if (CLS_FREE != GetCommLineStatus()) return (ret_val); SetCommLineStatus(CLS_ATCMD); if (open_mode == CHECK_AND_OPEN) { // first try if the GPRS context has not been already initialized ret_val = SendATCmdWaitResp("AT+CIPSTATUS", 1000, 1000, "STATE: IP GPRSACT", 2); if (ret_val != AT_RESP_OK) { // context is not initialized => init the context //Enable GPRS ret_val = SendATCmdWaitResp("AT+CSTT", 1000, 1000, "OK", 1); if (ret_val == AT_RESP_OK) { // cstt OK ret_val = SendATCmdWaitResp("AT+CIICR", 60000, 1000, "OK", 1); if (ret_val == AT_RESP_OK) { // context was activated SendATCmdWaitResp("AT+CIFSR", 2000, 1000, "", 1);//get ip ret_val = 1; } else ret_val = 0; // not activated } else ret_val = 0; // not activated } else ret_val = 1; // context has been already activated } else { // CLOSE_AND_REOPEN mode //disable GPRS context ret_val = SendATCmdWaitResp("AT+CIPSHUT", 2000, 1000, "SHUT OK", 3); if (ret_val == AT_RESP_OK) { // context is dactivated // => activate GPRS context again ret_val = SendATCmdWaitResp("AT+CSTT", 1000, 1000, "OK", 1); if (ret_val == AT_RESP_OK) { // cstt OK ret_val = SendATCmdWaitResp("AT+CIICR", 10000, 1000, "OK", 1); if (ret_val == AT_RESP_OK) { // context was activated SendATCmdWaitResp("AT+CIFSR", 2000, 1000, "", 1);//get ip ret_val = 1; } else ret_val = 0; // not activated } else ret_val = 0; // not activated } else ret_val = 0; // not activated } SetCommLineStatus(CLS_FREE); return (ret_val); }
/********************************************************** Turns on/off the speaker off_on: 0 - off 1 - on **********************************************************/ void GSM::SetSpeaker(byte off_on) { if (CLS_FREE != GetCommLineStatus()) return; SetCommLineStatus(CLS_ATCMD); if (off_on) { //SendATCmdWaitResp("AT#GPIO=5,1,2", 500, 50, "#GPIO:", 1); } else { //SendATCmdWaitResp("AT#GPIO=5,0,2", 500, 50, "#GPIO:", 1); } SetCommLineStatus(CLS_FREE); }
void GSM::Echo(byte state) { if (state == 0 or state == 1) { SetCommLineStatus(CLS_ATCMD); _cell.print("ATE"); _cell.print((int)state); _cell.print("\r"); delay(500); SetCommLineStatus(CLS_FREE); } }
/********************************************************** Method returns state of user button return: 0 - not pushed = released 1 - pushed **********************************************************/ byte GSM::IsUserButtonPushed(void) { byte ret_val = 0; if (CLS_FREE != GetCommLineStatus()) return(0); SetCommLineStatus(CLS_ATCMD); if (AT_RESP_OK == SendATCmdWaitResp("AT#GPIO=9,2", 500, 20, "#GPIO: 0,0", 1)) { // user button is pushed ret_val = 1; } else ret_val = 0; SetCommLineStatus(CLS_FREE); return (ret_val); }
/********************************************************** Method calls the specific number number_string: pointer to the phone number string e.g. gsm.Call("+420123456789"); **********************************************************/ void GSM::Call(char *number_string) { if (CLS_FREE != GetCommLineStatus()) return; SetCommLineStatus(CLS_ATCMD); // ATDxxxxxx;<CR> Serial.print(F("ATD")); Serial.print(number_string); Serial.print(F(";\r")); // 10 sec. for initial comm tmout // 20 msec. for inter character timeout WaitResp(10000, 20); SetCommLineStatus(CLS_FREE); }
/********************************************************** Method checks if the GSM module is registered in the GSM net - this method communicates directly with the GSM module in contrast to the method IsRegistered() which reads the flag from the module_status (this flag is set inside this method) - must be called regularly - from 1sec. to cca. 10 sec. return values: REG_NOT_REGISTERED - not registered REG_REGISTERED - GSM module is registered REG_NO_RESPONSE - GSM doesn't response REG_COMM_LINE_BUSY - comm line between GSM module and Arduino is not free for communication **********************************************************/ byte GSM::CheckRegistration(void) { byte status; byte ret_val = REG_NOT_REGISTERED; if (CLS_FREE != GetCommLineStatus()) return (REG_COMM_LINE_BUSY); SetCommLineStatus(CLS_ATCMD); _cell.println(F("AT+CREG?")); // 5 sec. for initial comm tmout // 50 msec. for inter character timeout status = WaitResp(5000, 50); if (status == RX_FINISHED) { // something was received but what was received? // --------------------------------------------- if(IsStringReceived("+CREG: 0,1") || IsStringReceived("+CREG: 0,5")) { // it means module is registered // ---------------------------- module_status |= STATUS_REGISTERED; // in case GSM module is registered first time after reset // sets flag STATUS_INITIALIZED // it is used for sending some init commands which // must be sent only after registration // -------------------------------------------- if (!IsInitialized()) { module_status |= STATUS_INITIALIZED; SetCommLineStatus(CLS_FREE); InitParam(PARAM_SET_1); } ret_val = REG_REGISTERED; } else { // NOT registered // -------------- module_status &= ~STATUS_REGISTERED; ret_val = REG_NOT_REGISTERED; } } else { // nothing was received // -------------------- ret_val = REG_NO_RESPONSE; } SetCommLineStatus(CLS_FREE); return (ret_val); }
/********************************************************** Method checks status of call return: CALL_NONE - no call activity CALL_INCOM_VOICE - incoming voice CALL_ACTIVE_VOICE - active voice CALL_NO_RESPONSE - no response to the AT command CALL_COMM_LINE_BUSY - comm line is not free **********************************************************/ byte GSM::CallStatus(void) { byte ret_val = CALL_NONE; if (CLS_FREE != GetCommLineStatus()) return (CALL_COMM_LINE_BUSY); SetCommLineStatus(CLS_ATCMD); Serial.println(F("AT+CPAS")); // 5 sec. for initial comm tmout // 20 msec. for inter character timeout if (RX_TMOUT_ERR == WaitResp(5000, 20)) { // nothing was received (RX_TMOUT_ERR) // ----------------------------------- ret_val = CALL_NO_RESPONSE; } else { // something was received but what was received? // --------------------------------------------- // ready (device allows commands from TA/TE) // <CR><LF>+CPAS: 0<CR><LF> <CR><LF>OK<CR><LF> // unavailable (device does not allow commands from TA/TE) // <CR><LF>+CPAS: 1<CR><LF> <CR><LF>OK<CR><LF> // unknown (device is not guaranteed to respond to instructions) // <CR><LF>+CPAS: 2<CR><LF> <CR><LF>OK<CR><LF> - NO CALL // ringing // <CR><LF>+CPAS: 3<CR><LF> <CR><LF>OK<CR><LF> - NO CALL // call in progress // <CR><LF>+CPAS: 4<CR><LF> <CR><LF>OK<CR><LF> - NO CALL if(IsStringReceived("0")) { // ready - there is no call // ------------------------ ret_val = CALL_NONE; } else if(IsStringReceived("3")) { // incoming call // -------------- ret_val = CALL_INCOM_VOICE; } else if(IsStringReceived("4")) { // active call // ----------- ret_val = CALL_ACTIVE_VOICE; } } SetCommLineStatus(CLS_FREE); return (ret_val); }
/********************************************************** Method calls the number stored at the specified SIM position sim_position: position in the SIM <1...> e.g. gsm.Call(1); **********************************************************/ void GSM::Call(int sim_position) { if (CLS_FREE != GetCommLineStatus()) return; SetCommLineStatus(CLS_ATCMD); // ATD>"SM" 1;<CR> Serial.print(F("ATD>\"SM\" ")); Serial.print(sim_position); Serial.print(F(";\r")); // 10 sec. for initial comm tmout // 20 msec. for inter character timeout WaitResp(10000, 20); SetCommLineStatus(CLS_FREE); }
/********************************************************** Methods receives data from the serial port return: number of received bytes an example of usage: GSM gsm; byte num_of_bytes; num_of_bytes = gsm.RcvData(5000, 100); if (num_of_bytes) { // some data were received } **********************************************************/ uint16_t GSM::RcvData(uint16_t start_comm_tmout, uint16_t max_interchar_tmout, byte** ptr_to_rcv_data) { byte status; RxInit(start_comm_tmout, max_interchar_tmout, 0, 0); // wait until response is not finished do { status = IsRxFinished(); } while (status == RX_NOT_FINISHED); if (comm_buf_len) *ptr_to_rcv_data = comm_buf; else *ptr_to_rcv_data = NULL; // check <CR><LF>NO CARRIER<CR><LF> // in case this string was received => socked is closed if (comm_buf_len) { if (StrInBin(comm_buf, "\r\nNO CARRIER\r\n", comm_buf_len) != -1) { // NO CARRIER was received => socket was closed from the host side // we can set the communication line to the FREE state SetCommLineStatus(CLS_FREE); } } return (comm_buf_len); }
/********************************************************** Method disables GPRS context return: ERROR ret. val: --------------- -1 - comm. line is not free OK ret val: ----------- 0 - GPRS context was not disabled 1 - GPRS context was disabled an example of usage: GSM gsm; gsm.DisableGPRS(); **********************************************************/ char GSM::DisableGPRS(void) { char ret_val = -1; if (CLS_FREE != GetCommLineStatus()) return (ret_val); SetCommLineStatus(CLS_ATCMD); ret_val = SendATCmdWaitResp("AT+CIPSHUT", 2000, 1000, "SHUT OK", 2); if (ret_val == AT_RESP_OK) { // context was disabled ret_val = 1; } else ret_val = 0; // context was not disabled SetCommLineStatus(CLS_FREE); return (ret_val); }
/********************************************************** Method closes previously opened socket return: ERROR ret. val: --------------- -1 - comm. line is not in the data(GPRS) state OK ret val: ----------- 0 - socket was not closed 1 - socket was successfully closed an example of usage: GSM gsm; gsm.CloseSocket(); **********************************************************/ char GSM::CloseSocket(void) { char ret_val = -1; byte i; byte* rx_data; if (CLS_FREE == GetCommLineStatus()) { ret_val = 1; // socket was already closed return (ret_val); } // we are in the DATA state so try to close the socket // --------------------------------------------------- for (i = 0; i < 3; i++) { // make dalay 500msec. before escape seq. "+++" RcvData(1500, 100, &rx_data); // trick - function is used for generation a delay // send escape sequence +++ and wait for "NO CARRIER" SendData("+++"); if (RX_FINISHED_STR_RECV == WaitResp(5000, 1000, "OK")) { SetCommLineStatus(CLS_ATCMD); ret_val = SendATCmdWaitResp("AT+CIPCLOSE", 5000, 1000, "CLOSE OK", 2); if (ret_val == AT_RESP_OK) { // socket was successfully closed ret_val = 1; } else ret_val = 0; // socket was not successfully closed SetCommLineStatus(CLS_FREE); break; } else { // try common AT command just to be sure that the socket // has not been already closed ret_val = SendATCmdWaitResp("AT", 1000, 1000, "OK", 2); if (ret_val == AT_RESP_OK) { // socket was successfully closed ret_val = 1; SetCommLineStatus(CLS_FREE); break; } else { ret_val = 0; } } } return (ret_val); }
/********************************************************** Method enables GPRS context open_mode: 0 (= CHECK_AND_OPEN) - checks the current state of context and in case context has been already activated nothing else in made 1 (= CLOSE_AND_REOPEN) - context is deactivated anyway and then activated again it was found during testing, that you may need to reset the module etc., and in these cases, you may not be able to activate the GPRS context unless you deactivate it first return: ERROR ret. val: --------------- -1 - comm. line is not free OK ret val: ----------- 0 - GPRS context was disabled 1 - GPRS context was enabled an example of usage: GSM gsm; if (gsm.EnableGPRS(CHECK_AND_OPEN) == 1) { // GPRS context was enabled, so we have IP address // and we can communicate if necessary } **********************************************************/ char GSM::EnableGPRS(byte open_mode) { char ret_val = -1; if (CLS_FREE != GetCommLineStatus()) return (ret_val); SetCommLineStatus(CLS_ATCMD); if (open_mode == CHECK_AND_OPEN) { // first try if the GPRS context has not been already initialized ret_val = SendATCmdWaitResp("AT#GPRS?", 1000, 100, "#GPRS: 0", 2); if (ret_val == AT_RESP_OK) { // context is not initialized => init the context //Enable GPRS ret_val = SendATCmdWaitResp("AT#GPRS=1", 10000, 1000, "OK", 1); if (ret_val == AT_RESP_OK) { // context was activated ret_val = 1; } else ret_val = 0; // not activated } else ret_val = 1; // context has been already activated } else { // CLOSE_AND_REOPEN mode //disable GPRS context ret_val = SendATCmdWaitResp("AT#GPRS=0", 10000, 1000, "OK", 3); if (ret_val == AT_RESP_OK) { // context is dactivated // => activate GPRS context again ret_val = SendATCmdWaitResp("AT#GPRS=1", 10000, 1000, "OK", 1); if (ret_val == AT_RESP_OK) { // context was activated ret_val = 1; } else ret_val = 0; // not activated } else ret_val = 0; // not activated } SetCommLineStatus(CLS_FREE); return (ret_val); }
char GSM::InitSMSMemory(void) { char ret_val = -1; if (CLS_FREE != GetCommLineStatus()) return (ret_val); SetCommLineStatus(CLS_ATCMD); ret_val = 0; // not initialized yet // Disable messages about new SMS from the GSM module SendATCmdWaitResp(F("AT+CNMI=2,0"), 1000, 50, str_ok, 2); // send AT command to init memory for SMS in the SIM card // response: // +CPMS: <usedr>,<totalr>,<usedw>,<totalw>,<useds>,<totals> if (AT_RESP_OK == SendATCmdWaitResp(F("AT+CPMS=\"SM\",\"SM\",\"SM\""), 1000, 1000, "+CPMS:", 10)) { ret_val = 1; } else ret_val = 0; SetCommLineStatus(CLS_FREE); return (ret_val); }
/********************************************************** Method opens the socket <socket type> - socket protocol type 0 - TCP 1 - UDP <remote port> - remote host port to be opened 0..65535 - port number <remote addr> - address of the remote host, string type. This parameter can be either: - any valid IP address in the format: xxx.xxx.xxx.xxx - any host name to be solved with a DNS query in the format: <host name> return: ERROR ret. val: --------------- -1 - comm. line is not free OK ret val: ----------- 0 - socket was not opened 1 - socket was successfully opened an example of usage: GSM gsm; gsm.OpenSocket(TCP, 80, "www.google.com"); **********************************************************/ char GSM::OpenSocket(byte socket_type, uint16_t remote_port, char* remote_addr) { char ret_val = -1; char cmd[200]; char tmp_str[10]; if (CLS_FREE != GetCommLineStatus()) return (ret_val); SetCommLineStatus(CLS_ATCMD); // prepare command: AT+CIPSTART="TCP","www.google.com","port" strcpy(cmd, "AT+CIPSTART=\""); // add socket type if (socket_type == UDP_SOCKET) { strcat(cmd, "UDP\""); } else { strcat(cmd, "TCP\",\""); } // add remote addr strcat(cmd, remote_addr); strcat(cmd, "\",\""); // add characters ," // add remote_port strcat(cmd, itoa(remote_port, tmp_str, 10)); strcat(cmd, "\""); // add characters " // send AT command and waits for the response "CONNECT\r\n" - max. 3 times ret_val = SendATCmdWaitResp(cmd, 20000, 3000, "CONNECT\r\n", 3); if (ret_val == AT_RESP_OK) { ret_val = 1; SetCommLineStatus(CLS_DATA); } else { ret_val = 0; SetCommLineStatus(CLS_FREE); } return (ret_val); }
/********************************************************** Method opens the socket <socket type> - socket protocol type 0 - TCP 1 - UDP <remote port> - remote host port to be opened 0..65535 - port number <remote addr> - address of the remote host, string type. This parameter can be either: - any valid IP address in the format: xxx.xxx.xxx.xxx - any host name to be solved with a DNS query in the format: <host name> <closure type> - socket closure behaviour for TCP 0 - local host closes immediately when remote host has closed (default) 255 - local host closes after an escape sequence (+++) or after an abortive disconnect from remote. <local port> - local host port to be used on UDP socket return: ERROR ret. val: --------------- -1 - comm. line is not free OK ret val: ----------- 0 - socket was not opened 1 - socket was successfully opened an example of usage: GSM gsm; gsm.OpenSocket(TCP, 80, "www.google.com", 0, 0); **********************************************************/ char GSM::OpenSocket(byte socket_type, uint16_t remote_port, char* remote_addr, byte closure_type, uint16_t local_port) { char ret_val = -1; char cmd[100]; char tmp_str[10]; if (CLS_FREE != GetCommLineStatus()) return (ret_val); SetCommLineStatus(CLS_ATCMD); // prepare command: AT+CGDCONT=1,"IP","apn" strcpy(cmd, "AT#SKTD="); // add socket type strcat(cmd, itoa(socket_type, tmp_str, 10)); strcat(cmd, ","); // add character , // add remote_port strcat(cmd, itoa(remote_port, tmp_str, 10)); strcat(cmd, ",\""); // add characters ," // add remote addr strcat(cmd, remote_addr); strcat(cmd, "\","); // add characters ", // add closure type strcat(cmd, itoa(closure_type, tmp_str, 10)); strcat(cmd, ","); // add character , // add local port strcat(cmd, itoa(local_port, tmp_str, 10)); // send AT command and waits for the response "CONNECT" - max. 3 times ret_val = SendATCmdWaitResp(cmd, 20000, 100, "CONNECT", 3); if (ret_val == AT_RESP_OK) { ret_val = 1; SetCommLineStatus(CLS_DATA); } else { ret_val = 0; SetCommLineStatus(CLS_FREE); } return (ret_val); }
/********************************************************** Method gets temperature measured by the Telit GSM module the temperature is calculated by the formula: T[C] = (Vin-600)/10 where Vin is the millivolts value return: ERROR ret. val: --------------- -1000 - comm. line to the GSM module is not free -2000 - GSM temperature answer is not valid OK ret val: ----------- temperature in the C in the format XXX ~ XX,XC so e.g. 235 means 23.5 C -100 means -10.0 C **********************************************************/ int GSM::GetTemp(void) { int ret_val = -1000; char *pos; if (CLS_FREE != GetCommLineStatus()) return(ret_val); SetCommLineStatus(CLS_ATCMD); ret_val = -2000; // we do not have right value yet // response is in the format: #ADC: 885 if (AT_RESP_OK == SendATCmdWaitResp("AT#ADC=2,2,0", 500, 20, "#ADC", 1)) { // parse the received string pos = strchr((char *)comm_buf, ' '); if (pos != NULL) { // we are in front of the number ret_val = atoi(pos); ret_val = ret_val - 600; } } SetCommLineStatus(CLS_FREE); return (ret_val); }
/********************************************************** Method initializes GPRS apn: APN string login: user id string password: password string return: ERROR ret. val: --------------- -1 - comm. line is not free OK ret val: ----------- 0 - GPRS was not initialized 1 - GPRS was initialized an example of usage: APN is called internet user id and password are not used GSM gsm; gsm.InitGPRS("internet", "", ""); **********************************************************/ char GSM::InitGPRS(char* apn, char* login, char* password) { char ret_val = -1; char cmd[150]; if (CLS_FREE != GetCommLineStatus()) return (ret_val); SetCommLineStatus(CLS_ATCMD); ret_val = SendATCmdWaitResp("AT+CIPSHUT", 2000, 1000, "SHUT OK", 3); if (ret_val == AT_RESP_OK) { //Set Single IP Connection ret_val = SendATCmdWaitResp("AT+CIPMUX=0", 1000, 1000, "OK", 3); if (ret_val == AT_RESP_OK) { // Set transparent mode ret_val = SendATCmdWaitResp("AT+CIPMODE=1", 1000, 2000, "OK", 3); if (ret_val == AT_RESP_OK) { //prepare AT+CSTT command: AT+CSTT="apn","user","pass" strcpy(cmd, "AT+CSTT=\""); strcat(cmd, apn); strcat(cmd, "\",\""); // add character " and , and " strcat(cmd, login); strcat(cmd, "\",\""); // add character " and , and " strcat(cmd, password); strcat(cmd, "\""); // add character " ret_val = SendATCmdWaitResp(cmd, 1000, 2000, "OK", 5); if (ret_val == AT_RESP_OK) ret_val = 1; else ret_val = 0; } else ret_val = 0; } else ret_val = 0; } else ret_val = 0; SetCommLineStatus(CLS_FREE); return (ret_val); }