MHEG5  18.9.0
MHEG5 Documentation
stmr_header.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2010 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 <assert.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include <sys/types.h>
30 
31 #include <glue_memory.h>
32 #include "mh5parse.h"
33 
34 #include "stmr_header.h"
35 #include "stmr_common.h"
36 
37 /*---constant definitions for this file--------------------------------------*/
38 
39 #define DBG(x)
40 
41 
42 /*---local typedef structs for this file-------------------------------------*/
43 
44 /*---local (static) variable declarations for this file----------------------*/
45 
46 /*---local function definitions----------------------------------------------*/
47 
56 static BOOLEAN DecodeKey(U8BIT **data, U8BIT *key, U16BIT len)
57 {
58  static char *base64 =
59  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
60  "abcdefghijklmnopqrstuvwxyz"
61  "0123456789+/=";
62  char *p = (char *)(*data);
63  int symbols, bytes, i, j;
64  int b0, b1, b2, b3;
65  BOOLEAN success;
66 
67  success = FALSE;
68 
69  symbols = strspn(p, base64);
70  if (symbols > 0 && symbols % 4 == 0)
71  {
72  bytes = symbols * 3 / 4;
73  if (p[symbols - 1] == '=')
74  {
75  --bytes;
76  }
77  if (p[symbols - 2] == '=')
78  {
79  --bytes;
80  }
81  if (bytes == len)
82  {
83  for (i = 0, j = 0; i < symbols; i += 4)
84  {
85  b0 = strchr(base64, *p++) - base64;
86  b1 = strchr(base64, *p++) - base64;
87  b2 = strchr(base64, *p++) - base64;
88  b3 = strchr(base64, *p++) - base64;
89 
90  key[j++] = b0 << 2 | b1 >> 4;
91  if (b2 < 64)
92  {
93  key[j++] = b1 << 4 | b2 >> 2;
94  if (b3 < 64)
95  {
96  key[j++] = b2 << 6 | b3;
97  }
98  }
99  }
100 
101  *data += symbols;
102  success = TRUE;
103  }
104  }
105 
106  return success;
107 }
108 
109 /*---global function definitions---------------------------------------------*/
110 
120 {
121  S_ICSPidInfo *pid_info;
122  U16BIT colons;
123  U16BIT num_pids, i;
124  U8BIT *p;
125  BOOLEAN success;
126 
127  /*
128  * Input format:
129  *
130  * KeyFile ::= KeyString
131  * KeyHeader ::= ~X-Keys:~ <space> KeyString
132  * KeyString ::= PIDString [ ~:~ KeyString]
133  * PIDString ::= PID ~:~ IV ~:~ OddKey ~:~ EvenKey
134  * PID ::= <integer encoded as decimal ascii value>
135  * IV ::= <128bit binary value encoded as Base64>
136  * OddKey ::= <128bit binary value encoded as Base64>
137  * EvenKey ::= <128bit binary value encoded as Base64>
138  */
139 
140  /* Count number of colons to determine maximum number of key sets */
141  colons = 0;
142  p = (U8BIT *)strchr((char *)data, ':');
143  while (p != NULL)
144  {
145  ++colons;
146  p = (U8BIT *)strchr((char *)p + 1, ':');
147  }
148 
149  if (colons % 4 == 3)
150  {
151  num_pids = (colons + 1) / 4;
152  keys->num_pids = 0;
153  keys->pid_info = MHEG5getMem(num_pids * sizeof *keys->pid_info);
154  if (keys->pid_info != NULL)
155  {
156  /* Try to parse as many sets as possible */
157  for (i = 0; i < num_pids; ++i)
158  {
159  pid_info = &keys->pid_info[i];
160 
161  /* Parse PID */
162  pid_info->PID = 0;
163  p = (U8BIT *)strchr((char *)data, ':');
164  assert(p != NULL);
165  while (*data >= '0' && *data <= '9')
166  {
167  pid_info->PID *= 10;
168  pid_info->PID += *data - '0';
169  ++data;
170  }
171 
172  if (data != p)
173  {
174  /* Colon was expected */
175  break;
176  }
177  ++data;
178 
179  /* Parse IV */
180  success = DecodeKey(&data, pid_info->iv, 16);
181  if (!success || *data != ':')
182  {
183  break;
184  }
185  ++data;
186 
187  /* Parse odd key */
188  success = DecodeKey(&data, pid_info->odd_key, 16);
189  if (!success || *data != ':')
190  {
191  break;
192  }
193  ++data;
194 
195  /* Parse even key */
196  success = DecodeKey(&data, pid_info->even_key, 16);
197  if (!success)
198  {
199  break;
200  }
201 
202  if (*data == ':')
203  {
204  /* Skip colon for next set */
205  ++data;
206  }
207 
208  ++keys->num_pids;
209  }
210 
211  success = TRUE;
212 
213  /* If nothing was parsed, clear key information */
214  if (keys->num_pids == 0)
215  {
216  MHEG5freeMem(keys->pid_info);
217  keys->pid_info = NULL;
218  success = FALSE;
219  }
220  }
221  }
222  else
223  {
224  keys->num_pids = 0;
225  keys->pid_info = NULL;
226  }
227 }
228 
238 {
239  MHEG5parseStreamKeys(data, strlen((char *)data), keys);
240 }
241 
250 {
251  static const char *lws = "\r\n \t";
252 
253  /* Find end of string */
254  keyLocation->len = strcspn((char *)data, lws);
255 
256  /* Copy URL */
257  keyLocation->data = STR_DataAlloc((keyLocation->len + 1));
258  if (keyLocation->data != NULL)
259  {
260  memcpy(keyLocation->data, data, keyLocation->len);
261  keyLocation->data[keyLocation->len] = '\0';
262  }
263  else
264  {
265  keyLocation->len = 0;
266  }
267 }
268 
278  BOOLEAN *knownBitrate)
279 {
280  *bytesPerSecond = 0;
281  *knownBitrate = FALSE;
282 
283  if (*data >= '1' && *data <= '9')
284  {
285  *bytesPerSecond = *data - '0';
286  ++data;
287  }
288  while (*data >= '0' && *data <= '9')
289  {
290  *bytesPerSecond *= 10;
291  *bytesPerSecond += *data - '0';
292  ++data;
293  }
294 
295  if (*data == '\r' || *data == '\n')
296  {
297  *knownBitrate = TRUE;
298  }
299 }
300 
IC Streamer http header parser.
const char * data
Definition: mh5gate.c:56
Common header internal to IC streamer.
unsigned char * STR_DataAlloc(unsigned int size)
Definition: glue_memory.c:596
#define MHEG5getMem
Definition: glue_memory.h:93
S_ICSPidInfo * pid_info
Definition: stmr_header.h:52
uint8_t U8BIT
Definition: techtype.h:82
string parsing utility functions for MHEG5
Memory functions.
void MHEG5ParseXKeys(U8BIT *data, U32BIT len, S_ICSKeys *keys)
Parse "X-Keys" header and return the key information. If the keys cannot be parsed, keys->num_pids will be zero.
Definition: stmr_header.c:237
#define MHEG5freeMem
Definition: glue_memory.h:94
void MHEG5ParseXBytesPerSecond(U8BIT *data, U32BIT len, U32BIT *bytesPerSecond, BOOLEAN *knownBitrate)
Parse "X-BytesPerSecond" header and return its value.
Definition: stmr_header.c:277
U8BIT even_key[16]
Definition: stmr_header.h:46
MHEG5Byte * data
Definition: mh5base.h:85
int len
Definition: mh5gate.c:57
uint16_t U16BIT
Definition: techtype.h:84
void MHEG5parseStreamKeys(U8BIT *data, U16BIT len, S_ICSKeys *keys)
Parse IC stream keys. These keys are delivered in the HTTP headers or in a separate file...
Definition: stmr_header.c:119
U16BIT PID
Definition: stmr_header.h:44
void MHEG5ParseXKeyLocation(U8BIT *data, U32BIT len, MHEG5String *keyLocation)
Parse "X-KeyLocation" header and return the key location.
Definition: stmr_header.c:249
#define FALSE
Definition: techtype.h:68
MHEG5Int len
Definition: mh5base.h:84
U8BIT BOOLEAN
Definition: techtype.h:99
#define TRUE
Definition: techtype.h:69
U8BIT odd_key[16]
Definition: stmr_header.h:45
U16BIT num_pids
Definition: stmr_header.h:53
U8BIT iv[16]
Definition: stmr_header.h:47
uint32_t U32BIT
Definition: techtype.h:86