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