1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef USB_CONFIG_H
17 #define USB_CONFIG_H
18 
19 #include <iostream>
20 #include <memory>
21 #include <mutex>
22 #include <sstream>
23 #include <vector>
24 #include "usb_common.h"
25 #include "usb_interface.h"
26 #include "cJSON.h"
27 
28 namespace OHOS {
29 namespace USB {
30 class USBConfig {
31 public:
USBConfig(uint32_t id,uint32_t attributes,std::string name,uint32_t maxPower,std::vector<UsbInterface> interfaces)32     USBConfig(uint32_t id, uint32_t attributes, std::string name, uint32_t maxPower,
33         std::vector<UsbInterface> interfaces)
34     {
35         this->id_ = static_cast<int32_t>(id);
36         this->attributes_ = attributes;
37         this->maxPower_ = static_cast<int32_t>(maxPower);
38         this->name_ = name;
39         this->interfaces_ = interfaces;
40     }
41 
USBConfig(const cJSON * config)42     explicit USBConfig(const cJSON *config)
43     {
44         if (config == nullptr) {
45             USB_HILOGE(MODULE_USB_SERVICE, "config pointer is nullptr");
46         }
47         id_ = GetIntValue(config, "id");
48         attributes_ = static_cast<uint32_t>(GetIntValue(config, "attributes"));
49         maxPower_ = GetIntValue(config, "maxPower");
50         name_ = GetStringValue(config, "name");
51         cJSON *jsonInterfaces = cJSON_GetObjectItem(config, "interfaces");
52         if (jsonInterfaces != nullptr) {
53             for (int i = 0; i < cJSON_GetArraySize(jsonInterfaces); i++) {
54                 cJSON *jsonInterface = cJSON_GetArrayItem(jsonInterfaces, i);
55                 if (jsonInterface == nullptr) {
56                     USB_HILOGE(MODULE_USB_SERVICE, "get item nullptr");
57                     continue;
58                 }
59                 UsbInterface interface(jsonInterface);
60                 interfaces_.emplace_back(interface);
61             }
62         }
63     }
64 
USBConfig()65     USBConfig() {}
~USBConfig()66     ~USBConfig() {}
67 
GetIntValue(const cJSON * jsonObject,const char * key)68     static int GetIntValue(const cJSON *jsonObject, const char *key)
69     {
70         cJSON *item = cJSON_GetObjectItem(jsonObject, key);
71         if (item != nullptr && cJSON_IsNumber(item)) {
72             return item->valueint;
73         } else {
74             USB_HILOGE(MODULE_USB_SERVICE, "Invalid or missing %s field", key);
75             return 0;
76         }
77     }
78 
GetStringValue(const cJSON * jsonObject,const char * key)79     static std::string GetStringValue(const cJSON *jsonObject, const char *key)
80     {
81         cJSON *item = cJSON_GetObjectItem(jsonObject, key);
82         if (item != nullptr && cJSON_IsString(item)) {
83             return item->valuestring;
84         } else {
85             USB_HILOGE(MODULE_USB_SERVICE, "Invalid or missing %s field", key);
86             return "";
87         }
88     }
89 
GetId()90     const int32_t &GetId() const
91     {
92         return id_;
93     }
94 
GetAttributes()95     const uint32_t &GetAttributes() const
96     {
97         return attributes_;
98     }
99 
GetInterface(uint32_t index,UsbInterface & interface)100     bool GetInterface(uint32_t index, UsbInterface &interface) const
101     {
102         if (index >= interfaces_.size()) {
103             return false;
104         }
105         interface = interfaces_[index];
106         return true;
107     }
108 
GetInterfaceCount()109     uint32_t GetInterfaceCount() const
110     {
111         return interfaces_.size();
112     }
113 
GetMaxPower()114     int32_t GetMaxPower() const
115     {
116         // 2 represent maxPower units
117         return maxPower_ * 2;
118     }
119 
GetName()120     const std::string &GetName() const
121     {
122         return name_;
123     }
124 
IsRemoteWakeup()125     bool IsRemoteWakeup() const
126     {
127         return (attributes_ & USB_CFG_REMOTE_WAKEUP) != 0;
128     }
129 
IsSelfPowered()130     bool IsSelfPowered() const
131     {
132         return (attributes_ & USB_CFG_SELF_POWERED) != 0;
133     }
134 
SetInterfaces(const std::vector<UsbInterface> & interfaces)135     void SetInterfaces(const std::vector<UsbInterface> &interfaces)
136     {
137         this->interfaces_ = interfaces;
138     }
139 
GetInterfaces()140     std::vector<UsbInterface> &GetInterfaces()
141     {
142         return interfaces_;
143     }
144 
SetId(int32_t id)145     void SetId(int32_t id)
146     {
147         this->id_ = id;
148     }
149 
SetAttribute(uint32_t attributes)150     void SetAttribute(uint32_t attributes)
151     {
152         this->attributes_ = attributes;
153     }
154 
SetMaxPower(int32_t maxPower)155     void SetMaxPower(int32_t maxPower)
156     {
157         this->maxPower_ = maxPower;
158     }
159 
ToString()160     std::string ToString() const
161     {
162         std::ostringstream ss;
163         ss << "name=" << name_ << ","
164            << "id=" << id_ << ","
165            << "iConfiguration=" << (int32_t)iConfiguration_ << ","
166            << "attributes=" << attributes_ << ","
167            << "maxPower=" << maxPower_ << ";  ";
168         std::string str = "USBConfig[" + ss.str() + "]";
169         ss.str("");
170         for (size_t i = 0; i < interfaces_.size(); ++i) {
171             const UsbInterface &interface = interfaces_[i];
172             str += interface.ToString();
173         }
174         return str;
175     }
176 
SetName(const std::string & name)177     void SetName(const std::string &name)
178     {
179         this->name_ = name;
180     }
181 
SetiConfiguration(uint8_t idx)182     void SetiConfiguration(uint8_t idx)
183     {
184         this->iConfiguration_ = idx;
185     }
186 
GetiConfiguration()187     uint8_t GetiConfiguration()
188     {
189         return this->iConfiguration_;
190     }
191 
getJsonString()192     const std::string getJsonString() const
193     {
194         cJSON* config = cJSON_CreateObject();
195         if (!config) {
196             USB_HILOGE(MODULE_USB_SERVICE, "Create config error");
197             return "";
198         }
199         cJSON_AddNumberToObject(config, "id", static_cast<double>(id_));
200         cJSON_AddNumberToObject(config, "attributes", static_cast<double>(attributes_));
201         cJSON_AddNumberToObject(config, "maxPower", static_cast<double>(maxPower_));
202         cJSON_AddStringToObject(config, "name", name_.c_str());
203         cJSON_AddBoolToObject(config, "isRemoteWakeup", IsRemoteWakeup());
204         cJSON_AddBoolToObject(config, "isSelfPowered", IsSelfPowered());
205 
206         cJSON* interfaces = cJSON_CreateArray();
207         if (!interfaces) {
208             USB_HILOGE(MODULE_USB_SERVICE, "Create interfaces error");
209             cJSON_Delete(config);
210             return "";
211         }
212         for (auto &intf : interfaces_) {
213             cJSON* pInterface =  cJSON_Parse(intf.getJsonString().c_str());
214             cJSON_AddItemToArray(interfaces, pInterface);
215         }
216         cJSON_AddItemToObject(config, "interfaces", interfaces);
217         char *pConfigStr = cJSON_PrintUnformatted(config);
218         cJSON_Delete(config);
219         if (!pConfigStr) {
220             USB_HILOGE(MODULE_USB_SERVICE, "Print config error");
221             return "";
222         }
223         std::string configStr(pConfigStr);
224         cJSON_free(pConfigStr);
225         return configStr;
226     }
227 
228 private:
229     int32_t id_ = INVALID_USB_INT_VALUE;
230     uint32_t attributes_ = 0;
231     std::vector<UsbInterface> interfaces_;
232     int32_t maxPower_ = INVALID_USB_INT_VALUE;
233     std::string name_;
234     uint8_t iConfiguration_ = UINT8_MAX;
235 };
236 } // namespace USB
237 } // namespace OHOS
238 
239 #endif // USB_CONFIG_H
240