MHEG5  18.9.0
MHEG5 Documentation
mh5streamevent.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2006 Ocean Blue Software Ltd
4  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
25 /*---includes for this file--------------------------------------------------*/
26 #include "mh5base.h"
27 #include "mh5profile.h"
28 #include "mh5streamevent.h"
29 #include "mh5gate.h"
30 #include "mh5memory.h" /* for stream event name */
31 #include "mh5object.h"
32 #include "mh5queue.h"
33 
34 #ifndef CI_PLUS_ONLY
35  #include "mheg5_control.h"
36  #include "glue_dsmcc.h"
37  #include "glue_queue.h"
38 #endif
39 #include "mh5hfs.h"
40 #include "glue_main.h"
41 
42 /*---constant definitions for this file--------------------------------------*/
43 
44 #define MAX_STREAMS 16
45 
46 
47 /*---local typedef structs for this file-------------------------------------*/
48 
49 #ifndef CI_PLUS_ONLY
50 /* Event information for each listening link */
51 typedef struct sSeEventInfo
52 {
53  struct sSeEventInfo *next;
54  MHEG5Link *link; /* MHEG link object */
55  MHEG5Stream *stream; /* MHEG stream object associated with 'link' */
56  H_DsmEvent eventHandle; /* DSM-CC stream event subscription handle */
58 } EventInfo;
59 #endif
60 
61 /*---local (static) variable declarations for this file----------------------*/
62 
63 #ifndef CI_PLUS_ONLY
64 static EventInfo *event_info_list = 0;
65 static MHEG5Stream *stream_array[MAX_STREAMS] = {
66  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
67  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
68 };
69 static U32BIT gUniqueIds = 0;
70 #endif
71 
72 /*---local function definitions----------------------------------------------*/
73 
74 /*---global function definitions---------------------------------------------*/
75 
76 
77 #ifndef CI_PLUS_ONLY
78 
79 static void FreeFromEventList(EventInfo *eventInfo)
80 {
81  EventInfo **pp_EventInfo;
82 
83  pp_EventInfo = &event_info_list;
84  while (*pp_EventInfo != NULL)
85  {
86  if (*pp_EventInfo == eventInfo)
87  {
88  TRACE(TSTRM, (" FREE evtInfo=0x%x evHl=%p", eventInfo, eventInfo->eventHandle))
89  if (eventInfo->eventHandle != 0)
90  {
91  DSMCC_ClientEventUnsubscribe(MHEG5_DsmccInstance(), eventInfo->eventHandle);
92  }
93  *pp_EventInfo = eventInfo->next;
94  MHEG5freeMem(eventInfo);
95  break;
96  }
97  pp_EventInfo = &((*pp_EventInfo)->next);
98  }
99 }
100 
108 static void StreamEventCallback(S_StreamEvent *param)
109 {
110  EventInfo *eventInfo;
111 
112  eventInfo = event_info_list;
113  while (eventInfo != NULL)
114  {
115  if (eventInfo->unique.ptr == param->unique.ptr)
116  {
117  TRACE(TSTRM|TEVNTS, ("link_id=%d name=%s",
118  eventInfo->link->ingredient.root.id, MHEG5linkEventName(eventInfo->link)))
119 
120  /**** Append action list for this Asynchronous event ****
121  * This by-passes normal Async Queue (used by MHEG5sendEvent), but this is OK since,
122  * by definition, async events do not have any particular order.
123  * We need to do this, because this function is called for each link that is listening.
124  * Using MHEG5sendEvent() would mean that when more than one link is listening on same
125  * stream (where at least one link is 'any match'), you would get multiple instances
126  * of the one stream event on a link, which would be wrong */
127  MHEG5AppendActionList( eventInfo->link->linkEffect );
128  break;
129  }
130  eventInfo = eventInfo->next;
131  }
132 }
133 
141 static void MHEG5streamEventNotifyCallback(void *info, U8BIT *eventName,
142  U32BIT data_len, U8BIT *data_ptr)
143 {
144  MHEG5eventMessage_t event_msg;
145  TRACE(TSTRM | TEVNTS, ("name=%s data=(%.*s) id=%u", eventName, (int)data_len, data_ptr, (unsigned int)info))
146  event_msg.proc_msg_func = (F_MSG_PROCESS)StreamEventCallback;
147  event_msg.data_type = DT_VALUE;
148  event_msg.data.streamEvent.unique.ptr = info;
149  if (VQ_PutMsg(&event_msg, PRTY_HIGH) != MHERR_OK)
150  {
151  DBGTRACE(TERROR,"")
152  }
153 }
154 
161 static void StreamEventSubscribe( MHEG5Link *link, MHEG5Stream *stream )
162 {
163  EventInfo *eventInfo;
164 
165  eventInfo = event_info_list;
166  while (eventInfo != NULL)
167  {
168  if (eventInfo->link == link)
169  {
170  break;
171  }
172  eventInfo = eventInfo->next;
173  }
174  if (eventInfo != NULL)
175  {
176  if (stream->reloading)
177  {
178  if (DSMCC_ClientEventSubscribeName( MHEG5_DsmccInstance(), stream->dsmRef,
179  MHEG5linkEventName(eventInfo->link),
180  MHEG5streamEventNotifyCallback,
181  eventInfo->unique.ptr, &eventInfo->eventHandle) == FS_STATUS_OK)
182  {
183  TRACE(TSTRM, ("dsmcc EventSubscribe OK, id=%p evHl=%p", eventInfo->unique.ptr, eventInfo->eventHandle))
184  }
185  else
186  {
187  TRACE(TERROR, ("evtInfo=0x%x reloading", eventInfo))
188  FreeFromEventList(eventInfo);
189  }
190  }
191  }
192  else
193  {
194  eventInfo = (EventInfo *) MHEG5getMem( sizeof(EventInfo));
195  if (!eventInfo)
196  {
197  TRACE(TERROR, ("unable to allocate memory"));
198  }
199  else
200  {
201  eventInfo->eventHandle = 0;
202  eventInfo->stream = stream;
203  eventInfo->link = link;
204  eventInfo->unique.u32 = ++gUniqueIds;
205 
206  if (DSMCC_ClientEventSubscribeName( MHEG5_DsmccInstance(), stream->dsmRef,
207  MHEG5linkEventName(eventInfo->link),
208  MHEG5streamEventNotifyCallback,
209  eventInfo->unique.ptr, &eventInfo->eventHandle) == FS_STATUS_OK)
210  {
211  TRACE(TSTRM, ("dsmcc EventSubscribe OK, id=%p evHl=%p", eventInfo->unique.ptr, eventInfo->eventHandle))
212  /* Successful subscription - add to list */
213  eventInfo->next = event_info_list;
214  event_info_list = eventInfo;
215  }
216  else
217  {
218  TRACE(TERROR, ("evtInfo=0x%x", eventInfo))
219  MHEG5freeMem(eventInfo);
220  }
221  }
222  }
223 }
224 
231 static void SubscribeActive(MHEG5Stream *stream)
232 {
233  MHEG5Link *link;
234 
235  /* Find every Link with an interest in this stream */
237  while (link)
238  {
239  if ((link->source == stream->ingredient.root.id) &&
240  ((stream->ingredient.root.grp == link->sourcegid.ptr.group) ||
241  ((link->sourcegid.len != 0) && MHEG5sameGroup(stream->ingredient.root.grp, link->sourcegid))))
242  {
243  if (stream->dsmRef != 0)
244  {
245  StreamEventSubscribe( link, stream );
246  }
247  }
248  /* Process the next link in the list */
249  link = link->nextActiveLink;
250  }
251 }
252 
259 static void UnsubscribeActive(MHEG5Stream *stream)
260 {
261  EventInfo *eventInfo;
262 
263  /* Unsubscribe from each event with this stream as source */
264  eventInfo = event_info_list;
265  while (eventInfo != NULL)
266  {
267  if (eventInfo->stream == stream)
268  {
269  EventInfo *next = eventInfo->next;
270  TRACE(TSTRM, (" FREE evtInfo=0x%x evHl=%p", eventInfo, eventInfo->eventHandle))
271  FreeFromEventList(eventInfo);
272  eventInfo = next;
273  }
274  else
275  {
276  eventInfo = eventInfo->next;
277  }
278  }
279 }
280 
287 static MHEG5Stream* FindEventSource(MHEG5Link *link)
288 {
289  int ndx;
290  MHEG5Stream *pStream;
291  for (ndx = 0; ndx != MAX_STREAMS; ndx++)
292  {
293  if (stream_array[ndx] != NULL)
294  {
295  pStream = stream_array[ndx];
296  if (link->source == pStream->ingredient.root.id)
297  {
298  if ((pStream->ingredient.root.grp == link->sourcegid.ptr.group) ||
299  ((link->sourcegid.len != 0) && MHEG5sameGroup(pStream->ingredient.root.grp, link->sourcegid)))
300  {
301  break;
302  }
303  }
304  pStream = NULL;
305  }
306  }
307  return pStream;
308 }
309 
315 static void MHEG5streamClear(MHEG5Stream *stream)
316 {
317  assert( stream );
318 
319  if (stream->dsmClearFunc)
320  {
321  /* Unload stream object */
322  stream->dsmClearFunc( stream->dsmRef );
323  /* invalidate the references */
324  stream->dsmClearFunc = NULL;
325  stream->dsmRef = NULL;
326  }
327 }
328 
329 #endif /* !CI_PLUS_ONLY */
330 
331 
338 {
339  #ifndef CI_PLUS_ONLY
340  int ndx;
341  for (ndx = 0; ndx != MAX_STREAMS; ndx++)
342  {
343  if (stream_array[ndx] == NULL)
344  {
345  stream_array[ndx] = stream;
346  break;
347  }
348  }
349  assert( ndx != MAX_STREAMS );
350  #endif
351 }
352 
359 {
360  #ifndef CI_PLUS_ONLY
361  int ndx;
362 
363  assert( stream );
364 
365  /* Unsubscribe from each event with this stream as source */
366  UnsubscribeActive(stream);
367 
368  for (ndx = 0; ndx != MAX_STREAMS; ndx++)
369  {
370  if (stream_array[ndx] == stream)
371  {
372  stream_array[ndx] = NULL;
373  break;
374  }
375  }
376  assert( stream->dsmRef == NULL || ndx != MAX_STREAMS );
377 
378  MHEG5streamClear( stream );
379  #endif
380 }
381 
387 {
388  #ifndef CI_PLUS_ONLY
389  int ndx;
390  TRACE(TSTRM, (""))
391  for (ndx = 0; ndx != MAX_STREAMS; ndx++)
392  {
393  if (stream_array[ndx] != NULL)
394  {
395  TRACE(TSTRM, ("name=%s", stream_array[ndx]->ingredient.content.ref.referenced.reference.data))
396 
397  /* Clear the multiplex reference for stream objects. */
398  memset(&(stream_array[ndx]->dvbLocator), 0, sizeof(S_DVB_LOCATOR));
399 
400  if (stream_array[ndx]->dsmRef)
401  {
402  stream_array[ndx]->reloading = MHEG5TRUE;
403  }
404  MHEG5streamClear( stream_array[ndx] );
405  }
406  }
407  #endif
408 }
409 
415 {
416  #ifndef CI_PLUS_ONLY
417  int ndx;
418  for (ndx = 0; ndx != MAX_STREAMS; ndx++)
419  {
420  if (stream_array[ndx] != NULL)
421  {
422  TRACE(TSTRM, ("name=%s", stream_array[ndx]->ingredient.content.ref.referenced.reference.data))
423  assert( stream_array[ndx]->dsmRef == NULL );
424  if (stream_array[ndx]->ingredient.contentHook == CHOOK_STREAM_NORMAL)
425  {
426  stream_array[ndx]->reloading = MHEG5TRUE;
427  MHEG5ingredientContentPrepare((MHEG5Ingredient *)stream_array[ndx]);
428  }
429  }
430  }
431  #endif
432 }
433 
440 {
441  #ifndef CI_PLUS_ONLY
442  assert(stream);
443  /* only get in this function if load was successful */
444  if (stream->dsmRef &&
445  stream->ingredient.root.runningStatus)
446  {
447  /* running stream has dsm events */
448  SubscribeActive(stream);
449  }
450  stream->reloading = FALSE;
451  #endif
452 }
453 
460 {
461  #ifndef CI_PLUS_ONLY
462  assert(stream);
463  if (stream->dsmRef)
464  {
465  /* running stream has dsm events */
466  SubscribeActive(stream);
467  }
468  #endif
469 }
470 
477 {
478  #ifndef CI_PLUS_ONLY
479  assert(stream);
480  if (stream->dsmRef)
481  {
482  /* running stream has dsm events */
483  UnsubscribeActive(stream);
484  }
485  #endif
486 }
487 
494 {
495  #ifndef CI_PLUS_ONLY
497 
498  stream = FindEventSource(link);
499 
500  if (stream != NULL)
501  {
502  TRACE(TSTRM, (" lnk=%d sir=%x, sio=%x", link->ingredient.root.id,
503  stream->ingredient.root.runningStatus, stream->dsmRef))
504 
505  if (stream->ingredient.root.runningStatus &&
506  stream->dsmRef != 0)
507  {
508  StreamEventSubscribe( link, stream );
509  }
510  }
511  #endif
512 }
513 
520 {
521  #ifndef CI_PLUS_ONLY
522  EventInfo *eventInfo;
523 
524  eventInfo = event_info_list;
525  while (eventInfo != NULL)
526  {
527  if (eventInfo->link == link)
528  {
529  TRACE(TSTRM, (" FREE evtInfo=0x%x evHl=%p", eventInfo, eventInfo->eventHandle))
530  FreeFromEventList(eventInfo);
531  break;
532  }
533  eventInfo = eventInfo->next;
534  }
535  #endif
536 }
537 
Basis MHEG5 data types.
E_MhegErr VQ_PutMsg(S_MhegMessage *pMsg, E_PRIORITY priority)
Post event or section message on queue. Copies data into queue.
Definition: glue_queue.c:248
F_MSG_PROCESS proc_msg_func
Definition: glue_queue.h:198
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
Interface functions to DSM-CC instance for MHEG5.
MHEG5Bool reloading
Definition: mh5stream.h:70
MHEG5Ingredient ingredient
Definition: mh5stream.h:65
#define DBGTRACE(...)
Definition: glue_debug.h:126
void * ptr
Definition: glue_type.h:38
U_PARAM unique
#define CHOOK_STREAM_NORMAL
Definition: mh5profile.h:107
MHEG5 queue.
Definition: mg_png.c:59
#define MHEG5getMem
Definition: glue_memory.h:93
void MHEG5AppendActionList(MHEG5ActionList actions)
The supplied list of actions should execute after any already on queue.
Definition: mh5queue.c:1032
void MHEG5notifyLinkInactive(MHEG5Link *link)
Notify that a link has become inactive.
Stream event subscription management.
U_PARAM unique
Definition: glue_queue.h:92
union sMH5GroupRef::@5 ptr
void * MHEG5_DsmccInstance(void)
Get the DSMCC instance handle.
Definition: glue_dsmcc.c:778
void MHEG5ingredientContentPrepare(MHEG5Ingredient *ingredient)
Implementation of the ContentPrepare behaviour COR.1 6.6: ContentPreparation Apply the following sequ...
void MHEG5streamReloadAll(void)
Load and Subscribe all stream events.
MH5GroupPtr grp
Definition: mh5root.h:57
void(* F_MSG_PROCESS)(void *data)
Function to Process voyager message.
Definition: glue_queue.h:70
void MHEG5notifyLinkActive(MHEG5Link *link)
Notify that a link is active.
uint8_t U8BIT
Definition: techtype.h:82
#define MHEG5freeMem
Definition: glue_memory.h:94
F_DESTROY dsmClearFunc
Definition: mh5stream.h:83
This file provides the control interface for MHEG5 engine. The use of this component MUST comply with...
This file defines the profile for the MHEG engine.
#define MAX_STREAMS
S_StreamEvent streamEvent
Definition: glue_queue.h:216
Implement Functions to support Service Gateways. Functions for standarizing several GroupIDs like +DS...
void MHEG5notifyStreamStopped(MHEG5Stream *stream)
Notify that a stream has stopped.
MHEG5Link * link
U32BIT u32
Definition: glue_type.h:39
Event handling. Implementation of a combined queue for events and actions. This is the eventsystem wh...
#define MHEG5TRUE
Definition: mh5base.h:49
E_DATA_TYPE data_type
Definition: glue_queue.h:199
Implement functions to retrieve MHEG5objects by GroupID and ID.
void MHEG5refreshStreamObject(MHEG5Stream *stream)
Refresh the DSM-CC Stream Object for a given MHEG-5 Stream Object.
void MHEG5streamUnloadAll(void)
Unsubscribe and unload all stream events.
MHEG5Int len
Definition: mh5base.h:99
MHEG5Bool runningStatus
Definition: mh5root.h:51
struct sSeEventInfo * next
H_DsmEvent eventHandle
redirection include
MHEG5Int id
Definition: mh5root.h:48
#define FALSE
Definition: techtype.h:68
FS_HANDLE dsmRef
Definition: mh5stream.h:84
MHEG5Stream * stream
MH5GroupPtr group
Definition: mh5base.h:103
struct sSeEventInfo EventInfo
void MHEG5streamRemove(MHEG5Stream *stream)
Remove an MHEG-5 Stream Object from repository.
void MHEG5notifyStreamRunning(MHEG5Stream *stream)
Notify that a stream is running.
union s_mhg_message::@13 data
uint32_t U32BIT
Definition: techtype.h:86
Functions relating to Hybrid file system.
void MHEG5streamAdd(MHEG5Stream *stream)
Add an MHEG-5 Stream Object to repository.
#define TRACE(t, x)
Definition: glue_debug.h:118