/[projects]/smsdaemon/ModemTransceiver.cpp
ViewVC logotype

Diff of /smsdaemon/ModemTransceiver.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

smsdaemon/GsmModem.cpp revision 26 by torben, Mon Jun 9 18:15:53 2008 UTC smsdaemon/ModemTransceiver.cpp revision 182 by torben, Fri Dec 12 13:23:01 2008 UTC
# Line 2  Line 2 
2   */   */
3    
4  #include <iostream>  #include <iostream>
   
5  #include <string>  #include <string>
 #include <cstring>  
6  #include <stdexcept>  #include <stdexcept>
7    
 #include <sys/time.h>  
8  #include <time.h>  #include <time.h>
9    
10    
11  #include "SerialPort.h"  #include "serialport/SerialPort.h"
12    
13  #include "GsmModem.h"  #include "ModemTransceiver.h"
14    
15  #include "util.h"  #include "Util.h"
16  #include "common.h"  #include "Common.h"
17    #include "Logger.h"
18    #include "ConfigFile.h"
19    
20    #include "SmsPdu.h"
21    #include "Exceptions.h"
22    
23  using namespace std;  using namespace std;
24    
25    
26    
27  GsmModem::GsmModem(SerialPort& serialport)  ModemTransceiver::ModemTransceiver(SerialPort& serialport)
28  : m_port(serialport)                  : m_port(serialport)
29  {  {
         Init();  
30  }  }
31    
32    
33    
34  string GsmModem::GetResponse()  string ModemTransceiver::GetResponse()
35  {  {
36    
37          SerialPort::DataBuffer buf;          SerialPort::DataBuffer buf;
# Line 44  string GsmModem::GetResponse() Line 44  string GsmModem::GetResponse()
44          return str;          return str;
45  }  }
46    
47  string GsmModem::Command(string command, string term)  
48    string ModemTransceiver::Command(string command, string term)
49  {  {
50          time_t  start,now;          time_t  start,now;
51          start = time(0);          start = time(0);
52            _timeout = false;
53    
54            if (term != "> ")
55                    command.append("\r"); //Dont append CarriageReturn if sending SMS
56    
         command.append("\r");  
57          m_port.Write(command);          m_port.Write(command);
58    
59          Util::Sleep(25);          Util::Sleep(1);
60          string response = GetResponse();          string response = GetResponse();
61    
   
62          unsigned int tlen = term.length();          unsigned int tlen = term.length();
63          while ( 1 )          while ( 1 )
64          {          {
# Line 66  string GsmModem::Command(string command, Line 69  string GsmModem::Command(string command,
69                  }                  }
70    
71                  response += GetResponse();                  response += GetResponse();
72                  Util::Sleep(25);                  Util::Sleep(1);
   
         now = time(0);  
         if ( (now-start) > 10 )  
         {  
                 Common::instance()->logMessage( string("GsmModem::Command time out --") + command);  
             break;  
         }  
   
73    
74                    now = time(0);
75                    if ( (now-start) > 10 )
76                    {
77                            Logger::logMessage( string("ModemTransceiver::Command time out --") + command);
78                            Logger::logMessage( string("Modem responded: ") + Util::str_trim(response) );
79                            _timeout = true;
80                            break;
81                    }
82          }          }
83    
84          Util::Sleep(5);          Util::Sleep(5);
85    
 //      cout  << response.length() << ":" << response << endl;  
 //      DumpString(response);  
