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