/* using http://sourceforge.net/projects/libserial/ */ #include #include #include #include #include "serialport/SerialPort.h" #include "GsmModem.h" #include "util.h" #include "common.h" #include "SmsPdu.h" #include "SmsHelper.h" using namespace std; GsmModem::GsmModem(SerialPort& serialport) : m_port(serialport) { } string GsmModem::GetResponse() { SerialPort::DataBuffer buf; m_port.Read(buf); buf.push_back(0); std::string str((char*) &buf[0]); return str; } string GsmModem::Command(string command, string term) { time_t start,now; start = time(0); _timeout = false; if (term != "> ") command.append("\r"); //Dont append CarriageReturn if sending SMS m_port.Write(command); Util::Sleep(1); string response = GetResponse(); unsigned int tlen = term.length(); while ( 1 ) { if (response.length() >= tlen) { if (response.substr(response.length()-tlen,tlen) == term) break; } response += GetResponse(); Util::Sleep(1); now = time(0); if ( (now-start) > 10 ) { Common::instance()->logMessage( string("GsmModem::Command time out --") + command); Common::instance()->logMessage( string("Modem responded: ") + Util::str_trim(response) ); _timeout = true; break; } } Util::Sleep(5); return response; } vector GsmModem::ReadSms(bool readAll) { Command( "AT+CMGF=0" ); //Set SMS format to PDU const string search = "+CMGL: "; std::string cmd = "AT+CMGL"; if (readAll) cmd.append("=4"); string result = Command(cmd); vector retval; if (result.find(search) == string::npos) return retval; result = result.substr(2, result.length() - 8); //remove trailing "\r\nOK\r\n" and initial "\r\n" while ( 1 ) { unsigned int endpos = result.find(search,5); string sms_entry = result.substr(0,endpos); retval.push_back( SmsHelper::FromPduString(sms_entry) );; if (endpos == string::npos) break; result = result.substr(endpos, result.length() - endpos); } return retval; } void GsmModem::SendSmsPdu(std::string pdu, int len) //pdu inclussive leading "00" { Common::instance()->logMessage( string("SMS pdu send") ); Command("AT+CMGF=0"); Util::Sleep(2); string line1 = "AT+CMGS="; line1.append( Util::str_formatint(len) ); line1.append("\r"); Command(line1,"> "); pdu.append("\032"); // \032 == Ctrl+Z Command( pdu ); Util::Sleep( 50 ); Common::instance()->smsCounter.outgoing++; } void GsmModem::SendSms(string to, string message, bool allowMultipart) { Common::instance()->logMessage( string("SMS send to ") + to); if (to.at(0) == '+') to.erase(0,0); vector pdu_vec = SmsPdu::CreateSmsPdu(to, Util::str_latin2gsm(message), allowMultipart); for (unsigned i=0; ilogMessage( "All PDU's send"); } void GsmModem::DeleteSms(std::string smsIndex) { string cmd = "AT+CMGD="; cmd.append(smsIndex); Command(cmd); } int GsmModem::DeleteAllSms() { vector sms = ReadSms(true); for (unsigned int i= 0; i 10) throw std::runtime_error("Sim card timed out:"); Util::Sleep(100); } } void GsmModem::HandlePincode() { string result = Command("AT+CPIN?"); result = Util::str_trim(result); result.erase(result.length() -2, 2); //remove trailing ok result = Util::str_trim(result); if (result != "+CPIN: READY") { if (result == "+CPIN: SIM PIN") { Command("AT^SSET=1"); result = Command("AT+CPIN=0067"); if ( result.substr(result.length()-4, 4) != "OK\r\n") throw std::runtime_error(string("Illegal pincode: ") + result); WaitForSimcard(); } else { throw std::runtime_error(string("AT+CPIN? returned unhandled code: ") + result); } } } void GsmModem::Init() { Command( "AT" ); if (_timeout) throw std::runtime_error("Modem did not respond!"); Command( "ATZ" ); //Reset any previous setup Command( "AT\\Q3" ); //Hardware flow control Command( "ATE0" ); //Disable echo Command ("AT^SM20=0,0" ); //No SM20 compability //Command("AT+CGATT=1"); //GPRS Attach //Command("AT+CGSMS=2"); //SMS over GPRS preferred HandlePincode(); } void DebugGsmModem::SendSms(std::string to, std::string message, bool allowMultipart) { _to=to; _message = message; _multipart = allowMultipart; if (_print) { cout << "DebugGsmModem::SendSms --------------" << endl; cout << "To: " << to << endl;; cout << "Message: " << message << endl; cout << "Multipart: " << allowMultipart << endl; } }