blob: 536f38508cc172882f083a333a186060e0ef35d6 [file] [log] [blame]
Arman Uguray26b7cf32013-02-17 13:56:12 -08001// 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/activating_iccid_store.h"
6
7#include "shill/key_file_store.h"
8#include "shill/logging.h"
9
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080010using base::FilePath;
Arman Uguray26b7cf32013-02-17 13:56:12 -080011using std::string;
12
13namespace shill {
14
15const char ActivatingIccidStore::kGroupId[] = "iccid_list";
16const char ActivatingIccidStore::kStorageFileName[] =
17 "activating_iccid_store.profile";
18
19namespace {
20
21string FormattedICCID(const string &iccid) {
22 return "[ICCID=" + iccid + "]";
23}
24
25} // namespace
26
27ActivatingIccidStore::ActivatingIccidStore() {}
28ActivatingIccidStore::~ActivatingIccidStore() {
29 if (storage_.get())
30 storage_->Flush(); // Make certain that everything is persisted.
31}
32
33bool ActivatingIccidStore::InitStorage(
34 GLib *glib,
35 const FilePath &storage_path) {
36 // Close the current file.
37 if (storage_.get()) {
38 storage_->Flush();
39 storage_.reset(); // KeyFileStore closes the file in its destructor.
40 }
Arman Ugurayc7b15602013-02-16 00:56:18 -080041 if (!glib) {
42 LOG(ERROR) << "Null pointer passed for |glib|.";
43 return false;
44 }
Arman Uguray26b7cf32013-02-17 13:56:12 -080045 if (storage_path.empty()) {
46 LOG(ERROR) << "Empty storage directory path provided.";
47 return false;
48 }
49 FilePath path = storage_path.Append(kStorageFileName);
50 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
51 storage->set_path(path);
52 bool already_exists = storage->IsNonEmpty();
53 if (!storage->Open()) {
54 LOG(ERROR) << "Failed to open file at '" << path.AsUTF8Unsafe() << "'";
55 if (already_exists)
56 storage->MarkAsCorrupted();
57 return false;
58 }
59 if (!already_exists)
60 storage->SetHeader("ICCIDs pending cellular activation.");
61 storage_.reset(storage.release());
62 return true;
63}
64
65ActivatingIccidStore::State ActivatingIccidStore::
66 GetActivationState(const string &iccid) const {
67 string formatted_iccid = FormattedICCID(iccid);
68 SLOG(Cellular, 2) << __func__ << ": " << formatted_iccid;
69 if (!storage_.get()) {
70 LOG(ERROR) << "Underlying storage not initialized.";
71 return kStateUnknown;
72 }
73 int state = 0;
74 if (!storage_->GetInt(kGroupId, iccid, &state)) {
75 SLOG(Cellular, 2) << "No entry exists for " << formatted_iccid;
76 return kStateUnknown;
77 }
78 if (state <= 0 || state >= kStateMax) {
79 SLOG(Cellular, 2) << "State value read for " << formatted_iccid
80 << " is invalid.";
81 return kStateUnknown;
82 }
83 return static_cast<State>(state);
84}
85
86bool ActivatingIccidStore::SetActivationState(
87 const string &iccid,
88 State state) {
89 SLOG(Cellular, 2) << __func__ << ": State=" << state << ", "
90 << FormattedICCID(iccid);
91 if (!storage_.get()) {
92 LOG(ERROR) << "Underlying storage not initialized.";
93 return false;
94 }
95 if (state == kStateUnknown) {
96 SLOG(Cellular, 2) << "kStateUnknown cannot be used as a value.";
97 return false;
98 }
99 if (!storage_->SetInt(kGroupId, iccid, static_cast<int>(state))) {
100 SLOG(Cellular, 2) << "Failed to store the given ICCID and state values.";
101 return false;
102 }
103 return storage_->Flush();
104}
105
106bool ActivatingIccidStore::RemoveEntry(const std::string &iccid) {
107 SLOG(Cellular, 2) << __func__ << ": " << FormattedICCID(iccid);
108 if (!storage_.get()) {
109 LOG(ERROR) << "Underlying storage not initialized.";
110 return false;
111 }
112 if (!storage_->DeleteKey(kGroupId, iccid)) {
113 SLOG(Cellular, 2) << "Failed to remove the given ICCID.";
114 return false;
115 }
116 return storage_->Flush();
117}
118
119} // namespace shill