blob: 0f3c22bb7a955b2e650ad90d912141095796ee68 [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
7#include "shill/key_file_store.h"
8#include "shill/logging.h"
9
10using base::FilePath;
11using std::string;
12
13namespace shill {
14
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070015namespace Logging {
16static auto kModuleLogScope = ScopeLogger::kCellular;
17static string ObjectID(const PendingActivationStore *p) {
18 return "(pending_activation_store)";
19}
20}
21
Arman Uguray41cc6342013-03-29 16:34:39 -070022const char PendingActivationStore::kIccidGroupId[] = "iccid_list";
23const char PendingActivationStore::kMeidGroupId[] = "meid_list";
24// We're keeping the old file name here for backwards compatibility.
25const char PendingActivationStore::kStorageFileName[] =
26 "activating_iccid_store.profile";
27
28PendingActivationStore::PendingActivationStore() {}
29
30PendingActivationStore::~PendingActivationStore() {
31 if (storage_.get())
32 storage_->Flush(); // Make certain that everything is persisted.
33}
34
35namespace {
36
37string StateToString(PendingActivationStore::State state) {
38 switch (state) {
39 case PendingActivationStore::kStateUnknown:
40 return "Unknown";
41 case PendingActivationStore::kStatePending:
42 return "Pending";
43 case PendingActivationStore::kStateActivated:
44 return "Activated";
Arman Uguray41cc6342013-03-29 16:34:39 -070045 default:
46 return "Invalid";
47 }
48}
49
50string FormattedIdentifier(PendingActivationStore::IdentifierType type,
51 const string &identifier) {
52 string label;
53 switch (type) {
54 case PendingActivationStore::kIdentifierICCID:
55 label = "ICCID";
56 break;
57 case PendingActivationStore::kIdentifierMEID:
58 label = "MEID";
59 break;
60 default:
61 NOTREACHED();
62 }
63 return "[" + label + "=" + identifier + "]";
64}
65
66} // namespace
67
68// static
69string PendingActivationStore::IdentifierTypeToGroupId(IdentifierType type) {
Alex Vakulenko8a532292014-06-16 17:18:44 -070070 switch (type) {
Arman Uguray41cc6342013-03-29 16:34:39 -070071 case kIdentifierICCID:
72 return kIccidGroupId;
73 case kIdentifierMEID:
74 return kMeidGroupId;
75 default:
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -070076 SLOG(Cellular, nullptr, 2) << "Incorrect identifier type: " << type;
Arman Uguray41cc6342013-03-29 16:34:39 -070077 return "";
78 }
79}
80
81bool PendingActivationStore::InitStorage(
82 GLib *glib,
83 const FilePath &storage_path) {
84 // Close the current file.
85 if (storage_.get()) {
86 storage_->Flush();
87 storage_.reset(); // KeyFileStore closes the file in its destructor.
88 }
89 if (!glib) {
90 LOG(ERROR) << "Null pointer passed for |glib|.";
91 return false;
92 }
93 if (storage_path.empty()) {
94 LOG(ERROR) << "Empty storage directory path provided.";
95 return false;
96 }
97 FilePath path = storage_path.Append(kStorageFileName);
Ben Chanc20ed132014-10-16 12:25:03 -070098 std::unique_ptr<KeyFileStore> storage(new KeyFileStore(glib));
Arman Uguray41cc6342013-03-29 16:34:39 -070099 storage->set_path(path);
100 bool already_exists = storage->IsNonEmpty();
101 if (!storage->Open()) {
102 LOG(ERROR) << "Failed to open file at '" << path.AsUTF8Unsafe() << "'";
103 if (already_exists)
104 storage->MarkAsCorrupted();
105 return false;
106 }
107 if (!already_exists)
108 storage->SetHeader("Identifiers pending cellular activation.");
109 storage_.reset(storage.release());
110 return true;
111}
112
113PendingActivationStore::State PendingActivationStore::GetActivationState(
114 IdentifierType type,
115 const string &identifier) const {
116 string formatted_identifier = FormattedIdentifier(type, identifier);
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700117 SLOG(this, 2) << __func__ << ": " << formatted_identifier;
Arman Uguray41cc6342013-03-29 16:34:39 -0700118 if (!storage_.get()) {
119 LOG(ERROR) << "Underlying storage not initialized.";
120 return kStateUnknown;
121 }
122 int state = 0;
123 if (!storage_->GetInt(IdentifierTypeToGroupId(type), identifier, &state)) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700124 SLOG(this, 2) << "No entry exists for " << formatted_identifier;
Arman Uguray41cc6342013-03-29 16:34:39 -0700125 return kStateUnknown;
126 }
127 if (state <= 0 || state >= kStateMax) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700128 SLOG(this, 2) << "State value read for " << formatted_identifier
129 << " is invalid.";
Arman Uguray41cc6342013-03-29 16:34:39 -0700130 return kStateUnknown;
131 }
132 return static_cast<State>(state);
133}
134
135bool PendingActivationStore::SetActivationState(
136 IdentifierType type,
137 const string &identifier,
138 State state) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700139 SLOG(this, 2) << __func__ << ": State=" << StateToString(state) << ", "
140 << FormattedIdentifier(type, identifier);
Arman Uguray41cc6342013-03-29 16:34:39 -0700141 if (!storage_.get()) {
142 LOG(ERROR) << "Underlying storage not initialized.";
143 return false;
144 }
145 if (state == kStateUnknown) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700146 SLOG(this, 2) << "kStateUnknown cannot be used as a value.";
Arman Uguray41cc6342013-03-29 16:34:39 -0700147 return false;
148 }
149 if (state < 0 || state >= kStateMax) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700150 SLOG(this, 2) << "Cannot set state to \"" << StateToString(state)
151 << "\"";
Arman Uguray41cc6342013-03-29 16:34:39 -0700152 return false;
153 }
154 if (!storage_->SetInt(
155 IdentifierTypeToGroupId(type), identifier, static_cast<int>(state))) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700156 SLOG(this, 2) << "Failed to store the given identifier and state "
157 << "values.";
Arman Uguray41cc6342013-03-29 16:34:39 -0700158 return false;
159 }
160 return storage_->Flush();
161}
162
163bool PendingActivationStore::RemoveEntry(IdentifierType type,
164 const std::string &identifier) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700165 SLOG(this, 2) << __func__ << ": "
166 << FormattedIdentifier(type, identifier);
Arman Uguray41cc6342013-03-29 16:34:39 -0700167 if (!storage_.get()) {
168 LOG(ERROR) << "Underlying storage not initialized.";
169 return false;
170 }
171 if (!storage_->DeleteKey(IdentifierTypeToGroupId(type), identifier)) {
Rebecca Silbersteinc9c31d82014-10-21 15:01:00 -0700172 SLOG(this, 2) << "Failed to remove the given identifier.";
Arman Uguray41cc6342013-03-29 16:34:39 -0700173 return false;
174 }
175 return storage_->Flush();
176}
177
178} // namespace shill