blob: 46b8340106b4745c95d143ea7c92e2e4b72b3010 [file] [log] [blame]
Arman Uguray41cc6342013-03-29 16:34:39 -07001// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/pending_activation_store.h"
6
Arman Uguray41cc6342013-03-29 16:34:39 -07007#include "shill/logging.h"
mukesh agrawal04147472015-08-18 13:25:28 -07008#include "shill/store_factory.h"
9#include "shill/store_interface.h"
Arman Uguray41cc6342013-03-29 16:34:39 -070010
11using base::FilePath;
12using std::string;
13
14namespace shill {
15
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070016namespace Logging {
17static auto kModuleLogScope = ScopeLogger::kCellular;
Paul Stewart1a212a62015-06-16 13:13:10 -070018static string ObjectID(const PendingActivationStore* p) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070019 return "(pending_activation_store)";
20}
21}
22
Arman Uguray41cc6342013-03-29 16:34:39 -070023const char PendingActivationStore::kIccidGroupId[] = "iccid_list";
24const char PendingActivationStore::kMeidGroupId[] = "meid_list";
25// We're keeping the old file name here for backwards compatibility.
26const char PendingActivationStore::kStorageFileName[] =
27 "activating_iccid_store.profile";
28
29PendingActivationStore::PendingActivationStore() {}
30
31PendingActivationStore::~PendingActivationStore() {
32 if (storage_.get())
33 storage_->Flush(); // Make certain that everything is persisted.
34}
35
36namespace {
37
38string StateToString(PendingActivationStore::State state) {
39 switch (state) {
40 case PendingActivationStore::kStateUnknown:
41 return "Unknown";
42 case PendingActivationStore::kStatePending:
43 return "Pending";
44 case PendingActivationStore::kStateActivated:
45 return "Activated";
Arman Uguray41cc6342013-03-29 16:34:39 -070046 default:
47 return "Invalid";
48 }
49}
50
51string FormattedIdentifier(PendingActivationStore::IdentifierType type,
Paul Stewart1a212a62015-06-16 13:13:10 -070052 const string& identifier) {
Arman Uguray41cc6342013-03-29 16:34:39 -070053 string label;
54 switch (type) {
55 case PendingActivationStore::kIdentifierICCID:
56 label = "ICCID";
57 break;
58 case PendingActivationStore::kIdentifierMEID:
59 label = "MEID";
60 break;
61 default:
62 NOTREACHED();
63 }
64 return "[" + label + "=" + identifier + "]";
65}
66
67} // namespace
68
69// static
70string PendingActivationStore::IdentifierTypeToGroupId(IdentifierType type) {
Alex Vakulenko8a532292014-06-16 17:18:44 -070071 switch (type) {
Arman Uguray41cc6342013-03-29 16:34:39 -070072 case kIdentifierICCID:
73 return kIccidGroupId;
74 case kIdentifierMEID:
75 return kMeidGroupId;
76 default:
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070077 SLOG(Cellular, nullptr, 2) << "Incorrect identifier type: " << type;
Arman Uguray41cc6342013-03-29 16:34:39 -070078 return "";
79 }
80}
81
mukesh agrawaleca9dd62015-08-25 17:24:50 -070082bool PendingActivationStore::InitStorage(const FilePath& storage_path) {
Arman Uguray41cc6342013-03-29 16:34:39 -070083 // Close the current file.
84 if (storage_.get()) {
85 storage_->Flush();
86 storage_.reset(); // KeyFileStore closes the file in its destructor.
87 }
Arman Uguray41cc6342013-03-29 16:34:39 -070088 if (storage_path.empty()) {
89 LOG(ERROR) << "Empty storage directory path provided.";
90 return false;
91 }
92 FilePath path = storage_path.Append(kStorageFileName);
mukesh agrawal04147472015-08-18 13:25:28 -070093 std::unique_ptr<StoreInterface> storage(
94 StoreFactory::GetInstance()->CreateStore());
Arman Uguray41cc6342013-03-29 16:34:39 -070095 storage->set_path(path);
96 bool already_exists = storage->IsNonEmpty();
97 if (!storage->Open()) {
98 LOG(ERROR) << "Failed to open file at '" << path.AsUTF8Unsafe() << "'";
99 if (already_exists)
100 storage->MarkAsCorrupted();
101 return false;
102 }
103 if (!already_exists)
104 storage->SetHeader("Identifiers pending cellular activation.");
105 storage_.reset(storage.release());
106 return true;
107}
108
109PendingActivationStore::State PendingActivationStore::GetActivationState(
110 IdentifierType type,
Paul Stewart1a212a62015-06-16 13:13:10 -0700111 const string& identifier) const {
Arman Uguray41cc6342013-03-29 16:34:39 -0700112 string formatted_identifier = FormattedIdentifier(type, identifier);
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700113 SLOG(this, 2) << __func__ << ": " << formatted_identifier;
Arman Uguray41cc6342013-03-29 16:34:39 -0700114 if (!storage_.get()) {
115 LOG(ERROR) << "Underlying storage not initialized.";
116 return kStateUnknown;
117 }
118 int state = 0;
119 if (!storage_->GetInt(IdentifierTypeToGroupId(type), identifier, &state)) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700120 SLOG(this, 2) << "No entry exists for " << formatted_identifier;
Arman Uguray41cc6342013-03-29 16:34:39 -0700121 return kStateUnknown;
122 }
123 if (state <= 0 || state >= kStateMax) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700124 SLOG(this, 2) << "State value read for " << formatted_identifier
125 << " is invalid.";
Arman Uguray41cc6342013-03-29 16:34:39 -0700126 return kStateUnknown;
127 }
128 return static_cast<State>(state);
129}
130
131bool PendingActivationStore::SetActivationState(
132 IdentifierType type,
Paul Stewart1a212a62015-06-16 13:13:10 -0700133 const string& identifier,
Arman Uguray41cc6342013-03-29 16:34:39 -0700134 State state) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700135 SLOG(this, 2) << __func__ << ": State=" << StateToString(state) << ", "
136 << FormattedIdentifier(type, identifier);
Arman Uguray41cc6342013-03-29 16:34:39 -0700137 if (!storage_.get()) {
138 LOG(ERROR) << "Underlying storage not initialized.";
139 return false;
140 }
141 if (state == kStateUnknown) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700142 SLOG(this, 2) << "kStateUnknown cannot be used as a value.";
Arman Uguray41cc6342013-03-29 16:34:39 -0700143 return false;
144 }
145 if (state < 0 || state >= kStateMax) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700146 SLOG(this, 2) << "Cannot set state to \"" << StateToString(state)
147 << "\"";
Arman Uguray41cc6342013-03-29 16:34:39 -0700148 return false;
149 }
150 if (!storage_->SetInt(
151 IdentifierTypeToGroupId(type), identifier, static_cast<int>(state))) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700152 SLOG(this, 2) << "Failed to store the given identifier and state "
153 << "values.";
Arman Uguray41cc6342013-03-29 16:34:39 -0700154 return false;
155 }
156 return storage_->Flush();
157}
158
159bool PendingActivationStore::RemoveEntry(IdentifierType type,
Paul Stewart1a212a62015-06-16 13:13:10 -0700160 const std::string& identifier) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700161 SLOG(this, 2) << __func__ << ": "
162 << FormattedIdentifier(type, identifier);
Arman Uguray41cc6342013-03-29 16:34:39 -0700163 if (!storage_.get()) {
164 LOG(ERROR) << "Underlying storage not initialized.";
165 return false;
166 }
167 if (!storage_->DeleteKey(IdentifierTypeToGroupId(type), identifier)) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700168 SLOG(this, 2) << "Failed to remove the given identifier.";
Arman Uguray41cc6342013-03-29 16:34:39 -0700169 return false;
170 }
171 return storage_->Flush();
172}
173
174} // namespace shill