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 /** */
16 /** USBX Component */
17 /** */
18 /** Pictbridge Application */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23
24 /* Include necessary system files. */
25
26 #define UX_SOURCE_CODE
27
28 #include "ux_api.h"
29 #include "ux_pictbridge.h"
30 #include "ux_device_stack.h"
31 #include "ux_device_class_pima.h"
32
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _ux_pictbridge_dpsclient_start PORTABLE C */
39 /* 6.1.12 */
40 /* AUTHOR */
41 /* */
42 /* Chaoqiong Xiao, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function starts the DPS client (usually a camera or phone) */
47 /* */
48 /* INPUT */
49 /* */
50 /* pima Pima instance associated */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* Completion Status */
55 /* */
56 /* CALLS */
57 /* */
58 /* */
59 /* CALLED BY */
60 /* */
61 /* user application */
62 /* */
63 /* RELEASE HISTORY */
64 /* */
65 /* DATE NAME DESCRIPTION */
66 /* */
67 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
68 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
69 /* used UX prefix to refer to */
70 /* TX symbols instead of using */
71 /* them directly, */
72 /* resulting in version 6.1 */
73 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
74 /* used macros for RTOS calls, */
75 /* resulting in version 6.1.12 */
76 /* */
77 /**************************************************************************/
_ux_pictbridge_dpsclient_start(UX_PICTBRIDGE * pictbridge)78 UINT _ux_pictbridge_dpsclient_start(UX_PICTBRIDGE *pictbridge)
79 {
80 UINT status;
81 UX_SLAVE_CLASS_PIMA_OBJECT *object_info;
82
83 /* Allocate 1 object for the host. */
84 pictbridge -> ux_pictbridge_object_host = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, sizeof(UX_SLAVE_CLASS_PIMA_OBJECT));
85
86 /* Check status. */
87 if (pictbridge -> ux_pictbridge_object_host == UX_NULL)
88 return(UX_MEMORY_INSUFFICIENT);
89
90 /* Initialize status to success for things going on. */
91 status = UX_SUCCESS;
92
93 /* Allocate 1 object for the client. */
94 pictbridge -> ux_pictbridge_object_client = (VOID *)_ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, sizeof(UX_SLAVE_CLASS_PIMA_OBJECT));
95
96 /* Check status. */
97 if (pictbridge -> ux_pictbridge_object_client == UX_NULL)
98 status = (UX_MEMORY_INSUFFICIENT);
99
100 /* Allocate 1 object for the job. */
101 if (status == UX_SUCCESS)
102 {
103 pictbridge -> ux_pictbridge_jobinfo.ux_pictbridge_jobinfo_object = (VOID *)_ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, sizeof(UX_SLAVE_CLASS_PIMA_OBJECT));
104
105 /* Check status. */
106 if (pictbridge -> ux_pictbridge_jobinfo.ux_pictbridge_jobinfo_object == UX_NULL)
107 status = (UX_MEMORY_INSUFFICIENT);
108 }
109
110 /* Allocate some memory for the XML objects. For the client script. */
111 if (status == UX_SUCCESS)
112 {
113 object_info = (UX_SLAVE_CLASS_PIMA_OBJECT *) pictbridge -> ux_pictbridge_object_client;
114 object_info -> ux_device_class_pima_object_buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, UX_PICTBRIDGE_MAX_PIMA_OBJECT_BUFFER);
115
116 /* Check status. */
117 if (object_info -> ux_device_class_pima_object_buffer == UX_NULL)
118 status = (UX_MEMORY_INSUFFICIENT);
119 }
120
121 /* Allocate some memory for the XML objects. For the host script. */
122 if (status == UX_SUCCESS)
123 {
124 object_info = (UX_SLAVE_CLASS_PIMA_OBJECT *) pictbridge -> ux_pictbridge_object_host;
125 object_info -> ux_device_class_pima_object_buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, UX_PICTBRIDGE_MAX_PIMA_OBJECT_BUFFER);
126
127 /* Check status. */
128 if (object_info -> ux_device_class_pima_object_buffer == UX_NULL)
129 return(UX_MEMORY_INSUFFICIENT);
130 }
131
132 /* Create a event flag group for the client to communicate with the application. */
133 if (status == UX_SUCCESS)
134 {
135 status = _ux_system_event_flags_create(&pictbridge -> ux_pictbridge_event_flags_group, "ux_pictbridge_client_event_flag");
136
137 /* Check status. */
138 if (status != UX_SUCCESS)
139
140 /* Do not proceed if error. */
141 status = (UX_EVENT_ERROR);
142 }
143
144 /* Create the semaphore to wake up the thread. */
145 if (status == UX_SUCCESS)
146 {
147 status = _ux_system_semaphore_create(&pictbridge -> ux_pictbridge_notification_semaphore, "ux_pictbridge_client_semaphore", 0);
148 if (status != UX_SUCCESS)
149
150 /* Do not proceed if error. */
151 status = (UX_SEMAPHORE_ERROR);
152 }
153
154 /* Allocate a Thread stack. */
155 if (status == UX_SUCCESS)
156 {
157 pictbridge -> ux_pictbridge_thread_stack =
158 _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_PICTBRIDGE_THREAD_STACK_SIZE);
159
160 /* Check the completion status. */
161 if (pictbridge -> ux_pictbridge_thread_stack == UX_NULL)
162
163 /* Do not proceed if error. */
164 return(UX_MEMORY_INSUFFICIENT);
165 }
166
167 /* Create the pictbridge class thread. */
168 if (status == UX_SUCCESS)
169 {
170 status = _ux_system_thread_create(&pictbridge -> ux_pictbridge_thread,
171 "ux_pictbridge_thread", _ux_pictbridge_dpsclient_thread,
172 (ULONG)(ALIGN_TYPE) pictbridge,
173 pictbridge -> ux_pictbridge_thread_stack,
174 UX_PICTBRIDGE_THREAD_STACK_SIZE,
175 UX_PICTBRIDGE_THREAD_PRIORITY_CLASS,
176 UX_PICTBRIDGE_THREAD_PRIORITY_CLASS,
177 UX_NO_TIME_SLICE, UX_AUTO_START);
178
179 /* Check the completion status. */
180 if (status != UX_SUCCESS)
181
182 /* Do not proceed if error. */
183 status = (UX_THREAD_ERROR);
184
185 UX_THREAD_EXTENSION_PTR_SET(&(pictbridge -> ux_pictbridge_thread), pictbridge)
186 }
187
188 /* Go on to next step. */
189 if (status == UX_SUCCESS)
190 {
191 /* Initialize the pictbridge request/response state to request expected. */
192 pictbridge -> ux_pictbridge_request_response = UX_PICTBRIDGE_REQUEST;
193
194 /* Set the host/client cycle to idle. */
195 pictbridge -> ux_pictbridge_host_client_state_machine = UX_PICTBRIDGE_STATE_MACHINE_IDLE;
196
197 /* Initialize the first XML object valid in the pictbridge instance. Initialize the handle, type and file name.
198 The storage handle and the object handle have a fixed value of 1 in our implementation. */
199 object_info = pictbridge -> ux_pictbridge_object_client;
200 object_info -> ux_device_class_pima_object_format = UX_DEVICE_CLASS_PIMA_OFC_SCRIPT;
201 object_info -> ux_device_class_pima_object_storage_id = 1;
202 object_info -> ux_device_class_pima_object_handle_id = 2;
203 _ux_utility_string_to_unicode(_ux_pictbridge_ddiscovery_name, object_info -> ux_device_class_pima_object_filename);
204
205 /* Initialize the head and tail of the notification round robin buffers.
206 At first, the head and tail are pointing to the beginning of the array. */
207 pictbridge -> ux_pictbridge_event_array_head = pictbridge -> ux_pictbridge_event_array;
208 pictbridge -> ux_pictbridge_event_array_tail = pictbridge -> ux_pictbridge_event_array;
209 pictbridge -> ux_pictbridge_event_array_end = pictbridge -> ux_pictbridge_event_array + UX_PICTBRIDGE_MAX_EVENT_NUMBER;
210
211 /* Initialize the pima device parameter. */
212 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_manufacturer = pictbridge -> ux_pictbridge_dpslocal.ux_pictbridge_devinfo_vendor_name;
213 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_model = pictbridge -> ux_pictbridge_dpslocal.ux_pictbridge_devinfo_product_name;
214 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_serial_number = pictbridge -> ux_pictbridge_dpslocal.ux_pictbridge_devinfo_serial_no;
215 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_storage_id = 1;
216 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_storage_type = UX_DEVICE_CLASS_PIMA_STC_FIXED_RAM;
217 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_storage_file_system_type = UX_DEVICE_CLASS_PIMA_FSTC_GENERIC_FLAT;
218 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_storage_access_capability = UX_DEVICE_CLASS_PIMA_AC_READ_WRITE;
219 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_storage_max_capacity_low = pictbridge -> ux_pictbridge_dpslocal.ux_pictbridge_devinfo_storage_size;
220 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_storage_max_capacity_high = 0;
221 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_storage_free_space_low = pictbridge -> ux_pictbridge_dpslocal.ux_pictbridge_devinfo_storage_size;
222 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_storage_free_space_high = 0;
223 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_storage_free_space_image = 0;
224 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_storage_description = _ux_pictbridge_volume_description;
225 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_storage_volume_label = _ux_pictbridge_volume_label;
226 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_object_number_get = _ux_pictbridge_dpsclient_object_number_get;
227 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_object_handles_get = _ux_pictbridge_dpsclient_object_handles_get;
228 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_object_info_get = _ux_pictbridge_dpsclient_object_info_get;
229 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_object_data_get = _ux_pictbridge_dpsclient_object_data_get;
230 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_object_info_send = _ux_pictbridge_dpsclient_object_info_send;
231 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_object_data_send = _ux_pictbridge_dpsclient_object_data_send;
232 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_object_delete = _ux_pictbridge_dpsclient_object_delete;
233
234 /* Store the instance owner. */
235 pictbridge -> ux_pictbridge_pima_parameter.ux_device_class_pima_parameter_application = (VOID *) pictbridge;
236
237 /* Initialize the device pima class. The class is connected with interface 0 */
238 status = _ux_device_stack_class_register(_ux_system_slave_class_pima_name, _ux_device_class_pima_entry,
239 1, 0, (VOID *)&pictbridge -> ux_pictbridge_pima_parameter);
240 }
241
242 /* Check status. */
243 if (status != UX_SUCCESS)
244 {
245
246 /* Free resources allocated so far. */
247 if (_ux_system_thread_created(&pictbridge -> ux_pictbridge_thread))
248 _ux_system_thread_delete(&pictbridge -> ux_pictbridge_thread);
249 if (pictbridge -> ux_pictbridge_thread_stack)
250 _ux_utility_memory_free(pictbridge -> ux_pictbridge_thread_stack);
251 if (_ux_system_semaphore_created(&pictbridge -> ux_pictbridge_notification_semaphore))
252 _ux_system_semaphore_delete(&pictbridge -> ux_pictbridge_notification_semaphore);
253 if (_ux_system_event_flags_created(&pictbridge -> ux_pictbridge_event_flags_group))
254 _ux_system_event_flags_delete(&pictbridge -> ux_pictbridge_event_flags_group);
255 if (pictbridge -> ux_pictbridge_jobinfo.ux_pictbridge_jobinfo_object)
256 {
257 _ux_utility_memory_free(pictbridge -> ux_pictbridge_jobinfo.ux_pictbridge_jobinfo_object);
258 }
259 if (pictbridge -> ux_pictbridge_object_client)
260 {
261 object_info = (UX_SLAVE_CLASS_PIMA_OBJECT *) pictbridge -> ux_pictbridge_object_client;
262 if (object_info -> ux_device_class_pima_object_buffer)
263 _ux_utility_memory_free(object_info -> ux_device_class_pima_object_buffer);
264 _ux_utility_memory_free(pictbridge -> ux_pictbridge_object_client);
265 }
266 object_info = (UX_SLAVE_CLASS_PIMA_OBJECT *) pictbridge -> ux_pictbridge_object_host;
267 if (object_info -> ux_device_class_pima_object_buffer)
268 _ux_utility_memory_free(object_info -> ux_device_class_pima_object_buffer);
269 _ux_utility_memory_free(pictbridge -> ux_pictbridge_object_host);
270
271 /* Do not proceed if error. */
272 return(status);
273 }
274
275 /* We are done. */
276 return(UX_SUCCESS);
277 }
278
279