1 //
2 // Copyright (C) 2020 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15
16 #include <android-base/logging.h>
17 #include <gtest/gtest.h>
18 #include <stdlib.h>
19
20 #include <filesystem>
21 #include <fstream>
22
23 #include "common/libs/fs/shared_select.h"
24 #include "common/libs/utils/files.h"
25 #include "host/commands/assemble_cvd/flags_defaults.h"
26 #include "host/commands/modem_simulator/channel_monitor.h"
27 #include "host/commands/modem_simulator/device_config.h"
28 #include "host/commands/modem_simulator/modem_simulator.h"
29 #include "host/libs/config/cuttlefish_config.h"
30 namespace fs = std::filesystem;
31
32 static const char *myiccfile =
33 #include "iccfile.txt"
34 ;
35
36 static const std::string tmp_test_dir = std::string(fs::temp_directory_path()) +
37 std::string("/cuttlefish_modem_test");
38 using namespace cuttlefish;
39
40 class ModemServiceTest : public ::testing::Test {
41 protected:
SetUpTestSuite()42 static void SetUpTestSuite() {
43 {
44 cuttlefish::CuttlefishConfig tmp_config_obj;
45 std::string config_file = tmp_test_dir + "/.cuttlefish_config.json";
46 tmp_config_obj.set_root_dir(tmp_test_dir + "/cuttlefish");
47 std::vector<int> instance_nums;
48 for (int i = 0; i < 1; i++) {
49 instance_nums.push_back(cuttlefish::GetInstance() + i);
50 }
51 for (const auto &num : instance_nums) {
52 auto instance = tmp_config_obj.ForInstance(num); // Trigger creation in map
53 instance.set_ril_dns(CF_DEFAULTS_RIL_DNS);
54 }
55
56 for (auto instance : tmp_config_obj.Instances()) {
57 fs::create_directories(instance.instance_dir());
58 if (!tmp_config_obj.SaveToFile(
59 instance.PerInstancePath("cuttlefish_config.json"))) {
60 LOG(ERROR) << "Unable to save copy config object";
61 return;
62 }
63 std::string icfilename =
64 instance.PerInstancePath("/iccprofile_for_sim0.xml");
65 std::ofstream offile = modem::DeviceConfig::open_ofstream_crossplat(icfilename.c_str(), std::ofstream::out);
66 offile << std::string(myiccfile);
67 offile.close();
68 fs::copy_file(instance.PerInstancePath("/cuttlefish_config.json"),
69 config_file, fs::copy_options::overwrite_existing);
70 }
71
72 ::setenv("CUTTLEFISH_CONFIG_FILE", config_file.c_str(), 1);
73 }
74 cuttlefish::SharedFD ril_shared_fd, modem_shared_fd;
75 if (!SharedFD::SocketPair(AF_LOCAL, SOCK_STREAM, 0, &ril_shared_fd,
76 &modem_shared_fd)) {
77 LOG(ERROR) << "Unable to create client socket pair: " << strerror(errno);
78 }
79 ASSERT_TRUE(ril_shared_fd->IsOpen());
80 ASSERT_TRUE(modem_shared_fd->IsOpen());
81
82 NvramConfig::InitNvramConfigService(1, 1);
83
84 ril_side_ = new Client(ril_shared_fd);
85 modem_side_ = new Client(modem_shared_fd);
86 modem_simulator_ = new ModemSimulator(0);
87
88 cuttlefish::SharedFD server;
89 auto channel_monitor =
90 std::make_unique<ChannelMonitor>(*modem_simulator_, server);
91 modem_simulator_->Initialize(std::move(channel_monitor));
92 }
93
TearDownTestSuite()94 static void TearDownTestSuite() {
95 delete ril_side_;
96 delete modem_side_;
97 delete modem_simulator_;
98 fs::remove_all(tmp_test_dir);
99 };
100
SendCommand(std::string command,std::string prefix="")101 void SendCommand(std::string command, std::string prefix = "") {
102 command_prefix_ = prefix;
103 modem_simulator_->DispatchCommand(*modem_side_, command);
104 }
105
ReadCommandResponse(std::vector<std::string> & response)106 void ReadCommandResponse(std::vector<std::string>& response) {
107 do {
108 std::vector<char> buffer(4096); // kMaxCommandLength
109 auto bytes_read =
110 ril_side_->client_read_fd_->Read(buffer.data(), buffer.size());
111 if (bytes_read <= 0) {
112 // Close here to ensure the other side gets reset if it's still
113 // connected
114 ril_side_->client_read_fd_->Close();
115 ril_side_->client_write_fd_->Close();
116 LOG(WARNING) << "Detected close from the other side";
117 break;
118 }
119
120 std::string& incomplete_command = ril_side_->incomplete_command;
121
122 // Add the incomplete command from the last read
123 auto commands = std::string{incomplete_command.data()};
124 commands.append(buffer.data());
125
126 incomplete_command.clear();
127 incomplete_command.resize(0);
128
129 // replacing '\n' with '\r'
130 commands = android::base::StringReplace(commands, "\n", "\r", true);
131
132 // split into commands and dispatch
133 size_t pos = 0, r_pos = 0; // '\r' or '\n'
134 while (r_pos != std::string::npos) {
135 r_pos = commands.find('\r', pos);
136 if (r_pos != std::string::npos) {
137 auto command = commands.substr(pos, r_pos - pos);
138 if (command.size() > 0) { // "\r\r" ?
139 LOG(DEBUG) << "AT< " << command;
140 if (IsFinalResponseSuccess(command) || IsFinalResponseError(command)) {
141 response.push_back(command);
142 return;
143 } else if (IsIntermediateResponse(command)) {
144 response.push_back(command);
145 } else {
146 ; // Ignore unsolicited command
147 }
148 }
149 pos = r_pos + 1; // skip '\r'
150 } else if (pos < commands.length()) { // incomplete command
151 incomplete_command = commands.substr(pos);
152 LOG(VERBOSE) << "incomplete command: " << incomplete_command;
153 }
154 }
155 } while (true);
156
157 // read response
158 }
159
IsFinalResponseSuccess(std::string response)160 inline bool IsFinalResponseSuccess(std::string response) {
161 auto iter = kFinalResponseSuccess.begin();
162 for (; iter != kFinalResponseSuccess.end(); ++iter) {
163 if (*iter == response) {
164 return true;
165 }
166 }
167
168 return false;
169 }
170
IsFinalResponseError(std::string response)171 inline bool IsFinalResponseError(std::string response) {
172 auto iter = kFinalResponseError.begin();
173 for (; iter != kFinalResponseError.end(); ++iter) {
174 if (response.compare(0, iter->size(), *iter) == 0) {
175 return true;
176 }
177 }
178
179 return false;
180 }
181
IsIntermediateResponse(std::string response)182 inline bool IsIntermediateResponse(std::string response) {
183 if (response.compare(0, command_prefix_.size(), command_prefix_) == 0) {
184 return true;
185 }
186
187 return false;
188 }
189
openLogicalChannel(std::string & name)190 int openLogicalChannel(std::string& name) {
191 // Create and send command
192 std::string command = "AT+CCHO=";
193 command.append(name);
194 std::vector<std::string> response;
195 SendCommand(command);
196 ReadCommandResponse(response);
197 int channel = std::stoi(response[0]);
198 return channel;
199 }
200
closeLogicalChannel(int channel)201 bool closeLogicalChannel(int channel) {
202 std::string command = "AT+CCHC=";
203 command += std::to_string(channel);
204 std::vector<std::string> response;
205 SendCommand(command);
206 ReadCommandResponse(response);
207 std::string expect = "+CCHC";
208 return (response[0].compare(0, expect.size(), expect) == 0);
209 }
210
211 const std::vector<std::string> kFinalResponseSuccess = {"OK", "CONNECT", "> "};
212 const std::vector<std::string> kFinalResponseError = {
213 "ERROR",
214 "+CMS ERROR:",
215 "+CME ERROR:",
216 "NO CARRIER", /* sometimes! */
217 "NO ANSWER",
218 "NO DIALTONE",
219 };
220
221 static Client* ril_side_;
222 static Client* modem_side_;
223 static ModemSimulator* modem_simulator_;
224
225 // For distinguishing the response from command response or unsolicited command
226 std::string command_prefix_;
227 };
228
229 ModemSimulator* ModemServiceTest::modem_simulator_ = nullptr;
230 Client* ModemServiceTest::ril_side_ = nullptr;
231 Client* ModemServiceTest::modem_side_ = nullptr;
232
233 /* Sim Service Test */
TEST_F(ModemServiceTest,GetIccCardStatus)234 TEST_F(ModemServiceTest, GetIccCardStatus) {
235 const char *expects[] = {"+CPIN: READY",
236 "OK"};
237
238 std::string command = "AT+CPIN?";
239 std::vector<std::string> response;
240 SendCommand(command, "+CPIN:");
241 ReadCommandResponse(response);
242 ASSERT_EQ(response.size(), 2);
243 ASSERT_STREQ(response[0].c_str(), expects[0]);
244 ASSERT_STREQ(response[1].c_str(), expects[1]);
245 }
246
TEST_F(ModemServiceTest,ChangeOrEnterPIN)247 TEST_F(ModemServiceTest, ChangeOrEnterPIN) {
248 std::vector<std::string> commands = {"AT+CPIN=1234,0000",
249 "AT+CPIN=1111,2222",};
250 std::vector<std::string> expects = {"OK",
251 "+CME ERROR: 16",};
252 std::vector<std::string> response;
253 auto expects_iter = expects.begin();
254 for (auto iter = commands.begin(); iter != commands.end(); ++iter, ++expects_iter) {
255 SendCommand(*iter);
256 ReadCommandResponse(response);
257 ASSERT_STREQ(response[0].c_str(), (*expects_iter).c_str());
258 response.clear();
259 }
260 }
261
TEST_F(ModemServiceTest,SIM_IO)262 TEST_F(ModemServiceTest, SIM_IO) {
263 std::vector<std::string> commands = {"AT+CRSM=192,12258,0,0,15",
264 "AT+CRSM=192,28436,0,0,15",
265 "AT+CRSM=220,28618,1,4,5,0000000000"};
266 std::vector<std::string> expects = {"+CRSM: 144,0,62178202412183022FE28A01058B032F06038002000A880110",
267 "+CRSM: 106,130",
268 "+CRSM: 144,0"};
269
270 std::vector<std::string> response;
271 auto expects_iter = expects.begin();
272 for (auto iter = commands.begin(); iter != commands.end(); ++iter, ++expects_iter) {
273 SendCommand(*iter);
274 ReadCommandResponse(response);
275 ASSERT_EQ(response.size(), 2);
276 ASSERT_STREQ(response[0].c_str(), (*expects_iter).c_str());
277 response.clear();
278 }
279 }
280
TEST_F(ModemServiceTest,GetIMSI)281 TEST_F(ModemServiceTest, GetIMSI) {
282 std::string command = "AT+CIMI";
283 std::vector<std::string> response;
284 SendCommand(command);
285 ReadCommandResponse(response);
286 ASSERT_EQ(response.size(), 2);
287 const char *expect = "460110031689666";
288 ASSERT_STREQ(response[0].c_str(),expect);
289 }
290
TEST_F(ModemServiceTest,GetIccId)291 TEST_F(ModemServiceTest, GetIccId) {
292 std::string command = "AT+CICCID";
293 std::vector<std::string> response;
294 SendCommand(command);
295 ReadCommandResponse(response);
296 ASSERT_EQ(response.size(), 2);
297 const char *expect = "89860318640220133897";
298 ASSERT_STREQ(response[0].c_str(),expect);
299 }
300
TEST_F(ModemServiceTest,FacilityLock)301 TEST_F(ModemServiceTest, FacilityLock) {
302 std::vector<std::string> commands =
303 { "AT+CLCK=\"FD\",2,"",7",
304 "AT+CLCK=\"SC\",2,"",7",
305 "AT+CLCK=\"SC\",1,\"1234\",7",
306 "AT+CLCK=\"SC\",1,\"023000\",7"
307 };
308 std::vector<std::string> expects =
309 { "+CLCK: 0",
310 "+CLCK: 0",
311 "+CME ERROR: 16",
312 "+CME ERROR: 16"
313 };
314 std::vector<std::string> response;
315 auto expects_iter = expects.begin();
316 for (auto iter = commands.begin(); iter != commands.end(); ++iter, ++expects_iter) {
317 SendCommand(*iter);
318 ReadCommandResponse(response);
319 ASSERT_STREQ(response[0].c_str(), (*expects_iter).c_str());
320 response.clear();
321 }
322 }
323
TEST_F(ModemServiceTest,OpenLogicalChannel)324 TEST_F(ModemServiceTest, OpenLogicalChannel) {
325 std::string command= "A000000063504B43532D3135";
326 int firstChannel = openLogicalChannel(command);
327 ASSERT_EQ(firstChannel, 1);
328
329 command= "A000000063504B43532D3135";
330 int secondChannel = openLogicalChannel(command);
331 ASSERT_GE(secondChannel, 1);
332
333 closeLogicalChannel(firstChannel);
334 closeLogicalChannel(secondChannel);
335 }
336
TEST_F(ModemServiceTest,CloseLogicalChannel)337 TEST_F(ModemServiceTest, CloseLogicalChannel) {
338 std::string command= "A000000063504B43532D3135";
339 int channel = openLogicalChannel(command);
340 ASSERT_EQ(channel, 1);
341
342 ASSERT_FALSE(closeLogicalChannel(channel + 3));
343 ASSERT_TRUE(closeLogicalChannel(channel));
344 }
345
TEST_F(ModemServiceTest,TransmitLogicalChannel)346 TEST_F(ModemServiceTest, TransmitLogicalChannel) {
347 std::string command= "A000000063504B43532D3135";
348 int channel = openLogicalChannel(command);
349 ASSERT_EQ(channel, 1);
350 command = "AT+CGLA=";
351 command += channel;
352 command += ",10,80caff4000";
353 std::vector<std::string> response;
354 SendCommand(command);
355 ReadCommandResponse(response);
356 const char *expect = "+CME ERROR: 21";
357 ASSERT_STREQ(response[0].c_str(),expect);
358 ASSERT_TRUE(closeLogicalChannel(channel));
359 }
360
361 /* Network Service Test */
TEST_F(ModemServiceTest,testRadioPowerReq)362 TEST_F(ModemServiceTest, testRadioPowerReq) {
363 std::string command = "AT+CFUN?";
364 std::vector<std::string> response;
365 SendCommand(command, "+CFUN:");
366 ReadCommandResponse(response);
367 ASSERT_EQ(response.size(), 2);
368 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
369 }
370
TEST_F(ModemServiceTest,testSetRadioPower)371 TEST_F(ModemServiceTest, testSetRadioPower) {
372 std::string command = "AT+CFUN=1";
373 std::vector<std::string> response;
374 SendCommand(command);
375 ReadCommandResponse(response);
376 ASSERT_EQ(response.size(), 1);
377 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
378 }
379
TEST_F(ModemServiceTest,testSignalStrength)380 TEST_F(ModemServiceTest, testSignalStrength) {
381 std::string command = "AT+CSQ";
382 std::vector<std::string> response;
383 SendCommand(command, "+CSQ:");
384 ReadCommandResponse(response);
385 ASSERT_EQ(response.size(), 2);
386 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
387 }
388
TEST_F(ModemServiceTest,testQueryNetworkSelectionMode)389 TEST_F(ModemServiceTest, testQueryNetworkSelectionMode) {
390 std::string command = "AT+COPS?";
391 std::vector<std::string> response;
392 SendCommand(command, "+COPS:");
393 ReadCommandResponse(response);
394 ASSERT_EQ(response.size(), 2);
395 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
396 }
397
TEST_F(ModemServiceTest,testRequestOperator)398 TEST_F(ModemServiceTest, testRequestOperator) {
399 std::string command = "AT+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?";
400 std::vector<std::string> response;
401 SendCommand(command, "+COPS:");
402 ReadCommandResponse(response);
403 ASSERT_EQ(response.size(), 4);
404 }
405
TEST_F(ModemServiceTest,testVoiceNetworkRegistration)406 TEST_F(ModemServiceTest, testVoiceNetworkRegistration) {
407 std::string command = "AT+CREG?";
408 std::vector<std::string> response;
409 SendCommand(command, "+CREG:");
410 ReadCommandResponse(response);
411 ASSERT_EQ(response.size(), 2);
412 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
413 }
414
TEST_F(ModemServiceTest,testDataNetworkRegistration)415 TEST_F(ModemServiceTest, testDataNetworkRegistration) {
416 std::string command = "AT+CGREG?";
417 std::vector<std::string> response;
418 SendCommand(command, "+CGREG:");
419 ReadCommandResponse(response);
420 ASSERT_EQ(response.size(), 2);
421 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
422 }
423
TEST_F(ModemServiceTest,testDataNetworkRegistrationWithLte2)424 TEST_F(ModemServiceTest, testDataNetworkRegistrationWithLte2) {
425 std::string command = "AT+CEREG?";
426 std::vector<std::string> response;
427 SendCommand(command, "+CEREG:");
428 ReadCommandResponse(response);
429 ASSERT_EQ(response.size(), 2);
430 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
431 }
432
TEST_F(ModemServiceTest,testGetPreferredNetworkType)433 TEST_F(ModemServiceTest, testGetPreferredNetworkType) {
434 std::string command = "AT+CTEC?";
435 std::vector<std::string> response;
436 SendCommand(command, "+CTEC:");
437 ReadCommandResponse(response);
438 ASSERT_EQ(response.size(), 2);
439 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
440 }
441
TEST_F(ModemServiceTest,testQuerySupportedTechs)442 TEST_F(ModemServiceTest, testQuerySupportedTechs) {
443 std::string command = "AT+CTEC=?";
444 std::vector<std::string> response;
445 SendCommand(command, "+CTEC:");
446 ReadCommandResponse(response);
447 ASSERT_EQ(response.size(), 2);
448 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
449 }
450
TEST_F(ModemServiceTest,testSetPreferredNetworkType)451 TEST_F(ModemServiceTest, testSetPreferredNetworkType) {
452 std::string command = "AT+CTEC=1,\"201\"";
453 std::vector<std::string> response;
454 SendCommand(command, "+CTEC:");
455 ReadCommandResponse(response);
456 ASSERT_EQ(response.size(), 2);
457 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
458 }
459
460 /* Call Service Test */
TEST_F(ModemServiceTest,testCurrentCalls)461 TEST_F(ModemServiceTest, testCurrentCalls) {
462 std::string command = "AT+CLCC";
463 std::vector<std::string> response;
464 SendCommand(command, "+CLCC:");
465 ReadCommandResponse(response);
466 ASSERT_EQ(response.size(), 1);
467 }
468
TEST_F(ModemServiceTest,testHangup)469 TEST_F(ModemServiceTest, testHangup) {
470 for (int i = 0; i < 5; i ++) {
471 std::stringstream ss;
472 ss.clear();
473 ss << "AT+CHLD=" << i;
474 SendCommand(ss.str());
475 }
476 std::vector<std::string> response;
477 ReadCommandResponse(response);
478 ASSERT_EQ(response.size(), 1);
479 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
480 }
481
TEST_F(ModemServiceTest,testMute)482 TEST_F(ModemServiceTest, testMute) {
483 std::string command = "AT+CMUT=1";
484 std::vector<std::string> response;
485 SendCommand(command);
486 ReadCommandResponse(response);
487 ASSERT_EQ(response.size(), 1);
488 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
489 }
490
TEST_F(ModemServiceTest,testSendDtmf)491 TEST_F(ModemServiceTest, testSendDtmf) {
492 std::string command = "AT+VTS=1";
493 std::vector<std::string> response;
494 SendCommand(command);
495 ReadCommandResponse(response);
496 ASSERT_EQ(response.size(), 1);
497 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
498 }
499
TEST_F(ModemServiceTest,testExitEmergencyMode)500 TEST_F(ModemServiceTest, testExitEmergencyMode) {
501 std::string command = "AT+WSOS=0";
502 std::vector<std::string> response;
503 SendCommand(command);
504 ReadCommandResponse(response);
505 ASSERT_EQ(response.size(), 1);
506 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
507 }
508
509 /* Data Service Test */
TEST_F(ModemServiceTest,SetPDPContext)510 TEST_F(ModemServiceTest, SetPDPContext) {
511 std::string command = "AT+CGDCONT=1,\"IPV4V6\",\"ctlte\",,0,0";
512 std::vector<std::string> response;
513 SendCommand(command);
514 ReadCommandResponse(response);
515 ASSERT_EQ(response.size(), 1);
516 ASSERT_STREQ(response.at(0).c_str(), kFinalResponseSuccess[0].c_str());
517 }
518
TEST_F(ModemServiceTest,QueryPDPContextList)519 TEST_F(ModemServiceTest, QueryPDPContextList) {
520 for (int i = 1; i < 5; i ++) {
521 std::stringstream ss;
522 ss.clear();
523 ss << "AT+CGDCONT=" << i << ",\"IPV4V6\",\"ctlte\",,0,0";
524 SendCommand(ss.str());
525 }
526 std::string command = "AT+CGDCONT?";
527 std::vector<std::string> response;
528 SendCommand(command, "+CGDCONT:");
529 ReadCommandResponse(response);
530 const char *result = response[response.size() - 1].c_str();
531 ASSERT_EQ(response.size(), 1);
532 ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
533 }
534
TEST_F(ModemServiceTest,ActivateDataCall)535 TEST_F(ModemServiceTest, ActivateDataCall) {
536 std::string command = "AT+CGACT= 1,0";
537 std::vector<std::string> response;
538 SendCommand(command);
539 ReadCommandResponse(response);
540 const char *result = response[0].c_str();
541 ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
542 }
543
TEST_F(ModemServiceTest,QueryDataCallList)544 TEST_F(ModemServiceTest, QueryDataCallList) {
545 std::string command = "AT+CGACT?";
546 std::vector<std::string> response;
547 SendCommand(command, "+CGACT:");
548 ReadCommandResponse(response);
549 const char *result = response[response.size() - 1].c_str();
550 ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
551 }
552
TEST_F(ModemServiceTest,ReadDynamicParamTrue)553 TEST_F(ModemServiceTest, ReadDynamicParamTrue) {
554 std::string command = "AT+CGCONTRDP=1";
555 std::vector<std::string> response;
556 SendCommand(command);
557 ReadCommandResponse(response);
558 const char *result = response[response.size() - 1].c_str();
559 ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
560 }
561
TEST_F(ModemServiceTest,ReadDynamicParamFalse)562 TEST_F(ModemServiceTest, ReadDynamicParamFalse) {
563 std::string command = "AT+CGCONTRDP=10";
564 std::vector<std::string> response;
565 SendCommand(command);
566 ReadCommandResponse(response);
567 const char *result = response[response.size() - 1].c_str();
568 const char *expect = "+CME ERROR: 21";
569 ASSERT_STREQ(result, expect);
570 }
571
TEST_F(ModemServiceTest,EnterDataState)572 TEST_F(ModemServiceTest, EnterDataState) {
573 std::string command = "AT+CGDATA=1,1";
574 std::vector<std::string> response;
575 SendCommand(command);
576 ReadCommandResponse(response);
577 const char *result = response[response.size() - 1].c_str();
578 ASSERT_STREQ(result, kFinalResponseSuccess[1].c_str());
579 }
580
581 /* SMS Service Test */
TEST_F(ModemServiceTest,SendSMS)582 TEST_F(ModemServiceTest, SendSMS) {
583 std::string command = "AT+CMGS=35";
584 std::vector<std::string> response;
585 SendCommand(command);
586 ReadCommandResponse(response);
587 const char *result = response[response.size() - 1].c_str();
588 const char *expect = "> ";
589 ASSERT_STREQ(result, expect);
590 command = "0001000D91688118109844F0000017AFD7903AB55A9BBA69D639D4ADCBF99E3DCCAE9701^Z";
591 //command += '\032';
592 SendCommand(command);
593 ReadCommandResponse(response);
594 // TODO (bohu) for some reason the following asserts fail, fix them
595 // ASSERT_EQ(response.size(), 3);
596 // ASSERT_STREQ(response[response.size() - 1].c_str(),
597 // kFinalResponseSuccess[0].c_str());
598 }
599
TEST_F(ModemServiceTest,WriteSMSToSim)600 TEST_F(ModemServiceTest, WriteSMSToSim) {
601 std::string command = "AT+CMGW=24,3";
602 std::vector<std::string> response;
603 SendCommand(command);
604 ReadCommandResponse(response);
605 const char *result = response[response.size() - 1].c_str();
606 const char *expect = "> ";
607 ASSERT_STREQ(result, expect);
608 command = "00240B815123106351F100000240516054410005C8329BFD06^Z";
609 SendCommand(command);
610 ReadCommandResponse(response);
611 ASSERT_EQ(response.size(), 3);
612 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
613 }
614
TEST_F(ModemServiceTest,SMSAcknowledge)615 TEST_F(ModemServiceTest, SMSAcknowledge) {
616 std::string command = "AT+CNMA=1";
617 std::vector<std::string> response;
618 SendCommand(command);
619 ReadCommandResponse(response);
620 const char *result = response[response.size() - 1].c_str();
621 ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
622 }
623
TEST_F(ModemServiceTest,DeleteSmsOnSimTure)624 TEST_F(ModemServiceTest, DeleteSmsOnSimTure) {
625 std::string command = "AT+CMGD=1";
626 std::vector<std::string> response;
627 SendCommand(command);
628 ReadCommandResponse(response);
629 const char *result = response[0].c_str();
630 ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
631 }
632
TEST_F(ModemServiceTest,DeleteSmsOnSimFalse)633 TEST_F(ModemServiceTest, DeleteSmsOnSimFalse) {
634 std::string command = "AT+CMGD=1";
635 std::vector<std::string> response;
636 SendCommand(command);
637 ReadCommandResponse(response);
638 const char *result = response[0].c_str();
639 const char *expect = "+CME ERROR: 21";
640 ASSERT_STREQ(result, expect);
641 }
642
TEST_F(ModemServiceTest,SetBroadcastConfig)643 TEST_F(ModemServiceTest, SetBroadcastConfig) {
644 std::string command = "AT+CSCB=0,\"4356\",\"0-255\"";
645 std::vector<std::string> response;
646 SendCommand(command);
647 ReadCommandResponse(response);
648 const char *result = response[0].c_str();
649 ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
650 }
651
TEST_F(ModemServiceTest,GetBroadcastConfig)652 TEST_F(ModemServiceTest, GetBroadcastConfig) {
653 std::string command = "AT+CSCB?";
654 std::vector<std::string> response;
655 SendCommand(command);
656 ReadCommandResponse(response);
657 ASSERT_EQ(response.size(), 2);
658 const char *result = response[response.size() - 1].c_str();
659 ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
660 }
661
TEST_F(ModemServiceTest,SetSmscAddress)662 TEST_F(ModemServiceTest, SetSmscAddress) {
663 std::string command = "AT+CSCA=\"91688115667566F4\",16";
664 std::vector<std::string> response;
665 SendCommand(command);
666 ReadCommandResponse(response);
667 ASSERT_EQ(response.size(), 1);
668 const char *result = response[response.size() - 1].c_str();
669 ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
670 }
671
TEST_F(ModemServiceTest,GetSmscAddress)672 TEST_F(ModemServiceTest, GetSmscAddress) {
673 std::string command = "AT+CSCA?";
674 std::vector<std::string> response;
675 SendCommand(command);
676 ReadCommandResponse(response);
677 ASSERT_EQ(response.size(), 2);
678 const char *result = response[response.size() - 1].c_str();
679 ASSERT_STREQ(result, kFinalResponseSuccess[0].c_str());
680 }
681
682 /* SUP Service Test */
TEST_F(ModemServiceTest,testUSSD)683 TEST_F(ModemServiceTest, testUSSD) {
684 std::string command = "AT+CUSD=1";
685 std::vector<std::string> response;
686 SendCommand(command);
687 ReadCommandResponse(response);
688 ASSERT_EQ(response.size(), 1);
689 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
690 }
691
TEST_F(ModemServiceTest,testCLIR)692 TEST_F(ModemServiceTest, testCLIR) {
693 std::string command = "AT+CLIR=2";
694 std::vector<std::string> response;
695 SendCommand(command);
696 ReadCommandResponse(response);
697 ASSERT_EQ(response.size(), 1);
698 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
699 }
700
TEST_F(ModemServiceTest,testQueryCLIR)701 TEST_F(ModemServiceTest, testQueryCLIR) {
702 std::string command = "AT+CLIR?";
703 std::vector<std::string> response;
704 SendCommand(command, "+CLIR:");
705 ReadCommandResponse(response);
706 ASSERT_EQ(response.size(), 2);
707 }
708
TEST_F(ModemServiceTest,testCallWaiting)709 TEST_F(ModemServiceTest, testCallWaiting) {
710 std::string command = "AT+CCWA";
711 std::vector<std::string> response;
712 SendCommand(command, "+CCWA:");
713 ReadCommandResponse(response);
714 ASSERT_EQ(response.size(), 1);
715 ASSERT_STREQ(response[response.size() - 1].c_str(), kFinalResponseSuccess[0].c_str());
716 }
717
TEST_F(ModemServiceTest,testCLIP)718 TEST_F(ModemServiceTest, testCLIP) {
719 std::string command = "AT+CLIP?";
720 std::vector<std::string> response;
721 SendCommand(command, "+CLIP:");
722 ReadCommandResponse(response);
723 ASSERT_EQ(response.size(), 2);
724 }
725
TEST_F(ModemServiceTest,testCallForward)726 TEST_F(ModemServiceTest, testCallForward) {
727 std::string command = "AT+CCFCU=1,1,2,145,\"10086\"";
728 std::vector<std::string> response;
729 SendCommand(command, "+CCFCU:");
730 ReadCommandResponse(response);
731 ASSERT_EQ(response.size(), 1);
732 }
733
734 /* STK Service Test */
TEST_F(ModemServiceTest,ReportStkServiceIsRunning)735 TEST_F(ModemServiceTest, ReportStkServiceIsRunning) {
736 std::string command = "AT+CUSATD?";
737 std::vector<std::string> response;
738 SendCommand(command);
739 ReadCommandResponse(response);
740 ASSERT_EQ(response.size(), 2);
741 const char *result = response[0].c_str();
742 const char *expect = "+CUSATD: 0,1";
743 ASSERT_STREQ(result, expect);
744 }
745
TEST_F(ModemServiceTest,SendEnvelope)746 TEST_F(ModemServiceTest, SendEnvelope) {
747 std::string command = "AT+CUSATT=\"810301250002028281830100\"";
748 std::vector<std::string> response;
749 SendCommand(command);
750 ReadCommandResponse(response);
751 ASSERT_EQ(response.size(), 2);
752 const char *result = response[0].c_str();
753 const char *expect = "+CUSATT: 0";
754 ASSERT_STREQ(result, expect);
755 }
756
TEST_F(ModemServiceTest,GetSendTerminalResponseToSim)757 TEST_F(ModemServiceTest, GetSendTerminalResponseToSim) {
758 std::string command = "AT+CUSATE=\"D3078202018190014E\"";
759 std::vector<std::string> response;
760 SendCommand(command);
761 ReadCommandResponse(response);
762 ASSERT_EQ(response.size(), 2);
763 const char *result = response[0].c_str();
764 const char *expect = "+CUSATE: 0";
765 ASSERT_STREQ(result, expect);
766 }
767
768 /* Misc Service Test */
TEST_F(ModemServiceTest,GetIMEI)769 TEST_F(ModemServiceTest, GetIMEI) {
770 std::string command = "AT+CGSN";
771 std::vector<std::string> response;
772 SendCommand(command);
773 ReadCommandResponse(response);
774 ASSERT_EQ(response.size(), 2);
775 const char *result = response[0].c_str();
776 const char *expect = "867400022047199";
777 ASSERT_STREQ(result, expect);
778 }
779