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