FreeCalypso > hg > freecalypso-citrine
comparison gpf/frame/vsi_trc.c @ 0:75a11d740a02
initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 09 Jun 2016 00:02:41 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:75a11d740a02 |
---|---|
1 /* | |
2 +------------------------------------------------------------------------------ | |
3 | File: vsi_trc.c | |
4 +------------------------------------------------------------------------------ | |
5 | Copyright 2002 Texas Instruments Berlin, AG | |
6 | All rights reserved. | |
7 | | |
8 | This file is confidential and a trade secret of Texas | |
9 | Instruments Berlin, AG | |
10 | The receipt of or possession of this file does not convey | |
11 | any rights to reproduce or disclose its contents or to | |
12 | manufacture, use, or sell anything it may describe, in | |
13 | whole, or in part, without the specific written consent of | |
14 | Texas Instruments Berlin, AG. | |
15 +----------------------------------------------------------------------------- | |
16 | Purpose : This Module defines the virtual system interface part | |
17 | for the tracing functionality. | |
18 +----------------------------------------------------------------------------- | |
19 */ | |
20 | |
21 #ifndef __VSI_TRC_C__ | |
22 #define __VSI_TRC_C__ | |
23 #endif | |
24 | |
25 #undef TEST_EXT_TRACE | |
26 | |
27 /*==== LINT =======================================================*/ | |
28 | |
29 /*lint -emacro(506,va_start) Constant value Boolean */ | |
30 /*lint -emacro(506,va_arg) Constant value Boolean */ | |
31 /*lint -emacro(718,va_start) Symbol 'Symbol' undeclared, assumed to return int */ | |
32 /*lint -emacro(522,va_arg) Warning -- Expected void type, assignment, increment or decrement */ | |
33 /*lint -emacro(10,va_arg) Error -- Expecting '(' */ | |
34 /*lint -emacro(516,va_arg) Warning -- 'Symbol _va_argref()' has arg. type conflict (arg. no. 1 -- basic) */ | |
35 /*lint -e661 */ | |
36 /*lint -e662 */ | |
37 | |
38 /*==== INCLUDES ===================================================*/ | |
39 | |
40 #ifndef _VXWORKS_ | |
41 #include <stdarg.h> | |
42 #endif | |
43 #include <stdio.h> | |
44 #include <string.h> | |
45 | |
46 #include "gpfconf.h" | |
47 #include "typedefs.h" | |
48 | |
49 #include "vsi.h" | |
50 #include "os.h" | |
51 #include "tools.h" | |
52 #include "frame.h" | |
53 #include "frm_defs.h" | |
54 #include "frm_types.h" | |
55 #include "frm_glob.h" | |
56 #include "p_frame.h" | |
57 #ifndef _TOOLS_ | |
58 #include "../tst_pei/tstdriver.h" | |
59 #endif | |
60 | |
61 /*==== TYPES ======================================================*/ | |
62 | |
63 typedef struct | |
64 { | |
65 unsigned int magic_nr; | |
66 void (*trace_error)(const char * const format, va_list varpars); | |
67 void (*trace_assert)(const char * const format, va_list varpars); | |
68 } T_EXT_TRACE; | |
69 | |
70 /*==== CONSTANTS ==================================================*/ | |
71 | |
72 #define EXT_TRACE_INITIALIZED 0xaffedead | |
73 | |
74 /*==== EXTERNALS ==================================================*/ | |
75 | |
76 /* -------------- S H A R E D - BEGIN ---------------- */ | |
77 #ifdef _TOOLS_ | |
78 #pragma data_seg("FRAME_SHARED") | |
79 #endif | |
80 | |
81 /* | |
82 * contains the correspnding flags for each task | |
83 */ | |
84 extern T_HANDLE TestGroupHandle; | |
85 extern UBYTE FrameEnv; | |
86 extern char TaskName[]; | |
87 extern char FRM_TST_NAME[]; | |
88 | |
89 #ifdef _TOOLS_ | |
90 extern char FRM_SYST_NAME[]; | |
91 #else | |
92 extern OS_HANDLE TST_Handle; | |
93 extern OS_HANDLE RCV_Handle; | |
94 extern int time_is_tdma_frame; | |
95 extern char error_ind_dst[]; | |
96 extern T_FRM_ERROR_IND *frm_error_ind; | |
97 #endif | |
98 | |
99 /*==== VARIABLES ==================================================*/ | |
100 | |
101 /* | |
102 this file may be compiled twice for FLASH and RAM, make sure we | |
103 get the variable declarations exactly once | |
104 */ | |
105 | |
106 #ifndef RUN_INT_RAM | |
107 /* must be seen only from FLASH */ | |
108 GLOBAL char TraceBuffer [ TRACE_TEXT_SIZE ]={0}; | |
109 | |
110 /* must be seen from RAM and FLASH */ | |
111 GLOBAL OS_HANDLE trc_hCommTrace=VSI_ERROR; | |
112 GLOBAL BOOL trc_LittleEndian = FALSE; | |
113 /* used by the entities */ | |
114 GLOBAL char EntityNameBuf[RESOURCE_NAMELEN]; | |
115 GLOBAL USHORT emergeny_trace; | |
116 #else | |
117 /* must be seen from RAM and FLASH */ | |
118 extern OS_HANDLE trc_hCommTrace; | |
119 extern BOOL trc_LittleEndian; | |
120 extern USHORT emergeny_trace; | |
121 #endif | |
122 | |
123 #ifndef RUN_INT_RAM | |
124 T_EXT_TRACE ext_trace_func; | |
125 #else | |
126 extern T_EXT_TRACE ext_trace_func; | |
127 #endif | |
128 | |
129 #ifdef TEST_EXT_TRACE | |
130 | |
131 void trace_error ( const char * const format, va_list varpars ); | |
132 void trace_assert ( const char * const format, va_list varpars ); | |
133 | |
134 #ifndef RUN_INT_RAM | |
135 T_EXT_TRACE_FUNC ext_trace_functions = | |
136 { | |
137 trace_error, | |
138 trace_assert | |
139 }; | |
140 #else | |
141 extern T_EXT_TRACE_FUNC ext_trace_functions; | |
142 #endif | |
143 | |
144 #endif /* TEST_EXT_TRACE */ | |
145 | |
146 /*==== VARIABLES ==================================================*/ | |
147 | |
148 #ifdef _TOOLS_ | |
149 #pragma data_seg() | |
150 #endif | |
151 /* -------------- S H A R E D - END ---------------- */ | |
152 | |
153 /*==== PROTOTYPES ==================================================*/ | |
154 | |
155 void ext_trace_init ( void ); | |
156 int int_vsi_o_ttrace ( T_HANDLE Caller, ULONG TraceClass, const char * const format, va_list varpars ); | |
157 int int_vsi_o_itrace ( T_HANDLE Caller, ULONG TraceClass, ULONG index, const char * const format, va_list varpars ); | |
158 int vsi_o_datasend ( T_HANDLE caller, T_HANDLE dst, char *ext_dst, T_PRIM_HEADER *prim FILE_LINE_TYPE ); | |
159 U32 int_vsi_tc2trace_opc(ULONG trace_class); | |
160 | |
161 #ifdef _TARGET_ | |
162 SHORT tst_pei_primitive (void *primitive); | |
163 #endif | |
164 | |
165 /*==== FUNCTIONS ==================================================*/ | |
166 | |
167 #ifndef RUN_FLASH | |
168 U32 int_vsi_tc2trace_opc(ULONG trace_class) | |
169 { | |
170 switch (trace_class) | |
171 { | |
172 case TC_FUNC: | |
173 return FUNC_TRACE_OPC; | |
174 case TC_EVENT: | |
175 return EVENT_TRACE_OPC; | |
176 case TC_PRIM: | |
177 return PRIM_TRACE_OPC; | |
178 case TC_STATE: | |
179 return STATE_TRACE_OPC; | |
180 case TC_SYSTEM: | |
181 return SYSTEM_TRACE_OPC; | |
182 case TC_ISIG: | |
183 return ISIG_TRACE_OPC; | |
184 case TC_ERROR: | |
185 return ERROR_TRACE_OPC; | |
186 case TC_CCD: | |
187 return CCD_TRACE_OPC; | |
188 case TC_TIMER: | |
189 return TIMER_TRACE_OPC; | |
190 case TC_PROFILER: | |
191 return PROFILER_TRACE_OPC; | |
192 | |
193 case TC_USER1: | |
194 return USER1_TRACE_OPC; | |
195 case TC_USER2: | |
196 return USER2_TRACE_OPC; | |
197 case TC_USER3: | |
198 return USER3_TRACE_OPC; | |
199 case TC_USER4: | |
200 return USER4_TRACE_OPC; | |
201 case TC_USER5: | |
202 return USER5_TRACE_OPC; | |
203 case TC_USER6: | |
204 return USER6_TRACE_OPC; | |
205 case TC_USER7: | |
206 return USER7_TRACE_OPC; | |
207 case TC_USER8: | |
208 return USER8_TRACE_OPC; | |
209 | |
210 default: | |
211 return TRACE_OPC; | |
212 } | |
213 } | |
214 #endif /* RUN_FLASH */ | |
215 | |
216 #ifdef _TOOLS_ | |
217 /* | |
218 +------------------------------------------------------------------------------ | |
219 | Function : vsi_o_set_htrace | |
220 +------------------------------------------------------------------------------ | |
221 | Description : This function sets the module variable trc_hCommTrace | |
222 | | |
223 | Parameters : comhandle - the new value | |
224 | | |
225 | Return : none | |
226 +------------------------------------------------------------------------------ | |
227 */ | |
228 void vsi_o_set_htrace (T_HANDLE comhandle) | |
229 { | |
230 trc_hCommTrace = (OS_HANDLE) comhandle; | |
231 } | |
232 #endif /* _TOOLS_ */ | |
233 | |
234 #ifndef RUN_FLASH | |
235 /* | |
236 +--------------------------------------------------------------------+ | |
237 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
238 | STATE : code ROUTINE : vsi_o_trace | | |
239 +--------------------------------------------------------------------+ | |
240 | |
241 PURPOSE : traces a dynamic string | |
242 | |
243 */ | |
244 LOCAL int vsi_o_trace ( T_HANDLE Caller, T_PRIM_HEADER *prim, ULONG suspend ) | |
245 { | |
246 T_S_HEADER *s_hdr; | |
247 LONG Status; | |
248 OS_QDATA QMsg; | |
249 BOOL AlarmTrace = FALSE; | |
250 | |
251 s_hdr = (T_S_HEADER*)((ULONG*)prim + prim->sh_offset); | |
252 if ( TracesAborted[Caller] ) | |
253 { | |
254 #ifdef _TOOLS_ | |
255 /* | |
256 * Only needed for _TOOLS_ because Nucleus provides at least 52 Bytes in the partition | |
257 */ | |
258 os_DeallocatePartition ( Caller, (T_VOID_STRUCT*)prim ); | |
259 Status = os_AllocatePartition ( Caller, (T_VOID_STRUCT**)&prim, 80, suspend, TestGroupHandle ); | |
260 #endif | |
261 sprintf ((char*)P2D(prim),"Trc Abort: %d !",TracesAborted[Caller]+1 ); | |
262 prim->len = strlen ((char*)P2D(prim)) + sizeof(T_PRIM_HEADER); | |
263 prim->sh_offset = S_HDR_OFFSET(prim->len); | |
264 s_hdr = (T_S_HEADER*)((ULONG*)prim + prim->sh_offset); | |
265 AlarmTrace = TRUE; | |
266 } | |
267 | |
268 s_hdr->snd[0] = (char)Caller; | |
269 if ( Caller ) | |
270 s_hdr->snd[0] |= (char)HANDLE_BIT; | |
271 | |
272 s_hdr->org_rcv[0] = 0; | |
273 | |
274 #ifdef _TOOLS_ | |
275 get_local_time (&s_hdr->time); | |
276 #else | |
277 if ( time_is_tdma_frame == 1 ) | |
278 { | |
279 os_GetTime(Caller,&s_hdr->time); | |
280 s_hdr->time |= TIME_IS_TDMA; | |
281 } | |
282 else | |
283 { | |
284 os_GetTime(Caller,&s_hdr->time); | |
285 s_hdr->time &= ~TIME_IS_TDMA; | |
286 } | |
287 #endif | |
288 | |
289 QMsg.flags = 0; | |
290 QMsg.data16 = MSG_PRIMITIVE; | |
291 QMsg.data32 = 0; | |
292 QMsg.ptr = (T_VOID_STRUCT*)prim; | |
293 #ifdef _TOOLS_ | |
294 QMsg.len = ALIGN(prim->len) + sizeof(T_S_HEADER); | |
295 #endif | |
296 os_GetTime ( 0, &QMsg.time ); | |
297 | |
298 #ifndef _TOOLS_ | |
299 if ( trc_hCommTrace == VSI_ERROR ) | |
300 if ( (trc_hCommTrace = vsi_c_open ( TST_Handle, FRM_TST_NAME ) ) == OS_ERROR ) | |
301 { | |
302 os_DeallocatePartition ( Caller, (T_VOID_STRUCT*)prim ); | |
303 return VSI_ERROR; | |
304 } | |
305 #else | |
306 if ( trc_hCommTrace == VSI_ERROR ) | |
307 { | |
308 if ( FrameEnv == ENV_TOOLS ) | |
309 { | |
310 os_DeallocatePartition ( Caller, (T_VOID_STRUCT*)prim ); | |
311 return VSI_ERROR; | |
312 } | |
313 else | |
314 { | |
315 if ( os_OpenQueue ( NO_TASK, FRM_TST_NAME, &trc_hCommTrace ) == OS_ERROR ) | |
316 { | |
317 os_DeallocatePartition ( Caller, (T_VOID_STRUCT*)prim ); | |
318 return VSI_ERROR; | |
319 } | |
320 } | |
321 } | |
322 if ( FrameEnv == ENV_TOOLS ) | |
323 { | |
324 s_hdr->snd[0] = '~'; | |
325 if ( os_GetTaskName ( Caller, Caller, &s_hdr->snd[1] ) == OS_ERROR ) | |
326 { | |
327 char Sender[RESOURCE_NAMELEN]; | |
328 char *ptr = (char*)P2D(prim); | |
329 unsigned int NameLen; | |
330 | |
331 if ( *ptr == '~') | |
332 { | |
333 NameLen = GetNextToken ((char*)(ptr), Sender,"~"); | |
334 InsertString(Sender, &s_hdr->snd[1], 4); | |
335 prim->len -= 2+NameLen; | |
336 memcpy ( ptr, ptr+2+NameLen, prim->len-sizeof(T_PRIM_HEADER) ); | |
337 QMsg.len = ALIGN(prim->len) + sizeof(T_S_HEADER); | |
338 } | |
339 else | |
340 InsertString(FRM_SYST_NAME, &s_hdr->snd[1], 4); | |
341 } | |
342 } | |
343 #endif /* _TOOLS_ */ | |
344 | |
345 QMsg.e_id = trc_hCommTrace; | |
346 | |
347 #ifndef _TOOLS_ | |
348 if ( Caller == TST_Handle || Caller == RCV_Handle ) | |
349 { | |
350 tst_drv_write ( Caller, 0, NULL, (char*)P2D(prim) ); | |
351 os_DeallocatePartition ( Caller, (T_VOID_STRUCT*)prim ); | |
352 return VSI_OK; | |
353 } | |
354 #ifndef _TARGET_ | |
355 else | |
356 /* | |
357 * for the PC Simulation SuspendTrace[0] is != 0. To avoid that the system traces | |
358 * sent with caller NO_TASK block the system if the caller was TST, the Caller | |
359 * is set to the real caller here. This has no consequence on the caller name | |
360 * displayed in PCO because this is already formated into the header. | |
361 */ | |
362 { | |
363 if ( Caller == NO_TASK ) | |
364 { | |
365 Caller = e_running[os_MyHandle()]; | |
366 } | |
367 } | |
368 #endif | |
369 #endif | |
370 | |
371 QMsg.e_id = trc_hCommTrace; | |
372 #ifdef _TOOLS_ | |
373 Status = os_SendToQueue ( NO_TASK, trc_hCommTrace, MSG_TRACE_PRIO, suspend, &QMsg ); | |
374 #else | |
375 Status = os_SendToQueue ( NO_TASK, pf_TaskTable[trc_hCommTrace].QueueHandle, MSG_TRACE_PRIO, suspend, &QMsg ); | |
376 #endif | |
377 if ( Status == OS_OK || Status == OS_WAITED ) | |
378 { | |
379 TracesAborted[Caller] = 0; | |
380 if ( AlarmTrace ) | |
381 return VSI_ERROR; | |
382 else | |
383 return VSI_OK; | |
384 } | |
385 else | |
386 { | |
387 /* | |
388 * No queue space available -> free partition | |
389 */ | |
390 os_DeallocatePartition ( Caller, (T_VOID_STRUCT*)prim ); | |
391 TracesAborted[Caller]++; | |
392 } | |
393 return VSI_ERROR; | |
394 } | |
395 #endif | |
396 | |
397 #ifndef RUN_FLASH | |
398 /* | |
399 +--------------------------------------------------------------------+ | |
400 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM | | |
401 | STATE : code ROUTINE : vsi_o_primsend | | |
402 +--------------------------------------------------------------------+ | |
403 | |
404 PURPOSE : traces a data segment as a primitive | |
405 | |
406 */ | |
407 int vsi_o_primsend ( T_HANDLE caller, unsigned int mask, T_HANDLE dst, char *ext_dst, unsigned int opc, void *ptr, unsigned int len FILE_LINE_TYPE ) | |
408 { | |
409 int alloc_size; | |
410 T_PRIM_HEADER *prim; | |
411 T_HANDLE e_handle; | |
412 | |
413 if ( caller != 0 ) | |
414 e_handle = caller; | |
415 else | |
416 e_handle = e_running[os_MyHandle()]; | |
417 | |
418 if ( (e_handle >= 0) && (TraceMask[e_handle] & mask) ) | |
419 { | |
420 if ( opc != 0 ) | |
421 { | |
422 alloc_size = len + sizeof(T_PRIM_HEADER); | |
423 if ( alloc_size < (int)MaxPrimPartSize ) | |
424 { | |
425 prim = (T_PRIM_HEADER*)vsi_c_new ( 0, alloc_size, opc FILE_LINE ); | |
426 memcpy((char*)P2D(prim), ptr, len); | |
427 /* if primitive is FRM_WARNING_IND -> free */ | |
428 if ( opc == FRM_WARNING_IND ) | |
429 { | |
430 PFREE(ptr); | |
431 } | |
432 } | |
433 else | |
434 { | |
435 vsi_o_ttrace ( caller, TC_SYSTEM, "SYSTEM WARNING: Binary trace too long -> discarded in %s(%d)" FILE_LINE ); | |
436 return VSI_ERROR; | |
437 } | |
438 } | |
439 else | |
440 { | |
441 prim = D2P(ptr); | |
442 } | |
443 if ( vsi_o_datasend ( e_handle, dst, ext_dst, prim FILE_LINE ) == VSI_ERROR ) | |
444 { | |
445 vsi_c_free ( 0, (T_VOID_STRUCT**)&prim FILE_LINE ); | |
446 } | |
447 } | |
448 return VSI_OK; | |
449 } | |
450 #endif | |
451 | |
452 #ifndef RUN_FLASH | |
453 /* | |
454 +--------------------------------------------------------------------+ | |
455 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM | | |
456 | STATE : code ROUTINE : vsi_o_sdusend | | |
457 +--------------------------------------------------------------------+ | |
458 | |
459 PURPOSE : traces an SDU as a primitive | |
460 | |
461 */ | |
462 int vsi_o_sdusend ( T_HANDLE caller, T_HANDLE dst, char *ext_dst, int opc, char ent, char dir, char type, void *ptr, unsigned int len FILE_LINE_TYPE ) | |
463 { | |
464 T_PRIM_HEADER *prim; | |
465 T_HANDLE e_handle; | |
466 int alloc_size; | |
467 | |
468 if ( caller != 0 ) | |
469 e_handle = caller; | |
470 else | |
471 e_handle = e_running[os_MyHandle()]; | |
472 | |
473 if ( (e_handle >= 0) && (TraceMask[e_handle] & TC_SDU) ) | |
474 { | |
475 if ( opc != 0 ) | |
476 { | |
477 alloc_size = len + sizeof(T_PRIM_HEADER) + sizeof(T_SDU_TRACE); | |
478 if ( alloc_size < (int)MaxPrimPartSize ) | |
479 { | |
480 prim = (T_PRIM_HEADER*)vsi_c_new ( 0, alloc_size, opc FILE_LINE ); | |
481 ((T_SDU_TRACE*)(P2D(prim)))->entity = ent; | |
482 ((T_SDU_TRACE*)(P2D(prim)))->dir = dir; | |
483 ((T_SDU_TRACE*)(P2D(prim)))->type = type; | |
484 ((T_SDU_TRACE*)(P2D(prim)))->align1 = 0; | |
485 memcpy(((char*)P2D(prim))+sizeof(T_SDU_TRACE), ptr, len); | |
486 if ( vsi_o_datasend ( e_handle, dst, ext_dst, prim FILE_LINE ) == VSI_ERROR ) | |
487 { | |
488 vsi_c_free ( 0, (T_VOID_STRUCT**)&prim FILE_LINE ); | |
489 } | |
490 } | |
491 else | |
492 { | |
493 vsi_o_ttrace ( caller, TC_SYSTEM, "SYSTEM WARNING: Binary trace too long -> discarded in %s(%d)" FILE_LINE ); | |
494 } | |
495 } | |
496 } | |
497 return VSI_OK; | |
498 } | |
499 #endif | |
500 | |
501 #ifndef RUN_FLASH | |
502 /* | |
503 +--------------------------------------------------------------------+ | |
504 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM | | |
505 | STATE : code ROUTINE : vsi_o_datasend | | |
506 +--------------------------------------------------------------------+ | |
507 | |
508 PURPOSE : traces an already allocated primitive | |
509 | |
510 */ | |
511 int vsi_o_datasend ( T_HANDLE caller, T_HANDLE dst, char *ext_dst, T_PRIM_HEADER *prim FILE_LINE_TYPE ) | |
512 { | |
513 int alloc_size; | |
514 T_PRIM_HEADER *carrier; | |
515 T_S_HEADER *s_hdr; | |
516 LONG status; | |
517 OS_QDATA DMsg; | |
518 unsigned int i; | |
519 ULONG suspend; | |
520 | |
521 suspend = get_suspend_state(caller,CHECK_TRC_SUSPEND); | |
522 | |
523 /* allocate carrier */ | |
524 alloc_size = S_ALLOC_SIZE(4 + 1); | |
525 status = os_AllocatePartition ( caller, (T_VOID_STRUCT**)&carrier, alloc_size, suspend, TestGroupHandle ); | |
526 if ( status == OS_OK || status == OS_WAITED || status == OS_ALLOCATED_BIGGER ) | |
527 { | |
528 DMsg.data16 = MSG_PRIMITIVE; | |
529 DMsg.data32 = prim->opc; | |
530 #ifdef _TOOLS_ | |
531 DMsg.len = alloc_size; | |
532 #endif | |
533 DMsg.ptr = (T_VOID_STRUCT*)carrier; | |
534 | |
535 carrier->opc = prim->opc; | |
536 carrier->len = alloc_size; | |
537 carrier->sh_offset = S_HDR_OFFSET(alloc_size - sizeof(T_S_HEADER)); | |
538 s_hdr = (T_S_HEADER*)((ULONG*)carrier + carrier->sh_offset); | |
539 if ( dst != 0 ) | |
540 { | |
541 if ( vsi_e_name ( caller, dst, TaskName ) == VSI_OK ) | |
542 { | |
543 /* set org_rcv */ | |
544 for (i = 0; TaskName[i] && i < sizeof (s_hdr->rcv); i++) | |
545 s_hdr->org_rcv[i] = TaskName[i]; | |
546 if (i < sizeof s_hdr->rcv) | |
547 s_hdr->org_rcv[i] = 0; | |
548 } | |
549 else | |
550 { | |
551 s_hdr->org_rcv[0] = 0; | |
552 } | |
553 } | |
554 else | |
555 { | |
556 s_hdr->org_rcv[0] = 0; | |
557 } | |
558 strncpy (s_hdr->rcv, ext_dst, RESOURCE_NAMELEN); | |
559 s_hdr->rcv[RESOURCE_NAMELEN-1] = 0; | |
560 if ( caller != 0 ) | |
561 { | |
562 if ( vsi_e_name ( caller, caller, TaskName ) == VSI_OK ) | |
563 { | |
564 /* set snd */ | |
565 for (i = 0; TaskName[i] && i < sizeof (s_hdr->snd); i++) | |
566 s_hdr->snd[i] = TaskName[i]; | |
567 if (i < sizeof s_hdr->snd) | |
568 s_hdr->snd[i] = 0; | |
569 } | |
570 } | |
571 else | |
572 { | |
573 if ( pf_TaskTable[caller].Name[0] != 0 ) | |
574 { | |
575 s_hdr->snd[0] = (char)(caller | HANDLE_BIT); | |
576 } | |
577 else | |
578 { | |
579 s_hdr->rcv[0] = 0; | |
580 } | |
581 } | |
582 os_GetTime(0,&s_hdr->time); | |
583 | |
584 ((T_PRIM_X*)(carrier))->prim_ptr = prim; | |
585 DMsg.e_id = trc_hCommTrace; | |
586 } | |
587 else | |
588 { | |
589 TracesAborted[caller]++; | |
590 return VSI_ERROR; | |
591 } | |
592 | |
593 #ifdef MEMORY_SUPERVISION | |
594 vsi_ppm_send ( caller, pf_TaskTable[trc_hCommTrace].QueueHandle, prim FILE_LINE_MACRO ); | |
595 #endif /* MEMORY_SUPERVISION */ | |
596 if ( os_SendToQueue ( caller, pf_TaskTable[trc_hCommTrace].QueueHandle, OS_NORMAL, suspend, &DMsg ) == OS_TIMEOUT ) | |
597 { | |
598 os_DeallocatePartition ( caller, (T_VOID_STRUCT*)carrier ); | |
599 TracesAborted[caller]++; | |
600 return VSI_ERROR; | |
601 } | |
602 return VSI_OK; | |
603 } | |
604 #endif | |
605 | |
606 #ifndef RUN_FLASH | |
607 /* | |
608 +--------------------------------------------------------------------+ | |
609 | PROJECT : GSM-Frame (8415) MODULE : VSI_COM | | |
610 | STATE : code ROUTINE : vsi_o_memtrace | | |
611 +--------------------------------------------------------------------+ | |
612 | |
613 PURPOSE : check if PS already started | |
614 | |
615 */ | |
616 int vsi_o_memtrace ( T_HANDLE caller, void *ptr, unsigned int len ) | |
617 { | |
618 T_PRIM_HEADER *prim; | |
619 T_HANDLE e_handle; | |
620 LONG status; | |
621 unsigned int i; | |
622 ULONG suspend; | |
623 | |
624 if ( caller != 0 ) | |
625 e_handle = caller; | |
626 else | |
627 e_handle = e_running[os_MyHandle()]; | |
628 | |
629 if ( (e_handle >= 0) && (TraceMask[e_handle] & TC_DATA) ) | |
630 { | |
631 suspend = get_suspend_state(e_handle,CHECK_TRC_SUSPEND); | |
632 status = os_AllocatePartition ( e_handle, (T_VOID_STRUCT**)&prim, S_ALLOC_SIZE(len)*3, suspend, TestGroupHandle ); | |
633 if ( status == OS_OK || status == OS_WAITED || status == OS_ALLOCATED_BIGGER ) | |
634 { | |
635 unsigned char *dst_ptr = (unsigned char*)P2D(prim); | |
636 unsigned char *src_ptr = (unsigned char*)ptr; | |
637 for ( i = 0; i < len; i++, src_ptr++ ) | |
638 { | |
639 if (*src_ptr>>4 > 9) | |
640 *dst_ptr++ = (*src_ptr>>4) + ('A'-10); | |
641 else | |
642 *dst_ptr++ = (*src_ptr>>4) +'0'; | |
643 if ((*src_ptr&0xf) > 9) | |
644 *dst_ptr++ = (*src_ptr&0xf) + ('A'-10); | |
645 else | |
646 *dst_ptr++ = (*src_ptr&0xf) +'0'; | |
647 *dst_ptr++ = 0x20; | |
648 } | |
649 | |
650 prim->opc = int_vsi_tc2trace_opc(TC_DATA); | |
651 prim->len = 3*len + sizeof(T_PRIM_HEADER); | |
652 prim->sh_offset = S_HDR_OFFSET(prim->len); | |
653 | |
654 return ( vsi_o_trace ( e_handle, prim, suspend ) ); | |
655 } | |
656 TracesAborted[e_handle]++; | |
657 return VSI_ERROR; | |
658 | |
659 } | |
660 return VSI_OK; | |
661 } | |
662 #endif | |
663 | |
664 #ifndef RUN_FLASH | |
665 /* | |
666 +--------------------------------------------------------------------+ | |
667 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
668 | STATE : code ROUTINE : vsi_o_func_ttrace | | |
669 +--------------------------------------------------------------------+ | |
670 | |
671 PURPOSE : traces a function name | |
672 | |
673 */ | |
674 int vsi_o_func_ttrace ( const char * const format, ... ) | |
675 { | |
676 va_list varpars; | |
677 T_HANDLE Caller; | |
678 | |
679 Caller = e_running[os_MyHandle()]; | |
680 | |
681 if ( (Caller >= 0) && (TraceMask[Caller] & TC_FUNC) ) | |
682 { | |
683 va_start (varpars, format); | |
684 return int_vsi_o_ttrace ( Caller, TC_FUNC, format, varpars ); | |
685 } | |
686 return VSI_ERROR; | |
687 } | |
688 #endif | |
689 | |
690 #ifndef RUN_FLASH | |
691 /* | |
692 +--------------------------------------------------------------------+ | |
693 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
694 | STATE : code ROUTINE : vsi_o_event_ttrace | | |
695 +--------------------------------------------------------------------+ | |
696 | |
697 PURPOSE : traces an event | |
698 | |
699 */ | |
700 int vsi_o_event_ttrace ( const char * const format, ... ) | |
701 { | |
702 va_list varpars; | |
703 T_HANDLE Caller; | |
704 | |
705 Caller = e_running[os_MyHandle()]; | |
706 | |
707 if ( (Caller >= 0) && (TraceMask[Caller] & TC_EVENT) ) | |
708 { | |
709 va_start (varpars, format); | |
710 return int_vsi_o_ttrace ( Caller, TC_EVENT, format, varpars ); | |
711 } | |
712 return VSI_ERROR; | |
713 } | |
714 #endif | |
715 | |
716 #ifndef RUN_FLASH | |
717 /* | |
718 +--------------------------------------------------------------------+ | |
719 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
720 | STATE : code ROUTINE : vsi_o_error_ttrace | | |
721 +--------------------------------------------------------------------+ | |
722 | |
723 PURPOSE : traces an error | |
724 | |
725 */ | |
726 int vsi_o_error_ttrace ( const char * const format, ... ) | |
727 { | |
728 va_list varpars; | |
729 T_HANDLE Caller; | |
730 | |
731 Caller = e_running[os_MyHandle()]; | |
732 | |
733 if ( (Caller >= 0) && (TraceMask[Caller] & TC_ERROR) ) | |
734 { | |
735 va_start (varpars, format); | |
736 int_vsi_o_ttrace ( Caller, TC_ERROR, format, varpars ); | |
737 vsi_o_ttrace ( NO_TASK, TC_ERROR, "TRACE ERROR in %s", pf_TaskTable[Caller].Name ); | |
738 if ( ext_trace_func.trace_error != NULL ) | |
739 { | |
740 ext_trace_func.trace_error ( format, varpars ); | |
741 } | |
742 return VSI_OK; | |
743 } | |
744 return VSI_ERROR; | |
745 } | |
746 #endif | |
747 | |
748 #ifndef RUN_FLASH | |
749 /* | |
750 +--------------------------------------------------------------------+ | |
751 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
752 | STATE : code ROUTINE : vsi_o_state_ttrace | | |
753 +--------------------------------------------------------------------+ | |
754 | |
755 PURPOSE : traces a dynamic string | |
756 | |
757 */ | |
758 int vsi_o_state_ttrace ( const char * const format, ... ) | |
759 { | |
760 va_list varpars; | |
761 T_HANDLE Caller; | |
762 | |
763 Caller = e_running[os_MyHandle()]; | |
764 | |
765 if ( (Caller >= 0) && (TraceMask[Caller] & TC_STATE) ) | |
766 { | |
767 va_start (varpars, format); | |
768 return int_vsi_o_ttrace ( Caller, TC_STATE, format, varpars ); | |
769 } | |
770 return VSI_ERROR; | |
771 } | |
772 #endif | |
773 | |
774 #ifndef RUN_FLASH | |
775 /* | |
776 +--------------------------------------------------------------------+ | |
777 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
778 | STATE : code ROUTINE : vsi_o_class_ttrace | | |
779 +--------------------------------------------------------------------+ | |
780 | |
781 PURPOSE : traces a dynamic string | |
782 | |
783 */ | |
784 int vsi_o_class_ttrace ( ULONG trace_class, const char * const format, ... ) | |
785 { | |
786 va_list varpars; | |
787 T_HANDLE Caller; | |
788 | |
789 Caller = e_running[os_MyHandle()]; | |
790 | |
791 if ( (Caller >= 0) && (TraceMask[Caller] & trace_class) ) | |
792 { | |
793 va_start (varpars, format); | |
794 return int_vsi_o_ttrace ( Caller, trace_class, format, varpars ); | |
795 } | |
796 return VSI_ERROR; | |
797 } | |
798 #endif | |
799 | |
800 #ifndef RUN_FLASH | |
801 /* | |
802 +--------------------------------------------------------------------+ | |
803 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
804 | STATE : code ROUTINE : vsi_o_ttrace | | |
805 +--------------------------------------------------------------------+ | |
806 | |
807 PURPOSE : traces a dynamic string | |
808 | |
809 */ | |
810 int vsi_o_ttrace ( T_HANDLE Caller, ULONG TraceClass, const char * const format, ... ) | |
811 { | |
812 va_list varpars; | |
813 | |
814 if ( (Caller >= 0) && (TraceMask[Caller] & TraceClass) ) | |
815 { | |
816 va_start (varpars, format); | |
817 return int_vsi_o_ttrace ( Caller, TraceClass, format, varpars ); | |
818 } | |
819 return VSI_ERROR; | |
820 } | |
821 #endif | |
822 | |
823 #ifndef RUN_FLASH | |
824 /* | |
825 +--------------------------------------------------------------------+ | |
826 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
827 | STATE : code ROUTINE : int_vsi_o_ttrace | | |
828 +--------------------------------------------------------------------+ | |
829 | |
830 PURPOSE : traces a dynamic string | |
831 | |
832 */ | |
833 int int_vsi_o_ttrace ( T_HANDLE Caller, ULONG TraceClass, const char * const format, va_list varpars ) | |
834 { | |
835 T_PRIM_HEADER *prim; | |
836 LONG Status; | |
837 ULONG suspend; | |
838 unsigned int offset = 0; | |
839 unsigned int num; | |
840 | |
841 suspend = get_suspend_state(Caller,CHECK_TRC_SUSPEND); | |
842 Status = os_AllocatePartition ( Caller, (T_VOID_STRUCT**)&prim, TextTracePartitionSize, suspend, TestGroupHandle ); | |
843 if ( Status == OS_OK || Status == OS_WAITED || Status == OS_ALLOCATED_BIGGER ) | |
844 { | |
845 #if 0 | |
846 /* be activated when PCO can handle this */ | |
847 if ( TraceClass == TC_ERROR ) | |
848 { | |
849 *((char*)(P2D(prim))) = '#'; | |
850 offset = 1; | |
851 } | |
852 #endif | |
853 #ifdef _TOOLS_ | |
854 int trc_length = TextTracePartitionSize - sizeof(T_S_HEADER) - sizeof(T_PRIM_HEADER) - 1; | |
855 trc_length &= ~0x03; | |
856 num = offset + (unsigned int)_vsnprintf ((char*)(P2D(prim)) + offset, trc_length, format, varpars) + 1; /* + 1 for terminating 0 */ | |
857 #else | |
858 num = offset + (unsigned int)vsprintf ((char*)(P2D(prim)) + offset, format, varpars) + 1; /* + 1 for terminating 0 */ | |
859 #endif | |
860 va_end (varpars); | |
861 if ( num + sizeof(T_S_HEADER) + sizeof(T_PRIM_HEADER) >= TextTracePartitionSize ) | |
862 { | |
863 sprintf ( (char*)(P2D(prim))+60, "... %s trace too long", pf_TaskTable[Caller].Name ); | |
864 vsi_o_assert ( NO_TASK, OS_SYST_ERR_STR_TOO_LONG, __FILE__, __LINE__,(char*)(P2D(prim))); | |
865 } | |
866 prim->opc = int_vsi_tc2trace_opc(TraceClass); | |
867 prim->len = strlen((char*)P2D(prim)) + sizeof(T_PRIM_HEADER); | |
868 prim->sh_offset = S_HDR_OFFSET(prim->len); | |
869 | |
870 return ( vsi_o_trace ( Caller, prim, suspend ) ); | |
871 } | |
872 if ( FrameEnv == ENV_STACK ) | |
873 { | |
874 TracesAborted[Caller]++; | |
875 } | |
876 return VSI_ERROR; | |
877 } | |
878 #endif | |
879 | |
880 #ifndef RUN_FLASH | |
881 /* | |
882 +--------------------------------------------------------------------+ | |
883 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
884 | STATE : code ROUTINE : vsi_o_func_itrace | | |
885 +--------------------------------------------------------------------+ | |
886 | |
887 PURPOSE : traces a function name | |
888 | |
889 */ | |
890 int vsi_o_func_itrace ( ULONG index, const char * const format, ... ) | |
891 { | |
892 va_list varpars; | |
893 T_HANDLE Caller; | |
894 | |
895 Caller = e_running[os_MyHandle()]; | |
896 | |
897 if ( (Caller >= 0) && (TraceMask[Caller] & TC_FUNC) ) | |
898 { | |
899 va_start (varpars, format); | |
900 return int_vsi_o_itrace ( Caller, TC_FUNC, index, format, varpars ); | |
901 } | |
902 return VSI_ERROR; | |
903 } | |
904 #endif | |
905 | |
906 #ifndef RUN_FLASH | |
907 /* | |
908 +--------------------------------------------------------------------+ | |
909 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
910 | STATE : code ROUTINE : vsi_o_event_itrace | | |
911 +--------------------------------------------------------------------+ | |
912 | |
913 PURPOSE : traces an event | |
914 | |
915 */ | |
916 int vsi_o_event_itrace ( ULONG index, const char * const format, ... ) | |
917 { | |
918 va_list varpars; | |
919 T_HANDLE Caller; | |
920 | |
921 Caller = e_running[os_MyHandle()]; | |
922 | |
923 if ( (Caller >= 0) && (TraceMask[Caller] & TC_EVENT) ) | |
924 { | |
925 va_start (varpars, format); | |
926 return int_vsi_o_itrace ( Caller, TC_EVENT, index, format, varpars ); | |
927 } | |
928 return VSI_ERROR; | |
929 } | |
930 #endif | |
931 | |
932 #ifndef RUN_FLASH | |
933 /* | |
934 +--------------------------------------------------------------------+ | |
935 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
936 | STATE : code ROUTINE : vsi_o_error_itrace | | |
937 +--------------------------------------------------------------------+ | |
938 | |
939 PURPOSE : traces an error | |
940 | |
941 */ | |
942 int vsi_o_error_itrace ( ULONG index, const char * const format, ... ) | |
943 { | |
944 va_list varpars; | |
945 T_HANDLE Caller; | |
946 | |
947 Caller = e_running[os_MyHandle()]; | |
948 | |
949 if ( (Caller >= 0) && (TraceMask[Caller] & TC_ERROR) ) | |
950 { | |
951 va_start (varpars, format); | |
952 int_vsi_o_itrace ( Caller, TC_ERROR, index, format, varpars ); | |
953 os_GetTaskName ( Caller, Caller, TaskName ); | |
954 vsi_o_ttrace ( NO_TASK, TC_ERROR, "TRACE ERROR in %s", pf_TaskTable[Caller].Name ); | |
955 return VSI_OK; | |
956 } | |
957 return VSI_ERROR; | |
958 } | |
959 #endif | |
960 | |
961 #ifndef RUN_FLASH | |
962 /* | |
963 +--------------------------------------------------------------------+ | |
964 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
965 | STATE : code ROUTINE : vsi_o_state_itrace | | |
966 +--------------------------------------------------------------------+ | |
967 | |
968 PURPOSE : traces a dynamic string | |
969 | |
970 */ | |
971 int vsi_o_state_itrace ( ULONG index, const char * const format, ... ) | |
972 { | |
973 va_list varpars; | |
974 T_HANDLE Caller; | |
975 | |
976 Caller = e_running[os_MyHandle()]; | |
977 | |
978 if ( (Caller >= 0) && (TraceMask[Caller] & TC_STATE) ) | |
979 { | |
980 va_start (varpars, format); | |
981 return int_vsi_o_itrace ( Caller, TC_STATE, index, format, varpars ); | |
982 } | |
983 return VSI_ERROR; | |
984 } | |
985 #endif | |
986 | |
987 #ifndef RUN_FLASH | |
988 /* | |
989 +--------------------------------------------------------------------+ | |
990 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
991 | STATE : code ROUTINE : vsi_o_class_itrace | | |
992 +--------------------------------------------------------------------+ | |
993 | |
994 PURPOSE : traces a dynamic string | |
995 | |
996 */ | |
997 int vsi_o_class_itrace ( ULONG trace_class, ULONG Index, const char * const format, ... ) | |
998 { | |
999 va_list varpars; | |
1000 T_HANDLE Caller; | |
1001 | |
1002 Caller = e_running[os_MyHandle()]; | |
1003 | |
1004 if ( (Caller >= 0) && (TraceMask[Caller] & trace_class) ) | |
1005 { | |
1006 va_start (varpars, format); | |
1007 return int_vsi_o_itrace ( Caller, trace_class, Index, format, varpars ); | |
1008 } | |
1009 return VSI_ERROR; | |
1010 } | |
1011 #endif | |
1012 | |
1013 #ifndef RUN_FLASH | |
1014 /* | |
1015 +--------------------------------------------------------------------+ | |
1016 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
1017 | STATE : code ROUTINE : vsi_o_ttrace | | |
1018 +--------------------------------------------------------------------+ | |
1019 | |
1020 PURPOSE : traces a dynamic string | |
1021 | |
1022 */ | |
1023 int vsi_o_itrace ( T_HANDLE Caller, ULONG TraceClass, ULONG Index, const char * const format, ... ) | |
1024 { | |
1025 va_list varpars; | |
1026 | |
1027 if ( (Caller >= 0) && (TraceMask[Caller] & TraceClass) ) | |
1028 { | |
1029 va_start (varpars, format); | |
1030 return int_vsi_o_itrace ( Caller, TraceClass, Index, format, varpars ); | |
1031 } | |
1032 return VSI_ERROR; | |
1033 } | |
1034 #endif | |
1035 | |
1036 #ifndef RUN_FLASH | |
1037 /* | |
1038 +--------------------------------------------------------------------+ | |
1039 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
1040 | STATE : code ROUTINE : int_vsi_o_itrace | | |
1041 +--------------------------------------------------------------------+ | |
1042 | |
1043 PURPOSE : traces a dynamic string | |
1044 | |
1045 */ | |
1046 int int_vsi_o_itrace ( T_HANDLE Caller, ULONG TraceClass, ULONG index, const char * const format, | |
1047 va_list varpars ) | |
1048 { | |
1049 T_PRIM_HEADER *prim; | |
1050 LONG Status; | |
1051 ULONG suspend; | |
1052 unsigned int offset = 0; | |
1053 unsigned int paramCount; | |
1054 unsigned int i; | |
1055 | |
1056 /* | |
1057 * the offset is calculated prior to the actual write operation | |
1058 * to avoid writing beyond the allocated size | |
1059 * | |
1060 * all write operation are addressed relatively to the precalculated | |
1061 * offset e.g. *(&Prim->Data + offset - 5) | |
1062 */ | |
1063 if ( (Caller >= 0) && (TraceMask[Caller] & TraceClass) ) | |
1064 { | |
1065 suspend = get_suspend_state(Caller,CHECK_TRC_SUSPEND); | |
1066 Status = os_AllocatePartition ( Caller, (T_VOID_STRUCT**)&prim, (ULONG)TextTracePartitionSize, suspend, TestGroupHandle ); | |
1067 if ( Status == OS_OK || Status == OS_WAITED || Status == OS_ALLOCATED_BIGGER ) | |
1068 { | |
1069 | |
1070 /* | |
1071 * the index preceded by % | |
1072 */ | |
1073 #if 0 | |
1074 /* be activated when PCO can handle this */ | |
1075 if ( TraceClass == TC_ERROR ) | |
1076 { | |
1077 *((char*)(P2D(prim))) = '#'; | |
1078 offset = 1; | |
1079 } | |
1080 #endif | |
1081 offset += 5; | |
1082 if(offset <= TextTracePartitionSize - sizeof(T_S_HEADER) - sizeof(T_PRIM_HEADER)) | |
1083 { | |
1084 *((char*)(P2D(prim)) + offset - 5) = '%'; | |
1085 if(trc_LittleEndian) | |
1086 { | |
1087 *((char*)(P2D(prim)) + offset - 4) = *((char *)&index); | |
1088 *((char*)(P2D(prim)) + offset - 3) = *(((char *)&index)+1); | |
1089 *((char*)(P2D(prim)) + offset - 2) = *(((char *)&index)+2); | |
1090 *((char*)(P2D(prim)) + offset - 1) = *(((char *)&index)+3); | |
1091 } | |
1092 else | |
1093 { | |
1094 *((char*)(P2D(prim)) + offset - 4) = *(((char *)&index)+3); | |
1095 *((char*)(P2D(prim)) + offset - 3) = *(((char *)&index)+2); | |
1096 *((char*)(P2D(prim)) + offset - 2) = *(((char *)&index)+1); | |
1097 *((char*)(P2D(prim)) + offset - 1) = *((char *)&index); | |
1098 } | |
1099 } | |
1100 /* | |
1101 * parse the format string | |
1102 */ | |
1103 paramCount = strlen(format); | |
1104 | |
1105 for (i=0; i<paramCount; i++) | |
1106 { | |
1107 switch(*(format+i)) | |
1108 { | |
1109 case 'c': /* one byte */ | |
1110 offset+=1; | |
1111 if(offset <= TextTracePartitionSize - sizeof(T_S_HEADER) - sizeof(T_PRIM_HEADER)) | |
1112 *((char*)(P2D(prim)) + offset - 1) = *((char *)varpars); | |
1113 | |
1114 va_arg(varpars, int); /* int, not char because of promotion */ | |
1115 break; | |
1116 case 'i': /* four bytes */ | |
1117 case 'p': | |
1118 case '*': | |
1119 offset+=4; | |
1120 if(offset <= TextTracePartitionSize - sizeof(T_S_HEADER) - sizeof(T_PRIM_HEADER)) | |
1121 { | |
1122 if(trc_LittleEndian) | |
1123 { | |
1124 *((char*)(P2D(prim)) + offset - 4) = *((char *)varpars); | |
1125 *((char*)(P2D(prim)) + offset - 3) = *(((char *)varpars)+1); | |
1126 *((char*)(P2D(prim)) + offset - 2) = *(((char *)varpars)+2); | |
1127 *((char*)(P2D(prim)) + offset - 1) = *(((char *)varpars)+3); | |
1128 } | |
1129 else | |
1130 { | |
1131 *((char*)(P2D(prim)) + offset - 4) = *(((char *)varpars)+3); | |
1132 *((char*)(P2D(prim)) + offset - 3) = *(((char *)varpars)+2); | |
1133 *((char*)(P2D(prim)) + offset - 2) = *(((char *)varpars)+1); | |
1134 *((char*)(P2D(prim)) + offset - 1) = *((char *)varpars); | |
1135 } | |
1136 } | |
1137 va_arg(varpars, int); | |
1138 break; | |
1139 case 'd': /* eigth bytes */ | |
1140 offset += 8; | |
1141 | |
1142 /* | |
1143 * TI and Microsoft represent double values differently | |
1144 * | |
1145 Double Host representation (address incressing from byte 1 to 8) | |
1146 layout Microsoft TMS470x | |
1147 | |
1148 SEEEEEEE byte 8 byte 4 | |
1149 EEMMMMMM byte 7 byte 3 | |
1150 MMMMMMMM byte 6 byte 2 | |
1151 MMMMMMMM byte 5 byte 1 | |
1152 MMMMMMMM byte 4 byte 8 | |
1153 MMMMMMMM byte 3 byte 7 | |
1154 MMMMMMMM byte 2 byte 6 | |
1155 MMMMMMMM byte 1 byte 5 | |
1156 | |
1157 S - sign bit | |
1158 E - exponent bits | |
1159 M - mantissa bits | |
1160 | |
1161 * | |
1162 * double | |
1163 */ | |
1164 | |
1165 | |
1166 if(offset <= TextTracePartitionSize - sizeof(T_S_HEADER) - sizeof(T_PRIM_HEADER)) | |
1167 { | |
1168 #ifdef _TARGET_ | |
1169 /* TI TMS470 Compiler */ | |
1170 *((char*)(P2D(prim)) + offset - 4) = *((char *)varpars); | |
1171 *((char*)(P2D(prim)) + offset - 3) = *(((char *)varpars)+1); | |
1172 *((char*)(P2D(prim)) + offset - 2) = *(((char *)varpars)+2); | |
1173 *((char*)(P2D(prim)) + offset - 1) = *(((char *)varpars)+3); | |
1174 *((char*)(P2D(prim)) + offset - 8) = *(((char *)varpars)+4); | |
1175 *((char*)(P2D(prim)) + offset - 7) = *(((char *)varpars)+5); | |
1176 *((char*)(P2D(prim)) + offset - 6) = *(((char *)varpars)+6); | |
1177 *((char*)(P2D(prim)) + offset - 5) = *(((char *)varpars)+7); | |
1178 #else | |
1179 /* | |
1180 * This should work as well, since no reordering is done. | |
1181 * Don't believe the VC5/6 manual which states a complete | |
1182 * different byte order :( | |
1183 * | |
1184 */ | |
1185 /* PC- Simulation */ | |
1186 *((char*)(P2D(prim)) + offset - 8) = *((char *)varpars); | |
1187 *((char*)(P2D(prim)) + offset - 7) = *(((char *)varpars)+1); | |
1188 *((char*)(P2D(prim)) + offset - 6) = *(((char *)varpars)+2); | |
1189 *((char*)(P2D(prim)) + offset - 5) = *(((char *)varpars)+3); | |
1190 *((char*)(P2D(prim)) + offset - 4) = *(((char *)varpars)+4); | |
1191 *((char*)(P2D(prim)) + offset - 3) = *(((char *)varpars)+5); | |
1192 *((char*)(P2D(prim)) + offset - 2) = *(((char *)varpars)+6); | |
1193 *((char*)(P2D(prim)) + offset - 1) = *(((char *)varpars)+7); | |
1194 #endif /* _TARGET_ */ | |
1195 } | |
1196 | |
1197 va_arg(varpars, double); | |
1198 break; | |
1199 case 's': /* a string of bytes */ | |
1200 { | |
1201 /* | |
1202 * copy the string including the terminating NULL | |
1203 */ | |
1204 unsigned int len = strlen(*((char **)varpars)) + 1; | |
1205 | |
1206 offset += len; | |
1207 if(offset <= TextTracePartitionSize - sizeof(T_S_HEADER) - sizeof(T_PRIM_HEADER)) | |
1208 { | |
1209 memcpy((char*)(P2D(prim)) + offset - len, *((char **)varpars), len); | |
1210 } | |
1211 va_arg(varpars, char **); | |
1212 } | |
1213 break; | |
1214 default: /* unknown type */ | |
1215 vsi_o_assert ( NO_TASK, OS_SYST_ERR_STR_TOO_LONG, __FILE__, __LINE__, | |
1216 "Unknown Trace Format" ); | |
1217 break; | |
1218 } | |
1219 } | |
1220 | |
1221 va_end (varpars); | |
1222 /* | |
1223 * if the amount of trace data was bigger than the allocated | |
1224 * size - discard the trace and send an error trace instead | |
1225 */ | |
1226 if (offset > TextTracePartitionSize - sizeof(T_S_HEADER) - sizeof(T_PRIM_HEADER)) | |
1227 { | |
1228 unsigned int n = (unsigned int)sprintf ((char*)P2D(prim),"ERROR: Compressed trace (index %d) too long (%d bytes). Trace discarded !!!",index, offset); | |
1229 prim->len = n + sizeof(T_PRIM_HEADER); | |
1230 } | |
1231 else | |
1232 { | |
1233 prim->len = offset + sizeof(T_PRIM_HEADER); | |
1234 } | |
1235 | |
1236 prim->opc = int_vsi_tc2trace_opc(TraceClass); | |
1237 prim->sh_offset = S_HDR_OFFSET(prim->len); | |
1238 | |
1239 return ( vsi_o_trace ( Caller, prim, suspend ) ); | |
1240 } | |
1241 if ( FrameEnv == ENV_STACK ) | |
1242 { | |
1243 TracesAborted[Caller]++; | |
1244 } | |
1245 } | |
1246 return VSI_ERROR; | |
1247 } | |
1248 #endif | |
1249 | |
1250 #ifndef RUN_FLASH | |
1251 /* | |
1252 +--------------------------------------------------------------------+ | |
1253 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
1254 | STATE : code ROUTINE : vsi_o_ptrace | | |
1255 +--------------------------------------------------------------------+ | |
1256 | |
1257 PURPOSE : traces a primitive opc and direction | |
1258 | |
1259 */ | |
1260 int vsi_o_ptrace ( T_HANDLE Caller, ULONG opc, UBYTE dir ) | |
1261 { | |
1262 T_PRIM_HEADER *prim; | |
1263 ULONG suspend; | |
1264 LONG Status; | |
1265 ULONG size; | |
1266 int opc_len; | |
1267 | |
1268 if ( (Caller >= 0) && (TraceMask[Caller] & TC_PRIM) | |
1269 #ifdef _TOOLS_ | |
1270 && (SAP_NR(opc)!=TRACE_SAP) && (opc!=TRACE_OPC) | |
1271 #endif | |
1272 ) | |
1273 { | |
1274 suspend = get_suspend_state(Caller,CHECK_TRC_SUSPEND); | |
1275 size = S_ALLOC_SIZE(PTRACE_LEN_OPC32); | |
1276 Status = os_AllocatePartition ( Caller, (T_VOID_STRUCT**)&prim, size, suspend, TestGroupHandle ); | |
1277 if ( Status == OS_OK || Status == OS_WAITED || Status == OS_ALLOCATED_BIGGER ) | |
1278 { | |
1279 prim->opc = int_vsi_tc2trace_opc(TC_PRIM); | |
1280 | |
1281 if ( dir ) | |
1282 strcpy ( (char*)P2D(prim),"$---OUT:$p0x123456789" ); | |
1283 else | |
1284 strcpy ( (char*)P2D(prim),"$--- IN:$p0x123456789" ); | |
1285 | |
1286 if ( OPC32BIT(opc) ) | |
1287 { | |
1288 opc_len = CHARS_FOR_32BIT; | |
1289 prim->len = PTRACE_LEN_OPC32; | |
1290 } | |
1291 else | |
1292 { | |
1293 opc_len = CHARS_FOR_16BIT; | |
1294 prim->len = PTRACE_LEN_OPC16; | |
1295 } | |
1296 prim->len = prim->len + sizeof(T_PRIM_HEADER); | |
1297 HexToASCII ( opc, (char*)P2D(prim) + 12, opc_len ); | |
1298 strcpy (((char*)P2D(prim) + 12 + opc_len), "$" ); | |
1299 | |
1300 prim->sh_offset = S_HDR_OFFSET(prim->len); | |
1301 return ( vsi_o_trace ( Caller, prim, suspend ) ); | |
1302 } | |
1303 TracesAborted[Caller]++; | |
1304 } | |
1305 return VSI_ERROR; | |
1306 } | |
1307 #endif | |
1308 | |
1309 #ifndef RUN_FLASH | |
1310 /* | |
1311 +--------------------------------------------------------------------+ | |
1312 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
1313 | STATE : code ROUTINE : vsi_o_strace | | |
1314 +--------------------------------------------------------------------+ | |
1315 | |
1316 PURPOSE : traces a state and state transition | |
1317 | |
1318 */ | |
1319 int vsi_o_strace (T_HANDLE Caller, const char *const machine, | |
1320 const char *const curstate, | |
1321 const char *const newstate) | |
1322 { | |
1323 T_PRIM_HEADER *prim; | |
1324 LONG Status; | |
1325 ULONG size; | |
1326 ULONG suspend; | |
1327 | |
1328 if ( (Caller >= 0) && (TraceMask[Caller] & TC_STATE) ) | |
1329 { | |
1330 suspend = get_suspend_state(Caller,CHECK_TRC_SUSPEND); | |
1331 size = S_ALLOC_SIZE(STRACE_LEN); | |
1332 Status = os_AllocatePartition ( Caller, (T_VOID_STRUCT**)&prim, size, suspend, TestGroupHandle ); | |
1333 if ( Status == OS_OK || Status == OS_WAITED || Status == OS_ALLOCATED_BIGGER ) | |
1334 { | |
1335 strcpy ( (char *)P2D(prim), machine ); | |
1336 strcat ( (char *)P2D(prim), ":" ); | |
1337 strcat ( (char *)P2D(prim), curstate ); | |
1338 if ( newstate != NULL ) | |
1339 { | |
1340 strcat ( (char *)P2D(prim), " -> " ); | |
1341 strcat ( (char *)P2D(prim), newstate ); | |
1342 } | |
1343 | |
1344 prim->opc = int_vsi_tc2trace_opc(TC_STATE); | |
1345 prim->len = strlen((char*)P2D(prim)) + sizeof(T_PRIM_HEADER); | |
1346 prim->sh_offset = S_HDR_OFFSET(prim->len); | |
1347 | |
1348 return ( vsi_o_trace ( Caller, prim, suspend ) ); | |
1349 } | |
1350 TracesAborted[Caller]++; | |
1351 } | |
1352 return VSI_ERROR; | |
1353 } | |
1354 #endif | |
1355 | |
1356 #ifndef RUN_INT_RAM | |
1357 /* | |
1358 +--------------------------------------------------------------------+ | |
1359 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
1360 | STATE : code ROUTINE : vsi_o_assert | | |
1361 +--------------------------------------------------------------------+ | |
1362 | |
1363 PURPOSE : assert | |
1364 | |
1365 */ | |
1366 /*lint -esym(715,cause) suppress Info -- Symbol 'cause' not referenced */ | |
1367 int vsi_o_assert (T_HANDLE Caller, USHORT cause, const char *file, int line, const char * const format,...) | |
1368 { | |
1369 va_list varpars; | |
1370 #ifdef _TARGET_ | |
1371 OS_QDATA Msg; | |
1372 | |
1373 while ( os_ReceiveFromQueue( Caller, pf_TaskTable[trc_hCommTrace].QueueHandle, &Msg, OS_NO_SUSPEND ) == OS_OK ) | |
1374 { | |
1375 tst_pei_primitive (Msg.ptr); | |
1376 } | |
1377 #endif | |
1378 strcpy ( TraceBuffer, "SYSTEM ERROR: " ); | |
1379 va_start (varpars, format); | |
1380 vsprintf (TraceBuffer+strlen("SYSTEM ERROR: "), format, varpars); | |
1381 va_end (varpars); | |
1382 sprintf (TraceBuffer+strlen(TraceBuffer), ", %s(%d)", file, line ); | |
1383 #ifdef _TOOLS_ | |
1384 vsi_o_ttrace ( NO_TASK, TC_SYSTEM, TraceBuffer ); | |
1385 #else | |
1386 if ( cause & OS_SYST_ERR ) | |
1387 emergeny_trace = 1; | |
1388 tst_drv_write ( NO_TASK, 0, NULL, TraceBuffer ); | |
1389 | |
1390 if ( error_ind_dst[0] != 0 ) | |
1391 { | |
1392 frm_error_ind->error_code = cause; | |
1393 strncpy ((char*)frm_error_ind->error_string, TraceBuffer, FRM_PRIM_STR_SIZE); | |
1394 frm_error_ind->error_string[FRM_PRIM_STR_SIZE-1] = 0; | |
1395 tst_drv_write ( NO_TASK, FRM_ERROR_IND, error_ind_dst, (char*)frm_error_ind ); | |
1396 } | |
1397 #endif | |
1398 #if defined _NUCLEUS_ && !defined _TARGET_ | |
1399 printf ("%s\n",TraceBuffer); | |
1400 printf ( "Task %s suspended\n", pf_TaskTable[Caller].Name ); | |
1401 #endif | |
1402 if ( ext_trace_func.trace_assert != NULL ) | |
1403 { | |
1404 /* in case of OS_SYST_ERR_QUEUE_FULL we should not to send the trace to ACI, | |
1405 because ACI will probably no longer be scheduled. | |
1406 in case of OS_SYST_ERR_NO_PARTITION the PALLOC in ACI fails and will | |
1407 probably hide the root cause of the problem. | |
1408 */ | |
1409 if ( cause != OS_SYST_ERR_QUEUE_FULL && cause != OS_SYST_ERR_NO_PARTITION ) | |
1410 { | |
1411 ext_trace_func.trace_assert ( format, varpars ); | |
1412 os_SuspendTask ( Caller, 1000 ); | |
1413 } | |
1414 } | |
1415 #ifdef _NUCLEUS_ | |
1416 os_SystemError ( os_MyHandle(), cause, TraceBuffer ); | |
1417 #endif | |
1418 return VSI_OK; | |
1419 } | |
1420 #endif | |
1421 | |
1422 #ifndef RUN_INT_RAM | |
1423 /* | |
1424 +--------------------------------------------------------------------+ | |
1425 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
1426 | STATE : code ROUTINE : vsi_settracemask | | |
1427 +--------------------------------------------------------------------+ | |
1428 | |
1429 PURPOSE : set trace mask | |
1430 | |
1431 */ | |
1432 | |
1433 int vsi_settracemask ( T_HANDLE Caller, T_HANDLE Handle, ULONG Mask ) | |
1434 { | |
1435 | |
1436 if ( Handle == 0 || pf_TaskTable[Handle].Name[0] != 0 ) | |
1437 { | |
1438 TraceMask[Handle] = Mask; | |
1439 TraceMask[0] |= TC_SYSTEM; | |
1440 return VSI_OK; | |
1441 } | |
1442 else | |
1443 return VSI_ERROR; | |
1444 } | |
1445 #endif | |
1446 | |
1447 #ifndef RUN_INT_RAM | |
1448 /* | |
1449 +--------------------------------------------------------------------+ | |
1450 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
1451 | STATE : code ROUTINE : vsi_gettracemask | | |
1452 +--------------------------------------------------------------------+ | |
1453 | |
1454 PURPOSE : get trace mask | |
1455 | |
1456 */ | |
1457 | |
1458 int vsi_gettracemask ( T_HANDLE Caller, T_HANDLE Handle, ULONG *Mask ) | |
1459 { | |
1460 if ( Handle == 0 || pf_TaskTable[Handle].Name[0] != 0 ) | |
1461 { | |
1462 *Mask = TraceMask[Handle]; | |
1463 return VSI_OK; | |
1464 } | |
1465 else | |
1466 return VSI_ERROR; | |
1467 } | |
1468 #endif | |
1469 | |
1470 #ifndef RUN_INT_RAM | |
1471 /* | |
1472 +--------------------------------------------------------------------+ | |
1473 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
1474 | STATE : code ROUTINE : vsi_trcsuspend | | |
1475 +--------------------------------------------------------------------+ | |
1476 | |
1477 PURPOSE : set suspend for traces | |
1478 | |
1479 */ | |
1480 | |
1481 int vsi_trcsuspend ( T_HANDLE Caller, T_HANDLE Handle, ULONG Suspend ) | |
1482 { | |
1483 /* SuspendTrace[Handle] = Suspend; */ | |
1484 return VSI_OK; | |
1485 } | |
1486 #endif | |
1487 | |
1488 #ifndef RUN_FLASH | |
1489 /* | |
1490 +--------------------------------------------------------------------+ | |
1491 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
1492 | STATE : code ROUTINE : vsi_trc_free | | |
1493 +--------------------------------------------------------------------+ | |
1494 | |
1495 PURPOSE : monitor test interface partition allocation | |
1496 */ | |
1497 | |
1498 int vsi_trc_free ( T_HANDLE Caller, T_VOID_STRUCT **Prim ) | |
1499 { | |
1500 if ( os_DeallocatePartition ( Caller, *Prim ) != OS_ERROR ) | |
1501 { | |
1502 *Prim = NULL; | |
1503 return VSI_OK; | |
1504 } | |
1505 return VSI_ERROR; | |
1506 } | |
1507 #endif | |
1508 | |
1509 #ifndef RUN_INT_RAM | |
1510 /* | |
1511 +--------------------------------------------------------------------+ | |
1512 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
1513 | STATE : code ROUTINE : InitializeTestpools | | |
1514 +--------------------------------------------------------------------+ | |
1515 | |
1516 PURPOSE : initialize supervision, write index to each partition. | |
1517 | |
1518 */ | |
1519 void InitializeTrace ( void ) | |
1520 { | |
1521 USHORT i; | |
1522 ULONG ByteOrder; | |
1523 | |
1524 /* | |
1525 * test the byte order | |
1526 */ | |
1527 ByteOrder = 0x11223344; | |
1528 | |
1529 if(*((char *) &ByteOrder) == 0x44) | |
1530 trc_LittleEndian = TRUE; | |
1531 else if (*((char *) &ByteOrder) == 0x11) | |
1532 trc_LittleEndian = FALSE; | |
1533 else | |
1534 vsi_o_assert ( NO_TASK, OS_SYST_ERR_STR_TOO_LONG, __FILE__, __LINE__, | |
1535 "Unknown Byte Order" ); | |
1536 emergeny_trace = 0; | |
1537 trc_hCommTrace = VSI_ERROR;; | |
1538 for ( i = 0; i <= MaxEntities; i++ ) | |
1539 { | |
1540 TracesAborted[i] = 0; | |
1541 #ifdef _TARGET_ | |
1542 TraceMask[i] = TC_SYSTEM|TC_ERROR; | |
1543 #else /* _TARGET_ */ | |
1544 TraceMask[i] = 0xffffffff & ~TC_CCD; | |
1545 #endif /* _TARGET_ */ | |
1546 } | |
1547 #ifdef _TARGET_ | |
1548 #endif | |
1549 ext_trace_func.magic_nr = 0; | |
1550 ext_trace_init(); | |
1551 } | |
1552 #endif | |
1553 | |
1554 #ifndef RUN_FLASH | |
1555 /* | |
1556 +--------------------------------------------------------------------+ | |
1557 | PROJECT : GSM-Frame (8415) MODULE : VSI_TRC | | |
1558 | STATE : code ROUTINE : get_suspend_state | | |
1559 +--------------------------------------------------------------------+ | |
1560 | |
1561 PURPOSE : check if suspend is allowed. | |
1562 | |
1563 */ | |
1564 ULONG get_suspend_state ( T_HANDLE caller, int type ) | |
1565 { | |
1566 | |
1567 if ( caller != 0 ) | |
1568 { | |
1569 #ifdef _TARGET_ | |
1570 if ( type == CHECK_TRC_SUSPEND ) | |
1571 { | |
1572 if ( pf_TaskTable[caller].Flags & TRC_NO_SUSPEND ) | |
1573 { | |
1574 return OS_NO_SUSPEND; | |
1575 } | |
1576 else | |
1577 { | |
1578 return OS_SUSPEND; | |
1579 } | |
1580 } | |
1581 else if ( type == CHECK_PRIM_SUSPEND ) | |
1582 { | |
1583 if ( pf_TaskTable[caller].Flags & PRIM_NO_SUSPEND ) | |
1584 { | |
1585 return OS_NO_SUSPEND; | |
1586 } | |
1587 else | |
1588 { | |
1589 return OS_SUSPEND; | |
1590 } | |
1591 } | |
1592 else | |
1593 { | |
1594 return OS_NO_SUSPEND; | |
1595 } | |
1596 #else | |
1597 /* | |
1598 It is checked if the caller is a SYSTEM_PROCESS to ensure that | |
1599 TST and RCV do not block while tracing to avoid a deadlock. | |
1600 */ | |
1601 if ( pf_TaskTable[caller].Flags & SYSTEM_PROCESS ) | |
1602 return OS_NO_SUSPEND; | |
1603 else | |
1604 return OS_SUSPEND; | |
1605 #endif | |
1606 } | |
1607 else | |
1608 { | |
1609 #ifdef _TARGET_ | |
1610 return OS_NO_SUSPEND; | |
1611 #else | |
1612 return OS_SUSPEND; | |
1613 #endif | |
1614 } | |
1615 } | |
1616 #endif | |
1617 | |
1618 | |
1619 /* ------------------------------------------------------------------------- | |
1620 External Trace functions | |
1621 ----------------------------------------------------------------------------*/ | |
1622 | |
1623 #ifdef TEST_EXT_TRACE | |
1624 | |
1625 #ifndef RUN_INT_RAM | |
1626 void trace_error ( const char * const format, va_list varpars ) | |
1627 { | |
1628 #ifndef _TARGET_ | |
1629 char buf[99]; | |
1630 | |
1631 vsprintf (buf, format, varpars); | |
1632 printf ("%s\n",buf); | |
1633 #endif | |
1634 } | |
1635 #endif | |
1636 | |
1637 #ifndef RUN_INT_RAM | |
1638 void trace_assert ( const char * const format, va_list varpars ) | |
1639 { | |
1640 #ifndef _TARGET_ | |
1641 char buf[99]; | |
1642 | |
1643 vsprintf (buf, format, varpars); | |
1644 printf ("%s\n",buf); | |
1645 #endif | |
1646 } | |
1647 #endif | |
1648 | |
1649 #endif /* TEST_EXT_TRACE */ | |
1650 | |
1651 #ifndef RUN_INT_RAM | |
1652 /* | |
1653 +------------------------------------------------------------------------------ | |
1654 | Function : ext_trace_register | |
1655 +------------------------------------------------------------------------------ | |
1656 | Description : register the external trace functions. | |
1657 | | |
1658 | Parameters : func - pointer to API function pointer table | |
1659 | | |
1660 | Return : void | |
1661 +------------------------------------------------------------------------------ | |
1662 */ | |
1663 void vsi_ext_trace_register ( T_EXT_TRACE_FUNC * func ) | |
1664 { | |
1665 ext_trace_func.trace_error = func->trace_error; | |
1666 ext_trace_func.trace_assert = func->trace_assert; | |
1667 ext_trace_func.magic_nr = EXT_TRACE_INITIALIZED; | |
1668 } | |
1669 #endif | |
1670 | |
1671 #ifndef RUN_INT_RAM | |
1672 /* | |
1673 +------------------------------------------------------------------------------ | |
1674 | Function : ext_trace_init | |
1675 +------------------------------------------------------------------------------ | |
1676 | Description : initialize external trace function pointer table. | |
1677 | | |
1678 | Parameters : void | |
1679 | | |
1680 | Return : void | |
1681 +------------------------------------------------------------------------------ | |
1682 */ | |
1683 void ext_trace_init ( void ) | |
1684 { | |
1685 #ifdef TEST_EXT_TRACE | |
1686 vsi_ext_trace_register ( &ext_trace_functions ); | |
1687 #endif | |
1688 if ( ext_trace_func.magic_nr != EXT_TRACE_INITIALIZED ) | |
1689 { | |
1690 ext_trace_func.trace_error = NULL; | |
1691 ext_trace_func.trace_assert = NULL; | |
1692 } | |
1693 } | |
1694 #endif | |
1695 | |
1696 | |
1697 | |
1698 |