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

Contents of /smsdaemon/ModemTransceiver.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 158 - (show annotations) (download)
Mon Dec 8 21:49:49 2008 UTC (15 years, 5 months ago) by torben
File size: 4595 byte(s)
rename:
	util.* -> Util.*
	common.* -> Common.*

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

Properties

Name Value
svn:mergeinfo

  ViewVC Help
Powered by ViewVC 1.1.20