MHEG5  18.9.0
MHEG5 Documentation
mh5program.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  *******************************************************************************/
27 /*---includes for this file--------------------------------------------------*/
28 #include "mh5program.h"
29 #include "mh5object.h" /* for actions */
30 #include "mh5variable.h" /* for actions */
31 #include "mh5queue.h" /* Events */
32 #include "mh5final.h" /* for subclasses */
33 #include "mh5prgs.h" /* API to program execution */
34 #include "mh5memory.h" /* constructor/destructor */
35 #include "mh5debug.h"
36 
37 #ifdef MH5PRINTOUT
38 #include <string.h>
39 #endif
40 
41 /*---constant definitions for this file--------------------------------------*/
42 
43 
44 /*---local typedef structs for this file-------------------------------------*/
45 
46 /*---local (static) variable declarations for this file----------------------*/
47 
48 /*---local function definitions----------------------------------------------*/
49 
50 /*---global function definitions---------------------------------------------*/
51 
57 /*
58  Debug
59  */
60 #ifdef MH5PRINTOUT
61 
68 void MHEG5programPrint(MHEG5Program *program, char *out)
69 {
70  MHEG5ingredientPrint(&program->ingredient, out);
71  MHEG5indent(out);
72  MHEG_PRINT(out, ":Name ");
73  MHEG5stringPrint(program->name, out);
74  MHEG5newLine(out);
75 
76  if (!program->initiallyAvailable)
77  {
78  MHEG5indent(out);
79  MHEG_PRINT(out, ":InitiallyAvailable FALSE");
80  MHEG5newLine(out);
81  }
82  if (program->programConnectionTag != 0)
83  {
84  MHEG5indent(out);
85  MHEG_PRINT(out, ":ConnectionTag ");
86  MHEG5intPrint(program->programConnectionTag, out);
87  MHEG5newLine(out);
88  }
89 }
90 
91 #endif
92 
93 
94 /*
95  */
96 
97 /*
98  Constructor
99  */
105 static void MHEG5programInit(MHEG5Program *program)
106 {
107  assert(program);
108 
109  MHEG5ingredientInit(&program->ingredient);
110 
111  program->initiallyAvailable = MHEG5TRUE;
112 }
113 
122 {
123  assert(program);
124 
125  MHEG5ingredientFree(&program->ingredient);
126 
127  MHEG5stringDestruct(&program->name);
128 }
129 
130 /*
131  Constructors for Subclasses (as they have no additional functionality
132  */
139 {
140  assert(program);
141 
142  MHEG5programInit(program);
143 }
144 
153 {
154  assert(program);
155 
156  MHEG5programFree(program);
157 }
158 
165 {
166  assert(program);
167 
168  MHEG5programInit(program);
169 }
170 
179 {
180  assert(program);
181 
182  MHEG5programFree(program);
183 }
184 
191 {
192  assert(program);
193 
194  MHEG5programInit(program);
195 }
196 
205 {
206  assert(program);
207 
208  MHEG5programFree(program);
209 }
210 
211 /*
212  Internal behaviours
213  */
215 {
216  assert(program);
217 
218  MHEG5ProgramSetStartFunc(program);
219 
221 }
222 
223 /*
224  Activation
225  1. If not done during preparation, locate the external procedural code by using
226  the Name attribute.
227  2. If the external procedural code is not found, disregard this action. Otherwise,
228  3. Set the parameters of the external procedural code of the Program as
229  indicated by Parameters.
230  4. Apply the Activation behaviour as inherited from the base class.
231  5. Start execution of the external procedural code synchronously or
232  asynchronously according to the action invoking the execution..
233  6. Set the RunningStatus attribute to True.
234  7. Generate an IsRunning event.
235  */
237 {
238  MHEG5ErrorCode rc;
239  MHEG5Root *callVar;
240 
241  assert(program);
242 
243  /* 1. If not done during preparation, locate the external procedural code by using
244  * the Name attribute.
245  * 2. If the external procedural code is not found, disregard this action.
246  */
247  MHEG5resolveORef(program->parameter, &callVar);
248  if (!callVar || callVar->clazz != MHEG5BOOLEANVARIABLE)
249  {
250  rc = MHEG5ERR_WRONGPARAM;
251  }
252  else if (program->startFunc == NULL)
253  {
254  ((MHEG5BooleanVariable *) callVar)->value = MHEG5FALSE;
255  #ifdef TRACING
256  extra_trace_param = (int)program->name.data;
257  #endif
259  }
260  else
261  {
262  /* The following step is performed as part of the program implementation:
263  *
264  * 3. Set the parameters of the external procedural code of the Program as
265  * indicated by Parameters.
266  */
267  if (!program->ingredient.root.runningStatus)
268  {
269  /* 4. Apply the Activation behaviour as inherited from the base class. */
270  if (!program->ingredient.root.availabilityStatus)
271  {
272  MHEG5ingredientPrepare(&program->ingredient); /*program prepare*/
273  }
274  /* MHEG5ingredientActivate(&program->ingredient); <- this does nothing */
275 
276  /* 5. Start execution of the external procedural code synchronously or
277  * asynchronously according to the action invoking the execution.
278  */
279 
280  /* Set the forkSucceededValue to be NULL. This will be set to a pointer to
281  * an MHEG5Bool if the program implements the fork action (program has not
282  * finished when the program implementation function returns). For all
283  * others it remains NULL and the program will have finished when the
284  * program implementation function ends.
285  */
286  program->forkSucceededValue = NULL;
287 
288  ((MHEG5BooleanVariable *) callVar)->value = MHEG5FALSE;
289  rc = (program->startFunc)(program);
290 
291  /* 6. Set the RunningStatus attribute to True. */
293 
294  /* 7. Generate an IsRunning event. */
295  MHEG5sendSync((MHEG5Root *) program, MHEG5ISRUNNING, 0);
296  }
297  else
298  {
300  }
301  }
302  return rc;
303 }
304 
305 /*
306  Deactivation
307  If the RunningStatus attribute is False, ignore this action. Otherwise, execute the
308  following sequence of actions:
309  1. Force the end of execution of the Program.
310  2. Apply Deactivation behaviour as inherited from the base class.
311  NOTE - The Deactivation behaviour generates an IsStopped event, as defined in
312  Root.
313  */
315 {
316  assert(program);
317  if (program->stopFunc != NULL)
318  {
319  (program->stopFunc)(program);
320  }
321  if (program->ingredient.root.runningStatus)
322  {
324  }
325 }
326 
328 {
329  assert(program);
330  if (program->stopFunc != NULL)
331  {
332  (program->stopFunc)(program);
333  }
335 }
336 
337 /*
338  Actions
339  */
340 /*
341  Call (CallSucceeded, Parameters)
342  Request execution of an external piece of procedural code and wait for the end of
343  execution.
344  Execute the following sequence of actions:
345  1. If the Program is non-available, apply the Preparation behaviour.
346  2. If the Program is active, disregard this action. Otherwise,
347  3. Apply the Activation behaviour.
348  4. Wait for the execution of the external procedural code to finish. If the
349  Program finishes abnormally, set the Variable referenced by CallSucceeded
350  to False; otherwise, set it to True.
351  5. Set the value of the Variables referenced by Parameters to the values
352  returned by the Program (these may be invalid if CallSucceeded is False).
353  6. Apply the Deactivation behaviour.
354 
355  Provisions of use:
356  CallSucceeded shall be set to an active BooleanVariable object.
357  Parameters shall be set to a list of values corresponding to the expected
358  parameters of the external procedural code. The order of the Parameters list
359  shall correspond to the order of parameters of the procedural code. Parameters
360  passed by value shall be set directly to the corresponding value. Parameters
361  passed by reference shall be passed via active Variable objects of the
362  corresponding data type.
363  */
365 {
366  MHEG5ErrorCode rc;
367 
368  if (!params)
369  {
371  }
372  else
373  {
374  /* Check that target class is a subclass of Program */
375  switch (target->clazz)
376  {
377  default:
378  /* Target class is not a subclass of Program */
380  break;
381 
382  case MHEG5REMOTEPROGRAM:
384  /* Target class is not a supported by UK Profile - or any other ..yet */
386  break;
387 
389  /* 1. If the Program is non-available, apply the Preparation behaviour. */
390  if (!target->availabilityStatus)
391  {
393  }
394  /* 2. If the Program is active, disregard this action. */
395  if (target->runningStatus)
396  {
397  rc = MHEG5ERR_NOERROR;
398  }
399  else
400  {
401  /* 3. Apply the Activation behaviour. */
402  ((MHEG5Program *) target)->parameter = params;
403 
404  /* The program is Called, not Forked */
405  ((MHEG5Program *) target)->forked = MHEG5FALSE;
406 
407  rc = MHEG5programActivate((MHEG5Program *)target);
408 
409  /* The following steps are performed by the program implementation:
410  *
411  * 4. Wait for the execution of the external procedural code to finish. If the
412  * Program finishes abnormally, set the Variable referenced by CallSucceeded
413  * to False; otherwise, set it to True.
414  * 5. Set the value of the Variables referenced by Parameters to the values
415  * returned by the Program (these may be invalid if CallSucceeded is False).
416  */
417  /* 6. Apply the Deactivation behaviour - in ProgramCompleted() */
419  }
420  break;
421  }
422  }
423 
424  return rc;
425 }
426 
427 /*
428  Fork (ForkSucceeded, Parameters)
429  Request execution of an external piece of procedural code without waiting for the
430  end of execution.
431  Execute the following sequence of actions:
432  1. If the Program is non-available, apply the Preparation behaviour.
433  2. If the Program is active, disregard this action. Otherwise,
434  3. Apply the Activation behaviour.
435  4. Pass control back to the MHEG-5 engine without waiting for the execution
436  of the external procedural code to finish.
437  When the execution of the external procedural code finishes, execute the following
438  sequence of actions:
439  1. If the Program finishes abnormally, set the Variable referenced by
440  ForkSucceeded to False; otherwise, set it to True.
441  2. Set the value of the Variables referenced by Parameters to the values
442  returned by the Program (these may be invalid if ForkSucceeded is
443  False).
444  3. Apply the Deactivation behaviour.
445  4. Generate an AsynchStopped event.
446  NOTE - Parameters may be modified by the Program, in that case, these
447  parameters are not defined until the Program is normally finished, that is until an
448  AsynchStopped is generated.
449 
450  Provisions of use:
451  ForkSucceeded shall be set to an active BooleanVariable object.
452  Parameters shall be set to a list of values corresponding to the expected
453  parameters of the external procedural code. The order of the Parameters list
454  shall correspond to the order of parameters of the procedural code. Parameters
455  passed by value shall be set directly to the corresponding value. Parameters
456  passed by reference shall be passed via active Variable objects of the
457  corresponding data type.
458  */
460 {
461  MHEG5ErrorCode rc;
462 
463  assert(target);
464 
465  if (!params)
466  {
468  }
469  else
470  {
471  /* Check that target class is a subclass of Program */
472  switch (target->clazz)
473  {
474  default:
475  /* Target class is not a subclass of Program */
477  break;
478 
479  case MHEG5REMOTEPROGRAM:
481  /* Target class is not a supported by UK Profile - or any other ..yet */
483  break;
484 
486  /* 1. If the Program is non-available, apply the Preparation behaviour. */
487  if (!target->availabilityStatus)
488  {
490  }
491  /* 2. If the Program is active, disregard this action. Otherwise, */
492  if (target->runningStatus)
493  {
494  rc = MHEG5ERR_NOERROR;
495  }
496  else
497  {
498  /* 3. Apply the Activation behaviour. */
499  ((MHEG5Program *) target)->parameter = params;
500  ((MHEG5Program *) target)->forked = MHEG5TRUE;
501 
502  rc = MHEG5programActivate((MHEG5Program *)target);
503 
504  if (rc == MHEG5ERR_NOERROR)
505  {
506  if (((MHEG5Program *)target)->forkSucceededValue == NULL)
507  {
508  /* This program was invoked with a Fork action, and has already
509  * finished.
510  * Perform the final steps of the second part of the Fork action:
511  * 3. Apply the Deactivation behaviour.
512  * 4. Generate an AsynchStopped event.
513  */
516  }
517  }
518  }
519  break;
520  }
521  }
522  return rc;
523 }
524 
525 /*
526  void MHEG5stop(target,params)
527  Implemented in Presentable Class!!
528  */
MHEG5Bool availabilityStatus
Definition: mh5root.h:52
MHEG5Bool * forkSucceededValue
Definition: mh5program.h:59
void(* stopFunc)(struct MHEG5Program_struct *)
Definition: mh5program.h:63
void MHEG5ingredientInit(MHEG5Ingredient *ingredient)
Initialise a ingredient object with default values.
MHEG5Int programConnectionTag
Definition: mh5program.h:52
Distributor for Prepare, Destruct, Activate, Deactivate and Clone calls. Distribute the +Prepare +Des...
void MHEG5programDeactivate(MHEG5Program *program)
Definition: mh5program.c:314
void MHEG5programPrepare(MHEG5Program *program)
Definition: mh5program.c:214
MHEG5GList * parameter
Definition: mh5program.h:57
MHEG5String name
Definition: mh5program.h:50
Implement the MHEG5 Program Class Defines means to handle execution of external pieces of procedural ...
MHEG5Final clazz
Definition: mh5root.h:55
void MHEG5ingredientDestruct(MHEG5Ingredient *ingredient)
Implementation of the Destruction behaviour Execute the following sequence of actions: ...
void MHEG5remoteProgramInit(MHEG5Program *program)
Initialise a remoteProgram object with default values.
Definition: mh5program.c:164
MHEG5ErrorCode MHEG5call(MHEG5Root *target, MHEG5GList *params)
Definition: mh5program.c:364
MHEG5Ingredient ingredient
Definition: mh5program.h:47
void MHEG5programFree(MHEG5Program *program)
Free off all memory associated with the specified object, including any exchanged attributes and inte...
Definition: mh5program.c:121
Implement the MHEG5 Variable Class 21 Variable Class Defines a variable within the context of a Group...
void MHEG5stringDestruct(MHEG5String *item)
Destruct a MHEG5String.
Definition: mh5base.c:686
MHEG5Bool initiallyAvailable
Definition: mh5program.h:51
MHEG5ErrorCode(* startFunc)(struct MHEG5Program_struct *)
Definition: mh5program.h:62
Implementation of the resident programs which are defined by the current profile. ...
MHEG5ErrorCode
Definition: mh5base.h:222
MHEG5ErrorCode MHEG5fork(MHEG5Root *target, MHEG5GList *params)
Definition: mh5program.c:459
Event handling. Implementation of a combined queue for events and actions. This is the eventsystem wh...
MHEG5Byte * data
Definition: mh5base.h:85
#define MHEG5TRUE
Definition: mh5base.h:49
MHEG5ErrorCode MHEG5programActivate(MHEG5Program *program)
Definition: mh5program.c:236
void MHEG5ingredientDeactivate(MHEG5Ingredient *ingredient)
Implementation of Deactivate behaviour Inherrited from Root class.
Implement functions to retrieve MHEG5objects by GroupID and ID.
void MHEG5ingredientPrepare(MHEG5Ingredient *ingredient)
Implementation of the Preparation behaviour Inherrited from Root class.
Mheg5 logging and debug printing.
MHEG5Bool runningStatus
Definition: mh5root.h:51
redirection include
void MHEG5interchangedProgramFree(MHEG5Program *program)
Free off all memory associated with the specified object, including any exchanged attributes and inte...
Definition: mh5program.c:204
void MHEG5ProgramSetStartFunc(MHEG5Program *program)
Test if the program NAME is included in this profile and get the start function to execute...
Definition: mh5prgs.c:7420
void MHEG5sendEvent(MHEG5Root *source, MHEG5EventType event, MHEG5Int data)
Store an event in the asynchronous event queue.
Definition: mh5queue.c:1540
void MHEG5residentProgramInit(MHEG5Program *program)
Initialise a residentProgram object with default values.
Definition: mh5program.c:138
void MHEG5programDestruct(MHEG5Program *program)
Definition: mh5program.c:327
MHEG5GList * MHEG5resolveORef(MHEG5GList *params, MHEG5Root **object)
Definition: mh5object.c:126
void MHEG5remoteProgramFree(MHEG5Program *program)
Free off all memory associated with the specified object, including any exchanged attributes and inte...
Definition: mh5program.c:178
void MHEG5ingredientFree(MHEG5Ingredient *ingredient)
Free off all memory associated with the specified object, including any exchanged attributes and inte...
void MHEG5interchangedProgramInit(MHEG5Program *program)
Initialise a interchangedProgram object with default values.
Definition: mh5program.c:190
void MHEG5residentProgramFree(MHEG5Program *program)
Free off all memory associated with the specified object, including any exchanged attributes and inte...
Definition: mh5program.c:152
#define MHEG5FALSE
Definition: mh5base.h:48
void MHEG5sendSync(MHEG5Root *source, MHEG5EventType event, MHEG5Int data)
Store an event in the synchronous event queue.
Definition: mh5queue.c:1651