blob: 625a9ce88453ca890924c10b7221116ff36da603 [file] [log] [blame]
Peter Qiuc0beca52015-09-03 11:25:46 -07001//
2// Copyright (C) 2013 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//
Arman Uguray41cc6342013-03-29 16:34:39 -070016
17#include "shill/pending_activation_store.h"
18
Arman Uguray41cc6342013-03-29 16:34:39 -070019#include "shill/logging.h"
mukesh agrawal04147472015-08-18 13:25:28 -070020#include "shill/store_factory.h"
21#include "shill/store_interface.h"
Arman Uguray41cc6342013-03-29 16:34:39 -070022
23using base::FilePath;
24using std::string;
25
26namespace shill {
27
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070028namespace Logging {
29static auto kModuleLogScope = ScopeLogger::kCellular;
Paul Stewart1a212a62015-06-16 13:13:10 -070030static string ObjectID(const PendingActivationStore* p) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070031 return "(pending_activation_store)";
32}
33}
34
Arman Uguray41cc6342013-03-29 16:34:39 -070035const char PendingActivationStore::kIccidGroupId[] = "iccid_list";
36const char PendingActivationStore::kMeidGroupId[] = "meid_list";
37// We're keeping the old file name here for backwards compatibility.
38const char PendingActivationStore::kStorageFileName[] =
39 "activating_iccid_store.profile";
40
41PendingActivationStore::PendingActivationStore() {}
42
43PendingActivationStore::~PendingActivationStore() {
44 if (storage_.get())
45 storage_->Flush(); // Make certain that everything is persisted.
46}
47
48namespace {
49
50string StateToString(PendingActivationStore::State state) {
51 switch (state) {
52 case PendingActivationStore::kStateUnknown:
53 return "Unknown";
54 case PendingActivationStore::kStatePending:
55 return "Pending";
56 case PendingActivationStore::kStateActivated:
57 return "Activated";
Arman Uguray41cc6342013-03-29 16:34:39 -070058 default:
59 return "Invalid";
60 }
61}
62
63string FormattedIdentifier(PendingActivationStore::IdentifierType type,
Paul Stewart1a212a62015-06-16 13:13:10 -070064 const string& identifier) {
Arman Uguray41cc6342013-03-29 16:34:39 -070065 string label;
66 switch (type) {
67 case PendingActivationStore::kIdentifierICCID:
68 label = "ICCID";
69 break;
70 case PendingActivationStore::kIdentifierMEID:
71 label = "MEID";
72 break;
73 default:
74 NOTREACHED();
75 }
76 return "[" + label + "=" + identifier + "]";
77}
78
79} // namespace
80
81// static
82string PendingActivationStore::IdentifierTypeToGroupId(IdentifierType type) {
Alex Vakulenko8a532292014-06-16 17:18:44 -070083 switch (type) {
Arman Uguray41cc6342013-03-29 16:34:39 -070084 case kIdentifierICCID:
85 return kIccidGroupId;
86 case kIdentifierMEID:
87 return kMeidGroupId;
88 default:
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070089 SLOG(Cellular, nullptr, 2) << "Incorrect identifier type: " << type;
Arman Uguray41cc6342013-03-29 16:34:39 -070090 return "";
91 }
92}
93
mukesh agrawaleca9dd62015-08-25 17:24:50 -070094bool PendingActivationStore::InitStorage(const FilePath& storage_path) {
Arman Uguray41cc6342013-03-29 16:34:39 -070095 // Close the current file.
96 if (storage_.get()) {
97 storage_->Flush();
98 storage_.reset(); // KeyFileStore closes the file in its destructor.
99 }
Arman Uguray41cc6342013-03-29 16:34:39 -0700100 if (storage_path.empty()) {
101 LOG(ERROR) << "Empty storage directory path provided.";
102 return false;
103 }
104 FilePath path = storage_path.Append(kStorageFileName);
mukesh agrawal04147472015-08-18 13:25:28 -0700105 std::unique_ptr<StoreInterface> storage(
mukesh agrawal78e05842015-08-27 11:29:19 -0700106 StoreFactory::GetInstance()->CreateStore(path));
Arman Uguray41cc6342013-03-29 16:34:39 -0700107 bool already_exists = storage->IsNonEmpty();
108 if (!storage->Open()) {
109 LOG(ERROR) << "Failed to open file at '" << path.AsUTF8Unsafe() << "'";
110 if (already_exists)
111 storage->MarkAsCorrupted();
112 return false;
113 }
114 if (!already_exists)
115 storage->SetHeader("Identifiers pending cellular activation.");
116 storage_.reset(storage.release());
117 return true;
118}
119
120PendingActivationStore::State PendingActivationStore::GetActivationState(
121 IdentifierType type,
Paul Stewart1a212a62015-06-16 13:13:10 -0700122 const string& identifier) const {
Arman Uguray41cc6342013-03-29 16:34:39 -0700123 string formatted_identifier = FormattedIdentifier(type, identifier);
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700124 SLOG(this, 2) << __func__ << ": " << formatted_identifier;
Arman Uguray41cc6342013-03-29 16:34:39 -0700125 if (!storage_.get()) {
126 LOG(ERROR) << "Underlying storage not initialized.";
127 return kStateUnknown;
128 }
129 int state = 0;
130 if (!storage_->GetInt(IdentifierTypeToGroupId(type), identifier, &state)) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700131 SLOG(this, 2) << "No entry exists for " << formatted_identifier;
Arman Uguray41cc6342013-03-29 16:34:39 -0700132 return kStateUnknown;
133 }
134 if (state <= 0 || state >= kStateMax) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700135 SLOG(this, 2) << "State value read for " << formatted_identifier
136 << " is invalid.";
Arman Uguray41cc6342013-03-29 16:34:39 -0700137 return kStateUnknown;
138 }
139 return static_cast<State>(state);
140}
141
142bool PendingActivationStore::SetActivationState(
143 IdentifierType type,
Paul Stewart1a212a62015-06-16 13:13:10 -0700144 const string& identifier,
Arman Uguray41cc6342013-03-29 16:34:39 -0700145 State state) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700146 SLOG(this, 2) << __func__ << ": State=" << StateToString(state) << ", "
147 << FormattedIdentifier(type, identifier);
Arman Uguray41cc6342013-03-29 16:34:39 -0700148 if (!storage_.get()) {
149 LOG(ERROR) << "Underlying storage not initialized.";
150 return false;
151 }
152 if (state == kStateUnknown) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700153 SLOG(this, 2) << "kStateUnknown cannot be used as a value.";
Arman Uguray41cc6342013-03-29 16:34:39 -0700154 return false;
155 }
156 if (state < 0 || state >= kStateMax) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700157 SLOG(this, 2) << "Cannot set state to \"" << StateToString(state)
158 << "\"";
Arman Uguray41cc6342013-03-29 16:34:39 -0700159 return false;
160 }
161 if (!storage_->SetInt(
162 IdentifierTypeToGroupId(type), identifier, static_cast<int>(state))) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700163 SLOG(this, 2) << "Failed to store the given identifier and state "
164 << "values.";
Arman Uguray41cc6342013-03-29 16:34:39 -0700165 return false;
166 }
167 return storage_->Flush();
168}
169
170bool PendingActivationStore::RemoveEntry(IdentifierType type,
Paul Stewart1a212a62015-06-16 13:13:10 -0700171 const std::string& identifier) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700172 SLOG(this, 2) << __func__ << ": "
173 << FormattedIdentifier(type, identifier);
Arman Uguray41cc6342013-03-29 16:34:39 -0700174 if (!storage_.get()) {
175 LOG(ERROR) << "Underlying storage not initialized.";
176 return false;
177 }
178 if (!storage_->DeleteKey(IdentifierTypeToGroupId(type), identifier)) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700179 SLOG(this, 2) << "Failed to remove the given identifier.";
Arman Uguray41cc6342013-03-29 16:34:39 -0700180 return false;
181 }
182 return storage_->Flush();
183}
184
185} // namespace shill