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

Annotation of /smsdaemon/ModemTransceiver.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 210 - (hide annotations) (download)
Sun Dec 21 21:14:40 2008 UTC (15 years, 5 months ago) by torben
File size: 5899 byte(s)
No usage for DeleteAllSms(), since all incoming messages should be serviced

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

Properties

Name Value
svn:mergeinfo

  ViewVC Help
Powered by ViewVC 1.1.20