1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** USBX Component */
16 /** */
17 /** Device Pima 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_pima.h"
29 #include "ux_device_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_device_class_pima_object_references_get PORTABLE C */
37 /* 6.3.0 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* Return object references associated with an object handle. */
45 /* The pima class will call the application to get the array of */
46 /* references. */
47 /* */
48 /* INPUT */
49 /* */
50 /* pima Pointer to pima class */
51 /* object_handle Object Handle for which */
52 /* references are obtained. */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* Completion Status */
57 /* */
58 /* CALLS */
59 /* */
60 /* _ux_device_stack_transfer_request Transfer request */
61 /* _ux_utility_long_put Put 32-bit value */
62 /* _ux_utility_short_put Put 32-bit value */
63 /* _ux_utility_memory_copy Copy memory */
64 /* _ux_device_class_pima_response_send Send PIMA response */
65 /* */
66 /* CALLED BY */
67 /* */
68 /* Device Pima Class */
69 /* */
70 /* RELEASE HISTORY */
71 /* */
72 /* DATE NAME DESCRIPTION */
73 /* */
74 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
75 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
76 /* verified memset and memcpy */
77 /* cases, */
78 /* resulting in version 6.1 */
79 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
80 /* updated status handling, */
81 /* passed max length to app, */
82 /* resulting in version 6.1.10 */
83 /* 10-31-2023 Chaoqiong Xiao Modified comment(s), */
84 /* added a new mode to manage */
85 /* endpoint buffer in classes, */
86 /* resulting in version 6.3.0 */
87 /* */
88 /**************************************************************************/
_ux_device_class_pima_object_references_get(UX_SLAVE_CLASS_PIMA * pima,ULONG object_handle)89 UINT _ux_device_class_pima_object_references_get(UX_SLAVE_CLASS_PIMA *pima,
90 ULONG object_handle)
91 {
92
93 UINT status;
94 UX_SLAVE_TRANSFER *transfer_request;
95 UCHAR *pima_data_buffer;
96 UCHAR *pima_data_buffer_end;
97 UCHAR *object_references;
98 ULONG object_references_length;
99
100 /* If trace is enabled, insert this event into the trace buffer. */
101 UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_PIMA_GET_OBJECT_REFERENCES, pima, object_handle, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
102
103 /* Obtain the pointer to the transfer request. */
104 transfer_request = &pima -> ux_device_class_pima_bulk_in_endpoint -> ux_slave_endpoint_transfer_request;
105
106 /* Obtain memory for this object info. Use the transfer request pre-allocated memory. */
107 pima_data_buffer = transfer_request -> ux_slave_transfer_request_data_pointer;
108
109 /* Save end of buffer. */
110 pima_data_buffer_end = pima_data_buffer + UX_DEVICE_CLASS_PIMA_TRANSFER_BUFFER_LENGTH;
111
112 /* Fill in the data container type. */
113 _ux_utility_short_put(pima_data_buffer + UX_DEVICE_CLASS_PIMA_DATA_HEADER_TYPE,
114 UX_DEVICE_CLASS_PIMA_CT_DATA_BLOCK);
115
116 /* Fill in the data code. */
117 _ux_utility_short_put(pima_data_buffer + UX_DEVICE_CLASS_PIMA_DATA_HEADER_CODE,
118 UX_DEVICE_CLASS_PIMA_OC_GET_OBJECT_REFERENCES);
119
120 /* Fill in the Transaction ID. */
121 _ux_utility_long_put(pima_data_buffer + UX_DEVICE_CLASS_PIMA_DATA_HEADER_TRANSACTION_ID,
122 pima -> ux_device_class_pima_transaction_id);
123
124 /* Ask the application to retrieve for us the object references. */
125 object_references_length = UX_DEVICE_CLASS_PIMA_MAX_PAYLOAD;
126 status = pima -> ux_device_class_pima_object_references_get(pima, object_handle, &object_references, &object_references_length);
127
128 /* Result should always be OK, but to be sure .... */
129 if (status != UX_SUCCESS)
130
131 /* We return an error. */
132 _ux_device_class_pima_response_send(pima, status, 0, 0, 0, 0);
133
134 else
135 {
136
137 /* Check if there enough space in our buffer. */
138 if (pima_data_buffer + UX_DEVICE_CLASS_PIMA_DATA_HEADER_SIZE + object_references_length <= pima_data_buffer_end)
139 {
140
141 /* Copy the property dataset into the local buffer. */
142 _ux_utility_memory_copy(pima_data_buffer + UX_DEVICE_CLASS_PIMA_DATA_HEADER_SIZE, object_references, object_references_length); /* Use case of memcpy is verified. */
143
144 /* Add the header size to the payload. */
145 object_references_length += UX_DEVICE_CLASS_PIMA_DATA_HEADER_SIZE;
146
147 /* Fill in the size of the response header. */
148 _ux_utility_long_put(pima_data_buffer + UX_DEVICE_CLASS_PIMA_DATA_HEADER_LENGTH,
149 object_references_length);
150
151 /* Send a data payload with the object references array. */
152 status = _ux_device_stack_transfer_request(transfer_request, object_references_length, 0);
153
154 /* Now we return a response with success. */
155 _ux_device_class_pima_response_send(pima, UX_DEVICE_CLASS_PIMA_RC_OK, 0, 0, 0, 0);
156 }
157 else
158 {
159
160 /* Report the error to the application. */
161 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_MEMORY_INSUFFICIENT);
162
163 /* We return an error code to the host. */
164 _ux_device_class_pima_response_send(pima, UX_DEVICE_CLASS_PIMA_RC_GENERAL_ERROR, 0, 0, 0, 0);
165
166 /* Return error. */
167 status = UX_MEMORY_INSUFFICIENT;
168 }
169 }
170
171 /* Return completion status. */
172 return(status);
173 }
174
175
176