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_props_supported_get PORTABLE C */
37 /* 6.1.10 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* Return an Object Property Code array of supported object properties */
45 /* in the first parameter. */
46 /* */
47 /* INPUT */
48 /* */
49 /* pima Pointer to pima class */
50 /* object_format_code Object format for which the */
51 /* properties supported are. */
52 /* */
53 /* OUTPUT */
54 /* */
55 /* Completion Status */
56 /* */
57 /* CALLS */
58 /* */
59 /* _ux_device_stack_transfer_request Transfer request */
60 /* _ux_utility_long_put Put 32-bit value */
61 /* _ux_utility_short_put Put 32-bit value */
62 /* _ux_utility_memory_copy Copy memory */
63 /* _ux_device_class_pima_response_send Send PIMA response */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* Device Pima Class */
68 /* */
69 /* RELEASE HISTORY */
70 /* */
71 /* DATE NAME DESCRIPTION */
72 /* */
73 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
74 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
75 /* resulting in version 6.1 */
76 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
77 /* improved sanity checks, */
78 /* resulting in version 6.1.10 */
79 /* */
80 /**************************************************************************/
_ux_device_class_pima_object_props_supported_get(UX_SLAVE_CLASS_PIMA * pima,ULONG object_format_code)81 UINT _ux_device_class_pima_object_props_supported_get(UX_SLAVE_CLASS_PIMA *pima,
82 ULONG object_format_code)
83 {
84
85 UINT status;
86 UX_SLAVE_TRANSFER *transfer_request;
87 ULONG object_props_list_items;
88 ULONG object_props_list_length;
89 UCHAR *object_props_list;
90 USHORT *object_props_list_pointer;
91
92 /* If trace is enabled, insert this event into the trace buffer. */
93 UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_PIMA_OBJECTS_PROPS_SUPPORTED_GET, pima, object_format_code, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
94
95 /* Obtain the pointer to the transfer request. */
96 transfer_request = &pima -> ux_device_class_pima_bulk_in_endpoint -> ux_slave_endpoint_transfer_request;
97
98 /* Obtain memory for this object info. Use the transfer request pre-allocated memory. */
99 object_props_list = transfer_request -> ux_slave_transfer_request_data_pointer;
100
101 /* Fill in the data container type. */
102 _ux_utility_short_put(object_props_list + UX_DEVICE_CLASS_PIMA_DATA_HEADER_TYPE,
103 UX_DEVICE_CLASS_PIMA_CT_DATA_BLOCK);
104
105 /* Fill in the data code. */
106 _ux_utility_short_put(object_props_list + UX_DEVICE_CLASS_PIMA_DATA_HEADER_CODE,
107 UX_DEVICE_CLASS_PIMA_OC_GET_OBJECT_PROPS_SUPPORTED);
108
109 /* Fill in the Transaction ID. */
110 _ux_utility_long_put(object_props_list + UX_DEVICE_CLASS_PIMA_DATA_HEADER_TRANSACTION_ID,
111 pima -> ux_device_class_pima_transaction_id);
112
113 /* Get the pointer to the list of arrays. */
114 object_props_list_pointer = pima -> ux_device_class_pima_object_properties_list;
115
116 /* Find the object format within the object props arrays. */
117 while (*object_props_list_pointer != 0)
118 {
119 /* See what the format code is. */
120 if (*object_props_list_pointer == (USHORT) object_format_code)
121 {
122
123 /* We have found the format code requested, retrieve the array of props. */
124 /* Retrieve the number of properties for this format code. */
125 object_props_list_items = (ULONG) *(object_props_list_pointer + 1);
126
127 /* Compute the overall length of the object properties array = number of properties + size of array in USHORT. */
128 object_props_list_length = (object_props_list_items * (ULONG)sizeof(USHORT)) + (ULONG)sizeof(ULONG);
129
130 /* Add the header size. */
131 object_props_list_length += UX_DEVICE_CLASS_PIMA_DATA_HEADER_SIZE;
132
133 /* Sanity check of buffer length. */
134 UX_ASSERT(object_props_list_length <= UX_DEVICE_CLASS_PIMA_TRANSFER_BUFFER_LENGTH);
135
136 /* Fill in the size of the response header. */
137 _ux_utility_long_put(object_props_list + UX_DEVICE_CLASS_PIMA_DATA_HEADER_LENGTH,
138 object_props_list_length);
139
140 /* Update the destination pointer. */
141 object_props_list += UX_DEVICE_CLASS_PIMA_DATA_HEADER_SIZE;
142
143 /* Insert the number of elements in the array. */
144 _ux_utility_long_put(object_props_list, object_props_list_items);
145
146 /* Add the length of the array. */
147 object_props_list += sizeof(ULONG);
148
149 /* Point the object_props_list_pointer to the props supported. Skip the object format and the number
150 of properties. */
151 object_props_list_pointer += 2;
152
153 /* Create the array in little endian format for transfer to host. */
154 while(object_props_list_items--)
155 {
156
157 /* Insert the object property in little endian. */
158 _ux_utility_short_put(object_props_list, *object_props_list_pointer);
159
160 /* Update target pointer. */
161 object_props_list += sizeof(SHORT);
162
163 /* Update source pointer. */
164 object_props_list_pointer++;
165
166 }
167
168 /* Send a data payload with the object props array. */
169 status = _ux_device_stack_transfer_request(transfer_request, object_props_list_length, 0);
170
171 /* Now we return a response with success. */
172 _ux_device_class_pima_response_send(pima, UX_DEVICE_CLASS_PIMA_RC_OK, 0, 0, 0, 0);
173
174 /* Return status. */
175 return(status);
176 }
177 else
178 {
179
180 /* We need to skip this object format and point to the next. */
181 /* Retrieve the number of properties for this format code. */
182 object_props_list_items = *(object_props_list_pointer + 1);
183
184 /* Add the number of items to skip to the current list pointer. */
185 object_props_list_pointer += object_props_list_items + 2;
186
187 }
188 }
189
190 /* We get here when we did not find the object format code. */
191 status = _ux_device_class_pima_response_send(pima, UX_DEVICE_CLASS_PIMA_RC_INVALID_OBJECT_FORMAT_CODE, 0, 0, 0, 0);
192
193 /* Return completion status. */
194 return(status);
195 }
196
197
198