86    
87          return response;          return response;
88  }  }
89    
90  vector<SMS> GsmModem::ReadSms(bool readAll)  vector<SMS> ModemTransceiver::ReadSms(bool readAll)
91  {  {
92    
93            Command( "AT+CMGF=0" ); //Set SMS format to PDU
94    
95          const string search = "+CMGL: ";          const string search = "+CMGL: ";
96          std::string cmd = "AT+CMGL";          std::string cmd = "AT+CMGL";
97          if (readAll)          if (readAll)
98                  cmd.append("=ALL");                  cmd.append("=4");
99    
100          string result = Command(cmd);          string result = Command(cmd);
101                    
102          vector<SMS> retval;          vector<SMS> retval;
103          if (result.find(search) == string::npos)          if (result.find(search) == string::npos)
104                  return retval;                  return retval;
# Line 106  vector<SMS> GsmModem::ReadSms(bool readA Line 110  vector<SMS> GsmModem::ReadSms(bool readA
110          {          {
111                  unsigned int endpos = result.find(search,5);                  unsigned int endpos = result.find(search,5);
112    
113                    
114                  string sms_entry = result.substr(0,endpos);                  string sms_entry = result.substr(0,endpos);
115                  retval.push_back( SMS::FromRawString(sms_entry) );;  
116                    try
117                    {
118                            SMS sms = FromPduString(sms_entry);
119    
120                            retval.push_back( sms );
121                    }
122                    catch (smsnotfoundexception& e) //do nothing
123                    {
124                    }
125    
126                  if (endpos == string::npos)                  if (endpos == string::npos)
127                          break;                          break;
128            
129                  result = result.substr(endpos, result.length() - endpos);                  result = result.substr(endpos, result.length() - endpos);
130          }          }
131    
132          return retval;          return retval;
133  }  }
134    
135  void GsmModem::SendSms(string to, string message)  
136    void ModemTransceiver::SendSmsPdu(std::string pdu, int len) //pdu inclussive leading "00"
137  {  {
138          Common::instance()->logMessage( string("SMS send to ") + to);          Logger::logMessage( string("SMS pdu send") );
139    
140          Command("AT+CMGF=1");///Allways telling the format makes the application more stable          Command("AT+CMGF=0");
141          Util::Sleep(2);          Util::Sleep(2);
142    
143          string line1 = "AT+CMGS=";          string line1 = "AT+CMGS=";
144          line1.append(to);          line1.append( Util::str_formatint(len) );
145          line1.append("\r");          line1.append("\r");
146    
147    
148          Command(line1,"> ");          Command(line1,"> ");
149    
150            pdu.append("\032"); // \032 == Ctrl+Z
151            Command( pdu );
152            Util::Sleep( 50 );
153            Common::instance()->smsCounter.outgoing++;
154    }
155    
156          message.append("\032\r"); // \032 == Ctrl+Z  void ModemTransceiver::SendSms(string to, string message, bool allowMultipart)
157    {
158            Logger::logMessage( string("SMS send to ") + to);
159    
160            if (to.at(0) == '+')
161                    to.erase(0,0);
162    
163            vector<PduInfo> pdu_vec = SmsPdu::CreateSmsPdu(to, Util::str_latin2gsm(message), allowMultipart);
164    
165            for (unsigned i=0; i<pdu_vec.size(); ++i)
166            {
167                    PduInfo& pdu = pdu_vec[i];
168    
169                    SendSmsPdu(pdu.pdu, pdu.len);
170            }
171            Logger::logMessage( "All PDU's send");
172    
         Command(message);  
         Util::Sleep(50); //Give the modem some time to send the sms and be ready again  
173  }  }
174    
175  void GsmModem::DeleteSms(std::string smsIndex)  void ModemTransceiver::DeleteSms(std::string smsIndex)
176  {  {
177          string cmd = "AT+CMGD=";          string cmd = "AT+CMGD=";
178          cmd.append(smsIndex);          cmd.append(smsIndex);
179          Command(cmd);          Command(cmd);
180  }  }
181    
182  int  GsmModem::DeleteAllSms()  int  ModemTransceiver::DeleteAllSms()
183  {  {
184          vector<SMS> sms = ReadSms(true);          vector<SMS> sms = ReadSms(true);
185    
186          for (unsigned int i= 0; i<sms.size(); ++i)          for (unsigned int i= 0; i<sms.size(); ++i)
187          {          {
188                  DeleteSms( sms[i].sms_index);                  DeleteSms( sms[i].GetIndex() );
189          }          }
190          return sms.size();          return sms.size();
191  }  }
192    
193    
194    
195  void GsmModem::Init()  void ModemTransceiver::WaitForSimcard()
196    {
197            int start = time(0);
198            string result;
199    
200    
201            while (result != "^SSIM READY")
202            {
203                    result += GetResponse();
204                    result = Util::str_trim(result);
205    
206                    if ( (time(0) - start) > 10)
207                            throw std::runtime_error("Sim card timed out:");
208                    Util::Sleep(100);
209            }
210    
211    }
212    
213    void ModemTransceiver::HandlePincode()
214  {  {
215            string pin = Common::instance()->GetConfigfile()->GetValue("gsmmodem","pin");
216    
217            string result = Command("AT+CPIN?");
218            result = Util::str_trim(result);
219            result.erase(result.length() -2, 2); //remove trailing ok
220            result = Util::str_trim(result);
221            if (result != "+CPIN: READY")
222            {
223                    if (result == "+CPIN: SIM PIN")
224                    {
225                            Command("AT^SSET=1");
226                            result = Command( string("AT+CPIN=")+pin  );
227                            if ( result.substr(result.length()-4, 4) != "OK\r\n")
228                                    throw std::runtime_error(string("Illegal pincode: ") + result);
229    
230                            WaitForSimcard();
231                    }
232                    else
233                    {
234                            throw std::runtime_error(string("AT+CPIN? returned unhandled code: ") + result);
235                    }
236    
237            }
238    }
239    
240    void ModemTransceiver::Init()
241    {
242            Command( "AT" );
243            if (_timeout)
244                    throw std::runtime_error("Modem did not respond!");
245    
246          Command( "ATZ" ); //Reset any previous setup          Command( "ATZ" ); //Reset any previous setup
247    
248          Command( "ATE0" ); //Disable echo          Command( "AT\\Q3" ); //Hardware flow control
249    
250          Command( "AT+CMGF=1" ); //Set SMS format to text          Command( "ATE0" ); //Disable echo
251    
252          Command ("AT^SM20=0,0" ); //No SM20 compability          Command ("AT^SM20=0,0" ); //No SM20 compability
253    
254          //Set RealTimeClock ??          //Command("AT+CGATT=1"); //GPRS Attach
255            
256          //Enter pin code ??          //Command("AT+CGSMS=2"); //SMS over GPRS preferred
257    
258            HandlePincode();
259    }
260    
261    
262    SMS ModemTransceiver::FromRawString(const std::string& input)
263    {
264            std::string smsline = input.substr(7, input.length() -7); //strip "+CMGL: "
265    
266            std::vector<std::string> lines = Util::str_split(smsline, "\r\n");
267            std::vector<std::string> fields = Util::str_split(lines[0],",");
268    
269            std::string body;
270            for (unsigned i=1; i<lines.size(); ++i)
271            {
272                    std::string body_line = lines[i];
273    
274    
275                    if (body_line != "")
276                    {
277                            if (body.length() > 0)
278                                    body += "\r\n";
279                            body += body_line;
280                    }
281            }
282    
283            body = Util::str_trim(body);
284    
285            SMS sms;
286    
287            sms.SetIndex( fields[0] );
288    
289    
290            std::string sender = fields[2];
291            sender = Util::str_replace(sender, "\"");
292            sms.SetSender(sender);
293    
294            std::string timestamp = fields[4] + std::string(",") + fields[5];
295            timestamp = Util::str_replace(timestamp, "\"");
296            sms.SetTimestamp(timestamp);
297    
298            sms.SetMessage( Util::str_gsm2latin(body) );
299    
300            return sms;
301    }
302    
303    SMS ModemTransceiver::FromPduString(const std::string& input)
304    {
305            std::string smsline = input.substr(7, input.length() -7); //strip "+CMGL: "
306    
307            std::vector<std::string> lines = Util::str_split(smsline, "\r\n");
308            std::vector<std::string> fields = Util::str_split(lines[0],",");
309    
310            std::string index = fields[0];
311            DeleteSms(index);
312    
313            SMS sms = SmsPdu::ParseSmsPdu(lines[1]);
314    
315            sms.SetIndex(index);
316    
317            sms.SetMessage( Util::str_gsm2latin(sms.GetMessage()) ) ;
318    
319            return sms;
320  }  }
321    
322    
323    
324    

Legend:
Removed from v.26  
changed lines
  Added in v.182

  ViewVC Help
Powered by ViewVC 1.1.20