1 /*
2  * Copyright (c) 2024 Archermind Technology (Nanjing) Co. Ltd. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  *    conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *    of conditions and the following disclaimer in the documentation and/or other materials
12  *    provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15  *    to endorse or promote products derived from this software without specific prior written
16  *    permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <unistd.h>
32 #include "securec.h"
33 #include "osal_mem.h"
34 #include "osal_time.h"
35 
36 #include "hdf_base.h"
37 #include "hdf_log.h"
38 
39 #include "usb_ddk_pnp_loader.h"
40 #include "usb_ddk_interface.h"
41 #include "usb_net_host.h"
42 #include "rndis_rawapi.h"
43 
44 #define HDF_LOG_TAG USB_HOST_RNDIS_RAW_API
45 #define URB_LEGAL_ACTUAL_LENGTH 8
46 #define ZERO_INDEX  0
47 #define ONE_INDEX   1
48 #define TWO_INDEX   2
49 #define THREE_INDEX 3
50 #define FOUR_INDEX  4
51 #define FIVE_INDEX  5
52 
53 #define MSG_HEAD_LENGTH         4
54 #define UNION_OFFSET_LENGTH     8
55 #define COMMAND_COUNT_MAX       10
56 #define UNION_GETOFFSET_NUMBER  20
57 #define RNDIS_COMMAND_SLEEPTIME 40
58 #define RNDIS_QUERY_INPUT_LENGTH 48
59 
60 /* define rndis union */
61 union {
62     void *buf;
63     struct RndisMsgHdr *header;
64     struct RndisInit *init;
65     struct RndisInitC *initC;
66     struct RndisQuery *get;
67     struct RndisQueryC *getC;
68     struct RndisSet *set;
69     struct RndisSetC *setC;
70     struct RndisHalt *halt;
71 } g_u;
72 
UsbGetBulkEndpoint(struct UsbnetHost **ppUsbNet, const struct UsbRawEndpointDescriptor *endPoint)73 static int32_t UsbGetBulkEndpoint(struct UsbnetHost **ppUsbNet, const struct UsbRawEndpointDescriptor *endPoint)
74 {
75     if ((endPoint->endpointDescriptor.bEndpointAddress & USB_DDK_ENDPOINT_DIR_MASK) == USB_DDK_DIR_IN) {
76         /* get bulk in endpoint */
77         (*ppUsbNet)->dataInEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
78         if ((*ppUsbNet)->dataInEp == NULL) {
79             HDF_LOGE("%{public}s:%{public}d allocate dataInEp failed", __func__, __LINE__);
80             return HDF_FAILURE;
81         }
82         (*ppUsbNet)->dataInEp->addr = endPoint->endpointDescriptor.bEndpointAddress;
83         (*ppUsbNet)->dataInEp->interval = endPoint->endpointDescriptor.bInterval;
84         (*ppUsbNet)->dataInEp->maxPacketSize = endPoint->endpointDescriptor.wMaxPacketSize;
85         HARCH_INFO_PRINT("usbNet->dataInEp=[addr:%{public}#x, interval:%{public}d, maxPacketSize:%{public}hu]",
86             (*ppUsbNet)->dataInEp->addr, (*ppUsbNet)->dataInEp->interval, (*ppUsbNet)->dataInEp->maxPacketSize);
87     } else {
88         /* get bulk out endpoint */
89         (*ppUsbNet)->dataOutEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
90         if ((*ppUsbNet)->dataOutEp == NULL) {
91             HDF_LOGE("%{public}s:%{public}d allocate dataOutEp failed", __func__, __LINE__);
92             return HDF_FAILURE;
93         }
94         (*ppUsbNet)->dataOutEp->addr = endPoint->endpointDescriptor.bEndpointAddress;
95         (*ppUsbNet)->dataOutEp->interval = endPoint->endpointDescriptor.bInterval;
96         (*ppUsbNet)->dataOutEp->maxPacketSize = endPoint->endpointDescriptor.wMaxPacketSize;
97         HARCH_INFO_PRINT("usbNet->dataOutEp=[addr:%{public}#x, interval:%{public}d, maxPacketSize:%{public}hu]",
98             (*ppUsbNet)->dataOutEp->addr, (*ppUsbNet)->dataOutEp->interval, (*ppUsbNet)->dataOutEp->maxPacketSize);
99     }
100     return HDF_SUCCESS;
101 }
102 
UsbParseConfigDescriptorProcess(struct UsbnetHost **ppUsbNet, const struct UsbRawInterface *interface, uint8_t interfaceIndex)103 static void UsbParseConfigDescriptorProcess(struct UsbnetHost **ppUsbNet,
104     const struct UsbRawInterface *interface, uint8_t interfaceIndex)
105 {
106     uint8_t ifaceClass   = interface->altsetting->interfaceDescriptor.bInterfaceClass;
107     uint8_t numEndpoints = interface->altsetting->interfaceDescriptor.bNumEndpoints;
108     HARCH_INFO_PRINT("ifaceClass=%{public}d, numEndpoints=%{public}d", ifaceClass, numEndpoints);
109     switch (ifaceClass) {
110         case USB_DDK_CLASS_WIRELESS_CONTROLLER: //USB_DDK_CLASS_COMM:
111             (*ppUsbNet)->ctrlIface = interfaceIndex;
112             HARCH_INFO_PRINT("ctrlInface:%{public}d", interfaceIndex);
113             (*ppUsbNet)->statusEp = OsalMemAlloc(sizeof(struct UsbEndpoint));
114             if ((*ppUsbNet)->statusEp == NULL) {
115                 HDF_LOGE("%{public}s:%{public}d allocate endpoint failed", __func__, __LINE__);
116                 break;
117             }
118             /* get the first endpoint by default */
119             (*ppUsbNet)->statusEp->addr = interface->altsetting->endPoint[0].endpointDescriptor.bEndpointAddress;
120             (*ppUsbNet)->statusEp->interval = interface->altsetting->endPoint[0].endpointDescriptor.bInterval;
121             (*ppUsbNet)->statusEp->maxPacketSize = interface->altsetting->endPoint[0].endpointDescriptor.wMaxPacketSize;
122 
123             HARCH_INFO_PRINT("usbNet->statusEp=[addr:%{public}#x, interval:%{public}d, maxPacketSize:%{public}hu]",
124                 (*ppUsbNet)->statusEp->addr, (*ppUsbNet)->statusEp->interval, (*ppUsbNet)->statusEp->maxPacketSize);
125             break;
126         case USB_DDK_CLASS_CDC_DATA:
127             (*ppUsbNet)->dataIface = interfaceIndex;
128             HARCH_INFO_PRINT("dataIface:%{public}d", interfaceIndex);
129             for (uint8_t j = 0; j < numEndpoints; j++) {
130                 const struct UsbRawEndpointDescriptor *endPoint = &interface->altsetting->endPoint[j];
131                 if (UsbGetBulkEndpoint(ppUsbNet, endPoint) != HDF_SUCCESS) {
132                     HARCH_INFO_PRINT("");
133                     break;
134                 }
135                 HARCH_INFO_PRINT("");
136             }
137             break;
138         default:
139             HARCH_INFO_PRINT("wrong descriptor type");
140             break;
141     }
142 }
143 
UsbParseConfigDescriptor(struct UsbnetHost **ppUsbNet)144 static int32_t UsbParseConfigDescriptor(struct UsbnetHost **ppUsbNet)
145 {
146     const struct UsbRawInterface *interface = (*ppUsbNet)->config->interface[0];
147     //set 0 interface and 1 interface data endpoint and ctrl endpoint
148     int32_t ret = UsbRawClaimInterface((*ppUsbNet)->devHandle, 0);
149     if (ret != HDF_SUCCESS) {
150         HDF_LOGE("%{public}s:%{public}d claim interface failed", __func__, __LINE__);
151         return HDF_FAILURE;
152     }
153     HARCH_INFO_PRINT("");
154     UsbParseConfigDescriptorProcess(ppUsbNet, interface, 0);
155 
156     const struct UsbRawInterface *interface1 = (*ppUsbNet)->config->interface[1];
157     ret = UsbRawClaimInterface((*ppUsbNet)->devHandle, 1);
158     if (ret != HDF_SUCCESS) {
159         HDF_LOGE("%{public}s:%{public}d claim interface failed", __func__, __LINE__);
160         return HDF_FAILURE;
161     }
162     HARCH_INFO_PRINT("");
163     UsbParseConfigDescriptorProcess(ppUsbNet, interface1, 1);
164     return HDF_SUCCESS;
165 }
166 
167 /*
168  * RNDIS indicate messages.
169  */
HostRndisMsgIndicate(struct UsbnetHost *usbNet, struct RndisIndicate *msg, int buflen)170 static void HostRndisMsgIndicate(struct UsbnetHost *usbNet, struct RndisIndicate *msg, int buflen)
171 {
172     HARCH_INFO_PRINT("begin");
173     uint32_t status = CPU_TO_LE32(msg->status);
174     switch (status) {
175         case RNDIS_STATUS_MEDIA_CONNECT:
176             HARCH_INFO_PRINT("rndis media connect");
177             break;
178         case RNDIS_STATUS_MEDIA_DISCONNECT:
179             HARCH_INFO_PRINT("rndis media disconnect");
180             break;
181         default:
182             HARCH_INFO_PRINT("rndis indication: 0x%{public}08x\n", status);
183             /* fall-through */
184     }
185 }
186 
UsbnetHostHandleNonRsp(struct UsbnetHost *usbNet, struct RndisMsgHdr *buf, int buflen, uint32_t msgType)187 static void UsbnetHostHandleNonRsp(struct UsbnetHost *usbNet,
188     struct RndisMsgHdr *buf, int buflen, uint32_t msgType)
189 {
190     switch (msgType) {
191         /* fault/event */
192         case RNDIS_MSG_INDICATE:
193             HostRndisMsgIndicate(usbNet, (void *)buf, buflen);
194             break;
195         case RNDIS_MSG_KEEPALIVE: {
196                 /* ping */
197                 struct RndisKeepaliveC *msg = (void *)buf;
198                 msg->msgType = CPU_TO_LE32(RNDIS_MSG_KEEPALIVE_C);
199                 msg->msgLen = CPU_TO_LE32(sizeof(struct RndisKeepaliveC));
200                 msg->status = CPU_TO_LE32(RNDIS_STATUS_SUCCESS);
201 
202                 struct UsbnetHostCmdParam cmdParam = {};
203                 cmdParam.cmd = USB_DDK_CDC_SEND_ENCAPSULATED_COMMAND;
204                 cmdParam.reqtype = USB_DDK_DIR_OUT|USB_DDK_TYPE_CLASS|USB_DDK_RECIP_INTERFACE;
205                 cmdParam.value = 0;
206                 cmdParam.index = usbNet->curInterfaceNumber;
207                 cmdParam.data = msg;
208                 cmdParam.size = sizeof(struct RndisKeepaliveC);
209                 int32_t retval = UsbnetHostWriteCmdSync(usbNet, cmdParam);
210                 HARCH_INFO_PRINT("retval = %{public}d", retval);
211                 if (retval < 0) {
212                     HARCH_INFO_PRINT("rndis keepalive err %{public}d\n", retval);
213                 }
214             }
215             break;
216         default:
217             HARCH_INFO_PRINT("unexpected rndis msg %{public}08x len %{public}d\n",
218                 CPU_TO_LE32(buf->msgType), CPU_TO_LE32(buf->msgLen));
219             break;
220     }
221 }
222 
UsbnetHostHandleMsg(struct UsbnetHost *usbNet, struct RndisMsgHdr *buf, int buflen, uint32_t xid)223 static int32_t UsbnetHostHandleMsg(struct UsbnetHost *usbNet, struct RndisMsgHdr *buf, int buflen, uint32_t xid)
224 {
225     uint32_t msgType = CPU_TO_LE32(buf->msgType);
226     uint32_t msgLen = CPU_TO_LE32(buf->msgLen);
227     uint32_t status = CPU_TO_LE32(buf->status);
228     uint32_t requestId =  (uint32_t)buf->requestId;
229     uint32_t rsp = CPU_TO_LE32(buf->msgType) | RNDIS_MSG_COMPLETION;
230     HARCH_INFO_PRINT("rndis reply msgType = %{public}x, msgLen = %{public}x,"
231         "status = %{public}x, requestId = %{public}x",
232         msgType, msgLen, status, requestId);
233 
234     if (msgType == rsp) {
235         if (requestId == xid) {
236             HARCH_INFO_PRINT("rndis reply status %{public}08x\n", status);
237             HARCH_INFO_PRINT("rndis reply rsp %{public}08x\n", rsp);
238             if (rsp == RNDIS_MSG_RESET_C) {
239                 return HDF_SUCCESS;
240             }
241 
242             if (RNDIS_STATUS_SUCCESS == status) {
243                 return HDF_SUCCESS;
244             }
245 
246             HARCH_INFO_PRINT("rndis reply status %{public}08x\n", status);
247             return -EL3RST;
248         }
249         /* then likely retry */
250     } else {
251         HARCH_INFO_PRINT("unexpected rndis msg %{public}08x len %{public}d\n", CPU_TO_LE32(buf->msgType), msgLen);
252         UsbnetHostHandleNonRsp(usbNet, buf, buflen, msgType);
253     }
254     return HDF_SUCCESS;
255 }
256 
257 /*
258  * RPC done RNDIS-style.  Caller guarantees:
259  * - message is properly byteswapped
260  * - there's no other request pending
261  * - buf can hold up to 1KB response (required by RNDIS spec)
262  * On return, the first few entries are already byteswapped.
263  *
264  * Call context is likely probe(), before interface name is known,
265  * which is why we won't try to use it in the diagnostics.
266  */
HostRndisCommand(struct UsbnetHost *usbNet, struct RndisMsgHdr *buf, int buflen)267 static int32_t HostRndisCommand(struct UsbnetHost *usbNet, struct RndisMsgHdr *buf, int buflen)
268 {
269     HARCH_INFO_PRINT("begin");
270     uint32_t msgType = CPU_TO_LE32(buf->msgType);
271     uint32_t xid = 0;
272 
273     /* Issue the request; xid is unique, don't bother byteswapping it */
274     if (msgType != RNDIS_MSG_HALT && msgType != RNDIS_MSG_RESET) {
275         xid = usbNet->xid++;
276         if (!xid) {
277             xid = usbNet->xid++;
278         }
279         buf->requestId = (__le32) xid;
280     }
281     HARCH_INFO_PRINT("msgType= %{public}d, xid = %{public}d", msgType, xid);
282     struct UsbnetHostCmdParam cmdParam = {};
283     cmdParam.cmd = USB_DDK_CDC_SEND_ENCAPSULATED_COMMAND;
284     cmdParam.reqtype = USB_DDK_DIR_OUT|USB_DDK_TYPE_CLASS|USB_DDK_RECIP_INTERFACE;
285     cmdParam.value = 0;
286     cmdParam.index = usbNet->curInterfaceNumber;
287     cmdParam.data = buf;
288     cmdParam.size = CPU_TO_LE32(buf->msgLen);
289 
290     int retval = UsbnetHostWriteCmdSync(usbNet, cmdParam);
291     HARCH_INFO_PRINT("retval = %{public}d", retval);
292     if (retval < 0 || xid == 0) {
293         return retval;
294     }
295     UsbnetWriteLog((char *)buf, CPU_TO_LE32(buf->msgLen), 0);
296     HARCH_INFO_PRINT("rndis xid %{public}d\n", xid);
297     uint32_t count = 0;
298     /* Poll the control channel; the request probably completed immediately */
299     for (count = 0; count < COMMAND_COUNT_MAX; count++) {
300         HARCH_INFO_PRINT("count = %{public}d, buflen = %{public}d", count, buflen);
301         memset_s(buf, CONTROL_BUFFER_SIZE, 0, CONTROL_BUFFER_SIZE);
302         cmdParam.cmd = USB_DDK_CDC_GET_ENCAPSULATED_RESPONSE;
303         cmdParam.reqtype = USB_DDK_DIR_IN|USB_DDK_TYPE_CLASS|USB_DDK_RECIP_INTERFACE;
304         cmdParam.value = 0;
305         cmdParam.index = usbNet->curInterfaceNumber;
306         cmdParam.data = buf;
307         cmdParam.size = buflen;
308         retval= UsbnetHostWriteCmdSync(usbNet, cmdParam);
309         HARCH_INFO_PRINT("retval = %{public}d", retval);
310         UsbnetWriteLog((char *)buf, buflen, 0);
311 
312         if (retval > URB_LEGAL_ACTUAL_LENGTH) {
313             return UsbnetHostHandleMsg(usbNet, buf, buflen, xid);
314         } else {
315             /* device probably issued a protocol stall; ignore */
316             HARCH_INFO_PRINT("rndis response error = %{public}d", retval);
317         }
318         OsalMSleep(RNDIS_COMMAND_SLEEPTIME);
319     }
320     HARCH_INFO_PRINT("rndis response timeout");
321     return HDF_ERR_TIMEOUT;
322 }
323 
324 /* Performs a query for @oid along with 0 or more bytes of payload as
325  * specified by @in_len. If @replyLen is not set to -1 then the reply
326  * length is checked against this value, resulting in an error if it
327  * doesn't match.
328  *
329  * NOTE: Adding a payload exactly or greater than the size of the expected
330  * response payload is an evident requirement MSFT added for ActiveSync.
331  *
332  * The only exception is for OIDs that return a variably sized response,
333  * in which case no payload should be added.  This undocumented (and
334  * nonsensical!) issue was found by sniffing protocol requests from the
335  * ActiveSync 4.1 Windows driver.
336  */
HostRndisQuery(struct UsbnetHost *usbNet, struct RndisQueryParam queryParam, void **reply, int *replyLen)337 static int32_t HostRndisQuery(struct UsbnetHost *usbNet, struct RndisQueryParam queryParam, void **reply, int *replyLen)
338 {
339     HARCH_INFO_PRINT("begin");
340     int retval;
341     union {
342         void *buf;
343         struct RndisMsgHdr *header;
344         struct RndisQuery *get;
345         struct RndisQueryC *getC;
346     } uq;
347 
348     uq.buf = queryParam.buf;
349     memset_s(uq.get, sizeof(struct RndisQuery) + queryParam.in_len, 0, sizeof(struct RndisQuery) + queryParam.in_len);
350     uq.get->msgType = CPU_TO_LE32(RNDIS_MSG_QUERY);
351     uq.get->msgLen  = CPU_TO_LE32(sizeof(struct RndisQuery) + queryParam.in_len);
352     uq.get->oid = CPU_TO_LE32(queryParam.oid);
353     uq.get->len = CPU_TO_LE32(queryParam.in_len);
354     uq.get->offset = CPU_TO_LE32(UNION_GETOFFSET_NUMBER);
355 
356     retval = HostRndisCommand(usbNet, uq.header, CONTROL_BUFFER_SIZE);
357     HARCH_INFO_PRINT("retval = %{public}d", retval);
358     HARCH_INFO_PRINT("RNDIS_MSG_QUERY(0x%{public}08x) %{public}d\n", queryParam.oid, retval);
359     if (retval < 0) {
360         HDF_LOGE("RNDIS_MSG_QUERY(0x%{public}08x) failed, %{public}d", queryParam.oid, retval);
361         return retval;
362     }
363 
364     uint32_t off = CPU_TO_LE32(uq.getC->offset);
365     uint32_t len = CPU_TO_LE32(uq.getC->len);
366 
367     HARCH_INFO_PRINT("off = %{public}d, len = %{public}d, retval = %{public}d", off, len, retval);
368     // CONTROL_BUFFER_SIZE_-UNION_OFFSET_LENGTH is valid memory range
369     if ((off > CONTROL_BUFFER_SIZE - UNION_OFFSET_LENGTH) || (len > CONTROL_BUFFER_SIZE - UNION_OFFSET_LENGTH - off)) {
370         goto response_error;
371     }
372 
373     if (*replyLen != -1 && len != *replyLen) {
374         goto response_error;
375     }
376 
377     *reply = (unsigned char *) &uq.getC->requestId + off;
378     *replyLen = len;
379 
380     HARCH_INFO_PRINT("*replyLen = %{public}d, retval = %{public}d", len, retval);
381     return retval;
382 
383 response_error:
384     HDF_LOGE("RNDIS_MSG_QUERY(0x%{public}08x) invalid response - off %{public}d len %{public}d",
385         queryParam.oid, off, len);
386 
387     return -EDOM;
388 }
389 
HostRndisInitUsbnet(struct UsbnetHost **ppUsbNet, int32_t *retval)390 static void HostRndisInitUsbnet(struct UsbnetHost **ppUsbNet, int32_t *retval)
391 {
392     /* max transfer (in spec) is 0x4000 at full speed, but for
393      * TX we'll stick to one Ethernet packet plus RNDIS framing.
394      * For RX we handle drivers that zero-pad to end-of-packet.
395      * Don't let userspace change these settings.
396      *
397      * NOTE: there still seems to be wierdness here, as if we need
398      * to do some more things to make sure WinCE targets accept this.
399      * They default to jumbograms of 8KB or 16KB, which is absurd
400      * for such low data rates and which is also more than Linux
401      * can usually expect to allocate for SKB data...
402      */
403     (*ppUsbNet)->net.hardHeaderLen += sizeof(struct RndisDataHdr);
404     (*ppUsbNet)->net.hardMtu = (*ppUsbNet)->net.mtu + (*ppUsbNet)->net.hardHeaderLen;
405     HARCH_INFO_PRINT("hardHeaderLen = %{public}d, hardMtu = %{public}d\n",
406         (*ppUsbNet)->net.hardHeaderLen, (*ppUsbNet)->net.hardMtu);
407     (*ppUsbNet)->net.maxpacket = (*ppUsbNet)->dataOutEp->maxPacketSize;
408 
409     HARCH_INFO_PRINT("maxpacket = %{public}d\n", (*ppUsbNet)->net.maxpacket);
410     if ((*ppUsbNet)->net.maxpacket == 0) {
411         HDF_LOGE("usbNet->maxpacket can't be 0");
412         *retval = HDF_ERR_INVALID_PARAM;
413         return;
414     }
415 
416     (*ppUsbNet)->net.rxUrbSize = (*ppUsbNet)->net.hardMtu + ((*ppUsbNet)->net.maxpacket + 1);
417     (*ppUsbNet)->net.rxUrbSize &= ~((*ppUsbNet)->net.maxpacket - 1);
418     HARCH_INFO_PRINT("rxUrbSize = %{public}d\n", (*ppUsbNet)->net.rxUrbSize);
419 }
420 
HostRndisUpdateMtu(struct UsbnetHost **ppUsbNet, int32_t *retval)421 static void HostRndisUpdateMtu(struct UsbnetHost **ppUsbNet, int32_t *retval)
422 {
423     uint32_t tmp = CPU_TO_LE32(g_u.initC->maxTransferSize);
424     if (tmp < (*ppUsbNet)->net.hardMtu) {
425         if (tmp <= (*ppUsbNet)->net.hardHeaderLen) {
426             HARCH_INFO_PRINT("RNDIS init failed, %{public}d", *retval);
427             HDF_LOGE("usbNet can't take %{public}u byte packets (max %{public}u)", (*ppUsbNet)->net.hardMtu, tmp);
428             *retval = HDF_ERR_INVALID_PARAM;
429         }
430         HARCH_INFO_PRINT("usbNet can't take %{public}u byte packets (max %{public}u) adjusting MTU to %{public}u\n",
431             (*ppUsbNet)->net.hardMtu, tmp, tmp - (*ppUsbNet)->net.hardHeaderLen);
432         HDF_LOGW("usbNet can't take %{public}u byte packets (max %{public}u) adjusting MTU to %{public}u",
433             (*ppUsbNet)->net.hardMtu, tmp, tmp - (*ppUsbNet)->net.hardHeaderLen);
434         (*ppUsbNet)->net.hardMtu = tmp;
435         (*ppUsbNet)->net.mtu = (*ppUsbNet)->net.hardMtu - (*ppUsbNet)->net.hardHeaderLen;
436     }
437     HARCH_INFO_PRINT("hard mtu %{public}u (%{public}u from usbNet), rx buflen %{public}u, align %{public}d\n",
438         (*ppUsbNet)->net.hardMtu, tmp, (*ppUsbNet)->net.rxUrbSize, 1 << CPU_TO_LE32(g_u.initC->packetAlignment));
439 }
440 
HostRndisSetmacAddrByBp(struct UsbnetHost **ppUsbNet, int32_t *retval)441 static void HostRndisSetmacAddrByBp(struct UsbnetHost **ppUsbNet, int32_t *retval)
442 {
443     int replyLen = MAC_ADDR_SIZE;
444     unsigned char *bp;
445     struct RndisQueryParam queryParam = {g_u.buf, RNDIS_OID_802_3_PERMANENT_ADDRESS, RNDIS_QUERY_INPUT_LENGTH};
446     *retval = HostRndisQuery(*ppUsbNet, queryParam, (void **)&bp, &replyLen);
447     if (*retval < 0) {
448         HDF_LOGE("rndis get ethaddr, %{public}d", *retval);
449         *retval = HDF_ERR_NOPERM;
450     }
451 
452     HARCH_INFO_PRINT("bp 1= %{public}x", bp[ZERO_INDEX]);
453     HARCH_INFO_PRINT("bp 2= %{public}x", bp[ONE_INDEX]);
454     HARCH_INFO_PRINT("bp 3= %{public}x", bp[TWO_INDEX]);
455     HARCH_INFO_PRINT("bp 4= %{public}x", bp[THREE_INDEX]);
456     HARCH_INFO_PRINT("bp 5= %{public}x", bp[FOUR_INDEX]);
457     HARCH_INFO_PRINT("bp 6= %{public}x", bp[FIVE_INDEX]);
458 
459     if (bp[0] & 0x02) {
460         HARCH_INFO_PRINT("not GetmacAddr");
461         (*ppUsbNet)->net.isGetmacAddr = 0;
462         size_t macAddrLen = sizeof((*ppUsbNet)->net.macAddr) / sizeof((*ppUsbNet)->net.macAddr[0]);
463         if (memset_s((*ppUsbNet)->net.macAddr, macAddrLen, 0, macAddrLen) !=EOK) {
464             HARCH_INFO_PRINT("HostRndisSetmacAddrByBp memset_s fail!");
465             return;
466         }
467     } else {
468         HARCH_INFO_PRINT("GetmacAddr");
469         (*ppUsbNet)->net.isGetmacAddr = 1;
470         etherAddrCopy((*ppUsbNet)->net.macAddr, bp);
471     }
472 }
473 
HostRndisSetmacAddr(struct UsbnetHost **ppUsbNet, int32_t *retval)474 static void HostRndisSetmacAddr(struct UsbnetHost **ppUsbNet, int32_t *retval)
475 {
476     __le32 *phym = NULL;
477     __le32 phym_unspec;
478     int replyLen = sizeof(__le32);
479     /* Check physical medium */
480     struct RndisQueryParam queryParam = {g_u.buf, RNDIS_OID_GEN_PHYSICAL_MEDIUM, replyLen};
481     *retval = HostRndisQuery(*ppUsbNet, queryParam, (void **)&phym, &replyLen);
482     if ((retval != NULL && *retval != 0) || !phym) {
483         /* OID is optional so don't fail here. */
484         phym_unspec = CPU_TO_LE32(RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED);
485         phym = &phym_unspec;
486     }
487 
488     if (((*ppUsbNet)->flags & FLAG_RNDIS_PHYM_WIRELESS) &&
489         CPU_TO_LE32(*phym) != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
490         HDF_LOGE("driver requires wireless physical medium, but device is not");
491         *retval = HDF_ERR_NOPERM;
492     }
493 
494     if (((*ppUsbNet)->flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) &&
495         CPU_TO_LE32(*phym) == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
496         HDF_LOGE("driver requires non-wireless physical medium, but device is wireless");
497         *retval = HDF_ERR_NOPERM;
498     }
499 
500     /* Get designated host ethernet address */
501     HostRndisSetmacAddrByBp(ppUsbNet, retval);
502 }
503 
HostRndisInitUnion(struct UsbnetHost *usbNet, int32_t *retval)504 static int32_t HostRndisInitUnion(struct UsbnetHost *usbNet, int32_t *retval)
505 {
506     int32_t ret = HDF_SUCCESS;
507     g_u.buf = OsalMemAlloc(CONTROL_BUFFER_SIZE);
508     if (!g_u.buf) {
509         HDF_LOGE("g_u.buf can't be 0");
510         ret = HDF_ERR_MALLOC_FAIL;
511     }
512 
513     g_u.init->msgType = CPU_TO_LE32(RNDIS_MSG_INIT);
514     g_u.init->msgLen  = CPU_TO_LE32(sizeof(struct RndisInit));
515     g_u.init->majorVersion = CPU_TO_LE32(1);
516     g_u.init->minorVersion = CPU_TO_LE32(0);
517 
518     g_u.init->maxTransferSize = CPU_TO_LE32((usbNet)->net.rxUrbSize);
519     *retval = HostRndisCommand(usbNet, g_u.header, CONTROL_BUFFER_SIZE);
520     if (*retval < 0) {
521         /* it might not even be an RNDIS device!! */
522         HARCH_INFO_PRINT("RNDIS init failed, %{public}d", *retval);
523         HDF_LOGE("RNDIS init failed, %{public}d", *retval);
524         ret = HDF_DEV_ERR_OP;
525     }
526     return ret;
527 }
528 
HostRndisEnableDataTransfers(struct UsbnetHost *usbNet)529 static int32_t HostRndisEnableDataTransfers(struct UsbnetHost *usbNet)
530 {
531     int32_t ret = HDF_SUCCESS;
532     /* set a nonzero filter to enable data transfers */
533     memset_s(g_u.set, sizeof(struct RndisSet), 0, sizeof(struct RndisSet));
534     g_u.set->msgType = CPU_TO_LE32(RNDIS_MSG_SET);
535     g_u.set->msgLen = CPU_TO_LE32(MSG_HEAD_LENGTH + sizeof(struct RndisSet));
536     g_u.set->oid = CPU_TO_LE32(RNDIS_OID_GEN_CURRENT_PACKET_FILTER);
537     g_u.set->len = CPU_TO_LE32(MSG_HEAD_LENGTH);
538     g_u.set->offset = CPU_TO_LE32(sizeof(struct RndisSet) - UNION_OFFSET_LENGTH);
539     *(__le32 *)(g_u.buf + sizeof(struct RndisSet)) = CPU_TO_LE32(RNDIS_DEFAULT_FILTER);
540     int32_t retval = HostRndisCommand(usbNet, g_u.header, CONTROL_BUFFER_SIZE);
541     if (retval < 0) {
542         HDF_LOGE("rndis set packet filter, %{public}d", retval);
543         ret = HDF_FAILURE;
544     }
545     OsalMemFree(g_u.buf);
546     g_u.buf = NULL;
547     return ret;
548 }
549 
550 /* function
551     1.get usb endpoints info
552     2.init usb device
553     3.get usb device adrress and status
554     4.set usb device work
555 */
HostRndisBind(struct UsbnetHost *usbNet)556 static int32_t HostRndisBind(struct UsbnetHost *usbNet)
557 {
558     int32_t retval = 0;
559     int32_t ret = UsbParseConfigDescriptor(&usbNet);
560     if (ret != HDF_SUCCESS) {
561         HDF_LOGE("%{public}s:%{public}d UsbParseConfigDescriptor failed", __func__, __LINE__);
562         UsbRawFreeConfigDescriptor(usbNet->config);
563         usbNet->config = NULL;
564         return ret;
565     }
566 
567     HostRndisInitUsbnet(&usbNet, &retval);
568     if (retval == HDF_ERR_INVALID_PARAM) {
569         HDF_LOGE("%{public}s:%{public}d HostRndisInitUsbnet failed", __func__, __LINE__);
570         return retval;
571     }
572 
573     ret = HostRndisInitUnion(usbNet, &retval);
574     if (ret == HDF_ERR_MALLOC_FAIL) {
575         HDF_LOGE("%{public}s:%{public}d HostRndisInitUnion failed", __func__, __LINE__);
576         return ret;
577     } else if (ret == HDF_DEV_ERR_OP) {
578         HDF_LOGE("%{public}s:%{public}d HostRndisInitUnion failed", __func__, __LINE__);
579         OsalMemFree(g_u.buf);
580         g_u.buf = NULL;
581         return ret;
582     }
583 
584     HostRndisUpdateMtu(&usbNet, &retval);
585     if (retval == HDF_ERR_INVALID_PARAM) {
586         HDF_LOGE("%{public}s:%{public}d HostRndisUpdateMtu failed", __func__, __LINE__);
587         goto ERR_HALT_FAILED_AND_RELEASE;
588         return retval;
589     }
590 
591     HostRndisSetmacAddr(&usbNet, &retval);
592     if (retval == HDF_ERR_NOPERM) {
593         HDF_LOGE("%{public}s:%{public}d HostRndisSetmacAddr failed", __func__, __LINE__);
594         goto ERR_HALT_FAILED_AND_RELEASE;
595         return retval;
596     }
597 
598     ret = HostRndisEnableDataTransfers(usbNet);
599     if (ret != HDF_SUCCESS) {
600         HDF_LOGE("%{public}s:%{public}d HostRndisEnableDataTransfers failed", __func__, __LINE__);
601         goto ERR_HALT_FAILED_AND_RELEASE;
602     }
603     return ret;
604 ERR_HALT_FAILED_AND_RELEASE:
605     memset_s(g_u.halt, sizeof(struct RndisHalt), 0, sizeof(struct RndisHalt));
606     g_u.halt->msgType = CPU_TO_LE32(RNDIS_MSG_HALT);
607     g_u.halt->msgLen = CPU_TO_LE32(sizeof(struct RndisHalt));
608     (void)HostRndisCommand(usbNet, (void *)g_u.halt, CONTROL_BUFFER_SIZE);
609     return HDF_FAILURE;
610 }
611 
HostRndisUnbind(struct UsbnetHost *usbNet)612 static void HostRndisUnbind(struct UsbnetHost *usbNet)
613 {
614     HARCH_INFO_PRINT();
615     struct RndisHalt *halt = OsalMemAlloc(sizeof(struct RndisHalt));
616 
617     memset_s(halt, sizeof(struct RndisHalt), 0, sizeof(struct RndisHalt));
618     halt->msgType = CPU_TO_LE32(RNDIS_MSG_HALT);
619     halt->msgLen  = CPU_TO_LE32(sizeof(struct RndisHalt));
620     (void) HostRndisCommand(usbNet, (void *)halt, CONTROL_BUFFER_SIZE);
621     OsalMemFree(halt);
622 }
623 
624 static struct UsbnetHostDriverInfo g_hostRndisInfo = {
625     .description    =    "rndis device",
626     .bind           =    HostRndisBind,
627     .unbind         =    HostRndisUnbind,
628 };
629 
HostRndisDriverDeviceDispatch( struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)630 static int32_t HostRndisDriverDeviceDispatch(
631     struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
632 {
633     return HDF_SUCCESS;
634 }
635 
636 /* HdfDriverEntry implementations */
HostRndisDriverBind(struct HdfDeviceObject *device)637 static int32_t HostRndisDriverBind(struct HdfDeviceObject *device)
638 {
639     HARCH_INFO_PRINT("[-cbs-] HostRndisDriverBind begin !");
640     if (device == NULL) {
641         HDF_LOGE("%{public}s: device is null", __func__);
642         return HDF_ERR_INVALID_OBJECT;
643     }
644 
645     struct UsbnetHost *usbNet = (struct UsbnetHost *)OsalMemCalloc(sizeof(*usbNet));
646     if (usbNet == NULL) {
647         HDF_LOGE("%{public}s: Alloc  UsbnetHost memory failed", __func__);
648         return HDF_FAILURE;
649     }
650 
651     struct UsbPnpNotifyServiceInfo *info = NULL;
652     info = (struct UsbPnpNotifyServiceInfo *)device->priv;
653     if (info != NULL) {
654         HARCH_INFO_PRINT("[-cbs-]bus:%{public}d+dev:%{public}d", info->busNum, info->devNum);
655         HARCH_INFO_PRINT("[-cbs-]interfaceLength:%{public}d", info->interfaceLength);
656         HARCH_INFO_PRINT("[-cbs-]curInterfaceNum:%{public}d", info->curInterfaceNumber);
657 
658         usbNet->busNum = info->busNum;
659         usbNet->devAddr = info->devNum;
660         usbNet->curInterfaceNumber = info->curInterfaceNumber;
661     } else {
662         HDF_LOGE("%{public}s:%{public}d info is NULL!", __func__, __LINE__);
663         goto ERROR;
664     }
665 
666     HDF_LOGE("%{public}s:%{public}d", __func__, __LINE__);
667     device->service = &(usbNet->service);
668     if (device->service == NULL) {
669         HDF_LOGE("%{public}s:%{public}d", __func__, __LINE__);
670     }
671 
672     device->service->Dispatch = HostRndisDriverDeviceDispatch;
673     usbNet->deviceObject = device;
674 
675     /* here need to choose device driver */
676     struct  UsbnetHostDriverInfo *driver = &g_hostRndisInfo;
677     //function
678     usbNet->driverInfo = driver;
679 
680     HARCH_INFO_PRINT("bind ok");
681     return HDF_SUCCESS;
682 ERROR:
683     OsalMemFree(usbNet);
684     return HDF_SUCCESS;
685 }
686 
HostRndisDriverInit(struct HdfDeviceObject *device)687 static int32_t HostRndisDriverInit(struct HdfDeviceObject *device)
688 {
689     HARCH_INFO_PRINT("[-cbs-] HostRndisDriverInit begin !");
690     if (device == NULL) {
691         HDF_LOGE("%{public}s: device is null", __func__);
692         return HDF_ERR_INVALID_OBJECT;
693     }
694     int32_t ret = HDF_SUCCESS;
695 
696     struct UsbnetHost *usbNet = (struct UsbnetHost *)device->service;
697     //net init
698     ret = UsbnetHostProbe(usbNet);
699     if (ret != HDF_SUCCESS) {
700         HARCH_INFO_PRINT("[-cbs-] UsbnetHostProbe error !");
701     }
702     //usb init
703     return ret;
704 }
705 
HostRndisDriverRelease(struct HdfDeviceObject *device)706 static void HostRndisDriverRelease(struct HdfDeviceObject *device)
707 {
708     HARCH_INFO_PRINT();
709     struct UsbPnpNotifyServiceInfo *info = NULL;
710     info = (struct UsbPnpNotifyServiceInfo *)device->priv;
711     if (info != NULL) {
712         HARCH_INFO_PRINT("bus:%{public}d+dev:%{public}d", info->busNum, info->devNum);
713         HARCH_INFO_PRINT("interfaceLength:%{public}d", info->interfaceLength);
714     }
715     struct UsbnetHost *usbNet = (struct UsbnetHost *)device->service;
716     if (usbNet == NULL) {
717         HDF_LOGE("%{public}s: Alloc  UsbnetHost memory failed", __func__);
718         return;
719     }
720 
721     UsbnetHostRelease(usbNet);
722     usbNet->driverInfo->unbind(usbNet);
723 
724     //free momory
725     OsalMemFree(usbNet);
726     return;
727 }
728 
729 struct HdfDriverEntry g_hostRndisRawDriverEntry = {
730     .moduleVersion = 1,
731     .moduleName = "usbhost_rndis_rawapi",
732     .Bind = HostRndisDriverBind,
733     .Init = HostRndisDriverInit,
734     .Release = HostRndisDriverRelease,
735 };
736 HDF_INIT(g_hostRndisRawDriverEntry);
737