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 "host/commands/modem_simulator/misc_service.h"
17
18 #include <ctime>
19 #include <iomanip>
20
21 namespace cuttlefish {
22
MiscService(int32_t service_id,ChannelMonitor * channel_monitor,ThreadLooper * thread_looper)23 MiscService::MiscService(int32_t service_id, ChannelMonitor* channel_monitor,
24 ThreadLooper* thread_looper)
25 : ModemService(service_id, this->InitializeCommandHandlers(),
26 channel_monitor, thread_looper) {}
27
InitializeCommandHandlers()28 std::vector<CommandHandler> MiscService::InitializeCommandHandlers() {
29 std::vector<CommandHandler> command_handlers = {
30 /* initializeCallback */
31 CommandHandler("E0Q0V1",
32 [this](const Client& client) {
33 this->HandleCommandDefaultSupported(client);
34 }),
35 CommandHandler("S0=0",
36 [this](const Client& client) {
37 this->HandleCommandDefaultSupported(client);
38 }),
39 CommandHandler("+CMEE=1",
40 [this](const Client& client) {
41 this->HandleCommandDefaultSupported(client);
42 }),
43 CommandHandler("+CMOD=0",
44 [this](const Client& client) {
45 this->HandleCommandDefaultSupported(client);
46 }),
47 CommandHandler("+CSSN=0,1",
48 [this](const Client& client) {
49 this->HandleCommandDefaultSupported(client);
50 }),
51 CommandHandler("+COLP=0",
52 [this](const Client& client) {
53 this->HandleCommandDefaultSupported(client);
54 }),
55 CommandHandler("+CSCS=\"HEX\"",
56 [this](const Client& client) {
57 this->HandleCommandDefaultSupported(client);
58 }),
59 CommandHandler("+CMGF=0",
60 [this](const Client& client) {
61 this->HandleCommandDefaultSupported(client);
62 }),
63
64 CommandHandler("+CGSN",
65 [this](const Client& client, std::string& cmd) {
66 this->HandleGetIMEI(client, cmd);
67 }),
68 };
69 return (command_handlers);
70 }
71
HandleGetIMEI(const Client & client,std::string & command)72 void MiscService::HandleGetIMEI(const Client& client, std::string& command) {
73 const std::string identityGsmImei = "12345678902468";
74 const std::string identityGsmSvn = "01";
75 const std::string information = "modem simulator";
76
77 std::vector<std::string> responses;
78
79 if (command == "AT+CGSN") {
80 responses.push_back(identityGsmImei);
81 } else {
82 CommandParser cmd(command);
83 cmd.SkipPrefix();
84 int snt = cmd.GetNextInt();
85 switch (snt) {
86 case 0: // SN: IMEI and more information provided by manufacturers
87 responses.push_back(identityGsmImei + information);
88 break;
89 case 1: // IMEI
90 responses.push_back(identityGsmImei);
91 break;
92 case 2: // IMEI and software version number
93 responses.push_back(identityGsmImei + identityGsmSvn);
94 break;
95 case 3: // Software version number
96 responses.push_back(identityGsmSvn);
97 break;
98 default: // Default IMEI
99 responses.push_back(identityGsmImei);
100 break;
101 }
102 }
103
104 responses.push_back("OK");
105 client.SendCommandResponse(responses);
106 }
107
TimeUpdate()108 void MiscService::TimeUpdate() {
109 auto now = std::time(0);
110
111 auto local_time = *std::localtime(&now);
112 auto gm_time = *std::gmtime(&now);
113
114 auto t_local_time = std::mktime(&local_time);
115 auto t_gm_time = std::mktime(&gm_time);
116
117 auto tzdiff = (int)std::difftime(t_local_time, t_gm_time) / (60 * 60);
118
119 std::stringstream ss;
120 ss << "%CTZV: \"" << std::setfill('0') << std::setw(2) << local_time.tm_year % 100 << "/"
121 << std::setfill('0') << std::setw(2) << local_time.tm_mon + 1 << "/"
122 << std::setfill('0') << std::setw(2) << local_time.tm_mday << ","
123 << std::setfill('0') << std::setw(2) << local_time.tm_hour << ":"
124 << std::setfill('0') << std::setw(2) << local_time.tm_min << ":"
125 << std::setfill('0') << std::setw(2) << local_time.tm_sec
126 << (tzdiff >= 0 ? '+' : '-')
127 << (tzdiff >= 0 ? tzdiff : -tzdiff) << ":"
128 << local_time.tm_isdst << "\"";
129
130 SendUnsolicitedCommand(ss.str());
131 }
132
133 } // namespace cuttlefish
134