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_class_pima.h"
31 
32 
33 /**************************************************************************/
34 /*                                                                        */
35 /*  FUNCTION                                               RELEASE        */
36 /*                                                                        */
37 /*    _ux_pictbridge_dpsclient_thread                     PORTABLE C      */
38 /*                                                           6.1.12       */
39 /*  AUTHOR                                                                */
40 /*                                                                        */
41 /*    Chaoqiong Xiao, Microsoft Corporation                               */
42 /*                                                                        */
43 /*  DESCRIPTION                                                           */
44 /*                                                                        */
45 /*    This is the Pictbridge dpsclient thread that receives and execute   */
46 /*    commands from the dpshost.                                          */
47 /*                                                                        */
48 /*  INPUT                                                                 */
49 /*                                                                        */
50 /*    pictbridge                             Pictbridge instance          */
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 /*                                            verified memset and memcpy  */
70 /*                                            cases, used UX prefix to    */
71 /*                                            refer to TX symbols instead */
72 /*                                            of using them directly,     */
73 /*                                            resulting in version 6.1    */
74 /*  07-29-2022     Chaoqiong Xiao           Modified comment(s),          */
75 /*                                            used macros for RTOS calls, */
76 /*                                            resulting in version 6.1.12 */
77 /*                                                                        */
78 /**************************************************************************/
_ux_pictbridge_dpsclient_thread(ULONG parameter)79 VOID  _ux_pictbridge_dpsclient_thread(ULONG parameter)
80 {
81 
82 UX_PICTBRIDGE                       *pictbridge;
83 ULONG                               actual_flags;
84 UINT                                status = UX_SUCCESS;
85 ULONG                               object_length;
86 UCHAR                               *pima_object_buffer;
87 UX_SLAVE_CLASS_PIMA                 *pima;
88 UX_SLAVE_CLASS_PIMA_OBJECT          *pima_object;
89 
90     /* Cast the parameter passed in the thread into the pictbridge pointer.  */
91     UX_THREAD_EXTENSION_PTR_GET(pictbridge, UX_PICTBRIDGE, parameter)
92 
93     /* Loop forever waiting for changes signaled through the semaphore. */
94     while (1)
95     {
96 
97         /* Report errors via error handler.  */
98         if (status != UX_SUCCESS)
99             _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, status);
100 
101         /* We should wait for the host to send a script with a command.  */
102         status =  _ux_system_event_flags_get(&pictbridge -> ux_pictbridge_event_flags_group, (UX_PICTBRIDGE_EVENT_FLAG_NOTIFY_JOB_STATUS |
103                                                                                                 UX_PICTBRIDGE_EVENT_FLAG_NOTIFY_DEVICE_STATUS),
104                                                                                                 UX_OR_CLEAR, &actual_flags, UX_PICTBRIDGE_EVENT_TIMEOUT);
105 
106         /* Check the status.  */
107         if (status == UX_SUCCESS)
108         {
109 
110             /* The event flag is meaningful. What did we get ? */
111             if ((actual_flags & UX_PICTBRIDGE_EVENT_FLAG_NOTIFY_JOB_STATUS) || (actual_flags & UX_PICTBRIDGE_EVENT_FLAG_NOTIFY_DEVICE_STATUS))
112             {
113 
114                 /* We need to send a response now.  */
115                 /* Get the pima instance from the pictbridge container.  */
116                 pima = (UX_SLAVE_CLASS_PIMA *) pictbridge -> ux_pictbridge_pima;
117 
118                 /* Get the address of the object container.  We need the host container here, as it is a response for the host.  */
119                 pima_object =  (UX_SLAVE_CLASS_PIMA_OBJECT *) pictbridge -> ux_pictbridge_object_host;
120 
121                 /* Get the object buffer address.  */
122                 pima_object_buffer = pima_object -> ux_device_class_pima_object_buffer;
123 
124                 /* Reset the object length.  */
125                 object_length =  0;
126 
127                 /* Clear the object memory buffer.  */
128                 _ux_utility_memory_set(pima_object_buffer, 0, UX_PICTBRIDGE_MAX_PIMA_OBJECT_BUFFER); /* Use case of memset is verified. */
129 
130                 /* Add the line <?xml version="1.0"?>  */
131                 status = _ux_pictbridge_object_tag_line_add(pima_object_buffer, object_length, _ux_pictbridge_xml_tag_line_xmlversion,
132                                                             UX_PICTBRIDGE_TAG_FLAG_BEGIN | UX_PICTBRIDGE_TAG_FLAG_FORCE_LF,
133                                                             UX_NULL, 0, UX_NULL, &pima_object_buffer, &object_length);
134                 if (status != UX_SUCCESS)
135                     continue;
136 
137                 /* Add the line <dps xmlns="http://www.cipa.jp/dps/schema/">  */
138                 status = _ux_pictbridge_object_tag_line_add(pima_object_buffer, object_length, _ux_pictbridge_xml_tag_line_dpsxmlns,
139                                                             UX_PICTBRIDGE_TAG_FLAG_BEGIN | UX_PICTBRIDGE_TAG_FLAG_FORCE_LF,
140                                                             UX_NULL, 0, UX_NULL, &pima_object_buffer, &object_length);
141                 if (status != UX_SUCCESS)
142                     continue;
143 
144                 /* Add the line <output>  */
145                 status = _ux_pictbridge_object_tag_line_add(pima_object_buffer, object_length, _ux_pictbridge_xml_tag_line_output,
146                                                             UX_PICTBRIDGE_TAG_FLAG_BEGIN | UX_PICTBRIDGE_TAG_FLAG_FORCE_LF,
147                                                             UX_NULL, 0, UX_NULL, &pima_object_buffer, &object_length);
148                 if (status != UX_SUCCESS)
149                     continue;
150 
151                 /* Add the line <result> xxxxxxxx </result> */
152                 status = _ux_pictbridge_object_tag_line_add(pima_object_buffer, object_length, _ux_pictbridge_xml_tag_line_result,
153                                                         UX_PICTBRIDGE_TAG_FLAG_BEGIN | UX_PICTBRIDGE_TAG_FLAG_END | UX_PICTBRIDGE_TAG_FLAG_VARIABLE_HEXA,
154                                                         UX_NULL, 0, (VOID *)(ALIGN_TYPE) pictbridge -> ux_pictbridge_operation_result, &pima_object_buffer, &object_length);
155                 if (status != UX_SUCCESS)
156                     continue;
157 
158                 /* Check what function was demanded.  */
159                 if (actual_flags & UX_PICTBRIDGE_EVENT_FLAG_NOTIFY_JOB_STATUS)
160 
161                     /* Add the line <notifyJobStatus/> */
162                     status = _ux_pictbridge_object_tag_line_add(pima_object_buffer, object_length, _ux_pictbridge_xml_tag_line_notifyjobstatus,
163                                                             UX_PICTBRIDGE_TAG_FLAG_BEGIN | UX_PICTBRIDGE_TAG_FLAG_FORCE_SLASH_AT_END,
164                                                             UX_NULL, 0, UX_NULL, &pima_object_buffer, &object_length);
165 
166                 else
167 
168 
169                     /* Add the line <notifyDeviceStatus/> */
170                     status = _ux_pictbridge_object_tag_line_add(pima_object_buffer, object_length, _ux_pictbridge_xml_tag_line_notifydevicestatus,
171                                                             UX_PICTBRIDGE_TAG_FLAG_BEGIN | UX_PICTBRIDGE_TAG_FLAG_FORCE_SLASH_AT_END,
172                                                             UX_NULL, 0, UX_NULL, &pima_object_buffer, &object_length);
173                 if (status != UX_SUCCESS)
174                     continue;
175 
176                 /* Add the line </output>  */
177                 status = _ux_pictbridge_object_tag_line_add(pima_object_buffer, object_length, _ux_pictbridge_xml_tag_line_output,
178                                                 UX_PICTBRIDGE_TAG_FLAG_END,
179                                                 UX_NULL, 0, UX_NULL, &pima_object_buffer, &object_length);
180                 if (status != UX_SUCCESS)
181                     continue;
182 
183                 /* Add the line </dps>  */
184                 status = _ux_pictbridge_object_tag_line_add(pima_object_buffer, object_length, _ux_pictbridge_xml_tag_line_dps,
185                                                             UX_PICTBRIDGE_TAG_FLAG_END,
186                                                             UX_NULL, 0, UX_NULL, &pima_object_buffer, &object_length);
187                 if (status != UX_SUCCESS)
188                     continue;
189 
190                 /* Get the length of the object and store it into the object data set.  */
191                 pima_object -> ux_device_class_pima_object_length = object_length;
192                 pima_object -> ux_device_class_pima_object_compressed_size = object_length;
193 
194                 /* Save the handle for this object.  */
195                 pima_object -> ux_device_class_pima_object_handle_id =  UX_PICTBRIDGE_OBJECT_HANDLE_HOST_RESPONSE;
196 
197                 /* We need to change the file name to DRSPONSE.DPS. Encode the file name from ascii format into Unicode.  */
198                 _ux_utility_string_to_unicode(_ux_pictbridge_drsponse_name, pima_object -> ux_device_class_pima_object_filename);
199 
200                 /* Send the notification to the host that an object has been added.  */
201                 status = _ux_device_class_pima_object_add(pima, UX_PICTBRIDGE_OBJECT_HANDLE_HOST_RESPONSE);
202                 if (status != UX_SUCCESS)
203                     continue;
204 
205                 /* Check if user registered callback function is present.  */
206                 if (pictbridge -> ux_pictbridge_dps_event_callback_function != UX_NULL)
207                 {
208 
209                     /* Call the user callback function.  */
210                     (pictbridge -> ux_pictbridge_dps_event_callback_function)(pictbridge, actual_flags);
211                 }
212 
213             }
214         }
215     }
216 }
217 
218