MHEG-5  19.3.0
MHEG-5 Documentation
mh5application.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2004 Ocean Blue Software Ltd
4  * Copyright © 2000 Koninklijke Philips Electronics N.V
5  *
6  * This file is part of a DTVKit Software Component
7  * You are permitted to copy, modify or distribute this file subject to the terms
8  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
9  *
10  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
11  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
12  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * If you or your organisation is not a member of DTVKit then you have access
15  * to this source code outside of the terms of the licence agreement
16  * and you are expected to delete this and any associated files immediately.
17  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
18  *******************************************************************************/
31 /*---includes for this file--------------------------------------------------*/
32 #include "mh5application.h"
33 #include "mh5object.h" /* for actions */
34 #include "mh5variable.h" /* for actions */
35 #include "mh5memory.h" /* for constructor/destructor */
36 #include "mh5queue.h" /* Events */
37 #include "mh5display.h" /* UnlockScreen */
38 #include "mh5fileorm.h"
39 #include "mh5storage.h"
40 #include "mh5gate.h"
41 #include "mh5debug.h"
42 #include "mh5misc.h"
43 #include "glue_queue.h"
44 #include "glue_main.h"
45 #include "fpa1_parserInvoke.h"
46 #include "tmcolor.h"
47 #include "mh5profile.h"
48 #include "mh5support.h"
49 #include "mh5control.h"
50 #ifdef INCLUDE_IC
51 #include "mh5hfs.h"
52 #include "mh5tls.h"
53 #include "mh5access.h"
54 #endif
55 #ifndef CI_PLUS_ONLY
56 #include "glue_dsmcc.h"
57 #include "dsm_control.h"
58 #endif
59 
60 #include <string.h>
61 #include <time.h>
62 
63 #ifdef INCLUDE_TPS
64 #include "mh5tps.h"
65 #endif
66 
67 #ifdef INCLUDE_NVM
68 #ifdef INCLUDE_FREESAT
69 #error Cannot define INCLUDE_NVM and INCLUDE_FREESAT in the same build
70 #endif
71 #include "mh5nvm.h"
72 #define WRITE_BUFFER_MAX (64 * 1024)
73 
74 #elif defined(INCLUDE_FREESAT)
75 #define WRITE_BUFFER_MAX (64 * 1024)
76 #include "mh5fsnvm.h"
77 
78 #else
79 #define WRITE_BUFFER_MAX (2 * 1024)
80 #endif
81 
82 #ifdef ASN1TEST
83  #include "asn1_testHarness.h"
84 #endif
85 
86 /*---constant definitions for this file--------------------------------------*/
87 
88 
89 /*---local typedef structs for this file-------------------------------------*/
90 
91 typedef struct sMHEG5applStackItem
92 {
93  MHEG5String app_name;
94  void *carousel_handle;
95  MHEG5Bool spawned;
97 
98 typedef struct s_boot_data
99 {
100  E_FS_ORIGIN origin;
101  U32BIT stage;
102 } S_BOOT_DATA;
103 
104 /*---local (static) variable declarations for this file----------------------*/
105 
106 static const MHEG5String boot_origins[] = {
107  { 6, (U8BIT *)"DSM://" },
108  { 5, (U8BIT *)"CI://" },
109  { 9, (U8BIT *)"hybrid://" }
110 };
111 
112 static MHEG5Application *currentApplication = 0;
113 static MHEG5Bool Restarted = MHEG5FALSE;
114 static void *BootupFileOrmHandle = NULL;
115 /*
116  strict Application Stack Size for 5 Applications
117  important for strict DTG compliance
118  */
119 #define MAX_APPS 6
120 
121 static MHEG5String launchAppName;
122 static MHEG5AppStackItem applStack[MAX_APPS];
123 static U16BIT applStackCount = 0;
124 
125 
126 /*---local function definitions----------------------------------------------*/
127 
128 /*---global function definitions---------------------------------------------*/
129 
130 #ifdef MH5PRINTOUT
131 int mheg_trace_source = 1;
139 void MHEG5fontBodyPrint(MHEG5FontBody fontBody, char *out)
140 {
141  if (fontBody.ref.included.len != 0)
142  {
143  MHEG5indent(out);
144  MHEG_PRINT(out, ":Font ");
145  if (fontBody.referenced == MHEG5TRUE)
146  {
147  if (fontBody.ref.referenced.grp.len)
148  {
149  MHEG5stringPrint(*((MHEG5String *)&fontBody.ref.referenced.grp), out);
150  }
151  else
152  {
153  MHEG5stringPrint(((MHEG5Group *)fontBody.ref.referenced.grp.ptr.group)->groupName, out);
154  }
155  MHEG_PRINT(out, ", ");
156  MHEG5intPrint(fontBody.ref.referenced.id, out);
157  }
158  else
159  {
160  MHEG5stringPrint(fontBody.ref.included, out);
161  }
162  MHEG5newLine(out);
163  }
164 }
165 
172 void MHEG5applicationPrint(MHEG5Application *application, char *out)
173 {
174  MHEG5String path;
175  int save_indent = MHEG5setIndent(0);
176 
177  path = MHEG5convertGID(&application->group.groupName);
178  STB_DebugLogOpen(path.data);
179  MHEG5stringDestruct(&path);
180 
181  /* inherited class */
182  MHEG5groupPrint(&application->group, out);
183 
184  /* exchanged attributes */
185  if (application->onSpawnCloseDown.a_ptr)
186  {
187  MHEG5indent(out);
188  MHEG_PRINT(out, ":OnSpawnCloseDown ");
189  MHEG5actionPrint(application->onSpawnCloseDown, out);
190  MHEG5newLine(out);
191  }
192  if (application->onRestart.a_ptr)
193  {
194  MHEG5indent(out);
195  MHEG_PRINT(out, ":OnRestart ");
196  MHEG5actionPrint(application->onRestart, out);
197  MHEG5newLine(out);
198  }
199 
200  if (application->characterSet != 10)
201  {
202  MHEG5indent(out);
203  MHEG_PRINT(out, ":CharacterSet ");
204  MHEG5intPrint(application->characterSet, out);
205  MHEG5newLine(out);
206  }
207  if (application->backgroundColour.value.i != OSDgetColour(TRANSPARENTCOLOR))
208  {
209  MHEG5indent(out);
210  MHEG_PRINT(out, ":BackgroundColour ");
211  MHEG5colourPrint(application->backgroundColour, out);
212  MHEG5newLine(out);
213  }
214 
215  MHEG5indent(out);
216  MHEG_PRINT(out, ":TextColour ");
217  MHEG5colourPrint(application->textColour, out);
218  MHEG5newLine(out);
219 
220  MHEG5fontBodyPrint(application->fontBody, out);
221 
222  MHEG5indent(out);
223  MHEG_PRINT(out, ":FontAttributes ");
224  MHEG5stringPrint(application->fontAttributes, out);
225  MHEG5newLine(out);
226 
227  MHEG5indent(out);
228  MHEG_PRINT(out, ":BitmapCHook ");
229  MHEG5intPrint(application->bitmapContentHook, out);
230  MHEG5newLine(out);
231 
232  if (application->streamContentHook != 10)
233  {
234  MHEG5indent(out);
235  MHEG_PRINT(out, ":StreamCHook: ");
236  MHEG5intPrint(application->streamContentHook, out);
237  MHEG5newLine(out);
238  }
239  if (application->textContentHook != 10)
240  {
241  MHEG5indent(out);
242  MHEG_PRINT(out, ":TextCHook: ");
243  MHEG5intPrint(application->textContentHook, out);
244  MHEG5newLine(out);
245  }
246  if (application->lineArtContentHook != 0)
247  {
248  MHEG5indent(out);
249  MHEG_PRINT(out, ":lineArtCHook: ");
250  MHEG5intPrint(application->lineArtContentHook, out);
251  MHEG5newLine(out);
252  }
253 /*
254  MHEG5indent(out);
255  MHEG_PRINT(out,":InterchgPrgCHook ");
256  MHEG5intPrint(application->interchangedProgramContentHook,out);
257  MHEG5newLine(out);
258  MHEG5indent(out);
259  MHEG_PRINT(out,":buttonRefColour: ");
260  MHEG5colourPrint(application->buttonRefColour,out);
261  MHEG5newLine(out);
262 
263  MHEG5indent(out);
264  MHEG_PRINT(out,":highlightRefColour: ");
265  MHEG5colourPrint(application->highlightRefColour,out);
266  MHEG5newLine(out);
267 
268  MHEG5indent(out);
269  MHEG_PRINT(out,":sliderRefColour: ");
270  MHEG5colourPrint(application->sliderRefColour,out);
271  MHEG5newLine(out);
272  */
273 
274  MHEG5decIndent();
275  MHEG5indent(out);
276  MHEG_PRINT(out, "}");
277  MHEG5newLine(out);
278 
279  STB_DebugLogClose();
280  MHEG5setIndent(save_indent);
281 }
282 
283 #endif /* MH5PRINTOUT */
284 
285 static void MHEG5unloadApp(void)
286 {
287  #ifndef CI_PLUS_ONLY
288  H_DsmControl dsmcc;
289  H_ObjCarousel carousel;
290  U16BIT sp;
291  BOOLEAN changed;
292  #endif
293 
294  assert( applStackCount != 0 );
295 
296 #ifndef CI_PLUS_ONLY
297  dsmcc = MHEG5_DsmccInstance();
298  carousel = applStack[applStackCount].carousel_handle;
299 
300  assert( DSMCC_CurrentCarousel(dsmcc) == carousel );
301 
302  changed = (applStack[applStackCount - 1].carousel_handle != carousel) ? TRUE : FALSE;
303 
304  TRACE(TFILE, ("crsl_hdl=%p stk=%d name=%s", carousel, applStackCount, applStack[applStackCount].app_name.data))
305 
306  for (sp = 0; sp != applStackCount; sp++)
307  {
308  if (applStack[sp].carousel_handle == carousel)
309  {
310  /* Another application is using it - don't unload */
311  carousel = NULL;
312  break;
313  }
314  }
315  if (carousel)
316  {
317  TRACE(TFILE, ("unload crsl_hdl=%p", carousel))
318  applStack[applStackCount].carousel_handle = NULL;
319  DSMCC_UnloadCarousel( dsmcc, carousel, RST_MODE_FORCE );
320  #ifdef INCLUDE_IC
322  #endif
323  }
324 #endif
325 
326  MHEG5stringDestruct( &applStack[applStackCount].app_name );
327  applStackCount--;
328 
329  #ifndef CI_PLUS_ONLY
330  if (changed)
331  {
332  DSMCC_SetCurrentCarousel( dsmcc, applStack[applStackCount].carousel_handle );
333  }
334  #endif
335 }
336 
337 #ifndef CI_PLUS_ONLY
338 void MHEG5applicationCarouselUnload( void *carousel, BOOLEAN isNdt )
339 {
340  U16BIT sp, i;
341  sp = 0;
342  while (sp != applStackCount)
343  {
344  if (applStack[sp].carousel_handle == carousel)
345  {
346  MHEG5stringDestruct( &applStack[sp].app_name );
347  for (i = sp; i != applStackCount; i++)
348  {
349  applStack[i] = applStack[i + 1];
350  }
351  applStack[applStackCount].app_name.data = NULL;
352  applStack[applStackCount].app_name.len = 0;
353  applStack[applStackCount].carousel_handle = NULL;
354  applStackCount--;
355  }
356  else
357  {
358  sp++;
359  }
360  }
361  if (applStack[applStackCount].carousel_handle == carousel)
362  {
363  applStack[applStackCount].carousel_handle = NULL;
364  if (currentApplication != NULL && !isNdt)
365  {
366  MHEG5StartReboot(NULL);
367  }
368  }
369 }
370 
371 void MHEG5applicationNDTcarouselAttach(void *carousel)
372 {
373  TRACE(TFILE | TTUNE, ("****** app name len=%d Carousel=%p *******",
374  applStack[0].app_name.len, carousel))
375  if (applStack[0].app_name.len) /* just check it has a name */
376  {
377  applStack[0].carousel_handle = carousel;
378  }
379 }
380 
381 #endif
382 
383 /* Clear the application stack */
384 void MHEG5applicationStackClear( BOOLEAN isNdt )
385 {
386  MHEG5String appstr;
387  int asc;
388 #ifndef CI_PLUS_ONLY
389  H_ObjCarousel carousel;
390  E_DsmRstMode mode = (isNdt) ? RST_MODE_PENDING : RST_MODE_FORCE;
391 #endif
392 
393  TRACE(TFILE | TTUNE, ("clearing app stack cnt=%d isNdt=%d", applStackCount, isNdt))
394  appstr = applStack[applStackCount].app_name;
395  applStack[applStackCount].app_name.data = NULL;
396  applStack[applStackCount].app_name.len = 0;
397 
398  asc = (int)applStackCount;
399  while (asc--)
400  {
401  #ifndef CI_PLUS_ONLY
402  if (applStack[asc].carousel_handle != NULL)
403  {
404  TRACE(TFILE, ("asc=%d unload crsl_hdl=%p sa=%d", asc, applStack[asc].carousel_handle))
405  carousel = applStack[asc].carousel_handle;
406  applStack[asc].carousel_handle = NULL;
407  DSMCC_UnloadCarousel( MHEG5_DsmccInstance(), carousel, mode );
408  #ifdef INCLUDE_IC
410  #endif
411  }
412  #else
413  MHEG5stringDestruct( &applStack[asc].app_name );
414  #endif /* !CI_PLUS_ONLY */
415  }
416  if (isNdt)
417  {
418  applStack[0].app_name = appstr;
419  }
420  else
421  {
422  MHEG5stringDestruct( &appstr );
423  currentApplication = 0;
424  }
425  applStackCount = 0;
426  applStack[0].spawned = MHEG5FALSE;
427  Restarted = MHEG5FALSE;
428 }
429 
430 static U32BIT storageSizeForVariable(MHEG5Ingredient *v)
431 {
432  U32BIT len;
433  switch (((MHEG5Root *)v)->clazz)
434  {
435  case MHEG5CONTENTREFVARIABLE:
436  len = ((MHEG5ContentVariable *) v)->contentData.len;
437  len += sizeof(MHEG5Int);
438  break;
439  case MHEG5INTEGERVARIABLE:
440  len = sizeof(MHEG5Int);
441  break;
442  case MHEG5BOOLEANVARIABLE:
443  len = 1;
444  break;
445  case MHEG5OCTETSTRINGVARIABLE:
446  len = ((MHEG5OctetStringVariable *) v)->value.len;
447  len += sizeof(MHEG5Int);
448  break;
449  case MHEG5OBJECTREFVARIABLE:
450  len = ((MHEG5ObjectRefVariable *) v)->valueGrp.len;
451  len += sizeof(MHEG5Int) * 2;
452  break;
453  default:
454  len = 0;
455  }
456  return len;
457 }
458 
459 static void ClearGroupTargets(MHEG5ActionList actions, MHEG5Group *group)
460 {
461  while (actions.total != 0)
462  {
463  /* Check if the target has been resolved and is an ingredient of
464  * the given group, but not the group itself
465  */
466  if ((actions.a_ptr->target != NULL) &&
467  (actions.a_ptr->target != (MHEG5Root *)group) &&
468  (actions.a_ptr->target->grp == group))
469  {
470  /* "Unresolve" target */
471  actions.a_ptr->firstParam = actions.a_ptr->origFirstParam;
472  actions.a_ptr->target = NULL;
473  }
474  else if (actions.a_ptr->target == NULL)
475  {
476  /* Prepare link to be resolved again */
477  actions.a_ptr->firstParam = actions.a_ptr->origFirstParam;
478  }
479 
480  /* Move to next action */
481  actions.a_ptr++;
482  actions.total--;
483  }
484 }
485 
493 {
494  return currentApplication;
495 }
496 
509 static void MHEG5applicationRetrieved( void *userData, S_CONTENT *content )
510 {
511  MHEG5Scene *scene;
512  MHEG5Application *application, *newApplication;
513  MHEG5String path;
514  E_ProfileId currentProfileId, newProfileId;
515 
516  TRACE(TMHBOOT | TFILE | TEVNTS, ("(%.*s)", (int)launchAppName.len, launchAppName.data))
517 
518  if (userData == NULL)
519  {
520  /* When userData is NULL we are NOT launching the Boot aaplication. So
521  * event processing was disabled when the file load was initiated. Re-enable
522  * event processing now to allow queued actions to execute.
523  */
524  MHEG5enableEventProcessing(MHEG5TRUE);
525  }
526 
527  assert( content->data );
528 
529  /* BUG FIX - set working dir before parsing new application. Use gid used
530  * to locate file, not gid from within script, since this may start with
531  * "~/" or "/"
532  */
533  MHEG5setWorkingDir(launchAppName);
534 
535  /* Set profile - this is used while parsing the application, so must
536  * be set before parsing. If parsing fails, the old profile is restored
537  */
538  currentProfileId = MH5_GetCurrentProfile();
539 
540  TRACE(TFILE, ("Got App (datalen=%ld)", (long)content->size))
541  TRACE_MEM();
542 
543  if (*(content->data) == 0xA0) /* ASN1 */
544  {
545  /* Check profile to use (depends on GroupId) */
546  newProfileId = PROFILE_BROADCAST;
547  if (launchAppName.len >= 5)
548  {
549  if (memcmp(launchAppName.data, "CI://", 5) == 0)
550  {
551  /* CI:// application, use CI+ profile */
552  newProfileId = PROFILE_CI_PLUS;
553  }
554  }
555  MH5_SetCurrentProfile( newProfileId );
556 
557  newApplication = asn1_parseApplication( content->data, content->size );
558  #ifdef MH5PRINTOUT
559  if (mheg_trace_source)
560  MHEG5applicationPrint(newApplication, 0);
561  #endif
562  }
563  else /* TEXT */
564  {
565  TRACE(TERROR, ("This application is Text, and not ASN1 encoded!"))
566  newApplication = NULL;
567  }
568 
569  if (!newApplication)
570  {
571  TRACE(TERROR, ("Failed to parse application (%.*s)", (int)launchAppName.len, launchAppName.data))
572 
573  /* Revert to old profile */
574  MH5_SetCurrentProfile( currentProfileId );
575 
576  /* Application did not parse; revert to old Event cache,
577  */
578  if (currentApplication)
579  {
580  if ((applStackCount > 0) && (applStack[applStackCount].spawned))
581  {
582  /* spawn failed */
583  applStackCount--;
584  }
585  }
586 
587  MHEG5stringDestruct( &launchAppName );
588 
589  if (applStack[applStackCount].app_name.len)
590  {
591  /* reset working directory back to that for old and valid app, as the parse failed */
592  MHEG5setWorkingDir(applStack[applStackCount].app_name);
593  }
594  }
595  else /* Application is valid */
596  {
597  MHEG5FileOrmReset(MHEG5_FILE_ORM_RESET_ALL_OBJECTS);
598 
599  application = currentApplication;
600  if (application == NULL)
601  {
602  if (!Restarted && currentApplication == NULL)
603  {
604  /* Notify that a boot MHEG-5 Application has been launched. */
605  MHEG5NotifyEngineStarted();
606  }
607  }
608  else
609  {
610  if (applStackCount != 0 &&
611  (applStack[applStackCount].spawned) &&
612  (application->onSpawnCloseDown.a_ptr != NULL))
613  {
614  assert( MH5GlueActiveState() == TRUE );
615  TRACE(TEVNTS, ("onSpawnCloseDown %p, %p", application, application->onSpawnCloseDown))
616  MHEG5actionListExecute((MHEG5Group *)application, application->onSpawnCloseDown );
617  }
618  /* During destruction of an application triggered by Quit, Launch
619  * or Spawn actions, any stream decoder associated with Stream
620  * objects are not stopped. See UK1.05 section 6.3.4
621  */
622  application->streamContinuanceFlag = MHEG5TRUE;
623  }
624 
625  #ifdef INCLUDE_IC
626  if (applStackCount != 0 && applStack[applStackCount].spawned)
627  {
628  /* When spawning an application, the hybrid file system
629  * should be saved
630  */
632  }
633  #endif
634 
635  /* delete any old launch app name and save the new one */
636  MHEG5stringDestruct( &applStack[applStackCount].app_name );
637  applStack[applStackCount].app_name = launchAppName;
638 
639  #ifndef CI_PLUS_ONLY
640  applStack[applStackCount].carousel_handle = DSMCC_CurrentCarousel( MHEG5_DsmccInstance());
641  #endif
642 
643  /* Make the new application GID an absolute reference */
644  path = MHEG5convertGID(&newApplication->group.groupName);
645  MHEG5stringDestruct(&newApplication->group.groupName);
646  newApplication->group.groupName = path;
647 
648  /* Prevent event processing while we destruct the scene and application */
650 
651  scene = MHEG5getCurrentScene();
652  if (scene != 0)
653  {
654  MHEG5sceneDestruct(scene);
655  MHEG5sceneFree(scene);
656  MHEG5freeMem(scene);
657  }
658 
659  if (application != 0)
660  {
661  MHEG5applicationDestruct(application);
662  MHEG5applicationFree(application);
663  MHEG5freeMem(application);
664  }
665 
666  TRACE((TFILE | TPERFORM | TMEMORY), ("Stopped any App"))
667  TRACE_MEM();
668  #ifdef MHG_TRACK_MEM
669  mh5emt_print(0xfe /*(1<<SRCMEM_OSD)|(1<<SRCMEM_APP)*/);
670  #endif
671 
672  /* Reset receiver to default state */
674 
675  /* Enable event processing again */
677 
678  /* Move on to new application */
679  currentApplication = newApplication;
680 
681  /* The application can forget that it was spawned */
682  applStack[applStackCount].spawned = MHEG5FALSE;
683 
684  TRACE((TFILE | TPERFORM), ("Preparing %.*s", (int)newApplication->group.groupName.len, (char *)newApplication->group.groupName.data))
685  MHEG5applicationPrepare(currentApplication);
686 
687  if (MH5GlueActiveState() == TRUE)
688  {
689  TRACE((TFILE | TPERFORM), ("Running App"))
691  TRACE((TFILE | TPERFORM), ("Started App"))
692  TRACE_MEM();
693  }
694  }
695  launchAppName.len = 0;
696  launchAppName.data = 0;
697  BootupFileOrmHandle = NULL;
698 }
699 
700 /*
701  Display Stack
702  */
703 
704 
713 {
714  assert(item);
715  return item->item;
716 }
717 
725 {
726  if (!currentApplication)
727  {
728  return 0;
729  }
730  return currentApplication->displayStackBottom;
731 }
732 
742 {
743  assert(item);
744  return item->prev;
745 }
746 
756 {
758 
759  assert(visible);
760  if (!currentApplication)
761  {
762  return 0;
763  }
764  s = currentApplication->displayStackTop;
765  while (s && (s->item != visible))
766  {
767  s = s->next;
768  }
769  return s;
770 }
771 
781 void MHEG5displayStackAdd(MHEG5Root *visible, MHEG5Bool atTop)
782 {
784 
785  CALL_PRINT((">> MHEG5displayStackAdd(%p %d)\n", visible, atTop));
786 
787  assert(visible);
788 
789  if (visible->clazz == MHEG5RTGRAPHICS)
790  {
791  /* RTGraphics objects are not added to the display stack. They cannot be
792  * displayed independantly of a running VIdeo object
793  */
794  return;
795  }
796 
797  if (!currentApplication)
798  {
799  WARNING_PRINT(("MHEG5displayStackAdd : currentApplication == Null\n"));
800  CALL_PRINT(("<< MHEG5displayStackAdd\n"));
801  return;
802  }
803  s = currentApplication->displayStackTop;
804  while (s)
805  {
806  assert(s->item);
807  if (s->item == visible)
808  {
809  DEBUG_PRINT(("MHEG5displayStackAdd : Item already in display stack\n"));
810  CALL_PRINT(("<< MHEG5displayStackAdd\n"));
811  return;
812  }
813  s = s->next;
814  }
815  s = (MHEG5DisplayStackItem *) MHEG5getMem(sizeof(MHEG5DisplayStackItem));
816  if (!s)
817  {
818  ERROR_PRINT(("MHEG5displayStackAdd : MHEG5getMem failed\n"));
819  CALL_PRINT(("<< MHEG5displayStackAdd\n"));
820  return;
821  }
822  s->item = visible;
823  s->next = 0;
824  s->prev = 0;
825  if (atTop == MHEG5TRUE)
826  {
827  if (currentApplication->displayStackTop)
828  {
829  currentApplication->displayStackTop->prev = s;
830  s->next = currentApplication->displayStackTop;
831  currentApplication->displayStackTop = s;
832  }
833  else
834  {
835  currentApplication->displayStackBottom = s;
836  currentApplication->displayStackTop = s;
837  }
838  }
839  else
840  {
841  if (currentApplication->displayStackBottom)
842  {
843  currentApplication->displayStackBottom->next = s;
844  s->prev = currentApplication->displayStackBottom;
845  currentApplication->displayStackBottom = s;
846  }
847  else
848  {
849  currentApplication->displayStackBottom = s;
850  currentApplication->displayStackTop = s;
851  }
852  }
853 
854  CALL_PRINT(("<< MHEG5displayStackAdd\n"));
855 }
856 
865 {
867 
868  CALL_PRINT((">> MHEG5displayStackDelete(%p)\n", visible));
869 
870  assert(visible);
871  if (!currentApplication)
872  {
873  WARNING_PRINT(("MHEG5displayStackDelete : currentApplication == Null\n"));
874  CALL_PRINT(("<< MHEG5displayStackDelete MHEG5FALSE\n"));
875  return MHEG5FALSE;
876  }
877  s = currentApplication->displayStackTop;
878  while (s)
879  {
880  assert(s->item);
881  if (s->item == visible)
882  {
883  if (s->prev)
884  {
885  s->prev->next = s->next;
886  }
887  else
888  {
889  currentApplication->displayStackTop = s->next;
890  }
891  if (s->next)
892  {
893  s->next->prev = s->prev;
894  }
895  else
896  {
897  currentApplication->displayStackBottom = s->prev;
898  }
899  MHEG5freeMem(s);
900  CALL_PRINT(("<< MHEG5displayStackDelete MHEG5TRUE\n"));
901  return MHEG5TRUE;
902  }
903  s = s->next;
904  }
905 
906  CALL_PRINT(("<< MHEG5displayStackDelete MHEG5FALSE\n"));
907  return MHEG5FALSE;
908 }
909 
917 {
918  CALL_PRINT((">> MHEG5displayStackToTop(%p)\n", visible));
919 
920  assert(visible);
921 
922  MHEG5displayStackDelete(visible);
923  MHEG5displayStackAdd(visible, MHEG5TRUE);
924 
925  CALL_PRINT(("<< MHEG5displayStackToTop\n"));
926 }
927 
935 {
936  CALL_PRINT((">> MHEG5displayStackToBottom(%p)\n", visible));
937 
938  assert(visible);
939 
940  MHEG5displayStackDelete(visible);
941  MHEG5displayStackAdd(visible, MHEG5FALSE);
942 
943  CALL_PRINT(("<< MHEG5displayStackToBottom\n"));
944 }
945 
954 {
955  MHEG5DisplayStackItem *s, *w;
956 
957  CALL_PRINT((">> MHEG5displayStackPutBefore(%p, %p)\n", target, refVisible));
958 
959  assert(target);
960  assert(refVisible);
961 
962  if (!currentApplication)
963  {
964  WARNING_PRINT(("MHEG5displayStackPutBefore : currentApplication == Null\n"));
965  CALL_PRINT(("<< MHEG5displayStackPutBefore\n"));
966  return;
967  }
968  if (target == refVisible)
969  {
970  WARNING_PRINT(("MHEG5displayStackPutBefore : target == refVisible\n"));
971  CALL_PRINT(("<< MHEG5displayStackPutBefore\n"));
972  return;
973  }
974  w = currentApplication->displayStackTop;
975  s = (MHEG5DisplayStackItem *) MHEG5getMem(sizeof(MHEG5DisplayStackItem));
976  if (!s)
977  {
978  CALL_PRINT(("<< MHEG5displayStackPutBefore\n"));
979  return;
980  }
981  s->item = target;
982  s->next = 0;
983  s->prev = 0;
984  while (w)
985  {
986  assert(w->item);
987  if (w->item == refVisible)
988  {
989  /* Found refVisible in display stack */
990  if (MHEG5displayStackDelete(target))
991  {
992  /* Target existed in the display stack. Reinsert */
993  if (w->prev)
994  {
995  s->prev = w->prev;
996  s->next = w;
997  s->prev->next = s;
998  w->prev = s;
999  }
1000  else
1001  {
1002  s->next = w;
1003  w->prev = s;
1004  currentApplication->displayStackTop = s;
1005  }
1006  }
1007  CALL_PRINT(("<< MHEG5displayStackPutBefore\n"));
1008  return;
1009  }
1010  w = w->next;
1011  }
1012 
1013  /* Unable to find refVisible in display stack. */
1014  MHEG5freeMem(s);
1015 
1016  WARNING_PRINT(("MHEG5displayStackPutBefore : Unable to find refVisible in display stack\n"));
1017  CALL_PRINT(("<< MHEG5displayStackPutBefore\n"));
1018 }
1019 
1028 {
1029  MHEG5DisplayStackItem *s, *w;
1030 
1031  CALL_PRINT((">> MHEG5displayStackPutBehind(%p, %p)\n", target, refVisible));
1032 
1033  assert(target);
1034  assert(refVisible);
1035  if (!currentApplication)
1036  {
1037  WARNING_PRINT(("MHEG5displayStackPutBehind : currentApplication == Null\n"));
1038  CALL_PRINT(("<< MHEG5displayStackPutBehind\n"));
1039  return;
1040  }
1041  if (target == refVisible)
1042  {
1043  WARNING_PRINT(("MHEG5displayStackPutBehind : target == refVisible\n"));
1044  CALL_PRINT(("<< MHEG5displayStackPutBehind\n"));
1045  return;
1046  }
1047  w = currentApplication->displayStackTop;
1048  s = (MHEG5DisplayStackItem *) MHEG5getMem(sizeof(MHEG5DisplayStackItem));
1049  if (!s)
1050  {
1051  CALL_PRINT(("<< MHEG5displayStackPutBehind\n"));
1052  return;
1053  }
1054  s->item = target;
1055  s->next = 0;
1056  s->prev = 0;
1057  while (w)
1058  {
1059  assert(w->item);
1060  if (w->item == refVisible)
1061  {
1062  /* Found refVisible in display stack */
1063  if (MHEG5displayStackDelete(target))
1064  {
1065  /* Target existed in the display stack. Reinsert */
1066  if (w->next)
1067  {
1068  s->next = w->next;
1069  s->prev = w;
1070  s->next->prev = s;
1071  w->next = s;
1072  }
1073  else
1074  {
1075  s->prev = w;
1076  w->next = s;
1077  currentApplication->displayStackBottom = s;
1078  }
1079  }
1080  CALL_PRINT(("<< MHEG5displayStackPutBehind\n"));
1081  return;
1082  }
1083  w = w->next;
1084  }
1085 
1086  /* Unable to find refVisible in display stack. */
1087  MHEG5freeMem(s);
1088 
1089  WARNING_PRINT(("MHEG5displayStackPutBehind : Unable to find refVisible in display stack\n"));
1090  CALL_PRINT(("<< MHEG5displayStackPutBehind\n"));
1091 }
1092 
1099 {
1100  assert(application);
1101 
1102  MHEG5groupInit(&application->group);
1103 
1104  MHEG5colourInit(&application->backgroundColour, OSDgetColour(TRANSPARENTCOLOR));
1105  MHEG5colourInit(&application->textColour, OSDgetColour(DEFAULTTEXTCOLOR));
1106  MHEG5colourInit(&application->buttonRefColour, OSDgetColour(DEFAULTBUTTONCOLOR));
1107  MHEG5colourInit(&application->highlightRefColour, OSDgetColour(DEFAULTHIGHLIGHTCOLOR));
1108  MHEG5colourInit(&application->sliderRefColour, OSDgetColour(DEFAULTSLIDERCOLOR));
1109  MHEG5colourInit(&application->desktopColour, OSDgetColour(DEFAULTDESKTOPCOLOUR));
1110 
1111  /* Choose some sensible defaults for the following values. These are no
1112  * specified by MHEG5 specification, but have been added for defensive
1113  * receiver behaviour.
1114  */
1115  application->characterSet = 10;
1116  application->bitmapContentHook = 4;
1117  application->streamContentHook = 10;
1118  application->textContentHook = 10;
1119 }
1120 
1129 {
1130  assert(application);
1131 
1132  MHEG5groupFree(&application->group);
1133 
1134  MHEG5actionDestruct(application->onSpawnCloseDown);
1135  MHEG5actionDestruct(application->onRestart);
1136  MHEG5colourDestruct(&application->backgroundColour);
1137  MHEG5colourDestruct(&application->textColour);
1138  if (application->fontBody.referenced)
1139  {
1140  if (application->fontBody.ref.referenced.grp.len)
1141  {
1142  MHEG5stringDestruct((MHEG5String *)&application->fontBody.ref.referenced.grp);
1143  }
1144  }
1145  else
1146  {
1147  MHEG5stringDestruct(&application->fontBody.ref.included);
1148  }
1149  MHEG5stringDestruct(&application->fontAttributes);
1150  MHEG5colourDestruct(&application->buttonRefColour);
1151  MHEG5colourDestruct(&application->highlightRefColour);
1152  MHEG5colourDestruct(&application->sliderRefColour);
1153 }
1154 
1162 {
1163  int mcnt;
1164  MHEG5Ingredient *item;
1165  MHEG5Bool foundAudio = MHEG5FALSE;
1166  MHEG5Bool foundVideo = MHEG5FALSE;
1167 #ifndef MHEG5PROFILE_UK1_06
1168  MHEG5Bool foundRTGraphics = MHEG5FALSE;
1169 #endif
1170 
1171  assert(application);
1172 
1173  application->lockCount = 0;
1174 
1175  if (application->onSpawnCloseDown.a_ptr)
1176  {
1177  TRACE(TEVNTS, ("onSpawnCloseDown %p, %p", application, application->onSpawnCloseDown))
1178  MHEG5queueResolveTargets( application->onSpawnCloseDown );
1179  }
1180  if (application->onRestart.a_ptr)
1181  {
1182  TRACE(TEVNTS, ("onRestart %p, %p", application, application->onRestart))
1183  MHEG5queueResolveTargets( application->onRestart );
1184  }
1185 
1186  /* Call base class preparation */
1187  MHEG5groupPrepare(&application->group);
1188 
1189  /* Check for stream decoder components that are not present in the new
1190  * application and deactivate any that have been continued from the previous
1191  * application. See section 6.3.3 and 6.3.4 of UK profile 1.05
1192  */
1193  item = application->group.itemHead;
1194  while (item)
1195  {
1196  /* Check whether this item is an initially active stream object */
1197  if ((item->root.clazz == MHEG5STREAM) && (!item->initiallyStopped))
1198  {
1199  /* Search all multiplex items of the stream object for initially
1200  * active multiplex objects.
1201  */
1202  mcnt = 0;
1203  while ((mcnt != MAX_MLTPLX) && (((MHEG5Stream *)item)->multiplex[mcnt]))
1204  {
1205  if (!((MHEG5Stream *)item)->multiplex[mcnt]->initiallyStopped)
1206  {
1207  switch (((MHEG5Stream *)item)->multiplex[mcnt]->root.clazz)
1208  {
1209  case MHEG5AUDIO:
1210  /* Found an audio object */
1211  foundAudio = MHEG5TRUE;
1212  break;
1213  case MHEG5VIDEO:
1214  /* Found a video object */
1215  foundVideo = MHEG5TRUE;
1216  break;
1217  #ifndef MHEG5PROFILE_UK1_06
1218  case MHEG5RTGRAPHICS:
1219  /* Found an RTGraphics object */
1220  foundRTGraphics = MHEG5TRUE;
1221  break;
1222  #endif
1223  default:
1224  ERROR_PRINT(("ERROR: Unexpected object in stream multiplex\n"));
1225  break;
1226  }
1227  }
1228  mcnt++;
1229  }
1230  }
1231  item = item->next;
1232  }
1233 
1234  if (!foundAudio)
1235  {
1236  /* There are no Audio objects currently active. Stop audio media
1237  * decoders.
1238  */
1240  }
1241 
1242  if (!foundVideo)
1243  {
1244  /* There are no Video objects currently active. Stop video media
1245  * decoders.
1246  */
1248  }
1249 
1250 #ifndef MHEG5PROFILE_UK1_06
1251  if (!foundRTGraphics)
1252  {
1253  /* There are no RTGraphics objects currently active. Stop RTGraphics
1254  * media decoders.
1255  */
1257  }
1258 #endif
1259 }
1260 
1269 {
1271 
1272  if (!application)
1273  {
1274  return;
1275  }
1276 #ifdef INCLUDE_TPS
1277  MHEG5TpsClose();
1278 #endif
1279 #if defined(INCLUDE_CI_PLUS)
1280  MHEG5SuppressMHEGGraphics(MHEG5FALSE);
1281 #endif
1282  MHEG5groupDestruct(&application->group);
1283 
1284  while (application->displayStackTop)
1285  {
1286  t = application->displayStackTop;
1287  application->displayStackTop = application->displayStackTop->next;
1288  MHEG5freeMem(t);
1289  }
1290  application->displayStackBottom = 0;
1291 
1292  if (application == currentApplication)
1293  {
1294  currentApplication = 0;
1295 
1296  /* Could check that there are no links in the active Link list. */
1297  /*
1298  MHEG5EventType et;
1299  for (et=MHEG5NONEEVENT;et!=MHEG5LASTEVENT;et++)
1300  assert(MHEG5linkGetActiveLinks(et) == 0);
1301  */
1302  }
1303 }
1304 
1312 {
1313  if (!currentApplication->group.root.runningStatus)
1314  {
1315  /* Clear the screen */
1317 
1318  /* Streams should only be synchronised when IsRunning has been
1319  * processed.
1320  */
1322  MHEG5groupActivate(&currentApplication->group);
1323 
1324  /* Execute the OnRestart elementary action of the newly activated
1325  * Application object
1326  */
1327  if ((Restarted) && (currentApplication->onRestart.a_ptr != NULL))
1328  {
1329  TRACE(TEVNTS, ("onRestart %p, %p", currentApplication, currentApplication->onRestart))
1330  MHEG5actionListExecute((MHEG5Group *)currentApplication, currentApplication->onRestart );
1331  }
1332  Restarted = MHEG5FALSE;
1333  }
1334 }
1335 
1345 {
1346  assert(application);
1347  /*
1348  ToDo: CloseConnection
1349  */
1350 #ifdef MHEG5LOG
1351  MHEG5LogPrintf(MHEG5CALLS, "App Deactivate ");
1352  MHEG5LogPrintObjectPtr(MHEG5CALLS, (MHEG5Root *) application);
1353  MHEG5LogPrintf(MHEG5CALLS, "\n");
1354 #endif
1355 
1356  MHEG5groupDeactivate(&application->group);
1357 }
1358 
1359 /*
1360  Actions
1361  */
1373 MHEG5ErrorCode MHEG5storePersistent(MHEG5Root *target, MHEG5GList *params)
1374 {
1375  MHEG5Root *rc = 0, *param = 0;
1376  MHEG5GList *thirdParam, *lastParam;
1377  char *buf = NULL;
1378  MHEG5Int error = 0, pos = 0;
1379  MHEG5String fn;
1380  MHEG5Bool invalidString;
1381  MHEG5ErrorCode returnCode = MHEG5ERR_NOERROR;
1382 
1383  MHEG5Root *peek_param; /*Used for peeking at parameters to find buffer length*/
1384  MHEG5GList *nextParam;
1385  U32BIT buffer_length = 0;
1386 #ifdef INCLUDE_FREESAT
1387  MHEG5Int expires = -1;
1388  MHEG5Int priority = -1;
1389 #endif
1390  assert(target);
1391 
1392  if (target != (MHEG5Root *) currentApplication)
1393  {
1394  return MHEG5ERR_WRONGTARGET;
1395  }
1396  if (!params)
1397  {
1398  return MHEG5ERR_WRONGNUMBEROFPARAMS;
1399  }
1400  thirdParam = MHEG5resolveORef(params, &rc);
1401  if (!rc)
1402  {
1403  return MHEG5ERR_REFERENCEDPARAMNOTAVAILABLE;
1404  }
1405  if (rc->clazz != MHEG5BOOLEANVARIABLE)
1406  {
1407  return MHEG5ERR_WRONGPARAM;
1408  }
1409  if (!thirdParam)
1410  {
1411  return MHEG5ERR_WRONGNUMBEROFPARAMS;
1412  }
1413  if (thirdParam->generic.type != MHEG5BRACKETOPEN)
1414  {
1415  return MHEG5ERR_WRONGPARAM;
1416  }
1417 
1418  ((MHEG5BooleanVariable *) rc)->value = MHEG5FALSE;
1419 
1420  /* Find the end of the variable list so that we can get the file name */
1421  lastParam = thirdParam;
1422  while (lastParam->next)
1423  {
1424  lastParam = lastParam->next;
1425  }
1426 
1427  /* Get the file name */
1428  fn.len = 0;
1429  MHEG5resolveGenericOctetString(lastParam, &fn, &invalidString);
1430  if ((invalidString) || (fn.len == 0))
1431  {
1432  /* Parameter was not an octet string or a zero length string */
1433  return MHEG5ERR_WRONGPARAM;
1434  }
1435  thirdParam = thirdParam->next;
1436 #ifdef INCLUDE_FREESAT
1437  if (MH5_SupportMhegProfile(CPROFILE_FREESAT) &&
1438  fn.len >= 6 && memcmp(fn.data, "nvm://", 6) == 0)
1439  {
1440  if (thirdParam && (thirdParam->generic.type != MHEG5BRACKETCLOSE))
1441  {
1442  thirdParam = MHEG5resolveORef(thirdParam, &param);
1443  if (param->clazz == MHEG5INTEGERVARIABLE)
1444  {
1445  expires = ((MHEG5IntegerVariable *)param)->value;
1446  }
1447  }
1448  if (thirdParam && (thirdParam->generic.type != MHEG5BRACKETCLOSE))
1449  {
1450  thirdParam = MHEG5resolveORef(thirdParam, &param);
1451  if (param->clazz == MHEG5INTEGERVARIABLE)
1452  {
1453  priority = ((MHEG5IntegerVariable *)param)->value;
1454  }
1455  }
1456  }
1457 #endif
1458 
1459  peek_param = param;
1460  nextParam = thirdParam;
1461  while (nextParam && (nextParam->generic.type != MHEG5BRACKETCLOSE))
1462  {
1463  nextParam = MHEG5resolveORef(nextParam, &peek_param);
1464  if (!peek_param)
1465  {
1466  return MHEG5ERR_WRONGPARAM;
1467  }
1468  buffer_length += storageSizeForVariable((MHEG5Ingredient *)peek_param);
1469  }
1470  if (buffer_length > (U32BIT)MH5_MaxStorageFileLength())
1471  {
1472  return MHEG5ERR_WRONGPARAM;
1473  }
1474  buf = MHEG5getMem(buffer_length);
1475  if (buf != NULL)
1476  {
1477  while (thirdParam && (thirdParam->generic.type != MHEG5BRACKETCLOSE))
1478  {
1479  thirdParam = MHEG5resolveORef(thirdParam, &param);
1480  error = MHEG5variableStore((MHEG5Ingredient *)param, &buf[pos], buffer_length - pos);
1481  if (error < 0)
1482  {
1483  ((MHEG5BooleanVariable *) rc)->value = MHEG5FALSE;
1484  MHEG5freeMem(buf);
1485  return MHEG5ERR_NOERROR;
1486  }
1487  pos += error;
1488  }
1489 
1490  if (fn.len > 6 && memcmp(fn.data, "ram://", 6) == 0)
1491  {
1492  ((MHEG5BooleanVariable *) rc)->value = MHEG5storageWrite(fn, buf, pos);
1493  returnCode = MHEG5ERR_NOERROR;
1494  }
1495 #ifdef INCLUDE_NVM
1496  else if (!MH5_SupportMhegProfile(CPROFILE_FREESAT) &&
1497  fn.len >= 6 && memcmp(fn.data, "nvm://", 6) == 0)
1498  {
1499  fn.data += 6; fn.len -= 6;
1500  ((MHEG5BooleanVariable *) rc)->value = MHEG5nvmWrite(fn, buf, pos);
1501  returnCode = MHEG5ERR_NOERROR;
1502  }
1503 #endif /*INCLUDE_NVM*/
1504 #ifdef INCLUDE_TPS
1505  else if (fn.len >= 6 && memcmp(fn.data, "pst://", 6) == 0)
1506  {
1507  fn.data += 6;
1508  fn.len -= 6;
1509  ((MHEG5BooleanVariable *) rc)->value = MHEG5TpsWrite(fn, buf, pos);
1510  returnCode = MHEG5ERR_NOERROR;
1511  }
1512 #endif /*INCLUDE_TPS*/
1513 #ifdef INCLUDE_FREESAT
1514  else if (MH5_SupportMhegProfile(CPROFILE_FREESAT) &&
1515  fn.len >= 6 && memcmp(fn.data, "nvm://", 6) == 0)
1516  {
1517  fn.data += 6; fn.len -= 6;
1518  ((MHEG5BooleanVariable *) rc)->value = MHEG5FSnvmWrite(fn, buf, pos, expires, priority);
1519  returnCode = MHEG5ERR_NOERROR;
1520  }
1521 #endif /*INCLUDE_FREESAT*/
1522  else
1523  {
1524  ((MHEG5BooleanVariable *) rc)->value = MHEG5FALSE;
1525  returnCode = MHEG5ERR_WRONGPARAM;
1526  }
1527  if (buf)
1528  {
1529  MHEG5freeMem(buf);
1530  }
1531  }
1532  return returnCode;
1533 }
1534 
1546 MHEG5ErrorCode MHEG5readPersistent(MHEG5Root *target, MHEG5GList *params)
1547 {
1548  MHEG5Root *rc = 0, *param = 0;
1549  MHEG5GList *thirdParam, *lastParam;
1550  char *buf;
1551  MHEG5Int len;
1552  MHEG5Int error = 0, pos = 0;
1553  MHEG5Bool getSuccess = MHEG5FALSE;
1554  MHEG5String fn;
1555  MHEG5Bool invalidString;
1556  MHEG5Int maximum_len;
1557 #ifdef INCLUDE_FREESAT
1558  MHEG5String short_fn;
1559  MHEG5Int expires;
1560  MHEG5Int priority;
1561 #endif
1562  assert(target);
1563 
1564  if (target != (MHEG5Root *) currentApplication)
1565  {
1566  return MHEG5ERR_WRONGTARGET;
1567  }
1568  if (!params)
1569  {
1570  return MHEG5ERR_WRONGNUMBEROFPARAMS;
1571  }
1572  thirdParam = MHEG5resolveORef(params, &rc);
1573  if (!rc)
1574  {
1575  return MHEG5ERR_REFERENCEDPARAMNOTAVAILABLE;
1576  }
1577  if (rc->clazz != MHEG5BOOLEANVARIABLE)
1578  {
1579  return MHEG5ERR_WRONGPARAM;
1580  }
1581  if (!thirdParam)
1582  {
1583  return MHEG5ERR_WRONGNUMBEROFPARAMS;
1584  }
1585  if (thirdParam->generic.type != MHEG5BRACKETOPEN)
1586  {
1587  return MHEG5ERR_WRONGPARAM;
1588  }
1589  thirdParam = thirdParam->next;
1590  if (!thirdParam)
1591  {
1592  return MHEG5ERR_WRONGNUMBEROFPARAMS;
1593  }
1594 
1595  /* Find the end of the variable list so that we can get the file name */
1596  lastParam = thirdParam;
1597  while (lastParam->next)
1598  {
1599  lastParam = lastParam->next;
1600  }
1601 
1602  /* Get the file name */
1603  fn.len = 0;
1604  MHEG5resolveGenericOctetString(lastParam, &fn, &invalidString);
1605  if ((invalidString) || (fn.len == 0))
1606  {
1607  /* Parameter was not an octet string or a zero length string */
1608  return MHEG5ERR_WRONGPARAM;
1609  }
1610 
1611  if (fn.len > 6 && memcmp(fn.data, "ram://", 6) == 0)
1612  {
1613  getSuccess = MHEG5storageRead(fn, (void **) &buf, &len);
1614  }
1615 #ifdef INCLUDE_NVM
1616  else if (!MH5_SupportMhegProfile(CPROFILE_FREESAT) &&
1617  fn.len >= 6 && memcmp(fn.data, "nvm://", 6) == 0)
1618  {
1619  fn.data += 6; fn.len -= 6;
1620  getSuccess = MHEG5nvmRead(fn, (void **) &buf, &len);
1621  }
1622 #endif /*INCLUDE_NVM */
1623 #ifdef INCLUDE_FREESAT
1624  else if (MH5_SupportMhegProfile(CPROFILE_FREESAT) &&
1625  fn.len >= 6 && memcmp(fn.data, "nvm://", 6) == 0)
1626  {
1627  short_fn.data = fn.data + 6;
1628  short_fn.len = fn.len - 6;
1629  getSuccess = MHEG5FSnvmRead(short_fn, (void **) &buf, &len, &expires, &priority);
1630  }
1631 #endif /*INCLUDE_FREESAT */
1632 #ifdef INCLUDE_TPS
1633  else if (fn.len >= 6 && memcmp(fn.data, "pst://", 6) == 0)
1634  {
1635  fn.data += 6;
1636  fn.len -= 6;
1637  getSuccess = MHEG5TpsRead(fn, (void **) &buf, &len);
1638  }
1639 #endif /*INCLUDE_TPS */
1640  if (!getSuccess)
1641  {
1642  ((MHEG5BooleanVariable *) rc)->value = MHEG5FALSE;
1643  return MHEG5ERR_NOERROR;
1644  }
1645  maximum_len = MH5_MaxStorageFileLength();
1646 #ifdef INCLUDE_FREESAT
1647  if (MH5_SupportMhegProfile(CPROFILE_FREESAT) &&
1648  fn.len >= 6 && memcmp(fn.data, "nvm://", 6) == 0)
1649  {
1650  if (thirdParam && (thirdParam->generic.type != MHEG5BRACKETCLOSE))
1651  {
1652  thirdParam = MHEG5resolveORef(thirdParam, &param);
1653  error = MHEG5variableRead((MHEG5Ingredient *)param, (void *)&expires, maximum_len);
1654  if (error < 0)
1655  {
1656  ((MHEG5BooleanVariable *) rc)->value = MHEG5FALSE;
1657  return MHEG5ERR_NOERROR;
1658  }
1659  }
1660  if (thirdParam && (thirdParam->generic.type != MHEG5BRACKETCLOSE))
1661  {
1662  thirdParam = MHEG5resolveORef(thirdParam, &param);
1663  error = MHEG5variableRead((MHEG5Ingredient *)param, (void *)&priority, maximum_len);
1664  if (error < 0)
1665  {
1666  ((MHEG5BooleanVariable *) rc)->value = MHEG5FALSE;
1667  return MHEG5ERR_NOERROR;
1668  }
1669  }
1670  }
1671 #endif
1672  /* Now start reading the variables to copy into */
1673  while (thirdParam && (thirdParam->generic.type != MHEG5BRACKETCLOSE))
1674  {
1675  thirdParam = MHEG5resolveORef(thirdParam, &param);
1676  if (pos >= len)
1677  {
1678  /* Too many parameters to read, not enough data */
1679  return MHEG5ERR_WRONGNUMBEROFPARAMS;
1680  }
1681  error = MHEG5variableRead((MHEG5Ingredient *)param, &buf[pos], maximum_len);
1682  if (error < 0)
1683  {
1684  ((MHEG5BooleanVariable *) rc)->value = MHEG5FALSE;
1685  return MHEG5ERR_NOERROR;
1686  }
1687  pos += error;
1688  }
1689  ((MHEG5BooleanVariable *) rc)->value = MHEG5TRUE;
1690  return MHEG5ERR_NOERROR;
1691 }
1692 
1697 static void MHEG5applicationRetrieveFail( void *userData )
1698 {
1699  USE_UNWANTED_PARAM(userData);
1700 
1701  /* Re-enable event processing following a failed Application Launch/Spawn/Quit */
1702  MHEG5enableEventProcessing(MHEG5TRUE);
1703  if (currentApplication)
1704  {
1705  /* Raise a GroupIDRefError engine event */
1706  MHEG5sendEvent((MHEG5Root *)currentApplication, MHEG5ENGINEEVENT, EE_GROUP_ID_REF_ERROR );
1707  }
1708 
1709  TRACE(TERROR, ("%d, Failed to retrieve App %.*s", applStackCount, (int)launchAppName.len, launchAppName.data))
1710 
1711  assert( launchAppName.len );
1712 
1713  if (applStackCount == 0)
1714  {
1715  if (applStack[0].app_name.data == launchAppName.data)
1716  {
1717  #ifndef CI_PLUS_ONLY
1718  if (applStack[0].carousel_handle != NULL)
1719  {
1720  /* NDT app had spawned app2 which then quit,
1721  * the original NDT app is not on carousel so do reboot */
1722  MHEG5StartReboot(NULL);
1723  }
1724  #endif
1725  applStack[0].app_name.data = NULL;
1726  }
1727  }
1728  else if (applStack[applStackCount].spawned)
1729  {
1730  /* spawn failed */
1731  applStackCount--;
1732  }
1733 
1734  MHEG5stringDestruct( &launchAppName );
1735 }
1736 
1741 static void MHEG5applicationBootFail( void *userData )
1742 {
1743  S_BOOT_DATA *pBootData = (S_BOOT_DATA *)userData;
1744  U32BIT stage = pBootData->stage;
1745  MHEG5String oldName = launchAppName;
1746 
1747  TRACE(TMHBOOT, ("%d, Failed to retrieve App %.*s", applStackCount, (int)launchAppName.len, launchAppName.data))
1748 
1749  assert( pBootData );
1750  assert( launchAppName.len );
1751  assert( currentApplication == NULL );
1752  assert( applStackCount == 0 );
1753  assert( pBootData->origin < 3 );
1754 
1755  switch (stage)
1756  {
1757  case 0: launchAppName.len = oldName.len + 2; break;
1758  case 1: launchAppName.len = oldName.len + 6; break;
1759  case 2: launchAppName.len = boot_origins[pBootData->origin].len + 1; break;
1760  case 3: launchAppName.len = boot_origins[pBootData->origin].len + 7; break;
1761  default: launchAppName.len = 0;
1762  }
1763  if (launchAppName.len)
1764  {
1765  launchAppName.data = (MHEG5Byte *) STR_DataAlloc( launchAppName.len );
1766  if (launchAppName.data == 0)
1767  {
1768  TRACE(TERROR, ("Out of Memory"))
1769  launchAppName.len = 0;
1770  MHEG5stringDestruct( &oldName );
1771  }
1772  else
1773  {
1774  switch (stage)
1775  {
1776  case 0:
1777  memcpy(launchAppName.data, oldName.data, oldName.len);
1778  launchAppName.data[oldName.len] = '/';
1779  launchAppName.data[oldName.len + 1] = 'a';
1780  break;
1781 
1782  case 1:
1783  memcpy(launchAppName.data, oldName.data, oldName.len);
1784  launchAppName.data[oldName.len - 1] = '\0'; /* overwrite 'a' */
1785  strcat((char *)launchAppName.data, "startup");
1786  break;
1787 
1788  case 2:
1789  strcpy((char *)launchAppName.data, (char *)boot_origins[pBootData->origin].data );
1790  strcat((char *)launchAppName.data, "a");
1791  break;
1792 
1793  case 3:
1794  strcpy((char *)launchAppName.data, (char *)boot_origins[pBootData->origin].data );
1795  strcat((char *)launchAppName.data, "startup");
1796  break;
1797 
1798  default:
1799  assert( 0 );
1800  }
1801  }
1802  pBootData->stage++;
1803  MHEG5stringDestruct( &oldName );
1804 
1805  BootupFileOrmHandle = MHEG5FileOrmGet( launchAppName, FRP_APPLICATION | FRP_CACHE_DEFAULT,
1806  (void *)pBootData, MHEG5applicationRetrieved, MHEG5applicationBootFail );
1807  }
1808  else
1809  {
1810  MHEG5stringDestruct( &oldName );
1811  /* Notify that we were unable to find the startup application */
1812  MHEG5NotifyEngineStartFailed();
1813  }
1814  BootupFileOrmHandle = NULL;
1815 }
1816 
1828 MHEG5ErrorCode MHEG5applicationLaunch(MHEG5String gname, MHEG5Int id)
1829 {
1830  MHEG5ErrorCode err = MHEG5ERR_NOERROR;
1831  TRACE((TFILE | TPERFORM), ("Launch App %.*s", (int)gname.len, gname.data))
1832 
1833  USE_UNWANTED_PARAM(id);
1834 
1835  assert( launchAppName.len == 0 );
1836 
1837  launchAppName = MHEG5convertGID( &gname );
1838 
1839  if (launchAppName.len == 0)
1840  {
1841  ERROR_PRINT(("ERROR: MHEG5Applaunch - failed to resolve path\n"));
1842  if (currentApplication != NULL)
1843  {
1844  /* Generate GroupIDRefError EngineEvent */
1845  MHEG5sendEvent((MHEG5Root *)currentApplication, MHEG5ENGINEEVENT, 2);
1846  }
1847  err = MHEG5ERR_IGNORE_ACTION; /*could have something else*/
1848  }
1849  else
1850  {
1851  assert( launchAppName.data );
1852 
1853  /* The file retrieval process is asynchronous, but any queued actions
1854  * should not be processed until the file is loaded. Therefore we
1855  * disable event processing whilst loading this file.
1856  */
1857  MHEG5enableEventProcessing(MHEG5FALSE);
1858 
1859  TRACE(TFILE | TEVNTS, ("(%.*s)", (int)launchAppName.len, launchAppName.data))
1860 
1861  /* Retreive the file. We do not know the content cache priority yet, so
1862  * use the default
1863  */
1864  (void) MHEG5FileOrmGet( launchAppName, FRP_APPLICATION | FRP_CACHE_DEFAULT,
1865  NULL, MHEG5applicationRetrieved, MHEG5applicationRetrieveFail );
1866  }
1867  return err;
1868 }
1869 
1889 MHEG5ErrorCode MHEG5applicationBootup( char *app_name, BOOLEAN single )
1890 {
1891  static S_BOOT_DATA BootData;
1892  MHEG5String name;
1893  MHEG5ErrorCode err = MHEG5ERR_NOERROR;
1894 
1895 #ifndef NDEBUG
1896  assert( currentApplication == NULL );
1897 #else
1898  if (currentApplication != NULL)
1899  {
1900  return MHEG5ERR_NOERROR;
1901  }
1902 #endif
1903 
1904  /* Check provided appliction name not blank */
1905  if ((app_name == NULL) || (strlen(app_name) == 0))
1906  {
1907  BootData.stage = 3;
1908  #ifdef INCLUDE_IC
1910  {
1911  BootData.origin = ORIGIN_HYBRID;
1912  }
1913  else
1914  #endif
1915  {
1916  BootData.origin = ORIGIN_DSM;
1917  }
1918 
1919  launchAppName.len = boot_origins[BootData.origin].len + 1;
1920 
1921  launchAppName.data = (MHEG5Byte *) STR_DataAlloc( launchAppName.len );
1922  if (launchAppName.data == 0)
1923  {
1924  TRACE(TERROR, ("Out of Memory"))
1925  launchAppName.len = 0;
1926  }
1927  else
1928  {
1929  strcpy((char *)launchAppName.data, (char *)boot_origins[BootData.origin].data );
1930  strcat((char *)launchAppName.data, "a" );
1931  }
1932  }
1933  else
1934  {
1935  name.len = 0;
1936  /* Replace all '\' with '/' */
1937  while (app_name[name.len] != '\0')
1938  {
1939  if (app_name[name.len] == '\\')
1940  {
1941  app_name[name.len] = '/';
1942  }
1943  name.len++;
1944  }
1945 
1946  /* Remove all '/' from end of application name */
1947  while (name.len != 0 && app_name[name.len - 1] == '/')
1948  {
1949  name.len--;
1950  app_name[name.len] = '\0';
1951  }
1952 
1953  name.data = (MHEG5Byte *)app_name;
1954 
1955  /* Convert using name mapping rules */
1956  launchAppName = MHEG5convertGIDGetOrigin( &name, &BootData.origin );
1957  if (launchAppName.len != 0)
1958  {
1959  if ( BootData.origin == ORIGIN_CI || single )
1960  {
1961  BootData.stage = 4;
1962  }
1963  else
1964  {
1965  /* DSM-CC or hybrid origin */
1966  BootData.stage = 0;
1967  }
1968  }
1969  }
1970  TRACE(TMHBOOT | TFILE, ("(%.*s)", (int)launchAppName.len, launchAppName.data))
1971  if (launchAppName.len)
1972  {
1973  MHEG5setWorkingDir( launchAppName );
1974  BootupFileOrmHandle = MHEG5FileOrmGet( launchAppName, FRP_APPLICATION | FRP_CACHE_DEFAULT,
1975  &BootData, MHEG5applicationRetrieved, MHEG5applicationBootFail );
1976  }
1977  else
1978  {
1979  err = MHEG5ERR_TARGETNOTAVAILABLE;
1980  TRACE(TERROR, (""))
1981  }
1982  return err;
1983 }
1984 
1990 {
1991  if (BootupFileOrmHandle != NULL)
1992  {
1993  MHEG5FileOrmClear( BootupFileOrmHandle );
1994 
1995  MHEG5stringDestruct( &launchAppName );
1996  }
1997 }
1998 
2007  MHEG5Group *group)
2008 {
2009  MHEG5Ingredient *item;
2010  MHEG5Link *link;
2011 
2012  /* Check every link */
2013  item = application->group.itemHead;
2014  while (item)
2015  {
2016  /* Check whether this item is an initially active stream object */
2017  if ((item->root.clazz == MHEG5LINK) &&
2018  (item->root.availabilityStatus == MHEG5TRUE))
2019  {
2020  link = (MHEG5Link *)item;
2021  ClearGroupTargets(link->linkEffect, group);
2022  }
2023  item = item->next;
2024  }
2025 
2026  /* Check OnSpawnCloseDown */
2027  ClearGroupTargets(application->onSpawnCloseDown, group);
2028 
2029  /* Check OnRestart */
2030  ClearGroupTargets(application->onRestart, group);
2031 }
2032 
2039 {
2040  MHEG5Ingredient *item;
2041  MHEG5Link *link;
2042 
2043  /* Check every link */
2044  item = application->group.itemHead;
2045  while (item)
2046  {
2047  /* Check whether this item is an initially active stream object */
2048  if ((item->root.clazz == MHEG5LINK) &&
2049  (item->root.availabilityStatus == MHEG5TRUE))
2050  {
2051  link = (MHEG5Link *)item;
2052  MHEG5queueResolveTargets(link->linkEffect);
2053  }
2054  item = item->next;
2055  }
2056 
2057  /* Check OnSpawnCloseDown */
2058  MHEG5queueResolveTargets(application->onSpawnCloseDown);
2059 
2060  /* Check OnRestart */
2061  MHEG5queueResolveTargets(application->onRestart);
2062 }
2063 
2064 MHEG5ErrorCode MHEG5launch(MHEG5Root *target, MHEG5GList *params)
2065 {
2066  MH5GroupRef gref;
2067  MHEG5Int id = 0;
2068  MHEG5ErrorCode err;
2069 
2070  /* Resolve a generic object reference, returning groupName and Id of the
2071  * reference
2072  */
2073  MHEG5resolveGenericORefProper(params, &gref, &id);
2074 
2075  if ((id != 0) || (gref.len == 0))
2076  {
2077  ERROR_PRINT(("ERROR: MHEG5launch - id not zero (%ld) or name len zero (%ld)\n", id, gref.len));
2078  err = MHEG5ERR_IGNORE_ACTION; /*could have something else*/
2079  }
2080  else if (currentApplication && MHEG5sameGroup(&currentApplication->group, gref))
2081  {
2082  /* Ignore a Spawn to the currently running Application */
2083  WARNING_PRINT(("MHEG5launch - abort, application already active\n"));
2084  err = MHEG5ERR_IGNORE_ACTION;
2085  }
2086  else
2087  {
2088  MHEG5String name;
2089  name.len = gref.len;
2090  name.data = gref.ptr.name;
2091  TRACE((TFILE | TPERFORM), ("launch app %.*s id=%ld", (int)name.len, name.data, id))
2092  err = MHEG5applicationLaunch( name, id);
2093  }
2094  return err;
2095 }
2096 
2108 MHEG5ErrorCode MHEG5spawn(MHEG5Root *target, MHEG5GList *params)
2109 {
2110  MHEG5ErrorCode err = MHEG5ERR_IGNORE_ACTION;
2111 
2112  if (applStackCount < (MAX_APPS - 1))
2113  {
2114  applStackCount++;
2115  applStack[applStackCount].app_name.len = 0;
2116  applStack[applStackCount].app_name.data = NULL;
2117  applStack[applStackCount].carousel_handle = NULL;
2118  applStack[applStackCount].spawned = MHEG5TRUE;
2119 
2120  err = MHEG5launch(target, params);
2121  if (err != MHEG5ERR_NOERROR)
2122  {
2123  /* Spawn failed, restore stack pointer */
2124  applStackCount--;
2125  }
2126  }
2127  else
2128  {
2129  /* stack is full, launch instead */
2130  err = MHEG5launch(target, params);
2131  }
2132 
2133  return err;
2134 }
2135 
2145 MHEG5ErrorCode MHEG5quit(MHEG5Root *target, MHEG5GList *params)
2146 {
2147  assert(target);
2148 
2149  if (target != (MHEG5Root *) currentApplication)
2150  {
2151  return MHEG5ERR_WRONGTARGET;
2152  }
2153 
2154  MHEG5quitApp();
2155 
2156  return MHEG5ERR_NOERROR;
2157 }
2158 
2163 void MHEG5quitApp(void)
2164 {
2165  MHEG5Scene *scene;
2166  MHEG5Application *application;
2167 
2168  /* Prevent event processing while we destruct the scene and application,
2169  * And reset the event and action queues*/
2171 
2172  /* 1. Apply the Destruction behaviour of the currently active
2173  * Scene object, if any.
2174  */
2175  scene = MHEG5getCurrentScene();
2176  if (scene != 0)
2177  {
2178  MHEG5sceneDestruct(scene);
2179  MHEG5sceneFree(scene);
2180  MHEG5freeMem(scene);
2181  }
2182 
2183  /* 2. Apply the Destruction behaviour of the target Application
2184  * object.
2185  */
2186  application = currentApplication;
2187  if (application != 0)
2188  {
2189  /* During destruction of an application triggered by Quit, Launch
2190  * or Spawn actions, any stream decoder associated with Stream
2191  * objects are not stopped. See UK1.05 section 6.3.4
2192  */
2193  application->streamContinuanceFlag = MHEG5TRUE;
2194  MHEG5applicationDestruct(application);
2195  MHEG5applicationFree(application);
2196  MHEG5freeMem(application);
2197  currentApplication = NULL;
2198  }
2199 
2200 #ifdef MHG_TRACK_MEM
2201  /* -- Debug code - print engine memory tracking state */
2202  TRACE(TMEMORY, ("quit app done"))
2203  mh5emt_print(1 << SRCMEM_APP);
2204 #endif
2205 
2206  /* Reset receiver to default state */
2208 
2209  /* Enable event processing again */
2210  MHEG5queueEvents();
2211 
2212  if (applStackCount != 0)
2213  {
2214  MHEG5unloadApp();
2215 
2216  /* We have popped an Application from the stack. Now restart it. */
2217  Restarted = MHEG5TRUE;
2218 
2219  /* Launch the application that we have just popped off the stack */
2220  MHEG5FileOrmReset(MHEG5_FILE_ORM_RESET_ALL_OBJECTS);
2221  TRACE(TFILE, ("relaunching App"))
2222  MHEG5enableEventProcessing(MHEG5FALSE);
2223  launchAppName = applStack[applStackCount].app_name;
2224  applStack[applStackCount].app_name.len = 0; /* launchAppName owns the data for now */
2225  #ifdef INCLUDE_IC
2227  #endif
2228  (void)MHEG5FileOrmGet( launchAppName, FRP_APPLICATION | FRP_CACHE_DEFAULT, NULL,
2229  MHEG5applicationRetrieved, MHEG5applicationRetrieveFail );
2230  }
2231  else
2232  {
2233  /* The application stack is empty. */
2234  TRACE(TFILE, ("Restart Boot App"))
2235 
2236  /* Clear any outstanding file requests */
2237  MHEG5FileOrmReset(MHEG5_FILE_ORM_RESET_ALL_OBJECTS);
2238 
2239  /* Reset the media decoders to their default state */
2241 
2242  /* Clear current service */
2244 
2245  /* Notify that the final Application has Quit. */
2246  MHEG5NotifyEngineQuit();
2247 
2249 
2250  MHEG5StartReboot(NULL);
2251  }
2252 }
2253 
2263 MHEG5ErrorCode MHEG5lockScreen(MHEG5Root *target, MHEG5GList *params)
2264 {
2265  assert(target);
2266 
2267  if (target != (MHEG5Root *) currentApplication)
2268  {
2269  return MHEG5ERR_WRONGTARGET;
2270  }
2271 
2272  DEBUG_PRINT((" Old lockCount is %d\n", currentApplication->lockCount));
2273 
2274  if (currentApplication->lockCount <= 0)
2275  {
2276  currentApplication->lockCount = 0;
2277 
2278  /* Update the on screen display before locking the screen */
2280  }
2281  currentApplication->lockCount++;
2282  DEBUG_PRINT((" New lockCount is %d\n", currentApplication->lockCount));
2283 
2284  return MHEG5ERR_NOERROR;
2285 }
2286 
2297 MHEG5ErrorCode MHEG5unlockScreen(MHEG5Root *target, MHEG5GList *params)
2298 {
2299  assert(target);
2300 
2301  if (target != (MHEG5Root *) currentApplication)
2302  {
2303  return MHEG5ERR_WRONGTARGET;
2304  }
2305 
2306  DEBUG_PRINT((" Old lockCount is %d\n", currentApplication->lockCount));
2307 
2308  currentApplication->lockCount--;
2309  if (currentApplication->lockCount < 0)
2310  {
2311  currentApplication->lockCount = 0;
2312  }
2313  DEBUG_PRINT((" New lockCount is %d\n", currentApplication->lockCount));
2314 
2315  return MHEG5ERR_NOERROR;
2316 }
2317 
2318 #ifndef MHEG5PROFILE_UK1_06
2319 
2328 MHEG5ErrorCode MHEG5openConnection(MHEG5Root *target, MHEG5GList *params)
2329 {
2330  USE_UNWANTED_PARAM(params);
2331  return MHEG5ERR_NOTSUPPORTEDBYPROFILE;
2332 }
2333 
2343 MHEG5ErrorCode MHEG5closeConnection(MHEG5Root *target, MHEG5GList *params)
2344 {
2345  USE_UNWANTED_PARAM(params);
2346  return MHEG5ERR_NOTSUPPORTEDBYPROFILE;
2347 }
2348 
2349 #endif
2392 MHEG5ErrorCode MHEG5getEngineSupport(MHEG5Root *target, MHEG5GList *params)
2393 {
2394  MHEG5GList *thirdParam = 0;
2395  MHEG5Root *bVar;
2396  MHEG5String feature;
2397  MHEG5Bool invalidString;
2398 
2399  assert(target);
2400 
2401  if (target != (MHEG5Root *) currentApplication)
2402  {
2403  return MHEG5ERR_WRONGTARGET;
2404  }
2405  if (!params)
2406  {
2407  return MHEG5ERR_WRONGNUMBEROFPARAMS;
2408  }
2409  thirdParam = MHEG5resolveGenericOctetString(params, &feature, &invalidString);
2410  if (invalidString)
2411  {
2412  /* Parameter was not an octet string */
2413  return MHEG5ERR_WRONGPARAM;
2414  }
2415  if (!thirdParam)
2416  {
2417  return MHEG5ERR_WRONGNUMBEROFPARAMS;
2418  }
2419  MHEG5resolveORef(thirdParam, &bVar);
2420  if (!bVar)
2421  {
2422  return MHEG5ERR_WRONGNUMBEROFPARAMS;
2423  }
2424  if (bVar->clazz != MHEG5BOOLEANVARIABLE)
2425  {
2426  return MHEG5ERR_WRONGPARAM;
2427  }
2428 
2429  if (feature.len < 3)
2430  {
2431  ((MHEG5BooleanVariable *) bVar)->value = MHEG5FALSE;
2432  }
2433  else
2434  {
2435  ((MHEG5BooleanVariable *) bVar)->value = MH5_GetEngineSupport( feature );
2436  }
2437 
2438  return MHEG5ERR_NOERROR;
2439 }
2440 
2451 MHEG5ErrorCode MHEG5setDesktopColour(MHEG5Root *target, MHEG5GList *params)
2452 {
2453  MHEG5Colour newDesktopColour;
2454 
2455  assert(target);
2456 
2457  if (target != (MHEG5Root *) currentApplication)
2458  {
2459  return MHEG5ERR_WRONGTARGET;
2460  }
2461  if (!params)
2462  return MHEG5ERR_WRONGNUMBEROFPARAMS;
2463  MHEG5resolveGenericGeneric(params, &newDesktopColour);
2464 
2465  MHEG5genericCopy(&currentApplication->desktopColour, &newDesktopColour);
2466 
2468 
2469  return MHEG5ERR_NOERROR;
2470 }
2471 
void MH5_SetCurrentProfile(E_ProfileId profile)
Set current profile - CI plus or broadcast (Could extend this fnc to distuinguish between UK/HK/NZ/AU...
Definition: mh5support.c:528
Implement MHEG5 engine control functions (i.e. start/stop etc)
void MHEG5sceneDestruct(MHEG5Scene *scene)
Destruct a scene object.
Definition: mh5scene.c:446
void MHEG5groupDestruct(MHEG5Group *group)
Implementation of the Destruction behaviour Destruction.
Definition: mh5group.c:497
MHEG5Bool MHEG5storageRead(MHEG5String fn, void **buf, MHEG5Int *len)
Read a file from the persistent store.
Definition: mh5storage.c:297
MHEG5Bool MHEG5sameGroup(MH5GroupPtr gptr, MH5GroupRef gref)
Compares group ptr with group ref to see whether they both reference the same group. The first is pointer to group, the second can be a relative group name and will be converted to absolute prior to the comparison, so two different references that resolve to reference the same group name produces a True return value.
Definition: mh5gate.c:517
void MHEG5applicationBootAbort(void)
Aborts launch of Boot Application.
MHEG5Int MHEG5variableStore(MHEG5Ingredient *v, void *buf, MHEG5Int bufLen)
This functions stores the value of a variable in the persistant storage. Implementation of the StoreP...
Definition: mh5variable.c:1437
Interface functions to DSM-CC instance for MHEG5.
void MHEG5applicationClearGroupTargets(MHEG5Application *application, MHEG5Group *group)
Clear targets of actions if they are ingredients of the given group.
MHEG5ErrorCode MHEG5readPersistent(MHEG5Root *target, MHEG5GList *params)
Implementation of the ReadPersistent (ReadSucceded, OutVariables, InFileName) action from the applica...
void MHEG5queueEvents(void)
Allow future events to be stored in the event queues. See also MHEG5stopEventsAndQueueReset.
Definition: mh5queue.c:1528
MHEG5ErrorCode MHEG5unlockScreen(MHEG5Root *target, MHEG5GList *params)
Impelemtation of the UnlockScreen action of the application class This action may refresh the display...
True Persistent Storage functions.
void MHEG5sceneFree(MHEG5Scene *scene)
Free off all memory associated with the specified object, including any exchanged attributes and inte...
Definition: mh5scene.c:395
void MHEG5actionListExecute(MHEG5Group *source, MHEG5ActionList actions)
Execute the supplied list of actions immediately. The actions will have been executed by the time the...
Definition: mh5queue.c:1400
void MHEG5applicationResolveTargets(MHEG5Application *application)
Resolve unresolved targets of actions in the application.
void MHEG5SuppressMHEGGraphics(MHEG5Bool request)
Request that the external application toggles between showing MHEG graphics or subtitles This functio...
void MHEG5displayUpdate(void)
Update the display, redrawing any visible objects that are in the dirty rectangle.
Definition: mh5display.c:2035
MHEG5Application * asn1_parseApplication(unsigned char *asnData, unsigned long dataLength)
Top level ASN.1 parser interface function. Creates and fills a MHEG5Application object from a char ar...
MHEG5 queue.
void MHEG5groupInit(MHEG5Group *group)
Initialise an Group object with default Values.
Definition: mh5group.c:285
MHEG5Bool MHEG5TpsWrite(MHEG5String fn, void *data, MHEG5Int len)
Write data passed from the application into the TPS stroe.
Definition: mh5tps.c:196
void MHEG5TpsClose()
Close the clear the store and delete the cache none.
Definition: mh5tps.c:252
MHEG5ErrorCode MHEG5lockScreen(MHEG5Root *target, MHEG5GList *params)
Implementation of the LockScreen action of the application class Freeze the display screen and preven...
void MHEG5groupDeactivate(MHEG5Group *group)
Implementation of the Deactivation behaviour Deactivation If group is not active, ignore behaviour...
Definition: mh5group.c:802
void MHEG5groupFree(MHEG5Group *group)
Free off all memory associated with the specified object, including any exchanged attributes and inte...
Definition: mh5group.c:315
void MHEG5applicationInit(MHEG5Application *application)
Initialise an application object with default values. This function initialises an application object...
MHEG5Bool MHEG5nvmWrite(MHEG5String fn, void *buf, MHEG5Int len)
Write a file to the persistent store.
Definition: mh5nvm.c:171
void MHEG5applicationFree(MHEG5Application *application)
Free off all memory associated with the specified object, including any exchanged attributes and inte...
MHEG5Root * MHEG5displayStackGetVisible(MHEG5DisplayStackItem *item)
This function returns the visible at a specific display stack positon.
MHEG5Int MHEG5variableRead(MHEG5Ingredient *v, char *buf, MHEG5Int max_size)
This functions reads the value of a variable from the persistant storage. Implementation of the ReadP...
Definition: mh5variable.c:1509
void * MHEG5FileOrmGet(MHEG5String name, U16BIT priority, void *userData, F_CB_Good cbGood, F_CB_Fail cbFail)
Get a file. The file will be loaded and one of the callback functions called when request is resolved...
Definition: mh5fileorm.c:1179
void MHEG5genericCopy(MHEG5Generic *dest, MHEG5Generic *src)
Copy a MHEG5Generic.
Definition: mh5base.c:861
Miscellaneous.
void * MHEG5_DsmccInstance(void)
Get the DSMCC instance handle.
Definition: glue_dsmcc.c:778
void MHEG5groupPrepare(MHEG5Group *group)
Implementation of the Preparation behaviour Preparation.
Definition: mh5group.c:349
MHEG5Bool MHEG5storageWrite(MHEG5String fn, void *buf, MHEG5Int len)
Write a file to the persistent store.
Definition: mh5storage.c:164
Interface functions for invoking the ASN.1 parser.
void MHEG5applicationPrepare(MHEG5Application *application)
Apply the group preparation behaviour.
E_ProfileId MH5_GetCurrentProfile(void)
Get current profile - CI plus or broadcast.
Definition: mh5support.c:551
void MHEG5FileOrmReset(MHEG5FileOrmResetMode resetMode)
Reset the ORM module. This function supports two modes:
Definition: mh5fileorm.c:595
void MHEG5applicationDestruct(MHEG5Application *application)
Destruct an application object. This function destructs all parts of an application object...
MHEG5DisplayStackItem * MHEG5displayStackPrev(MHEG5DisplayStackItem *item)
This function returns a pointer to the previous item in the display stack. The input parameter is a D...
void MHEG5restoreReceiverDefaults(void)
Restore receiver defaults as described in section 3.12.10 of the 1.06 profile.
Definition: mh5misc.c:397
Implement the MHEG5 Variable Class 21 Variable Class Defines a variable within the context of a Group...
MHEG5ErrorCode MHEG5spawn(MHEG5Root *target, MHEG5GList *params)
Implementation of the Spawn action from the application class +Execute the OnSpawnCloseDown Action of...
void MHEG5stringDestruct(MHEG5String *item)
Destruct a MHEG5String.
Definition: mh5base.c:686
MHEG5Int MH5_MaxStorageFileLength(void)
Return maximum length of file for persistent storage depending on supported profiles (e...
Definition: mh5support.c:574
void MHEG5stopEventsAndResetQueue(void)
Discard any pending events and actions and prevent future events from being queued. And reset queues. See also MHEG5queueEvents.
Definition: mh5queue.c:914
MHEG5Bool MHEG5displayStackDelete(MHEG5Root *visible)
This function removes the reference to a visible object from the display stack.
Freesat NVM.
MHEG5ErrorCode MHEG5setDesktopColour(MHEG5Root *target, MHEG5GList *params)
Impelemtation of the SetDesktopColour action of the application class This action may refresh the dis...
void MHEG5displayVideoStop(void)
Stops playback of the video media decoder.
Definition: mh5display.c:2468
MHEG5Application * MHEG5getCurrentApplication(void)
Retrieve the current Application.
OSDColor OSDgetColour(const char *colour, int len)
Converts an MHEG5 colour value to an OSDColor type.
Definition: tmcolor.c:53
MHEG5ErrorCode MHEG5closeConnection(MHEG5Root *target, MHEG5GList *params)
Impelemtation of the CloseConnection(ConnectionTag) action of the application class |NOT IMPLEMENTED...
void MHEG5streamClearCurrentService(void)
Clear the current service.
Definition: mh5stream.c:1274
void MHEG5FileOrmClear(void *orm_ref)
Aborts a request for file.
Definition: mh5fileorm.c:979
void MHEG5displayStackToBottom(MHEG5Root *visible)
Move a visible to the Bottom of the display stack.
Persistent storage module. The engine provides a persistent storage for 1024 bytes of data...
void MHEG5displayAudioStop(void)
Stops playback of the audio media decoder.
Definition: mh5display.c:2450
void MHEG5displayStackToTop(MHEG5Root *visible)
Move a Visible to the Top of the display stack.
void MHEG5ClearTlsCertStore(void)
Clear the TLS certificate store.
Definition: mh5tls.c:86
This file defines the profile for the MHEG engine.
MHEG5DisplayStackItem * MHEG5displayStackBottom(void)
This function returns a pointer to the DisplayStackItem at the Bottom of the Stack.
MHEG5GList * MHEG5resolveGenericOctetString(MHEG5GList *params, MHEG5String *value, MHEG5Bool *invalidString)
Resolve a parameter reference to a generic octet string. The reference can be either direct or indire...
Definition: mh5object.c:478
void MHEG5displayStackAdd(MHEG5Root *visible, MHEG5Bool atTop)
This function adds a visible to the display stack. The parameter atTop defines if the Visible is adde...
Implement Functions to support Service Gateways. Functions for standarizing several GroupIDs like +DS...
MHEG5Bool MHEG5TpsRead(MHEG5String fn, void **data, MHEG5Int *len)
Read a file from the TPS store and pass it back to the application.
Definition: mh5tps.c:157
MHEG5String MHEG5convertGIDGetOrigin(MHEG5String *inRef, E_FS_ORIGIN *pOrigin)
Convert a group ID from a relative reference to an absolute reference. See UK1.05 section 8...
Definition: mh5gate.c:282
void MHEG5setWorkingDir(MHEG5String source)
Set the working directory for the current application. This is used to resolve relative paths...
Definition: mh5gate.c:583
Event handling. Implementation of a combined queue for events and actions. This is the eventsystem wh...
Functions relating to HTTPS Server Access.
MHEG5ErrorCode MHEG5quit(MHEG5Root *target, MHEG5GList *params)
Implementation of the Quit action from the application class Close an application and restart the pre...
void MHEG5ActivateCurrentApplication(void)
Apply the group activation behaviour.
void MHEG5displayStackPutBehind(MHEG5Root *target, MHEG5Root *refVisible)
Put a Visible exactly below another Visible in the display stack.
void MHEG5displayStackPutBefore(MHEG5Root *target, MHEG5Root *refVisible)
Put a Visible exactly in front of another Visible in the display stack.
void MHEG5quitApp(void)
Close an application because of the Quit Application Event defined by DTG.
Implement functions to retrieve MHEG5objects by GroupID and ID.
Implementation of the MHEG5 Application Class Defines a set of Ingredient objects, which are shared within an application scope. Base class: Group Subclasses: None Status: Concrete class.
Mheg5 logging and debug printing.
MHEG5ErrorCode MHEG5storePersistent(MHEG5Root *target, MHEG5GList *params)
Implementation of the StorePersistent (StoreSucceeded, InVariables, OutFileName) action from the appl...
MHEG5Bool MH5_SupportMhegProfile(E_MHEG_PROFILE profile)
Return whether Mheg profile (UK, NZ, AU, HK, SA, FREESAT) is currently supported. ...
Definition: mh5support.c:451
Persistent storage module. The engine provides a persistent storage for 1024 bytes of data...
MHEG5ErrorCode MHEG5openConnection(MHEG5Root *target, MHEG5GList *params)
Impelemtation of the OpenConnection (OpenSucceeded, Protocol, Address, ConnectionTag) action of the a...
File interface functions to DSMCC component.
MHEG5DisplayStackItem * MHEG5displayStackPrevVisible(MHEG5Root *visible)
This function returns a pointer to the previous item in the display stack. The input parameter is a V...
redirection include
void MHEG5actionDestruct(MHEG5ActionList actions)
<Function description>="">
Definition: mh5action.c:118
void MHEG5PopHybridFileSystem(void)
Clear the current hybrid file system and pop a stored hybrid file system from the stack...
Definition: mh5hfs.c:141
void MHEG5displayLockStreams(void)
Lock streams, disallow any stream updates.
Definition: mh5display.c:2954
MHEG5ErrorCode MHEG5applicationLaunch(MHEG5String gname, MHEG5Int id)
Implementation of the Launch action from the application class Activate a new application by flushing...
MHEG5Scene * MHEG5getCurrentScene(void)
<Function description>="">
Definition: mh5scene.c:207
void MHEG5sendEvent(MHEG5Root *source, MHEG5EventType event, MHEG5Int data)
Store an event in the asynchronous event queue.
Definition: mh5queue.c:1540
void MHEG5PushHybridFileSystem(void)
Push a copy of the current hybrid file system into the stack.
Definition: mh5hfs.c:131
Functions relating to TLS certificate store.
MHEG5Bool MH5_SupportInteractionChannel(void)
Return whether Interaction channel is supported by current profile.
Definition: mh5support.c:423
void MHEG5queueResolveTargets(MHEG5ActionList actions)
Finds targets for the action list.
Definition: mh5queue.c:1182
Definition of colour type for MHEG5 - settings and conversions.
void MHEG5displayShowAll(void)
Redisplay all active visible objects. AKD: Optimised 12/5/99.
Definition: mh5display.c:1362
MHEG5String MHEG5convertGID(MHEG5String *inRef)
Convert a group ID from a relative reference to an absolute reference. See UK1.05 section 8...
Definition: mh5gate.c:269
void MHEG5displayResetStreamDecoders(BOOLEAN update)
Reset all media decoders to default values. This is used when the MHEG-5 engine is terminated...
Definition: mh5display.c:2909
void MHEG5applicationDeactivate(MHEG5Application *application)
Apply the application deactivation behaviour +Apply the CloseConnection action to all opened auxiliar...
MHEG5ErrorCode MHEG5applicationBootup(char *app_name, BOOLEAN single)
Launches Boot Application according to name rules: This function will authenticate and resolve a file...
Implement generic MHEG5-display functions - independent from the OSD These are generic functions used...
void MHEG5displayRtgraphicsStop(void)
Stops playback of the RTGraphics (subtitle) media decoder.
void MHEG5enableEventProcessing(MHEG5Bool enable)
Enable or disable engine event processing. This function is used to implement the Call action for res...
Definition: mh5queue.c:1751
MHEG5Bool MHEG5nvmRead(MHEG5String fn, void **buf, MHEG5Int *len)
Read a file from the persistent store.
Definition: mh5nvm.c:109
Functions relating to Hybrid file system.
void MHEG5displayClear(void)
<Function description>="">
Definition: mh5display.c:220
MHEG5GList * MHEG5resolveGenericORefProper(MHEG5GList *params, MH5GroupRef *pgroupRef, MHEG5Int *id)
Resolve a generic object reference, returning the object reference. The reference can be direct or in...
Definition: mh5object.c:177
Engine support utility functions for MHEG5.
MHEG5Bool MH5_GetEngineSupport(MHEG5String feature)
Used by the GetEngineSupport action.
Definition: mh5support.c:584
void MHEG5groupActivate(MHEG5Group *group)
Implementation of the Activation behaviour Activation.
Definition: mh5group.c:672
#define TRACE(t, x)
Definition: glue_debug.h:118