• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 extern "C" {
17 #include "usb_device_cdcacm_test.h"
18 #include "hdf_remote_service.h"
19 #include "hdf_sbuf.h"
20 #include "servmgr_hdi.h"
21 }
22 
23 using namespace std;
24 
25 static struct UsbInterfaceAssocDescriptor g_acmIadDescriptor = {
26     .bLength           = sizeof(g_acmIadDescriptor),
27     .bDescriptorType   = USB_DDK_DT_INTERFACE_ASSOCIATION,
28 #ifdef CDC_ECM
29     .bFirstInterface   = 0x02,
30 #else
31     .bFirstInterface   = 0,
32 #endif
33     .bInterfaceCount   = INTF_COUNT,
34     .bFunctionClass    = USB_DDK_CLASS_COMM,
35     .bFunctionSubClass = USB_DDK_CDC_SUBCLASS_ACM,
36     .bFunctionProtocol = USB_DDK_CDC_ACM_PROTO_AT_V25TER,
37     .iFunction         = ACM_IAD_IDX,
38 };
39 
40 static struct UsbInterfaceDescriptor g_acmControlInterfaceDesc = {
41     .bLength            = USB_DDK_DT_INTERFACE_SIZE,
42     .bDescriptorType    = USB_DDK_DT_INTERFACE,
43 #ifdef CDC_ECM
44     .bInterfaceNumber   = 0x02,
45 #else
46     .bInterfaceNumber   = 0,
47 #endif
48     .bAlternateSetting  = 0,
49     .bNumEndpoints      = NOTIFY_EP_NUM,
50     .bInterfaceClass    = USB_DDK_CLASS_COMM,
51     .bInterfaceSubClass = USB_DDK_CDC_SUBCLASS_ACM,
52     .bInterfaceProtocol = USB_DDK_CDC_ACM_PROTO_AT_V25TER,
53     .iInterface         = ACM_CTRL_IDX,
54 };
55 
56 static struct UsbInterfaceDescriptor g_acmDataInterfaceDesc = {
57     .bLength            = USB_DDK_DT_INTERFACE_SIZE,
58     .bDescriptorType    = USB_DDK_DT_INTERFACE,
59 #ifdef CDC_ECM
60     .bInterfaceNumber   = 0x03,
61 #else
62     .bInterfaceNumber   = 1,
63 #endif
64     .bAlternateSetting  = 0,
65     .bNumEndpoints      = DATA_EP_NUM,
66     .bInterfaceClass    = USB_DDK_CLASS_CDC_DATA,
67     .bInterfaceSubClass = 0,
68     .bInterfaceProtocol = 2,
69     .iInterface         = ACM_DATA_IDX,
70 };
71 
72 static struct UsbCdcHeaderDesc g_acmHeaderDesc = {
73     .bLength            = sizeof(g_acmHeaderDesc),
74     .bDescriptorType    = USB_DDK_DT_CS_INTERFACE,
75     .bDescriptorSubType = USB_DDK_CDC_HEADER_TYPE,
76     .bcdCDC             = CpuToLe16(0x0110),
77 };
78 
79 static struct UsbCdcCallMgmtDescriptor g_acmCallMgmtDescriptor = {
80     .bLength            = sizeof(g_acmCallMgmtDescriptor),
81     .bDescriptorType    = USB_DDK_DT_CS_INTERFACE,
82     .bDescriptorSubType = USB_DDK_CDC_CALL_MANAGEMENT_TYPE,
83     .bmCapabilities     = 0,
84     .bDataInterface     = 1,
85 };
86 
87 static struct UsbCdcAcmDescriptor g_acmDescriptor = {
88     .bLength            = sizeof(g_acmDescriptor),
89     .bDescriptorType    = USB_DDK_DT_CS_INTERFACE,
90     .bDescriptorSubType = USB_DDK_CDC_ACM_TYPE,
91     .bmCapabilities     = USB_DDK_CDC_CAP_LINE,
92 };
93 
94 static struct UsbCdcUnionDesc g_acmUnionDesc = {
95     .bLength            = sizeof(g_acmUnionDesc),
96     .bDescriptorType    = USB_DDK_DT_CS_INTERFACE,
97     .bDescriptorSubType = USB_DDK_CDC_UNION_TYPE,
98 #ifdef CDC_ECM
99     .bMasterInterface0  = 0x02,
100     .bSlaveInterface0   = 0x03,
101 #else
102     .bMasterInterface0  = 0,
103     .bSlaveInterface0   = 1,
104 #endif
105 };
106 
107 static struct UsbEndpointDescriptor g_acmFsNotifyDesc = {
108     .bLength          = USB_DDK_DT_ENDPOINT_SIZE,
109     .bDescriptorType  = USB_DDK_DT_ENDPOINT,
110     .bEndpointAddress = EP_ADD_NOTIFY | USB_DDK_DIR_IN,
111     .bmAttributes     = USB_DDK_ENDPOINT_XFER_INT,
112     .wMaxPacketSize   = CpuToLe16(ACM_NOTIFY_MAXPACKET),
113     .bInterval        = ACM_NOTIFY_INTERVAL,
114 };
115 
116 static struct UsbEndpointDescriptor g_acmFsInDesc = {
117     .bLength          = USB_DDK_DT_ENDPOINT_SIZE,
118     .bDescriptorType  = USB_DDK_DT_ENDPOINT,
119     .bEndpointAddress = EP_ADD_DATA_IN | USB_DDK_DIR_IN,
120     .bmAttributes     = USB_DDK_ENDPOINT_XFER_BULK,
121 };
122 
123 static struct UsbEndpointDescriptor g_acmFsOutDesc = {
124     .bLength          = USB_DDK_DT_ENDPOINT_SIZE,
125     .bDescriptorType  = USB_DDK_DT_ENDPOINT,
126     .bEndpointAddress = EP_ADD_DATA_OUT | USB_DDK_DIR_OUT,
127     .bmAttributes     = USB_DDK_ENDPOINT_XFER_BULK,
128 };
129 
130 static struct UsbDescriptorHeader *g_acmFsFunction[] = {
131     (struct UsbDescriptorHeader *) &g_acmIadDescriptor,
132     (struct UsbDescriptorHeader *) &g_acmControlInterfaceDesc,
133     (struct UsbDescriptorHeader *) &g_acmHeaderDesc,
134     (struct UsbDescriptorHeader *) &g_acmCallMgmtDescriptor,
135     (struct UsbDescriptorHeader *) &g_acmDescriptor,
136     (struct UsbDescriptorHeader *) &g_acmUnionDesc,
137     (struct UsbDescriptorHeader *) &g_acmFsNotifyDesc,
138     (struct UsbDescriptorHeader *) &g_acmDataInterfaceDesc,
139     (struct UsbDescriptorHeader *) &g_acmFsInDesc,
140     (struct UsbDescriptorHeader *) &g_acmFsOutDesc,
141     nullptr,
142 };
143 
144 static struct UsbEndpointDescriptor g_acmHsNotifyDesc = {
145     .bLength          = USB_DDK_DT_ENDPOINT_SIZE,
146     .bDescriptorType  = USB_DDK_DT_ENDPOINT,
147     .bEndpointAddress = EP_ADD_NOTIFY | USB_DDK_DIR_IN,
148     .bmAttributes     = USB_DDK_ENDPOINT_XFER_INT,
149     .wMaxPacketSize   = CpuToLe16(ACM_NOTIFY_MAXPACKET),
150     .bInterval        = ACM_HS_NOTIFY_INTERVAL,
151 };
152 
153 static struct UsbEndpointDescriptor g_acmHsInDesc = {
154     .bLength          = USB_DDK_DT_ENDPOINT_SIZE,
155     .bDescriptorType  = USB_DDK_DT_ENDPOINT,
156     .bEndpointAddress = EP_ADD_DATA_IN | USB_DDK_DIR_IN,
157     .bmAttributes     = USB_DDK_ENDPOINT_XFER_BULK,
158     .wMaxPacketSize   = CpuToLe16(MAX_PACKET_SIZE),
159 };
160 
161 static struct UsbEndpointDescriptor g_acmHsOutDesc = {
162     .bLength           = USB_DDK_DT_ENDPOINT_SIZE,
163     .bDescriptorType   = USB_DDK_DT_ENDPOINT,
164     .bEndpointAddress  = EP_ADD_DATA_OUT | USB_DDK_DIR_OUT,
165     .bmAttributes      = USB_DDK_ENDPOINT_XFER_BULK,
166     .wMaxPacketSize    = CpuToLe16(MAX_PACKET_SIZE),
167 };
168 
169 static struct UsbDescriptorHeader *g_acmHsFunction[] = {
170     (struct UsbDescriptorHeader *) &g_acmIadDescriptor,
171     (struct UsbDescriptorHeader *) &g_acmControlInterfaceDesc,
172     (struct UsbDescriptorHeader *) &g_acmHeaderDesc,
173     (struct UsbDescriptorHeader *) &g_acmCallMgmtDescriptor,
174     (struct UsbDescriptorHeader *) &g_acmDescriptor,
175     (struct UsbDescriptorHeader *) &g_acmUnionDesc,
176     (struct UsbDescriptorHeader *) &g_acmHsNotifyDesc,
177     (struct UsbDescriptorHeader *) &g_acmDataInterfaceDesc,
178     (struct UsbDescriptorHeader *) &g_acmHsInDesc,
179     (struct UsbDescriptorHeader *) &g_acmHsOutDesc,
180     nullptr,
181 };
182 
183 static struct UsbEndpointDescriptor g_acmSsInDesc = {
184     .bLength          = USB_DDK_DT_ENDPOINT_SIZE,
185     .bDescriptorType  = USB_DDK_DT_ENDPOINT,
186     .bEndpointAddress = EP_ADD_DATA_IN | USB_DDK_DIR_IN,
187     .bmAttributes     = USB_DDK_ENDPOINT_XFER_BULK,
188     .wMaxPacketSize   = CpuToLe16(SS_MAX_PACKET_SIZE),
189 };
190 
191 static struct UsbEndpointDescriptor g_acmSsOutDesc = {
192     .bLength          = USB_DDK_DT_ENDPOINT_SIZE,
193     .bDescriptorType  = USB_DDK_DT_ENDPOINT,
194     .bEndpointAddress = EP_ADD_DATA_OUT | USB_DDK_DIR_OUT,
195     .bmAttributes     = USB_DDK_ENDPOINT_XFER_BULK,
196     .wMaxPacketSize   = CpuToLe16(SS_MAX_PACKET_SIZE),
197 };
198 
199 static struct UsbSsEpCompDescriptor g_acmSsBulkCompDesc = {
200     .bLength         = sizeof(g_acmSsBulkCompDesc),
201     .bDescriptorType = USB_DDK_DT_SS_ENDPOINT_COMP,
202 };
203 
204 static struct UsbDescriptorHeader *g_acmSsFunction[] = {
205     (struct UsbDescriptorHeader *) &g_acmIadDescriptor,
206     (struct UsbDescriptorHeader *) &g_acmControlInterfaceDesc,
207     (struct UsbDescriptorHeader *) &g_acmHeaderDesc,
208     (struct UsbDescriptorHeader *) &g_acmCallMgmtDescriptor,
209     (struct UsbDescriptorHeader *) &g_acmDescriptor,
210     (struct UsbDescriptorHeader *) &g_acmUnionDesc,
211     (struct UsbDescriptorHeader *) &g_acmHsNotifyDesc,
212     (struct UsbDescriptorHeader *) &g_acmSsBulkCompDesc,
213     (struct UsbDescriptorHeader *) &g_acmDataInterfaceDesc,
214     (struct UsbDescriptorHeader *) &g_acmSsInDesc,
215     (struct UsbDescriptorHeader *) &g_acmSsBulkCompDesc,
216     (struct UsbDescriptorHeader *) &g_acmSsOutDesc,
217     (struct UsbDescriptorHeader *) &g_acmSsBulkCompDesc,
218     nullptr,
219 };
220 
221 static struct UsbString g_acmStringDefs[] = {
222     [0].s = "CDC Abstract Control Model (ACM)",
223     [1].s = "CDC ACM Data",
224     [2].s = "CDC Serial",
225     {  } /* end of list */
226 };
227 
228 static struct UsbFnStrings g_acmStringTable = {
229     .language = 0x0409, /* en-us */
230     .strings  = g_acmStringDefs,
231 };
232 
233 static struct UsbFnStrings *g_acmStrings[] = {
234     &g_acmStringTable,
235     nullptr,
236 };
237 
238 static struct UsbFnFunction g_acmFunction = {
239     .funcName       = "f_generic.a",
240     .strings        = g_acmStrings,
241     .fsDescriptors  = g_acmFsFunction,
242     .hsDescriptors  = g_acmHsFunction,
243     .ssDescriptors  = g_acmSsFunction,
244     .sspDescriptors = nullptr,
245 };
246 
247 /** device **/
248 #define BCD_USB                 0x0200
249 #define DEVICE_VENDOR_ID        0x12D1
250 #define DEVICE_PRODUCT_ID       0x5000
251 #define DEVICE_VERSION          0x0223
252 
253 #define USB_MAX_PACKET_SIZE     0x40
254 #define POWER                   500
255 
256 #define USB_FUNC_CONFIG_IDX USB_FUNC_FIRST_AVAIL_IDX
257 #define DRIVER_DESC "HDC Device"
258 #define CONFIG_DESC "hdc"
259 
260 static struct UsbDeviceDescriptor g_cdcMasterDeviceDesc = {
261     .bLength            = sizeof(g_cdcMasterDeviceDesc),
262     .bDescriptorType    = USB_DDK_DT_DEVICE,
263     .bcdUSB             = CpuToLe16(BCD_USB),
264     .bDeviceClass       = 0,
265     .bDeviceSubClass    = 0,
266     .bDeviceProtocol    = 0,
267     .bMaxPacketSize0    = USB_MAX_PACKET_SIZE,
268     .idVendor           = CpuToLe16(DEVICE_VENDOR_ID),
269     .idProduct          = CpuToLe16(DEVICE_PRODUCT_ID),
270     .bcdDevice          = CpuToLe16(DEVICE_VERSION),
271     .iManufacturer      = USB_FUNC_MANUFACTURER_IDX,
272     .iProduct           = USB_FUNC_PRODUCT_IDX,
273     .iSerialNumber      = USB_FUNC_SERIAL_IDX,
274     .bNumConfigurations = 1,
275 };
276 
277 static struct UsbString g_stringsDev[] = {
278     {USB_FUNC_MANUFACTURER_IDX, "HISILICON"},
279     {USB_FUNC_PRODUCT_IDX, DRIVER_DESC},
280     {USB_FUNC_SERIAL_IDX, "0123456789POPLAR"},
281     {USB_FUNC_CONFIG_IDX, CONFIG_DESC},
282     {  } /* end of list */
283 };
284 
285 static struct UsbFnStrings g_stringTabDev = {
286     .language   = 0x0409,       /* en-us */
287     .strings    = g_stringsDev,
288 };
289 
290 static struct UsbFnStrings *g_devStrings[] = {
291     &g_stringTabDev,
292     nullptr,
293 };
294 
295 struct UsbFnFunction *g_functions[] = {
296 #ifdef CDC_ECM
297     &g_ecmFunction,
298 #endif
299 #ifdef CDC_ACM
300     &g_acmFunction,
301 #endif
302     nullptr
303 };
304 
305 static struct UsbFnConfiguration g_masterConfig = {
306     .configurationValue = 1,
307     .iConfiguration     = USB_FUNC_CONFIG_IDX,
308     .attributes         = USB_CFG_BUS_POWERED,
309     .maxPower           = POWER,
310     .functions          = g_functions,
311 };
312 
313 static struct UsbFnConfiguration *g_configs[] = {
314     &g_masterConfig,
315     nullptr,
316 };
317 
318 struct UsbFnDeviceDesc g_acmFnDevice = {
319     .deviceDesc    = &g_cdcMasterDeviceDesc,
320     .deviceStrings = g_devStrings,
321     .configs       = g_configs,
322 };
323 
324 enum DevMasterCmd {
325     DEV_MASTER_RELEASE = 1,
326 };
327 
SerialAlloc(void)328 static struct Serial *SerialAlloc(void)
329 {
330     struct Serial *port = nullptr;
331     port = (struct Serial *)OsalMemCalloc(sizeof(*port));
332     if (port == nullptr) {
333         return nullptr;
334     }
335     OsalMutexInit(&port->lock);
336     DListHeadInit(&port->readPool);
337     DListHeadInit(&port->readQueue);
338     DListHeadInit(&port->writePool);
339 
340     port->lineCoding.dwDTERate = CpuToLe32(PORT_RATE);
341     port->lineCoding.bCharFormat = CHAR_FORMAT;
342     port->lineCoding.bParityType = USB_CDC_NO_PARITY;
343     port->lineCoding.bDataBits = USB_CDC_1_STOP_BITS;
344     return port;
345 }
346 
ParseInterfaces(struct AcmDevice * acmDevice)347 static int ParseInterfaces(struct AcmDevice *acmDevice)
348 {
349     uint32_t i;
350     uint32_t j;
351     struct UsbFnInterface *fnIface = nullptr;
352     UsbFnInterfaceHandle handle = nullptr;
353     int ret;
354     for (i = 0; i < acmDevice->fnDev->numInterfaces; i++) {
355         fnIface = (struct UsbFnInterface *)UsbFnGetInterface(acmDevice->fnDev, i);
356         if (fnIface == nullptr) {
357             return -1;
358         }
359         handle = UsbFnOpenInterface(fnIface);
360         if (handle == nullptr) {
361             return -1;
362         }
363         for (j = 0; j < fnIface->info.numPipes; j++) {
364             struct UsbFnPipeInfo pipeInfo;
365             ret = UsbFnGetInterfacePipeInfo(fnIface, j, &pipeInfo);
366             if (ret != HDF_SUCCESS) {
367                 return -1;
368             }
369             if (pipeInfo.type == USB_PIPE_TYPE_INTERRUPT) {
370                 acmDevice->notifyPipe.id = pipeInfo.id;
371                 acmDevice->notifyPipe.maxPacketSize = pipeInfo.maxPacketSize;
372                 acmDevice->ctrlIface.fn = fnIface;
373                 acmDevice->ctrlIface.handle = handle;
374             } else if (pipeInfo.type == USB_PIPE_TYPE_BULK) {
375                 if (pipeInfo.dir == USB_PIPE_DIRECTION_IN) {
376                     acmDevice->dataInPipe.id = pipeInfo.id;
377                     acmDevice->dataInPipe.maxPacketSize = pipeInfo.maxPacketSize;
378                     acmDevice->dataIface.fn = fnIface;
379                     acmDevice->dataIface.handle = handle;
380                 } else {
381                     acmDevice->dataOutPipe.id = pipeInfo.id;
382                     acmDevice->dataOutPipe.maxPacketSize = pipeInfo.maxPacketSize;
383                     acmDevice->dataIface.fn = fnIface;
384                     acmDevice->dataIface.handle = handle;
385                 }
386             }
387         }
388     }
389     return 0;
390 }
391 
CtrlComplete(uint8_t pipe,struct UsbFnRequest * req)392 static void CtrlComplete(uint8_t pipe, struct UsbFnRequest *req)
393 {
394     struct CtrlInfo *ctrlInfo = (struct CtrlInfo *)req->context;
395     struct AcmDevice *acm = ctrlInfo->acm;
396 
397     if (req == nullptr) {
398         return;
399     }
400     if (USB_REQUEST_COMPLETED != req->status) {
401         goto out;
402     }
403 
404     if (ctrlInfo->request == USB_DDK_CDC_REQ_SET_LINE_CODING) {
405         struct UsbCdcLineCoding *value = (struct UsbCdcLineCoding *)req->buf;
406         if (req->actual == sizeof(*value)) {
407             acm->lineCoding = *value;
408         }
409     }
410 out:
411     DListInsertTail(&req->list, &acm->ctrlPool);
412 }
413 
AllocCtrlRequests(struct AcmDevice * acmDevice)414 static int AllocCtrlRequests(struct AcmDevice *acmDevice)
415 {
416     struct DListHead *head = &acmDevice->ctrlPool;
417     struct UsbFnRequest *req = nullptr;
418     struct CtrlInfo *ctrlInfo = nullptr;
419     int i;
420 
421     DListHeadInit(&acmDevice->ctrlPool);
422     acmDevice->ctrlReqNum = 0;
423 
424     for (i = 0; i < 2; i++) {
425         ctrlInfo = (struct CtrlInfo *)OsalMemCalloc(sizeof(*ctrlInfo));
426         if (nullptr == ctrlInfo) {
427             return -1;
428         }
429         ctrlInfo->acm = acmDevice;
430         req = UsbFnAllocCtrlRequest(acmDevice->ctrlIface.handle,
431             sizeof(struct UsbCdcLineCoding) + sizeof(struct UsbCdcLineCoding));
432         if (nullptr == req) {
433             return -1;
434         }
435         req->complete = CtrlComplete;
436         req->context  = ctrlInfo;
437         DListInsertTail(&req->list, head);
438         acmDevice->ctrlReqNum++;
439     }
440 
441     return 0;
442 }
443 
SendNotifyRequest(struct AcmDevice * acm,uint8_t type,uint16_t value,void * data,uint32_t length)444 static int32_t SendNotifyRequest(struct AcmDevice *acm, uint8_t type,
445     uint16_t value, void *data, uint32_t length)
446 {
447     struct UsbFnRequest *req = acm->notifyReq;
448     struct UsbCdcNotification *notify = nullptr;
449     int ret;
450     if (acm == nullptr || req->buf) {
451         return -1;
452     }
453     acm->notifyReq = nullptr;
454     acm->pending   = false;
455     req->length    = sizeof(*notify) + length;
456 
457     notify = (struct UsbCdcNotification *)req->buf;
458     notify->bmRequestType = USB_DDK_DIR_IN | USB_DDK_TYPE_CLASS | USB_DDK_RECIP_INTERFACE;
459     notify->bNotificationType = type;
460     notify->wValue = CpuToLe16(value);
461     notify->wIndex = CpuToLe16(acm->ctrlIface.fn->info.index);
462     notify->wLength = CpuToLe16(length);
463     memcpy_s((void *)(notify + 1), length, data, length);
464 
465     ret = UsbFnSubmitRequestAsync(req);
466     return ret;
467 }
468 
NotifySerialState(struct AcmDevice * acm)469 static int32_t NotifySerialState(struct AcmDevice *acm)
470 {
471     int32_t ret = 0;
472     uint16_t serialState;
473 
474     OsalMutexLock(&acm->lock);
475     if (acm->notifyReq) {
476         serialState = CpuToLe16(acm->serialState);
477         ret = SendNotifyRequest(acm, USB_DDK_CDC_NOTIFY_SERIAL_STATE,
478             0, &serialState, sizeof(acm->serialState));
479     } else {
480         acm->pending = true;
481     }
482     OsalMutexUnlock(&acm->lock);
483 
484     return ret;
485 }
486 
NotifyComplete(uint8_t pipe,struct UsbFnRequest * req)487 static void NotifyComplete(uint8_t pipe, struct UsbFnRequest *req)
488 {
489     struct AcmDevice *acm = (struct AcmDevice *)req->context;
490     bool pending = false;
491 
492     if (acm == nullptr) {
493         return;
494     }
495     OsalMutexLock(&acm->lock);
496     if (req->status != USB_REQUEST_NO_DEVICE) {
497         pending = acm->pending;
498     }
499     acm->notifyReq = req;
500     OsalMutexUnlock(&acm->lock);
501     if (pending) {
502         NotifySerialState(acm);
503     }
504 }
505 
AllocNotifyRequest(struct AcmDevice * acmDevice)506 static int32_t AllocNotifyRequest(struct AcmDevice *acmDevice)
507 {
508     /* allocate notification request */
509     acmDevice->notifyReq = UsbFnAllocRequest(acmDevice->ctrlIface.handle, acmDevice->notifyPipe.id,
510         sizeof(struct UsbCdcNotification));
511     if (acmDevice->notifyReq == nullptr) {
512         return -1;
513     }
514     acmDevice->notifyReq->complete = NotifyComplete;
515     acmDevice->notifyReq->context = acmDevice;
516 
517     return HDF_SUCCESS;
518 }
519 
Connect(struct AcmDevice * acm)520 static void Connect(struct AcmDevice *acm)
521 {
522     if (acm == nullptr) {
523         return;
524     }
525     acm->serialState |= SERIAL_STATE_DSR | SERIAL_STATE_DCD;
526     NotifySerialState(acm);
527 }
528 
Disconnect(struct AcmDevice * acm)529 static void Disconnect(struct AcmDevice *acm)
530 {
531     if (acm == nullptr) {
532         return;
533     }
534     acm->serialState &= ~(SERIAL_STATE_DSR | SERIAL_STATE_DCD);
535     NotifySerialState(acm);
536 }
537 
SendBreak(struct AcmDevice * acm,int duration)538 static int32_t SendBreak(struct AcmDevice *acm, int duration)
539 {
540     uint16_t state;
541 
542     if (acm == nullptr) {
543         return -1;
544     }
545     state = acm->serialState;
546     state &= ~SERIAL_STATE_BREAK;
547     if (duration)
548         state |= SERIAL_STATE_BREAK;
549 
550     acm->serialState = state;
551     return NotifySerialState(acm);
552 }
553 
554 static struct AcmNotifyMethod g_notifyMethod = {
555     .Connect    = Connect,
556     .Disconnect = Disconnect,
557     .SendBreak  = SendBreak,
558 };
559 
Enable(struct AcmDevice * acm)560 static uint32_t Enable(struct AcmDevice *acm)
561 {
562     struct Serial *port = acm->port;
563     OsalMutexLock(&port->lock);
564     port->acm = acm;
565     acm->lineCoding = port->lineCoding;
566     if (port->refCount) {
567         if (acm->notify && acm->notify->Connect) {
568             acm->notify->Connect(acm);
569         }
570     } else {
571         if (acm->notify && acm->notify->Disconnect) {
572             acm->notify->Disconnect(acm);
573         }
574     }
575     OsalMutexUnlock(&port->lock);
576 
577     return HDF_SUCCESS;
578 }
579 
Disable(struct AcmDevice * acm)580 static uint32_t Disable(struct AcmDevice *acm)
581 {
582     return HDF_SUCCESS;
583 }
584 
GetCtrlReq(struct AcmDevice * acm)585 static struct UsbFnRequest *GetCtrlReq(struct AcmDevice *acm)
586 {
587     struct UsbFnRequest *req = nullptr;
588     struct DListHead *pool = &acm->ctrlPool;
589     if (!DListIsEmpty(pool)) {
590         req = DLIST_FIRST_ENTRY(pool, struct UsbFnRequest, list);
591         DListRemove(&req->list);
592     }
593     return req;
594 }
595 
Setup(struct AcmDevice * acm,struct UsbFnCtrlRequest * setup)596 static void Setup(struct AcmDevice *acm, struct UsbFnCtrlRequest *setup)
597 {
598     struct UsbFnRequest *req = nullptr;
599     struct CtrlInfo *ctrlInfo = nullptr;
600     uint16_t value  = Le16ToCpu(setup->value);
601     uint16_t length = Le16ToCpu(setup->length);
602     int ret = 0;
603     req = GetCtrlReq(acm);
604     if (req == nullptr) {
605         return;
606     }
607     switch (setup->request) {
608         case USB_DDK_CDC_REQ_SET_LINE_CODING:
609             if (length != sizeof(struct UsbCdcLineCoding)) {
610                 goto out;
611             }
612             ret = length;
613             break;
614         case USB_DDK_CDC_REQ_GET_LINE_CODING:
615             ret = (length > sizeof(struct UsbCdcLineCoding)) ? \
616                 sizeof(struct UsbCdcLineCoding) : length;
617             if (acm->lineCoding.dwDTERate == 0) {
618                 acm->lineCoding = acm->port->lineCoding;
619             }
620             memcpy_s(req->buf, req->length, &acm->lineCoding, ret);
621             break;
622         case USB_DDK_CDC_REQ_SET_CONTROL_LINE_STATE:
623             ret = 0;
624             acm->handshakeBits = value;
625             break;
626         default:
627             break;
628     }
629 
630 out:
631     ctrlInfo = (struct CtrlInfo *)req->context;
632     ctrlInfo->request = setup->request;
633     req->length = ret;
634     ret = UsbFnSubmitRequestAsync(req);
635 }
636 
Suspend(struct AcmDevice * acm)637 static void Suspend(struct AcmDevice *acm)
638 {
639     struct Serial *port = acm->port;
640 
641     OsalMutexLock(&port->lock);
642     port->suspended = true;
643     OsalMutexUnlock(&port->lock);
644 }
645 
Resume(struct AcmDevice * acm)646 static void Resume(struct AcmDevice *acm)
647 {
648     struct Serial *port = acm->port;
649 
650     OsalMutexLock(&port->lock);
651     port->suspended = false;
652     if (acm->notify && acm->notify->Connect) {
653         acm->notify->Connect(acm);
654     }
655     port->startDelayed = false;
656     OsalMutexUnlock(&port->lock);
657 }
658 
AcmEventCallback(struct UsbFnEvent * event)659 void AcmEventCallback(struct UsbFnEvent *event)
660 {
661     struct AcmDevice *acm = nullptr;
662 
663     if (event == nullptr || event->context == nullptr)
664         return;
665     acm = (struct AcmDevice *)event->context;
666     switch (event->type) {
667         case USBFN_STATE_BIND:
668             break;
669         case USBFN_STATE_UNBIND:
670             break;
671         case USBFN_STATE_ENABLE:
672             Enable(acm);
673             break;
674         case USBFN_STATE_DISABLE:
675             Disable(acm);
676             acm->enableEvtCnt = 0;
677             break;
678         case USBFN_STATE_SETUP:
679             Setup(acm, event->setup);
680             break;
681         case USBFN_STATE_SUSPEND:
682             Suspend(acm);
683             break;
684         case USBFN_STATE_RESUME:
685             Resume(acm);
686             break;
687         default:
688             break;
689     }
690 }
691 
SetUpAcmDevice(void)692 struct AcmDevice * SetUpAcmDevice(void)
693 {
694     int32_t ret;
695 
696     struct AcmDevice *acmDevice = nullptr;
697     struct UsbFnDescriptorData descData;
698     descData.type = USBFN_DESC_DATA_TYPE_DESC;
699     descData.descriptor = &g_acmFnDevice;
700     acmDevice = (struct AcmDevice *)OsalMemCalloc(sizeof(*acmDevice));
701     if (acmDevice == nullptr) {
702         return nullptr;
703     }
704     acmDevice->fnDev = (struct UsbFnDevice *)UsbFnCreateDevice("100e0000.hidwc3_0", &descData);
705     if (acmDevice->fnDev == nullptr) {
706         return nullptr;
707     }
708     acmDevice->port = (struct Serial *)SerialAlloc();
709     if (acmDevice->port == nullptr) {
710         return nullptr;
711     }
712     ret = ParseInterfaces(acmDevice);
713     if (ret != 0) {
714         return nullptr;
715     }
716     ret = AllocCtrlRequests(acmDevice);
717     if (ret != 0) {
718         return nullptr;
719     }
720     ret = AllocNotifyRequest(acmDevice);
721     if (ret != 0) {
722         return nullptr;
723     }
724     ret = UsbFnStartRecvInterfaceEvent(acmDevice->ctrlIface.fn, 0xff, AcmEventCallback, acmDevice);
725     if (ret != 0) {
726         return nullptr;
727     }
728     acmDevice->notify = &g_notifyMethod;
729     return acmDevice;
730 }
731 
FreeNotifyRequest(struct AcmDevice * acmDevice)732 static int32_t FreeNotifyRequest(struct AcmDevice *acmDevice)
733 {
734     int ret;
735 
736     /* allocate notification request */
737     if (acmDevice->notifyReq == nullptr) {
738         HDF_LOGE("%{public}s: notifyReq is nullptr", __func__);
739         return -1;
740     }
741     acmDevice->notifyReq->complete = nullptr;
742     acmDevice->notifyReq->context = nullptr;
743     ret = UsbFnFreeRequest(acmDevice->notifyReq);
744     if (ret != HDF_SUCCESS) {
745         HDF_LOGE("%{public}s: free notifyReq failed", __func__);
746         return -1;
747     }
748     return HDF_SUCCESS;
749 }
750 
FreeCtrlRequests(struct AcmDevice * acmDevice)751 static int FreeCtrlRequests(struct AcmDevice *acmDevice)
752 {
753     struct DListHead *head = &acmDevice->ctrlPool;
754     struct UsbFnRequest *req = nullptr;
755 
756     while (!DListIsEmpty(head)) {
757         req = DLIST_FIRST_ENTRY(head, struct UsbFnRequest, list);
758         DListRemove(&req->list);
759         OsalMemFree(req->context);
760         (void)UsbFnFreeRequest(req);
761         acmDevice->ctrlReqNum--;
762     }
763     return 0;
764 }
765 
ReleaseAcmDevice(struct AcmDevice * acm)766 void ReleaseAcmDevice(struct AcmDevice *acm)
767 {
768     if (acm == nullptr) {
769         HDF_LOGE("%{public}s: acm is nullptr", __func__);
770         return;
771     }
772     FreeNotifyRequest(acm);
773     FreeCtrlRequests(acm);
774     (void)UsbFnCloseInterface(acm->ctrlIface.handle);
775     (void)UsbFnCloseInterface(acm->dataIface.handle);
776     UsbFnStopRecvInterfaceEvent(acm->ctrlIface.fn);
777     OsalMemFree(acm->port);
778 }
779 
780 static struct HdfSBuf *g_data;
781 static struct HdfSBuf *g_reply;
XtsRemoveDevice(void)782 int XtsRemoveDevice(void)
783 {
784     int status;
785     struct HdfRemoteService *devMasterService = NULL;
786     struct HDIServiceManager *servmgr = HDIServiceManagerGet();
787 
788     printf("+++XtsRemoveDevice start++\n");
789     if (servmgr == nullptr) {
790         printf("+++servmgr is null++\n");
791         return HDF_FAILURE;
792     }
793     devMasterService = servmgr->GetService(servmgr, DEV_MASTER_SERVICE_NAME);
794     HDIServiceManagerRelease(servmgr);
795     if (devMasterService == nullptr) {
796         printf("+++GetService error++\n");
797         return HDF_FAILURE;
798     }
799     g_data = HdfSBufTypedObtain(SBUF_IPC);
800     g_reply = HdfSBufTypedObtain(SBUF_IPC);
801     if (g_data == NULL || g_reply == NULL) {
802         HDF_LOGE("%{public}s: sbuf err", __func__);
803         return HDF_FAILURE;
804     }
805     status = devMasterService->dispatcher->Dispatch(devMasterService, DEV_MASTER_RELEASE, g_data, g_reply);
806     if (status !=  HDF_SUCCESS) {
807         printf("+++Dispatch error++\n");
808         return HDF_FAILURE;
809     }
810     HdfSBufRecycle(g_data);
811     HdfSBufRecycle(g_reply);
812     printf("+++XtsRemoveDevice finish++\n");
813     return HDF_SUCCESS;
814 }
815 
816