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

Contents of /smsdaemon/ModemTransceiver.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 171 - (show annotations) (download)
Wed Dec 10 08:59:58 2008 UTC (15 years, 5 months ago) by torben
File size: 4710 byte(s)
Load pin code from config file

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 "SmsHelper.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 retval.push_back( SmsHelper::FromPduString(sms_entry) );;
116
117 if (endpos == string::npos)
118 break;
119
120 result = result.substr(endpos, result.length() - endpos);
121 }
122
123 return retval;
124 }
125
126
127 void ModemTransceiver::SendSmsPdu(std::string pdu, int len) //pdu inclussive leading "00"
128 {
129 Logger::logMessage( string("SMS pdu send") );
130
131 Command("AT+CMGF=0");
132 Util::Sleep(2);
133
134 string line1 = "AT+CMGS=";
135 line1.append( Util::str_formatint(len) );
136 line1.append("\r");
137
138
139 Command(line1,"> ");
140
141 pdu.append("\032"); // \032 == Ctrl+Z
142 Command( pdu );
143 Util::Sleep( 50 );
144 Common::instance()->smsCounter.outgoing++;
145 }
146
147 void ModemTransceiver::SendSms(string to, string message, bool allowMultipart)
148 {
149 Logger::logMessage( string("SMS send to ") + to);
150
151 if (to.at(0) == '+')
152 to.erase(0,0);
153
154 vector<PduInfo> pdu_vec = SmsPdu::CreateSmsPdu(to, Util::str_latin2gsm(message), allowMultipart);
155
156 for (unsigned i=0; i<pdu_vec.size(); ++i)
157 {
158 PduInfo& pdu = pdu_vec[i];
159
160 SendSmsPdu(pdu.pdu, pdu.len);
161 }
162 Logger::logMessage( "All PDU's send");
163
164 }
165
166 void ModemTransceiver::DeleteSms(std::string smsIndex)
167 {
168 string cmd = "AT+CMGD=";
169 cmd.append(smsIndex);
170 Command(cmd);
171 }
172
173 int ModemTransceiver::DeleteAllSms()
174 {
175 vector<SMS> sms = ReadSms(true);
176
177 for (unsigned int i= 0; i<sms.size(); ++i)
178 {
179 DeleteSms( sms[i].GetIndex() );
180 }
181 return sms.size();
182 }
183
184
185
186 void ModemTransceiver::WaitForSimcard()
187 {
188 int start = time(0);
189 string result;
190
191
192 while (result != "^SSIM READY")
193 {
194 result += GetResponse();
195 result = Util::str_trim(result);
196
197 if ( (time(0) - start) > 10)
198 throw std::runtime_error("Sim card timed out:");
199 Util::Sleep(100);
200 }
201
202 }
203
204 void ModemTransceiver::HandlePincode()
205 {
206 string pin = Common::instance()->GetConfigfile()->GetValue("gsmmodem","pin");
207
208 string result = Command("AT+CPIN?");
209 result = Util::str_trim(result);
210 result.erase(result.length() -2, 2); //remove trailing ok
211 result = Util::str_trim(result);
212 if (result != "+CPIN: READY")
213 {
214 if (result == "+CPIN: SIM PIN")
215 {
216 Command("AT^SSET=1");
217 result = Command( string("AT+CPIN=")+pin );
218 if ( result.substr(result.length()-4, 4) != "OK\r\n")
219 throw std::runtime_error(string("Illegal pincode: ") + result);
220
221 WaitForSimcard();
222 }
223 else
224 {
225 throw std::runtime_error(string("AT+CPIN? returned unhandled code: ") + result);
226 }
227
228 }
229 }
230
231 void ModemTransceiver::Init()
232 {
233 Command( "AT" );
234 if (_timeout)
235 throw std::runtime_error("Modem did not respond!");
236
237 Command( "ATZ" ); //Reset any previous setup
238
239 Command( "AT\\Q3" ); //Hardware flow control
240
241 Command( "ATE0" ); //Disable echo
242
243 Command ("AT^SM20=0,0" ); //No SM20 compability
244
245 //Command("AT+CGATT=1"); //GPRS Attach
246
247 //Command("AT+CGSMS=2"); //SMS over GPRS preferred
248
249 HandlePincode();
250 }

Properties

Name Value
svn:mergeinfo

  ViewVC Help
Powered by ViewVC 1.1.20