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

Contents of /smsdaemon/GsmModem.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 144 - (show annotations) (download)
Sun Dec 7 16:27:34 2008 UTC (15 years, 5 months ago) by torben
File size: 4989 byte(s)
Refactor IGsmModem, in order to ease adding another sms transceiver

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

  ViewVC Help
Powered by ViewVC 1.1.20