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

Contents of /smsdaemon/GsmModem.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 136 - (show annotations) (download)
Sun Dec 7 10:15:44 2008 UTC (15 years, 5 months ago) by torben
File size: 4863 byte(s)
ToDo, SmsPdu.cpp: Fix issue whith Multipart SMS skips a byte in each intersection.

GsmModem.cpp: write a log line when all pdu's has been send.


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 "GsmModem.h"
14
15 #include "util.h"
16 #include "common.h"
17
18 #include "SmsPdu.h"
19
20 using namespace std;
21
22
23
24 GsmModem::GsmModem(SerialPort& serialport)
25 : m_port(serialport)
26 {
27 }
28
29
30
31 string GsmModem::GetResponse()
32 {
33
34 SerialPort::DataBuffer buf;
35 m_port.Read(buf);
36
37 buf.push_back(0);
38
39 std::string str((char*) &buf[0]);
40
41 return str;
42 }
43
44
45 string GsmModem::Command(string command, string term)
46 {
47 time_t start,now;
48 start = time(0);
49 _timeout = false;
50
51 if (term != "> ")
52 command.append("\r"); //Dont append CarriageReturn if sending SMS
53
54 m_port.Write(command);
55
56 Util::Sleep(1);
57 string response = GetResponse();
58
59 unsigned int tlen = term.length();
60 while ( 1 )
61 {
62 if (response.length() >= tlen)
63 {
64 if (response.substr(response.length()-tlen,tlen) == term)
65 break;
66 }
67
68 response += GetResponse();
69 Util::Sleep(1);
70
71 now = time(0);
72 if ( (now-start) > 10 )
73 {
74 Common::instance()->logMessage( string("GsmModem::Command time out --") + command);
75 Common::instance()->logMessage( string("Modem responded: ") + Util::str_trim(response) );
76 _timeout = true;
77 break;
78 }
79 }
80
81 Util::Sleep(5);
82
83
84 return response;
85 }
86
87 vector<SMS> GsmModem::ReadSms(bool readAll)
88 {
89
90 Command( "AT+CMGF=0" ); //Set SMS format to PDU
91
92 const string search = "+CMGL: ";
93 std::string cmd = "AT+CMGL";
94 if (readAll)
95 cmd.append("=4");
96
97 string result = Command(cmd);
98
99 vector<SMS> retval;
100 if (result.find(search) == string::npos)
101 return retval;
102
103 result = result.substr(2, result.length() - 8); //remove trailing "\r\nOK\r\n" and initial "\r\n"
104
105
106 while ( 1 )
107 {
108 unsigned int endpos = result.find(search,5);
109
110
111 string sms_entry = result.substr(0,endpos);
112 retval.push_back( SMS::FromPduString(sms_entry) );;
113
114 if (endpos == string::npos)
115 break;
116
117 result = result.substr(endpos, result.length() - endpos);
118 }
119
120 return retval;
121 }
122
123
124 void GsmModem::SendSmsPdu(std::string pdu, int len) //pdu inclussive leading "00"
125 {
126 Common::instance()->logMessage( string("SMS pdu send") );
127
128 Command("AT+CMGF=0");
129 Util::Sleep(2);
130
131 string line1 = "AT+CMGS=";
132 line1.append( Util::str_formatint(len) );
133 line1.append("\r");
134
135
136 Command(line1,"> ");
137
138 pdu.append("\032"); // \032 == Ctrl+Z
139 Command( pdu );
140 Util::Sleep( 50 );
141 Common::instance()->smsCounter.outgoing++;
142 }
143
144 void GsmModem::SendSms(string to, string message, bool allowMultipart)
145 {
146 Common::instance()->logMessage( string("SMS send to ") + to);
147
148 if (to.at(0) == '+')
149 to.erase(0,0);
150
151 vector<PduInfo> pdu_vec = SmsPdu::CreateSmsPdu(to, Util::str_latin2gsm(message), allowMultipart);
152
153 for (unsigned i=0; i<pdu_vec.size(); ++i)
154 {
155 PduInfo& pdu = pdu_vec[i];
156
157 SendSmsPdu(pdu.pdu, pdu.len);
158 }
159 Common::instance()->logMessage( "All PDU's send");
160
161 }
162
163 void GsmModem::DeleteSms(std::string smsIndex)
164 {
165 string cmd = "AT+CMGD=";
166 cmd.append(smsIndex);
167 Command(cmd);
168 }
169
170 int GsmModem::DeleteAllSms()
171 {
172 vector<SMS> sms = ReadSms(true);
173
174 for (unsigned int i= 0; i<sms.size(); ++i)
175 {
176 DeleteSms( sms[i].sms_index);
177 }
178 return sms.size();
179 }
180
181
182
183 void GsmModem::WaitForSimcard()
184 {
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 void GsmModem::HandlePincode()
202 {
203 string result = Command("AT+CPIN?");
204 result = Util::str_trim(result);
205 result.erase(result.length() -2, 2); //remove trailing ok
206 result = Util::str_trim(result);
207 if (result != "+CPIN: READY")
208 {
209 if (result == "+CPIN: SIM PIN")
210 {
211 Command("AT^SSET=1");
212 result = Command("AT+CPIN=0067");
213 if ( result.substr(result.length()-4, 4) != "OK\r\n")
214 throw std::runtime_error(string("Illegal pincode: ") + result);
215
216 WaitForSimcard();
217 }
218 else
219 {
220 throw std::runtime_error(string("AT+CPIN? returned unhandled code: ") + result);
221 }
222
223 }
224 }
225
226 void GsmModem::Init()
227 {
228 Command( "AT" );
229 if (_timeout)
230 throw std::runtime_error("Modem did not respond!");
231
232 Command( "ATZ" ); //Reset any previous setup
233
234 Command( "AT\\Q3" ); //Hardware flow control
235
236 Command( "ATE0" ); //Disable echo
237
238 Command ("AT^SM20=0,0" ); //No SM20 compability
239
240 //Command("AT+CGATT=1"); //GPRS Attach
241
242 //Command("AT+CGSMS=2"); //SMS over GPRS preferred
243
244 HandlePincode();
245 }
246
247
248
249
250 void DebugGsmModem::SendSms(std::string to, std::string message, bool allowMultipart)
251 {
252 _to=to;
253 _message = message;
254 _multipart = allowMultipart;
255
256 if (_print)
257 {
258 cout << "DebugGsmModem::SendSms --------------" << endl;
259 cout << "To: " << to << endl;;
260 cout << "Message: " << message << endl;
261 cout << "Multipart: " << allowMultipart << endl;
262
263 }
264 }

  ViewVC Help
Powered by ViewVC 1.1.20