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
28namespace OHOS {
29namespace USB {
30class USBConfig {
31public:
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
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
65    USBConfig() {}
66    ~USBConfig() {}
67
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
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
90    const int32_t &GetId() const
91    {
92        return id_;
93    }
94
95    const uint32_t &GetAttributes() const
96    {
97        return attributes_;
98    }
99
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
109    uint32_t GetInterfaceCount() const
110    {
111        return interfaces_.size();
112    }
113
114    int32_t GetMaxPower() const
115    {
116        // 2 represent maxPower units
117        return maxPower_ * 2;
118    }
119
120    const std::string &GetName() const
121    {
122        return name_;
123    }
124
125    bool IsRemoteWakeup() const
126    {
127        return (attributes_ & USB_CFG_REMOTE_WAKEUP) != 0;
128    }
129
130    bool IsSelfPowered() const
131    {
132        return (attributes_ & USB_CFG_SELF_POWERED) != 0;
133    }
134
135    void SetInterfaces(const std::vector<UsbInterface> &interfaces)
136    {
137        this->interfaces_ = interfaces;
138    }
139
140    std::vector<UsbInterface> &GetInterfaces()
141    {
142        return interfaces_;
143    }
144
145    void SetId(int32_t id)
146    {
147        this->id_ = id;
148    }
149
150    void SetAttribute(uint32_t attributes)
151    {
152        this->attributes_ = attributes;
153    }
154
155    void SetMaxPower(int32_t maxPower)
156    {
157        this->maxPower_ = maxPower;
158    }
159
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
177    void SetName(const std::string &name)
178    {
179        this->name_ = name;
180    }
181
182    void SetiConfiguration(uint8_t idx)
183    {
184        this->iConfiguration_ = idx;
185    }
186
187    uint8_t GetiConfiguration()
188    {
189        return this->iConfiguration_;
190    }
191
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
228private:
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