source: trunk/module-dvbapi-azbox.c@ 8439

Last change on this file since 8439 was 8439, checked in by gf, 9 years ago

webif/dvbapi: Do not prefix log messages comming from WebIf with "dvbapi: ".

module-dvbapi.h redefines cs_log() to include "dvbapi: " prefix.

Since module-webif.c includes module-dvbapi.h all cs_log lines coming
from webif were wrongly were prefixed with "dvbapi: ".

  • Property svn:eol-style set to LF
File size: 10.2 KB
Line 
1#include "globals.h"
2
3#if defined(HAVE_DVBAPI) && defined(WITH_AZBOX)
4
5#include "extapi/openxcas/openxcas_api.h"
6#include "extapi/openxcas/openxcas_message.h"
7
8#define DVBAPI_LOG_PREFIX 1
9#include "module-dvbapi.h"
10#include "module-dvbapi-azbox.h"
11#include "oscam-client.h"
12#include "oscam-ecm.h"
13#include "oscam-reader.h"
14#include "oscam-string.h"
15#include "oscam-time.h"
16
17#define LOG_PREFIX "openxcas: "
18#define LOG_PREFIX_MSG "openxcasmsg: "
19
20// These variables are declared in module-dvbapi.c
21extern void * dvbapi_client;
22extern DEMUXTYPE demux[MAX_DEMUX];
23
24// These are used in module-dvbapi.c
25int32_t openxcas_provid;
26uint16_t openxcas_sid, openxcas_caid, openxcas_ecm_pid;
27
28static unsigned char openxcas_cw[16];
29static int32_t openxcas_seq, openxcas_filter_idx, openxcas_stream_id, openxcas_cipher_idx, openxcas_busy;
30static uint16_t openxcas_video_pid, openxcas_audio_pid, openxcas_data_pid;
31
32void azbox_openxcas_ecm_callback(int32_t stream_id, uint32_t UNUSED(seq), int32_t cipher_index, uint32_t UNUSED(caid), unsigned char *ecm_data, int32_t l, uint16_t pid) {
33 cs_debug_mask(D_DVBAPI, LOG_PREFIX "ecm callback received");
34
35 openxcas_stream_id = stream_id;
36 //openxcas_seq = seq;
37 //openxcas_caid = caid;
38 openxcas_ecm_pid = pid;
39 openxcas_busy = 1;
40
41 ECM_REQUEST *er;
42 if (!(er=get_ecmtask()))
43 return;
44
45 er->srvid = openxcas_sid;
46 er->caid = openxcas_caid;
47 er->pid = openxcas_ecm_pid;
48 er->prid = openxcas_provid;
49
50 er->ecmlen = l;
51 memcpy(er->ecm, ecm_data, er->ecmlen);
52
53 request_cw(dvbapi_client, er);
54
55 //openxcas_stop_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM);
56 //openxcas_remove_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM);
57
58 openxcas_cipher_idx = cipher_index;
59
60 struct timeb tp;
61 cs_ftime(&tp);
62 tp.time+=500;
63}
64
65
66void azbox_openxcas_ex_callback(int32_t stream_id, uint32_t seq, int32_t idx, uint32_t pid, unsigned char *ecm_data, int32_t l) {
67 cs_debug_mask(D_DVBAPI, LOG_PREFIX "ex callback received");
68
69 openxcas_stream_id = stream_id;
70 openxcas_ecm_pid = pid;
71 openxcas_cipher_idx = idx; // is this really cipher_idx?
72
73 ECM_REQUEST *er;
74 if (!(er=get_ecmtask()))
75 return;
76
77 er->srvid = openxcas_sid;
78 er->caid = openxcas_caid;
79 er->pid = openxcas_ecm_pid;
80 er->prid = openxcas_provid;
81
82 er->ecmlen = l;
83 memcpy(er->ecm, ecm_data, er->ecmlen);
84
85 request_cw(dvbapi_client, er);
86
87 if (openxcas_stop_filter_ex(stream_id, seq, openxcas_filter_idx) < 0)
88 cs_log(LOG_PREFIX "unable to stop ex filter");
89 else
90 cs_debug_mask(D_DVBAPI, LOG_PREFIX "ex filter stopped");
91
92
93
94 unsigned char mask[12];
95 unsigned char comp[12];
96 memset(&mask, 0x00, sizeof(mask));
97 memset(&comp, 0x00, sizeof(comp));
98
99 mask[0] = 0xff;
100 comp[0] = ecm_data[0] ^ 1;
101
102 if ((openxcas_filter_idx = openxcas_start_filter_ex(stream_id, seq, openxcas_ecm_pid, mask, comp, (void *)azbox_openxcas_ex_callback)) < 0)
103 cs_log(LOG_PREFIX "unable to start ex filter");
104 else
105 cs_debug_mask(D_DVBAPI, LOG_PREFIX "ex filter started, pid = %x", openxcas_ecm_pid);
106}
107
108void * azbox_main_thread(void *cli) {
109 struct s_client * client = (struct s_client *) cli;
110 client->thread=pthread_self();
111 pthread_setspecific(getclient, cli);
112 dvbapi_client=cli;
113
114 struct s_auth *account;
115 int32_t ok = 0;
116 for (account = cfg.account; account; account=account->next) {
117 if ((ok = streq(cfg.dvbapi_usr, account->usr)))
118 break;
119 }
120 cs_auth_client(client, ok ? account : (struct s_auth *)(-1), "dvbapi");
121
122 dvbapi_read_priority();
123
124 openxcas_msg_t msg;
125 int32_t ret;
126 while ((ret = openxcas_get_message(&msg, 0)) >= 0) {
127 cs_sleepms(10);
128
129 if (ret) {
130 openxcas_stream_id = msg.stream_id;
131 openxcas_seq = msg.sequence;
132
133 switch(msg.cmd) {
134 case OPENXCAS_SELECT_CHANNEL:
135 cs_debug_mask(D_DVBAPI, LOG_PREFIX_MSG "OPENXCAS_SELECT_CHANNEL");
136
137 // parse channel info
138 struct stOpenXCASChannel chan;
139 memcpy(&chan, msg.buf, msg.buf_len);
140
141 cs_log(LOG_PREFIX "channel change: sid = %x, vpid = %x. apid = %x", chan.service_id, chan.v_pid, chan.a_pid);
142
143 openxcas_video_pid = chan.v_pid;
144 openxcas_audio_pid = chan.a_pid;
145 openxcas_data_pid = chan.d_pid;
146 break;
147 case OPENXCAS_START_PMT_ECM:
148 cs_debug_mask(D_DVBAPI, LOG_PREFIX_MSG "OPENXCAS_START_PMT_ECM");
149
150 // parse pmt
151 uchar *dest;
152 if (!cs_malloc(&dest, msg.buf_len + 7 - 12 - 4))
153 break;
154
155 memcpy(dest, "\x00\xFF\xFF\x00\x00\x13\x00", 7);
156
157 dest[1] = msg.buf[3];
158 dest[2] = msg.buf[4];
159 dest[5] = msg.buf[11]+1;
160
161 memcpy(dest + 7, msg.buf + 12, msg.buf_len - 12 - 4);
162
163 dvbapi_parse_capmt(dest, 7 + msg.buf_len - 12 - 4, -1, NULL);
164 free(dest);
165
166 unsigned char mask[12];
167 unsigned char comp[12];
168 memset(&mask, 0x00, sizeof(mask));
169 memset(&comp, 0x00, sizeof(comp));
170
171 mask[0] = 0xfe;
172 comp[0] = 0x80;
173
174 if ((ret = openxcas_add_filter(msg.stream_id, OPENXCAS_FILTER_ECM, 0, 0xffff, openxcas_ecm_pid, mask, comp, (void *)azbox_openxcas_ecm_callback)) < 0)
175 cs_log(LOG_PREFIX "unable to add ecm filter");
176 else
177 cs_debug_mask(D_DVBAPI, LOG_PREFIX "ecm filter added, pid = %x, caid = %x", openxcas_ecm_pid, 0);
178
179 if (openxcas_start_filter(msg.stream_id, msg.sequence, OPENXCAS_FILTER_ECM) < 0)
180 cs_log(LOG_PREFIX "unable to start ecm filter");
181 else
182 cs_debug_mask(D_DVBAPI, LOG_PREFIX "ecm filter started");
183
184 if (!openxcas_create_cipher_ex(msg.stream_id, openxcas_seq, 0, openxcas_ecm_pid, openxcas_video_pid, 0xffff, openxcas_audio_pid, 0xffff, 0xffff, 0xffff))
185 cs_log(LOG_PREFIX "failed to create cipher ex");
186 else
187 cs_debug_mask(D_DVBAPI, LOG_PREFIX "cipher created");
188 break;
189 case OPENXCAS_STOP_PMT_ECM:
190 cs_debug_mask(D_DVBAPI, LOG_PREFIX_MSG "OPENXCAS_STOP_PMT_ECM");
191 openxcas_stop_filter(msg.stream_id, OPENXCAS_FILTER_ECM);
192 openxcas_remove_filter(msg.stream_id, OPENXCAS_FILTER_ECM);
193 openxcas_stop_filter_ex(msg.stream_id, msg.sequence, openxcas_filter_idx);
194 openxcas_destory_cipher_ex(msg.stream_id, msg.sequence);
195 memset(&demux, 0, sizeof(demux));
196 break;
197 case OPENXCAS_ECM_CALLBACK:
198 cs_debug_mask(D_DVBAPI, LOG_PREFIX_MSG "OPENXCAS_ECM_CALLBACK");
199 struct stOpenXCAS_Data data;
200 memcpy(&data, msg.buf, msg.buf_len);
201 if (!openxcas_busy)
202 openxcas_filter_callback(msg.stream_id, msg.sequence, OPENXCAS_FILTER_ECM, &data);
203 break;
204 case OPENXCAS_PID_FILTER_CALLBACK:
205 cs_debug_mask(D_DVBAPI, LOG_PREFIX_MSG "OPENXCAS_PID_FILTER_CALLBACK");
206 openxcas_filter_callback_ex(msg.stream_id, msg.sequence, (struct stOpenXCAS_Data *)msg.buf);
207 break;
208 case OPENXCAS_QUIT:
209 cs_debug_mask(D_DVBAPI, LOG_PREFIX_MSG "OPENXCAS_QUIT");
210 openxcas_close();
211 cs_log(LOG_PREFIX "exited");
212 return NULL;
213 break;
214 case OPENXCAS_UKNOWN_MSG:
215 default:
216 cs_debug_mask(D_DVBAPI, LOG_PREFIX_MSG "OPENXCAS_UKNOWN_MSG (%d)", msg.cmd);
217 //cs_ddump_mask(D_DVBAPI, &msg, sizeof(msg), "msg dump:");
218 break;
219 }
220 }
221 }
222 cs_log(LOG_PREFIX "invalid message");
223 return NULL;
224}
225
226void azbox_send_dcw(struct s_client *client, ECM_REQUEST *er) {
227 cs_debug_mask(D_DVBAPI, LOG_PREFIX "send_dcw");
228
229 FILE *ecmtxt;
230 if ((ecmtxt = fopen(ECMINFO_FILE, "w"))) {
231 char tmp[25];
232 if(er->rc <= E_CACHEEX) {
233 fprintf(ecmtxt, "caid: 0x%04X\npid: 0x%04X\nprov: 0x%06X\n", er->caid, er->pid, (uint) er->prid);
234 fprintf(ecmtxt, "reader: %s\n", er->selected_reader->label);
235 if (is_cascading_reader(er->selected_reader))
236 fprintf(ecmtxt, "from: %s\n", er->selected_reader->device);
237 else
238 fprintf(ecmtxt, "from: local\n");
239 fprintf(ecmtxt, "protocol: %s\n", reader_get_type_desc(er->selected_reader, 1));
240 fprintf(ecmtxt, "hops: %d\n", er->selected_reader->currenthops);
241 fprintf(ecmtxt, "ecm time: %.3f\n", (float) client->cwlastresptime/1000);
242 fprintf(ecmtxt, "cw0: %s\n", cs_hexdump(1,demux[0].lastcw[0],8, tmp, sizeof(tmp)));
243 fprintf(ecmtxt, "cw1: %s\n", cs_hexdump(1,demux[0].lastcw[1],8, tmp, sizeof(tmp)));
244 fclose(ecmtxt);
245 ecmtxt = NULL;
246 } else {
247 fprintf(ecmtxt, "ECM information not found\n");
248 fclose(ecmtxt);
249 }
250 }
251
252 openxcas_busy = 0;
253
254 int32_t i;
255 for (i=0; i < MAX_DEMUX; i++) {
256 if (er->rc >= E_NOTFOUND) {
257 cs_debug_mask(D_DVBAPI, "cw not found");
258
259 if (demux[i].pidindex==-1)
260 dvbapi_try_next_caid(i);
261
262 openxcas_stop_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM);
263 openxcas_remove_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM);
264
265 unsigned char mask[12];
266 unsigned char comp[12];
267 memset(&mask, 0x00, sizeof(mask));
268 memset(&comp, 0x00, sizeof(comp));
269
270 mask[0] = 0xfe;
271 comp[0] = 0x80;
272
273 if (openxcas_add_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM, 0, 0xffff, openxcas_ecm_pid, mask, comp, (void *)azbox_openxcas_ecm_callback) < 0) {
274 cs_log(LOG_PREFIX "unable to add ecm filter (0)");
275 if (openxcas_add_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM, openxcas_caid, 0xffff, openxcas_ecm_pid, mask, comp, (void *)azbox_openxcas_ecm_callback) < 0)
276 cs_log(LOG_PREFIX "unable to add ecm filter (%04x)", openxcas_caid);
277 else
278 cs_debug_mask(D_DVBAPI, LOG_PREFIX "ecm filter added, pid = %x, caid = %x", openxcas_ecm_pid, openxcas_caid);
279 } else
280 cs_debug_mask(D_DVBAPI, LOG_PREFIX "ecm filter added, pid = %x, caid = %x", openxcas_ecm_pid, 0);
281
282 if (openxcas_start_filter(openxcas_stream_id, openxcas_seq, OPENXCAS_FILTER_ECM) < 0)
283 cs_log(LOG_PREFIX "unable to start ecm filter");
284 else
285 cs_debug_mask(D_DVBAPI, LOG_PREFIX "ecm filter started");
286
287 return;
288 }
289 }
290
291 unsigned char nullcw[8];
292 memset(nullcw, 0, 8);
293
294 int32_t n;
295 for (n=0;n<2;n++) {
296 if (memcmp(er->cw + (n * 8), demux[0].lastcw[n], 8) && memcmp(er->cw + (n * 8), nullcw, 8)) {
297 memcpy(demux[0].lastcw[n], er->cw + (n * 8), 8);
298 memcpy(openxcas_cw + (n * 8), er->cw + (n * 8), 8);
299 }
300 }
301
302 if (openxcas_set_key(openxcas_stream_id, openxcas_seq, 0, openxcas_cipher_idx, openxcas_cw, openxcas_cw + 8) != 1)
303 cs_log(LOG_PREFIX "set cw failed");
304 else
305 cs_ddump_mask(D_DVBAPI, openxcas_cw, 16, LOG_PREFIX "write cws to descrambler");
306}
307
308#ifdef WITH_CARDREADER
309#define __openxcas_open openxcas_open_with_smartcard
310#else
311#define __openxcas_open openxcas_open
312#endif
313
314void azbox_init(void) {
315 openxcas_debug_message_onoff(1); // debug
316 if (__openxcas_open("oscamCAS") < 0)
317 cs_log(LOG_PREFIX "could not init");
318}
319
320void azbox_close(void) {
321 if (openxcas_close() < 0)
322 cs_log(LOG_PREFIX "could not close");
323}
324
325#endif
Note: See TracBrowser for help on using the repository browser.