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

Contents of /smsdaemon/ModemTransceiver.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 182 - (show annotations) (download)
Fri Dec 12 13:23:01 2008 UTC (15 years, 5 months ago) by torben
File size: 6082 byte(s)
The transceiver should make sure the text is latin 1. It is not something the plugin  should care about!

1 /* 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 #include "serialport/SerialPort.h"
12
13 #include "ModemTransceiver.h"
14
15 #include "Util.h"
16 #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;
24
25
26
27 ModemTransceiver::ModemTransceiver(SerialPort& serialport)
28 : m_port(serialport)
29 {
30 }
31
32
33
34 string ModemTransceiver::GetResponse()
35 {
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
48 string ModemTransceiver::Command(string command, string term)
49 {
50 time_t start,now;
51 start = time(0);
52 _timeout = false;
53
54 if (term != "> ")
55 command.append("\r"); //Dont append CarriageReturn if sending SMS
56
57 m_port.Write(command);
58
59 Util::Sleep(1);
60 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 Util::Sleep(1);
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);
85
86
87 return response;
88 }
89
90 vector<SMS> ModemTransceiver::ReadSms(bool readAll)
91 {
92
93 Command( "AT+CMGF=0" ); //Set SMS format to PDU
94
95 const string search = "+CMGL: ";
96 std::string cmd = "AT+CMGL";
97 if (readAll)
98 cmd.append("=4");
99
100 string result = Command(cmd);
101
102 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
114 string sms_entry = result.substr(0,endpos);
115
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)
127 break;
128
129 result = result.substr(endpos, result.length() - endpos);
130 }
131
132 return retval;
133 }
134
135
136 void ModemTransceiver::SendSmsPdu(std::string pdu, int len) //pdu inclussive leading "00"
137 {
138 Logger::logMessage( string("SMS pdu send") );
139
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 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
173 }
174
175 void ModemTransceiver::DeleteSms(std::string smsIndex)
176 {
177 string cmd = "AT+CMGD=";
178 cmd.append(smsIndex);
179 Command(cmd);
180 }
181
182 int ModemTransceiver::DeleteAllSms()
183 {
184 vector<SMS> sms = ReadSms(true);
185
186 for (unsigned int i= 0; i<sms.size(); ++i)
187 {
188 DeleteSms( sms[i].GetIndex() );
189 }
190 return sms.size();
191 }
192
193
194
195 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
247
248 Command( "AT\\Q3" ); //Hardware flow control
249
250 Command( "ATE0" ); //Disable echo
251
252 Command ("AT^SM20=0,0" ); //No SM20 compability
253
254 //Command("AT+CGATT=1"); //GPRS Attach
255
256 //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 }

Properties

Name Value
svn:mergeinfo

  ViewVC Help
Powered by ViewVC 1.1.20