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 /** Pictbridge Application */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22
23 /* Include necessary system files. */
24
25 #define UX_SOURCE_CODE
26
27 #include "ux_api.h"
28 #include "ux_pictbridge.h"
29 #include "ux_device_class_pima.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_pictbridge_dpsclient_input_object_prepare PORTABLE C */
37 /* 6.1.12 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function prepares a client input object to be sent. */
45 /* This function puts a interrupt notification for the host to issue */
46 /* a get object request. */
47 /* */
48 /* INPUT */
49 /* */
50 /* pictbridge Pictbridge instance */
51 /* input_function input function */
52 /* */
53 /* OUTPUT */
54 /* */
55 /* Completion Status */
56 /* */
57 /* CALLS */
58 /* */
59 /* */
60 /* CALLED BY */
61 /* */
62 /* */
63 /* */
64 /* RELEASE HISTORY */
65 /* */
66 /* DATE NAME DESCRIPTION */
67 /* */
68 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
69 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
70 /* verified memset and memcpy */
71 /* cases, used UX prefix to */
72 /* refer to TX symbols instead */
73 /* of using them directly, */
74 /* resulting in version 6.1 */
75 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
76 /* cleared compile warning, */
77 /* used macros for RTOS calls, */
78 /* resulting in version 6.1.12 */
79 /* */
80 /**************************************************************************/
_ux_pictbridge_dpsclient_input_object_prepare(UX_PICTBRIDGE * pictbridge,ULONG input_function,ULONG input_subfunction,ULONG input_parameter)81 UINT _ux_pictbridge_dpsclient_input_object_prepare(UX_PICTBRIDGE *pictbridge,
82 ULONG input_function,
83 ULONG input_subfunction,
84 ULONG input_parameter)
85 {
86 UINT status;
87 ULONG object_length;
88 UCHAR *pima_object_buffer;
89 UX_SLAVE_CLASS_PIMA *pima;
90 UX_SLAVE_CLASS_PIMA_OBJECT *pima_object;
91 ULONG actual_flags;
92
93
94 /* Check the status of pictbridge, if we are in a host request cycle, cannot add object now. */
95 if (pictbridge -> ux_pictbridge_host_client_state_machine & UX_PICTBRIDGE_STATE_MACHINE_HOST_REQUEST)
96 {
97
98 /* Add to the state machine the client pending request. */
99 pictbridge -> ux_pictbridge_host_client_state_machine |= UX_PICTBRIDGE_STATE_MACHINE_CLIENT_REQUEST_PENDING;
100
101 /* We should wait for the state machine to allow our operation. */
102 status = _ux_system_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, UX_PICTBRIDGE_EVENT_FLAG_STATE_MACHINE_READY,
103 UX_AND_CLEAR, &actual_flags, UX_PICTBRIDGE_EVENT_TIMEOUT);
104
105 /* Check status. */
106 if (status != UX_SUCCESS)
107 return(UX_EVENT_ERROR);
108
109 /* Status good means flag match, no need to check variable again, mark it unused. */
110 (void)actual_flags;
111 }
112
113 /* Change the state machine to client request. */
114 pictbridge -> ux_pictbridge_host_client_state_machine |= UX_PICTBRIDGE_STATE_MACHINE_CLIENT_REQUEST;
115
116 /* Get the pima instance from the pictbridge container. */
117 pima = (UX_SLAVE_CLASS_PIMA *) pictbridge -> ux_pictbridge_pima;
118
119 /* Get the address of the object container. We choose the client container. */
120 pima_object = pictbridge -> ux_pictbridge_object_client;
121
122 /* Get the object buffer address. */
123 pima_object_buffer = pima_object -> ux_device_class_pima_object_buffer;
124
125 /* Reset the object length. */
126 object_length = 0;
127
128 /* Clear the object memory buffer. */
129 _ux_utility_memory_set(pima_object_buffer, 0, UX_PICTBRIDGE_MAX_PIMA_OBJECT_BUFFER); /* Use case of memset is verified. */
130
131 /* Add the line <?xml version="1.0"?> */
132 status = _ux_pictbridge_object_tag_line_add(pima_object_buffer, object_length, _ux_pictbridge_xml_tag_line_xmlversion,
133 UX_PICTBRIDGE_TAG_FLAG_BEGIN | UX_PICTBRIDGE_TAG_FLAG_FORCE_LF,
134 UX_NULL, 0, UX_NULL, &pima_object_buffer, &object_length);
135 if (status != UX_SUCCESS)
136 return(status);
137
138 /* Add the line <dps xmlns="http://www.cipa.jp/dps/schema/"> */
139 status = _ux_pictbridge_object_tag_line_add(pima_object_buffer, object_length, _ux_pictbridge_xml_tag_line_dpsxmlns,
140 UX_PICTBRIDGE_TAG_FLAG_BEGIN | UX_PICTBRIDGE_TAG_FLAG_FORCE_LF,
141 UX_NULL, 0, UX_NULL, &pima_object_buffer, &object_length);
142 if (status != UX_SUCCESS)
143 return(status);
144
145 /* Add the line <input> */
146 status = _ux_pictbridge_object_tag_line_add(pima_object_buffer, object_length, _ux_pictbridge_xml_tag_line_input,
147 UX_PICTBRIDGE_TAG_FLAG_BEGIN | UX_PICTBRIDGE_TAG_FLAG_FORCE_LF,
148 UX_NULL, 0, UX_NULL, &pima_object_buffer, &object_length);
149 if (status != UX_SUCCESS)
150 return(status);
151
152 /* Look into the tag code from the input object and proceed to individual functions. */
153 switch (input_function)
154 {
155
156
157 case UX_PICTBRIDGE_OR_CONFIGURE_PRINT_SERVICE :
158
159 status = _ux_pictbridge_dpsclient_input_object_configure_print_service(pictbridge, pima_object_buffer, object_length,
160 &pima_object_buffer, &object_length);
161 break;
162
163 case UX_PICTBRIDGE_OR_GET_CAPABILITY :
164
165 status = _ux_pictbridge_dpsclient_input_object_get_capability(pictbridge, input_subfunction, input_parameter, pima_object_buffer, object_length,
166 &pima_object_buffer, &object_length);
167 break;
168
169 case UX_PICTBRIDGE_OR_START_JOB :
170
171 status = _ux_pictbridge_dpsclient_input_object_startjob(pictbridge, input_subfunction, input_parameter, pima_object_buffer, object_length,
172 &pima_object_buffer, &object_length);
173 break;
174
175 case UX_PICTBRIDGE_OR_ABORT_JOB :
176
177 status = _ux_pictbridge_dpsclient_input_object_abortjob(pictbridge, input_subfunction, input_parameter, pima_object_buffer, object_length,
178 &pima_object_buffer, &object_length);
179 break;
180
181 case UX_PICTBRIDGE_OR_CONTINUE_JOB :
182
183 status = _ux_pictbridge_dpsclient_input_object_continuejob(pictbridge, input_subfunction, input_parameter, pima_object_buffer, object_length,
184 &pima_object_buffer, &object_length);
185 break;
186
187 case UX_PICTBRIDGE_OR_GET_DEVICE_STATUS :
188
189 /* Add the line <getDeviceStatus/> */
190 status = _ux_pictbridge_object_tag_line_add(pima_object_buffer, object_length, _ux_pictbridge_xml_tag_line_getdevicestatus,
191 UX_PICTBRIDGE_TAG_FLAG_BEGIN | UX_PICTBRIDGE_TAG_FLAG_FORCE_SLASH_AT_END,
192 UX_NULL, 0, UX_NULL, &pima_object_buffer, &object_length);
193
194 break;
195
196 default :
197
198 /* Function not yet supported. We should never come here anyway. */
199 status = (UX_ERROR);
200 }
201 if (status != UX_SUCCESS)
202 return(status);
203
204 /* Add the line </input> */
205 status = _ux_pictbridge_object_tag_line_add(pima_object_buffer, object_length, _ux_pictbridge_xml_tag_line_input,
206 UX_PICTBRIDGE_TAG_FLAG_END,
207 UX_NULL, 0, UX_NULL, &pima_object_buffer, &object_length);
208 if (status != UX_SUCCESS)
209 return(status);
210
211 /* Add the line </dps> */
212 status = _ux_pictbridge_object_tag_line_add(pima_object_buffer, object_length, _ux_pictbridge_xml_tag_line_dps,
213 UX_PICTBRIDGE_TAG_FLAG_END,
214 UX_NULL, 0, UX_NULL, &pima_object_buffer, &object_length);
215 if (status != UX_SUCCESS)
216 return(status);
217
218 /* Get the length of the object and store it into the object data set. */
219 pima_object -> ux_device_class_pima_object_length = object_length;
220 pima_object -> ux_device_class_pima_object_compressed_size = object_length;
221
222 /* Save the handle for this object. */
223 pima_object -> ux_device_class_pima_object_handle_id = UX_PICTBRIDGE_OBJECT_HANDLE_CLIENT_REQUEST;
224
225 /* We need to change the file name to DREQUEST.DPS. Encode the file name from ascii format into Unicode. */
226 _ux_utility_string_to_unicode(_ux_pictbridge_drequest_name, pima_object -> ux_device_class_pima_object_filename);
227
228 /* Send the notification to the host that an object has been added. */
229 status = _ux_device_class_pima_object_add(pima, UX_PICTBRIDGE_OBJECT_HANDLE_CLIENT_REQUEST);
230
231 /* Return completion status. */
232 return(status);
233 }
234
235