2
en50221 encoder An implementation for libdvb
3
an implementation for the en50221 transport layer
5
Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
6
Copyright (C) 2005 Julian Scheel (julian at jusst dot de)
7
Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
9
This library is free software; you can redistribute it and/or modify
10
it under the terms of the GNU Lesser General Public License as
11
published by the Free Software Foundation; either version 2.1 of
12
the License, or (at your option) any later version.
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU Lesser General Public License for more details.
19
You should have received a copy of the GNU Lesser General Public
20
License along with this library; if not, write to the Free Software
21
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
#include <libdvbmisc/dvbmisc.h>
27
#include "en50221_app_dvb.h"
28
#include "en50221_app_tags.h"
31
struct en50221_app_dvb {
32
struct en50221_app_send_functions *funcs;
34
en50221_app_dvb_tune_callback tune_callback;
35
void *tune_callback_arg;
37
en50221_app_dvb_replace_callback replace_callback;
38
void *replace_callback_arg;
40
en50221_app_dvb_clear_replace_callback clear_replace_callback;
41
void *clear_replace_callback_arg;
46
static int en50221_app_dvb_parse_tune(struct en50221_app_dvb *dvb,
48
uint16_t session_number,
50
uint32_t data_length);
52
static int en50221_app_dvb_parse_replace(struct en50221_app_dvb *dvb,
54
uint16_t session_number,
56
uint32_t data_length);
58
static int en50221_app_dvb_parse_clear_replace(struct en50221_app_dvb *dvb,
60
uint16_t session_number,
62
uint32_t data_length);
66
struct en50221_app_dvb *en50221_app_dvb_create(struct en50221_app_send_functions *funcs)
68
struct en50221_app_dvb *dvb = NULL;
70
// create structure and set it up
71
dvb = malloc(sizeof(struct en50221_app_dvb));
76
dvb->tune_callback = NULL;
77
dvb->replace_callback = NULL;
78
dvb->clear_replace_callback = NULL;
80
pthread_mutex_init(&dvb->lock, NULL);
86
void en50221_app_dvb_destroy(struct en50221_app_dvb *dvb)
88
pthread_mutex_destroy(&dvb->lock);
92
void en50221_app_dvb_register_tune_callback(struct en50221_app_dvb *dvb,
93
en50221_app_dvb_tune_callback callback,
96
pthread_mutex_lock(&dvb->lock);
97
dvb->tune_callback = callback;
98
dvb->tune_callback_arg = arg;
99
pthread_mutex_unlock(&dvb->lock);
102
void en50221_app_dvb_register_replace_callback(struct en50221_app_dvb *dvb,
103
en50221_app_dvb_replace_callback callback,
106
pthread_mutex_lock(&dvb->lock);
107
dvb->replace_callback = callback;
108
dvb->replace_callback_arg = arg;
109
pthread_mutex_unlock(&dvb->lock);
112
void en50221_app_dvb_register_clear_replace_callback(struct en50221_app_dvb *dvb,
113
en50221_app_dvb_clear_replace_callback callback,
116
pthread_mutex_lock(&dvb->lock);
117
dvb->clear_replace_callback = callback;
118
dvb->clear_replace_callback_arg = arg;
119
pthread_mutex_unlock(&dvb->lock);
122
int en50221_app_dvb_ask_release(struct en50221_app_dvb *dvb,
123
uint16_t session_number)
127
data[0] = (TAG_ASK_RELEASE >> 16) & 0xFF;
128
data[1] = (TAG_ASK_RELEASE >> 8) & 0xFF;
129
data[2] = TAG_ASK_RELEASE & 0xFF;
132
return dvb->funcs->send_data(dvb->funcs->arg, session_number, data, 4);
135
int en50221_app_dvb_message(struct en50221_app_dvb *dvb,
137
uint16_t session_number,
138
uint32_t resource_id,
139
uint8_t * data, uint32_t data_length)
144
if (data_length < 3) {
145
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
148
uint32_t tag = (data[0] << 16) | (data[1] << 8) | data[2];
152
return en50221_app_dvb_parse_tune(dvb, slot_id,
153
session_number, data + 3,
156
return en50221_app_dvb_parse_replace(dvb, slot_id,
160
case TAG_CLEAR_REPLACE:
161
return en50221_app_dvb_parse_clear_replace(dvb, slot_id,
167
print(LOG_LEVEL, ERROR, 1, "Received unexpected tag %x\n", tag);
180
static int en50221_app_dvb_parse_tune(struct en50221_app_dvb *dvb,
182
uint16_t session_number,
183
uint8_t * data, uint32_t data_length)
186
if (data_length < 9) {
187
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
191
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
194
uint8_t *tune_data = data + 1;
197
uint16_t network_id = (tune_data[0] << 8) | tune_data[1];
198
uint16_t original_network_id = (tune_data[2] << 8) | tune_data[3];
199
uint16_t transport_stream_id = (tune_data[4] << 8) | tune_data[5];
200
uint16_t service_id = (tune_data[6] << 8) | tune_data[7];
203
pthread_mutex_lock(&dvb->lock);
204
en50221_app_dvb_tune_callback cb = dvb->tune_callback;
205
void *cb_arg = dvb->tune_callback_arg;
206
pthread_mutex_unlock(&dvb->lock);
208
return cb(cb_arg, slot_id, session_number, network_id,
209
original_network_id, transport_stream_id,
215
static int en50221_app_dvb_parse_replace(struct en50221_app_dvb *dvb,
217
uint16_t session_number,
219
uint32_t data_length)
222
if (data_length < 6) {
223
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
227
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
230
uint8_t *replace_data = data + 1;
233
uint8_t replacement_ref = replace_data[0];
234
uint16_t replace_pid =
235
((replace_data[1] & 0x1f) << 8) | replace_data[2];
236
uint16_t replacement_pid =
237
((replace_data[3] & 0x1f) << 8) | replace_data[4];
240
pthread_mutex_lock(&dvb->lock);
241
en50221_app_dvb_replace_callback cb = dvb->replace_callback;
242
void *cb_arg = dvb->replace_callback_arg;
243
pthread_mutex_unlock(&dvb->lock);
245
return cb(cb_arg, slot_id, session_number, replacement_ref,
246
replace_pid, replacement_pid);
251
static int en50221_app_dvb_parse_clear_replace(struct en50221_app_dvb *dvb,
253
uint16_t session_number,
255
uint32_t data_length)
258
if (data_length < 2) {
259
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
263
print(LOG_LEVEL, ERROR, 1, "Received short data\n");
266
uint8_t *replace_data = data + 1;
269
uint8_t replacement_ref = replace_data[0];
272
pthread_mutex_lock(&dvb->lock);
273
en50221_app_dvb_clear_replace_callback cb =
274
dvb->clear_replace_callback;
275
void *cb_arg = dvb->clear_replace_callback_arg;
276
pthread_mutex_unlock(&dvb->lock);
278
return cb(cb_arg, slot_id, session_number,