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 /** ThreadX Component                                                     */
17 /**                                                                       */
18 /**   Module Manager                                                      */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define TX_SOURCE_CODE
24 
25 #include "tx_api.h"
26 #include "tx_initialize.h"
27 #include "tx_thread.h"
28 #include "tx_timer.h"
29 #include "tx_queue.h"
30 #include "tx_event_flags.h"
31 #include "tx_semaphore.h"
32 #include "tx_mutex.h"
33 #include "tx_block_pool.h"
34 #include "tx_byte_pool.h"
35 #include "txm_module.h"
36 #include "txm_module_manager_util.h"
37 
38 
39 /**************************************************************************/
40 /*                                                                        */
41 /*  FUNCTION                                               RELEASE        */
42 /*                                                                        */
43 /*    _txm_module_manager_object_pointer_get_extended     PORTABLE C      */
44 /*                                                           6.1          */
45 /*  AUTHOR                                                                */
46 /*                                                                        */
47 /*    Scott Larson, Microsoft Corporation                                 */
48 /*                                                                        */
49 /*  DESCRIPTION                                                           */
50 /*                                                                        */
51 /*    This function retrieves the object pointer of a particular type     */
52 /*    with a particular name. If the object is not found, an error is     */
53 /*    returned. Otherwise, if the object is found, the address of that    */
54 /*    object is placed in object_ptr.                                     */
55 /*                                                                        */
56 /*  INPUT                                                                 */
57 /*                                                                        */
58 /*    object_type                       Type of object, as follows:       */
59 /*                                                                        */
60 /*                                          TXM_BLOCK_POOL_OBJECT         */
61 /*                                          TXM_BYTE_POOL_OBJECT          */
62 /*                                          TXM_EVENT_FLAGS_OBJECT        */
63 /*                                          TXM_MUTEX_OBJECT              */
64 /*                                          TXM_QUEUE_OBJECT              */
65 /*                                          TXM_SEMAPHORE_OBJECT          */
66 /*                                          TXM_THREAD_OBJECT             */
67 /*                                          TXM_TIMER_OBJECT              */
68 /*    search_name                       Name to search for                */
69 /*    search_name_length                Length of the name excluding      */
70 /*                                        null-terminator                 */
71 /*    object_ptr                        Pointer to the object             */
72 /*                                                                        */
73 /*  OUTPUT                                                                */
74 /*                                                                        */
75 /*    TX_SUCCESS                        Successful completion             */
76 /*    TX_PTR_ERROR                      Invalid name or object ptr        */
77 /*    TX_OPTION_ERROR                   Invalid option type               */
78 /*    TX_NO_INSTANCE                    Object not found                  */
79 /*                                                                        */
80 /*  CALLS                                                                 */
81 /*                                                                        */
82 /*    _txm_module_manager_object_name_compare                             */
83 /*                                      String compare routine            */
84 /*    [_txm_module_manager_*_object_pointer_get]                          */
85 /*                                      Optional external component       */
86 /*                                        object pointer get              */
87 /*                                                                        */
88 /*  CALLED BY                                                             */
89 /*                                                                        */
90 /*    Application code                                                    */
91 /*                                                                        */
92 /*  RELEASE HISTORY                                                       */
93 /*                                                                        */
94 /*    DATE              NAME                      DESCRIPTION             */
95 /*                                                                        */
96 /*  09-30-2020      Scott Larson            Initial Version 6.1           */
97 /*                                                                        */
98 /**************************************************************************/
_txm_module_manager_object_pointer_get_extended(UINT object_type,CHAR * search_name,UINT search_name_length,VOID ** object_ptr)99 UINT  _txm_module_manager_object_pointer_get_extended(UINT object_type, CHAR *search_name, UINT search_name_length, VOID **object_ptr)
100 {
101 
102 TX_INTERRUPT_SAVE_AREA
103 
104 TX_THREAD               *thread_ptr;
105 TX_TIMER                *timer_ptr;
106 TX_QUEUE                *queue_ptr;
107 TX_EVENT_FLAGS_GROUP    *events_ptr;
108 TX_SEMAPHORE            *semaphore_ptr;
109 TX_MUTEX                *mutex_ptr;
110 TX_BLOCK_POOL           *block_pool_ptr;
111 TX_BYTE_POOL            *byte_pool_ptr;
112 ULONG                   i;
113 UINT                    status;
114 TXM_MODULE_INSTANCE     *module_instance;
115 
116 
117     /* Determine if the name or object pointer are NULL.  */
118     if ((search_name == TX_NULL) || (object_ptr == TX_NULL))
119     {
120 
121         /* Return error!  */
122         return(TX_PTR_ERROR);
123     }
124 
125     /* Default status to not found.  */
126     status =  TX_NO_INSTANCE;
127 
128     /* Set the return value to NULL.  */
129     *object_ptr =  TX_NULL;
130 
131     /* Disable interrupts.  */
132     TX_DISABLE
133 
134     /* Temporarily disable preemption.  This will keep other threads from creating and deleting threads.  */
135     _tx_thread_preempt_disable++;
136 
137     /* Restore interrupts.  */
138     TX_RESTORE
139 
140     /* Process relative to the object type.  */
141     switch(object_type)
142     {
143 
144     /* Determine if a thread object is requested.  */
145     case TXM_THREAD_OBJECT:
146     {
147 
148         /* Loop to find the first matching thread.  */
149         i = 0;
150         thread_ptr =  _tx_thread_created_ptr;
151         while (i < _tx_thread_created_count)
152         {
153 
154             /* Do we have a match?  */
155             if (_txm_module_manager_object_name_compare(search_name, search_name_length, thread_ptr -> tx_thread_name))
156             {
157 
158                 /* Yes, we found it - return the necessary info!  */
159                 *object_ptr =  (VOID *) thread_ptr;
160 
161                 /* Set the the status to success!  */
162                 status =  TX_SUCCESS;
163                 break;
164             }
165 
166             /* Increment the counter.  */
167             i++;
168 
169             /* Move to next thread.  */
170             thread_ptr =  thread_ptr -> tx_thread_created_next;
171         }
172         break;
173     }
174 
175     /* Determine if a timer object is requested.  */
176     case TXM_TIMER_OBJECT:
177     {
178 
179         /* Loop to find the first matching timer.  */
180         i = 0;
181         timer_ptr =  _tx_timer_created_ptr;
182         while (i < _tx_timer_created_count)
183         {
184 
185             /* Do we have a match?  */
186             if (_txm_module_manager_object_name_compare(search_name, search_name_length, timer_ptr -> tx_timer_name))
187             {
188 
189                 /* Yes, we found it - return the necessary info!  */
190                 *object_ptr =  (VOID *) timer_ptr;
191 
192                 /* Set the the status to success!  */
193                 status =  TX_SUCCESS;
194                 break;
195             }
196 
197             /* Increment the counter.  */
198             i++;
199 
200             /* Move to next timer.  */
201             timer_ptr =  timer_ptr -> tx_timer_created_next;
202         }
203         break;
204     }
205 
206     /* Determine if a queue object is requested.  */
207     case TXM_QUEUE_OBJECT:
208     {
209 
210         /* Loop to find the first matching queue.  */
211         i = 0;
212         queue_ptr =  _tx_queue_created_ptr;
213         while (i < _tx_queue_created_count)
214         {
215 
216             /* Do we have a match?  */
217             if (_txm_module_manager_object_name_compare(search_name, search_name_length, queue_ptr -> tx_queue_name))
218             {
219 
220                 /* Yes, we found it - return the necessary info!  */
221                 *object_ptr =  (VOID *) queue_ptr;
222 
223                 /* Set the the status to success!  */
224                 status =  TX_SUCCESS;
225                 break;
226             }
227 
228             /* Increment the counter.  */
229             i++;
230 
231             /* Move to next queue.  */
232             queue_ptr =  queue_ptr -> tx_queue_created_next;
233         }
234         break;
235     }
236 
237     /* Determine if a event flags object is requested.  */
238     case TXM_EVENT_FLAGS_OBJECT:
239     {
240 
241         /* Loop to find the first matching event flags group.  */
242         i = 0;
243         events_ptr =  _tx_event_flags_created_ptr;
244         while (i < _tx_event_flags_created_count)
245         {
246 
247             /* Do we have a match?  */
248             if (_txm_module_manager_object_name_compare(search_name, search_name_length, events_ptr -> tx_event_flags_group_name))
249             {
250 
251                 /* Yes, we found it - return the necessary info!  */
252                 *object_ptr =  (VOID *) events_ptr;
253 
254                 /* Set the the status to success!  */
255                 status =  TX_SUCCESS;
256                 break;
257             }
258 
259             /* Increment the counter.  */
260             i++;
261 
262             /* Move to next event flags group.  */
263             events_ptr =  events_ptr -> tx_event_flags_group_created_next;
264         }
265         break;
266     }
267 
268     /* Determine if a semaphore object is requested.  */
269     case TXM_SEMAPHORE_OBJECT:
270     {
271 
272         /* Loop to find the first matching semaphore.  */
273         i = 0;
274         semaphore_ptr =  _tx_semaphore_created_ptr;
275         while (i < _tx_semaphore_created_count)
276         {
277 
278             /* Do we have a match?  */
279             if (_txm_module_manager_object_name_compare(search_name, search_name_length, semaphore_ptr -> tx_semaphore_name))
280             {
281 
282                 /* Yes, we found it - return the necessary info!  */
283                 *object_ptr =  (VOID *) semaphore_ptr;
284 
285                 /* Set the the status to success!  */
286                 status =  TX_SUCCESS;
287                 break;
288             }
289 
290             /* Increment the counter.  */
291             i++;
292 
293             /* Move to next semaphore.  */
294             semaphore_ptr =  semaphore_ptr -> tx_semaphore_created_next;
295         }
296         break;
297     }
298 
299     /* Determine if a mutex object is requested.  */
300     case TXM_MUTEX_OBJECT:
301     {
302 
303         /* Loop to find the first matching mutex.  */
304         i = 0;
305         mutex_ptr =  _tx_mutex_created_ptr;
306         while (i < _tx_mutex_created_count)
307         {
308 
309             /* Do we have a match?  */
310             if (_txm_module_manager_object_name_compare(search_name, search_name_length, mutex_ptr -> tx_mutex_name))
311             {
312 
313                 /* Yes, we found it - return the necessary info!  */
314                 *object_ptr =  (VOID *) mutex_ptr;
315 
316                 /* Set the the status to success!  */
317                 status =  TX_SUCCESS;
318                 break;
319             }
320 
321             /* Increment the counter.  */
322             i++;
323 
324             /* Move to next mutex.  */
325             mutex_ptr =  mutex_ptr -> tx_mutex_created_next;
326         }
327         break;
328     }
329 
330     /* Determine if a block pool object is requested.  */
331     case TXM_BLOCK_POOL_OBJECT:
332     {
333 
334         /* Get the module instance.  */
335         module_instance =  _tx_thread_current_ptr -> tx_thread_module_instance_ptr;
336 
337         /* Is a module making this request?  */
338         if (module_instance != TX_NULL)
339         {
340 
341             /* Is memory protection enabled?  */
342             if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION)
343             {
344 
345                 /* Modules with memory protection can only access block pools they created.  */
346                 status =  TXM_MODULE_INVALID;
347                 break;
348             }
349         }
350 
351         /* Loop to find the first matching block pool.  */
352         i = 0;
353         block_pool_ptr =  _tx_block_pool_created_ptr;
354         while (i < _tx_block_pool_created_count)
355         {
356 
357             /* Do we have a match?  */
358             if (_txm_module_manager_object_name_compare(search_name, search_name_length, block_pool_ptr -> tx_block_pool_name))
359             {
360 
361                 /* Yes, we found it - return the necessary info!  */
362                 *object_ptr =  (VOID *) block_pool_ptr;
363 
364                 /* Set the the status to success!  */
365                 status =  TX_SUCCESS;
366                 break;
367             }
368 
369             /* Increment the counter.  */
370             i++;
371 
372             /* Move to next block pool.  */
373             block_pool_ptr =  block_pool_ptr -> tx_block_pool_created_next;
374         }
375         break;
376     }
377 
378     /* Determine if a byte pool object is requested.  */
379     case TXM_BYTE_POOL_OBJECT:
380     {
381 
382         /* Get the module instance.  */
383         module_instance =  _tx_thread_current_ptr -> tx_thread_module_instance_ptr;
384 
385         /* Is a module making this request?  */
386         if (module_instance != TX_NULL)
387         {
388 
389             /* Is memory protection enabled?  */
390             if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION)
391             {
392 
393                 /* Modules with memory protection can only access block pools they created.  */
394                 status =  TXM_MODULE_INVALID;
395                 break;
396             }
397         }
398 
399         /* Loop to find the first matching byte pool.  */
400         i = 0;
401         byte_pool_ptr =  _tx_byte_pool_created_ptr;
402         while (i < _tx_byte_pool_created_count)
403         {
404 
405             /* Do we have a match?  */
406             if (_txm_module_manager_object_name_compare(search_name, search_name_length, byte_pool_ptr -> tx_byte_pool_name))
407             {
408 
409                 /* Yes, we found it - return the necessary info!  */
410                 *object_ptr =  (VOID *) byte_pool_ptr;
411 
412                 /* Set the the status to success!  */
413                 status =  TX_SUCCESS;
414                 break;
415             }
416 
417             /* Increment the counter.  */
418             i++;
419 
420             /* Move to next byte pool.  */
421             byte_pool_ptr =  byte_pool_ptr -> tx_byte_pool_created_next;
422         }
423         break;
424     }
425 
426     default:
427 
428         /* Invalid object ID.  */
429         status =  TX_OPTION_ERROR;
430 
431         /* External Object pointer get.  */
432 
433 #ifdef TXM_MODULE_ENABLE_NETX
434 
435         /* Determine if there is a NetX object get request.  */
436         if ((object_type >= TXM_NETX_OBJECTS_START) && (object_type < TXM_NETX_OBJECTS_END))
437         {
438 
439             /* Call the NetX module object get function.  */
440             status =  _txm_module_manager_netx_object_pointer_get(object_type, search_name, search_name_length, object_ptr);
441         }
442 #endif
443 
444 #ifdef TXM_MODULE_ENABLE_NETXDUO
445 
446         /* Determine if there is a NetX Duo object get request.  */
447         if ((object_type >= TXM_NETXDUO_OBJECTS_START) && (object_type < TXM_NETXDUO_OBJECTS_END))
448         {
449 
450             /* Call the NetX Duo module object get function.  */
451             status =  _txm_module_manager_netxduo_object_pointer_get(object_type, search_name, search_name_length, object_ptr);
452         }
453 #endif
454 
455 #ifdef TXM_MODULE_ENABLE_FILEX
456 
457         /* Determine if there is a FileX object get request.  */
458         if ((object_type >= TXM_FILEX_OBJECTS_START) && (object_type < TXM_FILEX_OBJECTS_END))
459         {
460 
461             /* Call the FileX module object get function.  */
462             status =  _txm_module_manager_filex_object_pointer_get(object_type, search_name, search_name_length, object_ptr);
463         }
464 #endif
465 
466 
467 #ifdef TXM_MODULE_ENABLE_GUIX
468 
469         /* Determine if there is a GUIX object get request.  */
470         if ((object_type >= TXM_GUIX_OBJECTS_START) && (object_type < TXM_GUIX_OBJECTS_END))
471         {
472 
473             /* Call the GUIX module object get function.  */
474             status =  _txm_module_manager_guix_object_pointer_get(object_type, search_name, search_name_length, object_ptr);
475         }
476 #endif
477 
478 #ifdef TXM_MODULE_ENABLE_USBX
479 
480         /* Determine if there is a USBX object get request.  */
481         if ((object_type >= TXM_USBX_OBJECTS_START) && (object_type < TXM_USBX_OBJECTS_END))
482         {
483 
484             /* Call the USBX object get function.  */
485             status =  _txm_module_manager_usbx_object_pointer_get(object_type, search_name, search_name_length, object_ptr);
486         }
487 #endif
488 
489         break;
490     }
491 
492     /* Disable interrupts.  */
493     TX_DISABLE
494 
495     /* Enable preemption again.  */
496     _tx_thread_preempt_disable--;
497 
498     /* Restore interrupts.  */
499     TX_RESTORE
500 
501     /* Check for preemption.  */
502     _tx_thread_system_preempt_check();
503 
504     /* Return success.  */
505     return(status);
506 }
507