145 lines
5.6 KiB
C++
145 lines
5.6 KiB
C++
//
|
|
// Copyright (C) 2020 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "host/commands/modem_simulator/modem_service.h"
|
|
|
|
#include <android-base/logging.h>
|
|
|
|
#include <cstring>
|
|
|
|
#include "host/commands/modem_simulator/device_config.h"
|
|
|
|
namespace cuttlefish {
|
|
|
|
const std::string ModemService::kCmeErrorOperationNotAllowed = "+CME ERROR: 3";
|
|
const std::string ModemService::kCmeErrorOperationNotSupported = "+CME ERROR: 4";
|
|
const std::string ModemService::kCmeErrorSimNotInserted = "+CME ERROR: 10";
|
|
const std::string ModemService::kCmeErrorSimPinRequired = "+CME ERROR: 11";
|
|
const std::string ModemService::kCmeErrorSimPukRequired = "+CME ERROR: 12";
|
|
const std::string ModemService::kCmeErrorSimBusy = "+CME ERROR: 14";
|
|
const std::string ModemService::kCmeErrorIncorrectPassword = "+CME ERROR: 16";
|
|
const std::string ModemService::kCmeErrorMemoryFull = "+CME ERROR: 20";
|
|
const std::string ModemService::kCmeErrorInvalidIndex = "+CME ERROR: 21";
|
|
const std::string ModemService::kCmeErrorNotFound = "+CME ERROR: 22";
|
|
const std::string ModemService::kCmeErrorInvalidCharactersInTextString = "+CME ERROR: 27";
|
|
const std::string ModemService::kCmeErrorNoNetworkService = "+CME ERROR: 30";
|
|
const std::string ModemService::kCmeErrorNetworkNotAllowedEmergencyCallsOnly = "+CME ERROR: 32";
|
|
const std::string ModemService::kCmeErrorInCorrectParameters = "+CME ERROR: 50";
|
|
const std::string ModemService::kCmeErrorNetworkNotAttachedDueToMTFunctionalRestrictions = "+CME ERROR: 53";
|
|
const std::string ModemService::kCmeErrorFixedDialNumberOnlyAllowed = "+CME ERROR: 56";
|
|
|
|
const std::string ModemService::kCmsErrorOperationNotAllowed = "+CMS ERROR: 302";
|
|
const std::string ModemService::kCmsErrorOperationNotSupported = "+CMS ERROR: 303";
|
|
const std::string ModemService::kCmsErrorInvalidPDUModeParam = "+CMS ERROR: 304";
|
|
const std::string ModemService::kCmsErrorSCAddressUnknown = "+CMS ERROR: 304";
|
|
|
|
const std::pair<int, int> ModemService::kRemotePortRange =
|
|
std::make_pair(6520, 6527);
|
|
|
|
CommandHandler::CommandHandler(const std::string& command, f_func handler)
|
|
: command_prefix(command),
|
|
match_mode(FULL_MATCH),
|
|
f_command_handler(handler) {}
|
|
|
|
CommandHandler::CommandHandler(const std::string& command, p_func handler)
|
|
: command_prefix(command),
|
|
match_mode(PARTIAL_MATCH),
|
|
p_command_handler(handler) {}
|
|
|
|
int CommandHandler::Compare(const std::string& command) const {
|
|
int result = -1;
|
|
if (match_mode == PARTIAL_MATCH) {
|
|
result = command.compare(2, command_prefix.size(), command_prefix); // skip "AT"
|
|
} else {
|
|
result = command.compare(2, command.size(), command_prefix);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void CommandHandler::HandleCommand(const Client& client,
|
|
std::string& command) const {
|
|
if (match_mode == PARTIAL_MATCH && p_command_handler != nullptr) {
|
|
(*p_command_handler)(client, command);
|
|
} else if (match_mode == FULL_MATCH && f_command_handler != nullptr) {
|
|
(*f_command_handler)(client);
|
|
} else {
|
|
LOG(ERROR) << "Mismatched mode and handler, CHECK!";
|
|
}
|
|
}
|
|
|
|
ModemService::ModemService(int32_t service_id,
|
|
std::vector<CommandHandler> command_handlers,
|
|
ChannelMonitor* channel_monitor,
|
|
ThreadLooper* thread_looper)
|
|
: service_id_(service_id),
|
|
command_handlers_(command_handlers),
|
|
thread_looper_(thread_looper),
|
|
channel_monitor_(channel_monitor) {}
|
|
|
|
bool ModemService::HandleModemCommand(const Client& client,
|
|
std::string command) {
|
|
for (auto& handler : command_handlers_) {
|
|
if (handler.Compare(command) == 0) {
|
|
handler.HandleCommand(client, command);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void ModemService::HandleCommandDefaultSupported(const Client& client) {
|
|
std::string response{"OK\r"};
|
|
client.SendCommandResponse(response);
|
|
}
|
|
|
|
void ModemService::SendUnsolicitedCommand(std::string unsol_command) {
|
|
if (channel_monitor_) {
|
|
channel_monitor_->SendUnsolicitedCommand(unsol_command);
|
|
;
|
|
}
|
|
}
|
|
|
|
cuttlefish::SharedFD ModemService::ConnectToRemoteCvd(std::string port) {
|
|
std::string remote_sock_name = "modem_simulator" + port;
|
|
auto remote_sock = cuttlefish::SharedFD::SocketLocalClient(
|
|
remote_sock_name.c_str(), true, SOCK_STREAM);
|
|
if (!remote_sock->IsOpen()) {
|
|
LOG(ERROR) << "Failed to connect to remote cuttlefish: " << port
|
|
<< ", error: " << strerror(errno);
|
|
}
|
|
return remote_sock;
|
|
}
|
|
|
|
void ModemService::SendCommandToRemote(cuttlefish::SharedFD remote_client, std::string response) {
|
|
if (channel_monitor_) {
|
|
channel_monitor_->SendRemoteCommand(remote_client, response);
|
|
;
|
|
}
|
|
}
|
|
|
|
void ModemService::CloseRemoteConnection(cuttlefish::SharedFD remote_client) {
|
|
if (channel_monitor_) {
|
|
channel_monitor_->CloseRemoteConnection(remote_client);
|
|
;
|
|
}
|
|
}
|
|
|
|
std::string ModemService::GetHostId() {
|
|
return std::to_string(cuttlefish::modem::DeviceConfig::host_id());
|
|
}
|
|
|
|
} // namespace cuttlefish
|