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/modem_service.h"
17
18 #include <android-base/logging.h>
19
20 #include <cstring>
21
22 #include "host/commands/modem_simulator/device_config.h"
23
24 namespace cuttlefish {
25
26 const std::string ModemService::kCmeErrorOperationNotAllowed = "+CME ERROR: 3";
27 const std::string ModemService::kCmeErrorOperationNotSupported = "+CME ERROR: 4";
28 const std::string ModemService::kCmeErrorSimNotInserted = "+CME ERROR: 10";
29 const std::string ModemService::kCmeErrorSimPinRequired = "+CME ERROR: 11";
30 const std::string ModemService::kCmeErrorSimPukRequired = "+CME ERROR: 12";
31 const std::string ModemService::kCmeErrorSimBusy = "+CME ERROR: 14";
32 const std::string ModemService::kCmeErrorIncorrectPassword = "+CME ERROR: 16";
33 const std::string ModemService::kCmeErrorMemoryFull = "+CME ERROR: 20";
34 const std::string ModemService::kCmeErrorInvalidIndex = "+CME ERROR: 21";
35 const std::string ModemService::kCmeErrorNotFound = "+CME ERROR: 22";
36 const std::string ModemService::kCmeErrorInvalidCharactersInTextString = "+CME ERROR: 27";
37 const std::string ModemService::kCmeErrorNoNetworkService = "+CME ERROR: 30";
38 const std::string ModemService::kCmeErrorNetworkNotAllowedEmergencyCallsOnly = "+CME ERROR: 32";
39 const std::string ModemService::kCmeErrorInCorrectParameters = "+CME ERROR: 50";
40 const std::string ModemService::kCmeErrorNetworkNotAttachedDueToMTFunctionalRestrictions = "+CME ERROR: 53";
41 const std::string ModemService::kCmeErrorFixedDialNumberOnlyAllowed = "+CME ERROR: 56";
42
43 const std::string ModemService::kCmsErrorOperationNotAllowed = "+CMS ERROR: 302";
44 const std::string ModemService::kCmsErrorOperationNotSupported = "+CMS ERROR: 303";
45 const std::string ModemService::kCmsErrorInvalidPDUModeParam = "+CMS ERROR: 304";
46 const std::string ModemService::kCmsErrorSCAddressUnknown = "+CMS ERROR: 304";
47
48 const std::pair<int, int> ModemService::kRemotePortRange =
49 std::make_pair(6520, 6527);
50
CommandHandler(const std::string & command,f_func handler)51 CommandHandler::CommandHandler(const std::string& command, f_func handler)
52 : command_prefix(command),
53 match_mode(FULL_MATCH),
54 f_command_handler(handler) {}
55
CommandHandler(const std::string & command,p_func handler)56 CommandHandler::CommandHandler(const std::string& command, p_func handler)
57 : command_prefix(command),
58 match_mode(PARTIAL_MATCH),
59 p_command_handler(handler) {}
60
Compare(const std::string & command) const61 int CommandHandler::Compare(const std::string& command) const {
62 int result = -1;
63 if (match_mode == PARTIAL_MATCH) {
64 result = command.compare(2, command_prefix.size(), command_prefix); // skip "AT"
65 } else {
66 result = command.compare(2, command.size(), command_prefix);
67 }
68 return result;
69 }
70
HandleCommand(const Client & client,std::string & command) const71 void CommandHandler::HandleCommand(const Client& client,
72 std::string& command) const {
73 if (match_mode == PARTIAL_MATCH && p_command_handler != nullptr) {
74 (*p_command_handler)(client, command);
75 } else if (match_mode == FULL_MATCH && f_command_handler != nullptr) {
76 (*f_command_handler)(client);
77 } else {
78 LOG(ERROR) << "Mismatched mode and handler, CHECK!";
79 }
80 }
81
ModemService(int32_t service_id,std::vector<CommandHandler> command_handlers,ChannelMonitor * channel_monitor,ThreadLooper * thread_looper)82 ModemService::ModemService(int32_t service_id,
83 std::vector<CommandHandler> command_handlers,
84 ChannelMonitor* channel_monitor,
85 ThreadLooper* thread_looper)
86 : service_id_(service_id),
87 command_handlers_(command_handlers),
88 thread_looper_(thread_looper),
89 channel_monitor_(channel_monitor) {}
90
HandleModemCommand(const Client & client,std::string command)91 bool ModemService::HandleModemCommand(const Client& client,
92 std::string command) {
93 for (auto& handler : command_handlers_) {
94 if (handler.Compare(command) == 0) {
95 handler.HandleCommand(client, command);
96 return true;
97 }
98 }
99
100 return false;
101 }
102
HandleCommandDefaultSupported(const Client & client)103 void ModemService::HandleCommandDefaultSupported(const Client& client) {
104 std::string response{"OK\r"};
105 client.SendCommandResponse(response);
106 }
107
SendUnsolicitedCommand(std::string unsol_command)108 void ModemService::SendUnsolicitedCommand(std::string unsol_command) {
109 if (channel_monitor_) {
110 channel_monitor_->SendUnsolicitedCommand(unsol_command);
111 ;
112 }
113 }
114
ConnectToRemoteCvd(std::string port)115 cuttlefish::SharedFD ModemService::ConnectToRemoteCvd(std::string port) {
116 std::string remote_sock_name = "modem_simulator" + port;
117 auto remote_sock = cuttlefish::SharedFD::SocketLocalClient(
118 remote_sock_name.c_str(), true, SOCK_STREAM);
119 if (!remote_sock->IsOpen()) {
120 LOG(ERROR) << "Failed to connect to remote cuttlefish: " << port
121 << ", error: " << strerror(errno);
122 }
123 return remote_sock;
124 }
125
SendCommandToRemote(cuttlefish::SharedFD remote_client,std::string response)126 void ModemService::SendCommandToRemote(cuttlefish::SharedFD remote_client, std::string response) {
127 if (channel_monitor_) {
128 channel_monitor_->SendRemoteCommand(remote_client, response);
129 ;
130 }
131 }
132
CloseRemoteConnection(cuttlefish::SharedFD remote_client)133 void ModemService::CloseRemoteConnection(cuttlefish::SharedFD remote_client) {
134 if (channel_monitor_) {
135 channel_monitor_->CloseRemoteConnection(remote_client);
136 ;
137 }
138 }
139
GetHostId()140 std::string ModemService::GetHostId() {
141 return std::to_string(cuttlefish::modem::DeviceConfig::host_id());
142 }
143
144 } // namespace cuttlefish
145