1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** USBX Component */
16 /** */
17 /** Device RNDIS Class */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define UX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "ux_api.h"
28 #include "ux_device_class_rndis.h"
29 #include "ux_device_stack.h"
30
31
32
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _ux_device_class_rndis_msg_query PORTABLE C */
38 /* 6.1 */
39 /* AUTHOR */
40 /* */
41 /* Chaoqiong Xiao, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function analyzes and replies to the MSG QUERY */
46 /* */
47 /* INPUT */
48 /* */
49 /* rndis Pointer to rndis class */
50 /* transfer_request Pointer to the transfer request */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* None */
55 /* */
56 /* CALLS */
57 /* */
58 /* _ux_utility_long_get Get 32-bit value */
59 /* _ux_utility_long_put Put 32-bit value */
60 /* _ux_utility_string_length_check Check and return C string length */
61 /* _ux_utility_memory_copy Copy memory */
62 /* */
63 /* CALLED BY */
64 /* */
65 /* RNDIS Class */
66 /* */
67 /* RELEASE HISTORY */
68 /* */
69 /* DATE NAME DESCRIPTION */
70 /* */
71 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
72 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
73 /* verified memset and memcpy */
74 /* cases, */
75 /* resulting in version 6.1 */
76 /* */
77 /**************************************************************************/
_ux_device_class_rndis_msg_query(UX_SLAVE_CLASS_RNDIS * rndis,UX_SLAVE_TRANSFER * transfer_request)78 UINT _ux_device_class_rndis_msg_query(UX_SLAVE_CLASS_RNDIS *rndis, UX_SLAVE_TRANSFER *transfer_request)
79 {
80
81 UCHAR *rndis_msg;
82 UCHAR *rndis_response;
83 ULONG rndis_oid;
84 ULONG rndis_response_length;
85 UINT rndis_response_string_length = 0;
86 ULONG oid_index;
87 ULONG status;
88
89 /* Get the pointer to the RNDIS message. */
90 rndis_msg = transfer_request -> ux_slave_transfer_request_data_pointer;
91
92 /* Get the request ID and keep it for the response. */
93 rndis -> ux_slave_class_rndis_request_id = _ux_utility_long_get(rndis_msg + UX_DEVICE_CLASS_RNDIS_MSG_QUERY_REQUEST_ID);
94
95 /* Get the OID. */
96 rndis_oid = _ux_utility_long_get(rndis_msg + UX_DEVICE_CLASS_RNDIS_MSG_QUERY_OID);
97
98 /* If trace is enabled, insert this event into the trace buffer. */
99 UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_RNDIS_MSG_QUERY, rndis, rndis_oid, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
100
101 /* Now prepare the response. */
102 rndis_response = rndis -> ux_slave_class_rndis_response;
103
104 /* First store the command. */
105 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_MESSAGE_TYPE, UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY);
106
107 /* Store the request ID. */
108 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_REQUEST_ID, rndis -> ux_slave_class_rndis_request_id);
109
110 /* By default the function will succeed. */
111 status = UX_DEVICE_CLASS_RNDIS_STATUS_SUCCESS;
112
113 /* What OID are we dealing here ? */
114 switch (rndis_oid)
115 {
116
117 case UX_DEVICE_CLASS_RNDIS_OID_GEN_SUPPORTED_LIST :
118
119 /* Supported List of OIDs. Parse each OID until the end and store it in the response buffer. */
120 oid_index = 0;
121 while (ux_device_class_rndis_oid_supported_list[oid_index] != 0)
122 {
123
124 /* We have found a valid OID to return. */
125 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER + (oid_index * sizeof(ULONG)),
126 ux_device_class_rndis_oid_supported_list[oid_index]);
127
128 /* Next OID index. */
129 oid_index++;
130
131 }
132
133 /* Set the total response length. */
134 rndis_response_length = oid_index * (ULONG)sizeof(ULONG);
135
136 break;
137
138 case UX_DEVICE_CLASS_RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE :
139
140 /* Set the maximum frame size. */
141 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, UX_DEVICE_CLASS_RNDIS_MAX_FRAME_SIZE);
142
143 /* Set the total response length. */
144 rndis_response_length = sizeof(ULONG);
145
146 break;
147
148 case UX_DEVICE_CLASS_RNDIS_OID_GEN_MEDIA_SUPPORTED :
149
150 /* Set the media supported. */
151 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, UX_DEVICE_CLASS_RNDIS_MEDIA_802_3);
152
153 /* Set the total response length. */
154 rndis_response_length = sizeof(ULONG);
155
156 break;
157
158 case UX_DEVICE_CLASS_RNDIS_OID_GEN_MEDIA_IN_USE :
159
160 /* Set the media in use. */
161 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, UX_DEVICE_CLASS_RNDIS_MEDIA_802_3);
162
163 /* Set the total response length. */
164 rndis_response_length = sizeof(ULONG);
165
166 break;
167
168 case UX_DEVICE_CLASS_RNDIS_OID_GEN_HARDWARE_STATUS :
169
170 /* Set the hardware status. */
171 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, UX_DEVICE_CLASS_RNDIS_OID_HW_STATUS_READY);
172
173 /* Set the total response length. */
174 rndis_response_length = sizeof(ULONG);
175
176 break;
177
178 case UX_DEVICE_CLASS_RNDIS_OID_GEN_PHYSICAL_MEDIUM :
179
180 /* Set the physical medium. */
181 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, 0);
182
183 /* Set the total response length. */
184 rndis_response_length = sizeof(ULONG);
185
186 break;
187
188 case UX_DEVICE_CLASS_RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE :
189
190 /* Set the physical medium. */
191 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, UX_DEVICE_CLASS_RNDIS_MAX_PACKET_LENGTH);
192
193 /* Set the total response length. */
194 rndis_response_length = sizeof(ULONG);
195
196 break;
197
198
199 case UX_DEVICE_CLASS_RNDIS_OID_GEN_LINK_SPEED :
200
201 /* Set the link speed. For now we assume a full speed device. */
202 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, UX_DEVICE_CLASS_RNDIS_LINK_SPEED_FS);
203
204 /* Set the total response length. */
205 rndis_response_length = sizeof(ULONG);
206
207 break;
208
209 case UX_DEVICE_CLASS_RNDIS_OID_GEN_MEDIA_CONNECT_STATUS :
210
211 /* Set the media connection status. */
212 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, UX_DEVICE_CLASS_RNDIS_MEDIA_CONNECTED);
213
214 /* Set the total response length. */
215 rndis_response_length = sizeof(ULONG);
216
217 break;
218
219
220 case UX_DEVICE_CLASS_RNDIS_OID_GEN_MAC_OPTIONS :
221
222 /* Set the MAC options. */
223 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, UX_DEVICE_CLASS_RNDIS_MAC_OPTIONS);
224
225 /* Set the total response length. */
226 rndis_response_length = sizeof(ULONG);
227
228 break;
229
230 case UX_DEVICE_CLASS_RNDIS_OID_GEN_VENDOR_ID :
231
232 /* Set the vendor ID. */
233 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, rndis -> ux_slave_class_rndis_parameter.ux_slave_class_rndis_parameter_vendor_id);
234
235 /* Set the total response length. */
236 rndis_response_length = sizeof(ULONG);
237
238 break;
239
240 case UX_DEVICE_CLASS_RNDIS_OID_GEN_DRIVER_VERSION :
241
242 /* Set the driver version. */
243 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, rndis -> ux_slave_class_rndis_parameter.ux_slave_class_rndis_parameter_driver_version);
244
245 /* Set the total response length. */
246 rndis_response_length = sizeof(ULONG);
247
248 break;
249
250
251 case UX_DEVICE_CLASS_RNDIS_OID_GEN_VENDOR_DESCRIPTION :
252
253 /* Get the string length for the vendor description. */
254 status = _ux_utility_string_length_check(rndis -> ux_slave_class_rndis_parameter.ux_slave_class_rndis_parameter_vendor_description, &rndis_response_string_length, UX_DEVICE_CLASS_RNDIS_VENDOR_DESCRIPTION_MAX_LENGTH);
255 if (status)
256 return(status);
257
258 /* Set the total response length. */
259 rndis_response_length = (ULONG) rndis_response_string_length;
260
261 /* Copy the vendor description. */
262 _ux_utility_memory_copy(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, rndis -> ux_slave_class_rndis_parameter.ux_slave_class_rndis_parameter_vendor_description, rndis_response_length); /* Use case of memcpy is verified. */
263
264 break;
265
266 case UX_DEVICE_CLASS_RNDIS_OID_GEN_XMIT_OK :
267
268 /* Set the appropriate statistic value. */
269 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, rndis -> ux_slave_class_rndis_statistics_xmit_ok);
270
271 /* Set the total response length. */
272 rndis_response_length = sizeof(ULONG);
273
274 break;
275
276 case UX_DEVICE_CLASS_RNDIS_OID_GEN_RCV_OK :
277
278 /* Set the appropriate statistic value. */
279 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, rndis -> ux_slave_class_rndis_statistics_rcv_ok);
280
281 /* Set the total response length. */
282 rndis_response_length = sizeof(ULONG);
283
284 break;
285
286 case UX_DEVICE_CLASS_RNDIS_OID_GEN_XMIT_ERROR :
287
288 /* Set the appropriate statistic value. */
289 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, rndis -> ux_slave_class_rndis_statistics_xmit_error);
290
291 /* Set the total response length. */
292 rndis_response_length = sizeof(ULONG);
293
294 break;
295
296 case UX_DEVICE_CLASS_RNDIS_OID_GEN_RCV_ERROR :
297
298 /* Set the appropriate statistic value. */
299 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, rndis -> ux_slave_class_rndis_statistics_rcv_error);
300
301 /* Set the total response length. */
302 rndis_response_length = sizeof(ULONG);
303
304 break;
305
306 case UX_DEVICE_CLASS_RNDIS_OID_GEN_RCV_NO_BUFFER :
307
308 /* Set the appropriate statistic value. */
309 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, rndis -> ux_slave_class_rndis_statistics_rcv_no_buffer);
310
311 /* Set the total response length. */
312 rndis_response_length = sizeof(ULONG);
313
314 break;
315
316 case UX_DEVICE_CLASS_RNDIS_OID_802_3_CURRENT_ADDRESS :
317
318
319 /* Save the Hardware address in the return message. */
320 _ux_utility_memory_copy(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER,
321 rndis -> ux_slave_class_rndis_remote_node_id, UX_DEVICE_CLASS_RNDIS_NODE_ID_LENGTH); /* Use case of memcpy is verified. */
322
323 /* Set the total response length. */
324 rndis_response_length = UX_DEVICE_CLASS_RNDIS_NODE_ID_LENGTH;
325
326 break;
327
328
329 default :
330
331 /* Just return zero ULONG field. */
332 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER, 0);
333
334 /* Set the total response length. */
335 rndis_response_length = sizeof(ULONG);
336
337 break;
338
339 }
340
341 /* Set the status field. */
342 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_STATUS, status);
343
344 /* Set the buffer offset value. */
345 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER_OFFSET,
346 (UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER - UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_REQUEST_ID));
347
348 /* Store the length of the buffer. */
349 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER_LENGTH, rndis_response_length);
350
351 /* Update the response length to add the header. */
352 rndis_response_length += UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER;
353
354 /* Set the response length. */
355 rndis -> ux_slave_class_rndis_response_length = rndis_response_length;
356 _ux_utility_long_put(rndis_response + UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_MESSAGE_LENGTH, rndis_response_length);
357
358 /* We are done. Return UX_SUCCESS. */
359 return(status);
360 }
361
362