1 /*
2  * Copyright (c) 2024 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_INTERFACE_H
17 #define USB_INTERFACE_H
18 
19 #include <iostream>
20 #include <sstream>
21 #include <string>
22 #include <vector>
23 #include <optional>
24 #include "usb_endpoint.h"
25 
26 namespace OHOS {
27 namespace USB {
28 class UsbInterface {
29 public:
UsbInterface(int32_t id,int32_t protocol,int32_t interfaceClass,int32_t subClass,int32_t alternateSetting,std::string name,std::vector<USBEndpoint> endpoints)30     UsbInterface(int32_t id,
31                  int32_t protocol,
32                  int32_t interfaceClass,
33                  int32_t subClass,
34                  int32_t alternateSetting,
35                  std::string name,
36                  std::vector<USBEndpoint> endpoints)
37     {
38         this->id_ = id;
39         this->protocol_ = protocol;
40         this->klass_ = interfaceClass;
41         this->subClass_ = subClass;
42         this->alternateSetting_ = alternateSetting;
43         this->endpoints_ = endpoints;
44     }
45 
UsbInterface(const cJSON * interface)46     explicit UsbInterface(const cJSON *interface)
47     {
48         if (interface == nullptr) {
49             USB_HILOGE(MODULE_USB_SERVICE, "interface pointer is nullptr");
50         }
51         id_ = GetIntValue(interface, "id");
52         protocol_ = GetIntValue(interface, "protocol");
53         klass_ = GetIntValue(interface, "clazz");
54         subClass_ = GetIntValue(interface, "subClass");
55         alternateSetting_ = GetIntValue(interface, "alternateSetting");
56         name_ = GetStringValue(interface, "name");
57 
58         cJSON *endpoints = cJSON_GetObjectItem(interface, "endpoints");
59         for (int i = 0; i < cJSON_GetArraySize(endpoints); i++) {
60             cJSON *jsonEp = cJSON_GetArrayItem(endpoints, i);
61             if (jsonEp == nullptr) {
62                 USB_HILOGE(MODULE_USB_SERVICE, "get item nullptr");
63                 continue;
64             }
65             USBEndpoint ep(jsonEp);
66             endpoints_.emplace_back(ep);
67         }
68     }
69 
UsbInterface()70     UsbInterface() {}
71 
GetIntValue(const cJSON * jsonObject,const char * key)72     static int GetIntValue(const cJSON *jsonObject, const char *key)
73     {
74         cJSON *item = cJSON_GetObjectItem(jsonObject, key);
75         if (item != nullptr && cJSON_IsNumber(item)) {
76             return item->valueint;
77         } else {
78             USB_HILOGE(MODULE_USB_SERVICE, "Invalid or missing %s field", key);
79             return 0;
80         }
81     }
82 
GetStringValue(const cJSON * jsonObject,const char * key)83     static std::string GetStringValue(const cJSON *jsonObject, const char *key)
84     {
85         cJSON *item = cJSON_GetObjectItem(jsonObject, key);
86         if (item != nullptr && cJSON_IsString(item)) {
87             return item->valuestring;
88         } else {
89             USB_HILOGE(MODULE_USB_SERVICE, "Invalid or missing %s field", key);
90             return "";
91         }
92     }
93 
GetName()94     const std::string &GetName() const
95     {
96         return name_;
97     }
98 
GetId()99     int32_t GetId() const
100     {
101         return id_;
102     }
103 
GetClass()104     int32_t GetClass() const
105     {
106         return klass_;
107     }
108 
GetSubClass()109     int32_t GetSubClass() const
110     {
111         return subClass_;
112     }
113 
GetAlternateSetting()114     int32_t GetAlternateSetting() const
115     {
116         return alternateSetting_;
117     }
118 
GetProtocol()119     int32_t GetProtocol() const
120     {
121         return protocol_;
122     }
123 
GetEndpointCount()124     int32_t GetEndpointCount() const
125     {
126         return endpoints_.size();
127     }
128 
GetEndpoint(uint32_t index)129     std::optional<USBEndpoint> GetEndpoint(uint32_t index) const
130     {
131         if (index >= endpoints_.size()) {
132             USB_HILOGE(MODULE_USB_INNERKIT, "invalid index=%{public}u !", index);
133             return std::nullopt;
134         }
135 
136         return endpoints_[index];
137     }
138 
GetEndpoints()139     std::vector<USBEndpoint> &GetEndpoints()
140     {
141         return endpoints_;
142     }
143 
SetEndpoints(const std::vector<USBEndpoint> & eps)144     void SetEndpoints(const std::vector<USBEndpoint> &eps)
145     {
146         endpoints_ = eps;
147     }
148 
SetId(int32_t id)149     void SetId(int32_t id)
150     {
151         id_ = id;
152     }
153 
SetProtocol(int32_t protocol)154     void SetProtocol(int32_t protocol)
155     {
156         protocol_ = protocol;
157     }
158 
SetClass(int32_t klass)159     void SetClass(int32_t klass)
160     {
161         klass_ = klass;
162     }
163 
SetSubClass(int32_t subClass)164     void SetSubClass(int32_t subClass)
165     {
166         subClass_ = subClass;
167     }
168 
SetAlternateSetting(int32_t alternateSetting)169     void SetAlternateSetting(int32_t alternateSetting)
170     {
171         alternateSetting_ = alternateSetting;
172     }
173 
SetName(const std::string & name)174     void SetName(const std::string &name)
175     {
176         name_ = name;
177     }
178 
~UsbInterface()179     ~UsbInterface() {}
180 
ToString()181     std::string ToString() const
182     {
183         std::ostringstream ss;
184         ss << "id=" << id_ << ","
185            << "name_=" << name_ << ","
186            << "iInterface_=" << (int32_t)iInterface_ << ","
187            << "klass_=" << klass_ << ","
188            << "subClass_=" << subClass_ << ","
189            << "protocol_=" << protocol_ << ","
190            << "alternateSetting_=" << alternateSetting_ << "";
191         std::string str = "UsbInterface[" + ss.str() + "];    ";
192         ss.str("");
193         for (size_t i = 0; i < endpoints_.size(); ++i) {
194             const USBEndpoint &endpoint = endpoints_[i];
195             str += endpoint.ToString();
196         }
197         return str;
198     }
199 
SetiInterface(uint8_t idx)200     void SetiInterface(uint8_t idx)
201     {
202         this->iInterface_ = idx;
203     }
204 
GetiInterface()205     uint8_t GetiInterface()
206     {
207         return this->iInterface_;
208     }
209 
getJsonString()210     const std::string getJsonString() const
211     {
212         cJSON* interface = cJSON_CreateObject();
213         if (!interface) {
214             USB_HILOGE(MODULE_USB_SERVICE, "Create interface error");
215             return "";
216         }
217         cJSON_AddNumberToObject(interface, "id", static_cast<double>(id_));
218         cJSON_AddNumberToObject(interface, "protocol", static_cast<double>(protocol_));
219         cJSON_AddNumberToObject(interface, "clazz", static_cast<double>(klass_));
220         cJSON_AddNumberToObject(interface, "subClass", static_cast<double>(subClass_));
221         cJSON_AddNumberToObject(interface, "alternateSetting", alternateSetting_);
222         cJSON_AddStringToObject(interface, "name", name_.c_str());
223         cJSON* endpoints = cJSON_CreateArray();
224         if (!endpoints) {
225             USB_HILOGE(MODULE_USB_SERVICE, "Create endpoints error");
226             cJSON_Delete(interface);
227             return "";
228         }
229         for (size_t i = 0; i < endpoints_.size(); ++i) {
230             const USBEndpoint &ep = endpoints_[i];
231             cJSON* pEp =  cJSON_Parse(ep.getJsonString().c_str());
232             cJSON_AddItemToArray(endpoints, pEp);
233         }
234         cJSON_AddItemToObject(interface, "endpoints", endpoints);
235         char *pInterface = cJSON_PrintUnformatted(interface);
236         cJSON_Delete(interface);
237         if (!pInterface) {
238             USB_HILOGE(MODULE_USB_SERVICE, "Print interface error");
239             return "";
240         }
241         std::string interfaceJsonStr(pInterface);
242         cJSON_free(pInterface);
243         return interfaceJsonStr;
244     }
245 
246 private:
247     int32_t id_ = INT32_MAX;
248     int32_t protocol_ = INT32_MAX;
249     int32_t klass_ = INT32_MAX;
250     int32_t subClass_ = INT32_MAX;
251     int32_t alternateSetting_ = INT32_MAX;
252     std::string name_;
253     std::vector<USBEndpoint> endpoints_;
254     uint8_t iInterface_ = UINT8_MAX;
255 };
256 } // namespace USB
257 } // namespace OHOS
258 
259 #endif // USB_INTERFACE_H
260