mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-07-19 04:24:05 -04:00
[EGD-4063] Added handling of PIN/PUK codes for SIM card objects. SimCard class was added (supply pin and puk, change sim, get state, get sim lock infromation, get attempts counters) URCCpin via URC handler was added New message type to send data handled in URCCpin handler to ServiceCellular
170 lines
5.4 KiB
C++
170 lines
5.4 KiB
C++
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include "SimCard.hpp"
|
|
#include <log/log.hpp>
|
|
#include <variant>
|
|
#include "Result.hpp"
|
|
#include "UrcCpin.hpp" //for Cpin parseState
|
|
#include "UrcFactory.hpp"
|
|
|
|
SimCardResult SimCard::convertErrorFromATResult(const at::Result atres) const
|
|
{
|
|
if (std::holds_alternative<at::EquipmentErrorCode>(atres.errorCode)) {
|
|
|
|
auto cerr = static_cast<int>(std::get<at::EquipmentErrorCode>(atres.errorCode));
|
|
if ((cerr > static_cast<int>(SimCardResult::AT_ERROR_Begin)) &&
|
|
(cerr < static_cast<int>(SimCardResult::AT_ERROR_End))) {
|
|
return static_cast<SimCardResult>(cerr);
|
|
}
|
|
}
|
|
return SimCardResult::Unknown;
|
|
}
|
|
|
|
std::optional<at::response::qpinc::AttemptsCounters> SimCard::getAttemptsCounters() const
|
|
{
|
|
auto channel = cellularService.cmux->get(TS0710::Channel::Commands);
|
|
if (channel) {
|
|
auto resp = channel->cmd(at::factory(at::AT::QPINC) + "\"SC\"");
|
|
at::response::qpinc::AttemptsCounters ret;
|
|
if (at::response::parseQPINC(resp, ret)) {
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
return std::nullopt;
|
|
}
|
|
|
|
SimCardResult SimCard::supplyPin(const std::string pin) const
|
|
{
|
|
if (auto pc = getAttemptsCounters(); pc) {
|
|
if (pc.value().PinCounter > 0) {
|
|
if (auto channel = cellularService.cmux->get(TS0710::Channel::Commands); channel) {
|
|
auto resp = channel->cmd(at::factory(at::AT::CPIN) + "\"" + pin + "\"");
|
|
|
|
if (resp.code == at::Result::Code::OK) {
|
|
return SimCardResult::OK;
|
|
}
|
|
else {
|
|
return convertErrorFromATResult(resp);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (pc.value().PukCounter > 0) {
|
|
return SimCardResult::SIM_PUKRequired;
|
|
}
|
|
else {
|
|
return SimCardResult::Locked;
|
|
}
|
|
}
|
|
}
|
|
return SimCardResult::Unknown;
|
|
}
|
|
|
|
SimCardResult SimCard::supplyPuk(const std::string puk, const std::string pin) const
|
|
{
|
|
if (auto pc = getAttemptsCounters(); pc) {
|
|
if (pc.value().PukCounter != 0) {
|
|
if (auto channel = cellularService.cmux->get(TS0710::Channel::Commands); channel) {
|
|
auto resp = channel->cmd(at::factory(at::AT::CPIN) + "\"" + puk + "\"" + ",\"" + pin + "\"");
|
|
if (resp.code == at::Result::Code::OK) {
|
|
return SimCardResult::OK;
|
|
}
|
|
else {
|
|
return convertErrorFromATResult(resp);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
return SimCardResult::Locked;
|
|
}
|
|
}
|
|
|
|
return SimCardResult::Unknown;
|
|
}
|
|
|
|
bool SimCard::isPinLocked() const
|
|
{
|
|
if (auto channel = cellularService.cmux->get(TS0710::Channel::Commands); channel) {
|
|
auto resp = channel->cmd(at::factory(at::AT::CLCK) + "\"SC\",2\r");
|
|
int val = 0;
|
|
if (at::response::parseCLCK(resp, val)) {
|
|
return val != 0;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
SimCardResult SimCard::setPinLock(bool lock, const std::string pin) const
|
|
{
|
|
if (auto pc = getAttemptsCounters(); pc) {
|
|
if (pc.value().PukCounter != 0) {
|
|
auto channel = cellularService.cmux->get(TS0710::Channel::Commands);
|
|
if (channel) {
|
|
auto resp =
|
|
channel->cmd(at::factory(at::AT::CLCK) + "\"SC\"," + (lock ? "1" : "0") + ",\"" + pin + "\"");
|
|
if (resp.code == at::Result::Code::OK) {
|
|
return SimCardResult::OK;
|
|
}
|
|
else {
|
|
return convertErrorFromATResult(resp);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
return SimCardResult::Locked;
|
|
}
|
|
}
|
|
|
|
return SimCardResult::Unknown;
|
|
}
|
|
|
|
SimCardResult SimCard::changePin(const std::string oldPin, const std::string newPin) const
|
|
{
|
|
if (auto pc = getAttemptsCounters(); pc) {
|
|
if (pc.value().PukCounter != 0) {
|
|
auto channel = cellularService.cmux->get(TS0710::Channel::Commands);
|
|
if (channel) {
|
|
auto resp = channel->cmd(at::factory(at::AT::CPWD) + "\"SC\", \"" + oldPin + "\",\"" + newPin + "\"");
|
|
if (resp.code == at::Result::Code::OK) {
|
|
return SimCardResult::OK;
|
|
}
|
|
else {
|
|
return convertErrorFromATResult(resp);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
return SimCardResult::Locked;
|
|
}
|
|
}
|
|
|
|
return SimCardResult::Unknown;
|
|
}
|
|
|
|
std::optional<at::SimState> SimCard::simState() const
|
|
{
|
|
std::string buf;
|
|
return simStateWithMessage(buf);
|
|
}
|
|
|
|
std::optional<at::SimState> SimCard::simStateWithMessage(std::string &message) const
|
|
{
|
|
if (auto channel = cellularService.cmux->get(TS0710::Channel::Commands); channel) {
|
|
auto resp = channel->cmd(at::factory(at::AT::GET_CPIN));
|
|
if (resp.code == at::Result::Code::OK) {
|
|
if (resp.response.size()) {
|
|
for (auto el : resp.response) {
|
|
auto urc = at::urc::UrcFactory::Create(el);
|
|
auto cpin = std::unique_ptr<at::urc::Cpin>{static_cast<at::urc::Cpin *>(urc.release())};
|
|
if (cpin) {
|
|
return cpin->getState();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return at::SimState::Unknown;
|
|
}
|