00001
00002
00003
00004
00005
00006 #include <stdlib.h>
00007 #include <string.h>
00008
00009 #include "dsmccbiop.h"
00010 #include "dsmccreceiver.h"
00011 #include "dsmcccache.h"
00012 #include "dsmccobjcarousel.h"
00013 #include "dsmcc.h"
00014
00015 #include "mythcontext.h"
00016
00017 BiopNameComp::~BiopNameComp()
00018 {
00019 if (m_id)
00020 free(m_id);
00021 if (m_kind)
00022 free(m_kind);
00023 }
00024
00025 int BiopNameComp::Process(const unsigned char *data)
00026 {
00027 int off = 0;
00028
00029 m_id_len = data[off++];
00030 m_id = (char*) malloc(m_id_len);
00031 memcpy(m_id, data + off, m_id_len);
00032
00033 off += m_id_len;
00034 m_kind_len = data[off++];
00035 m_kind = (char*) malloc(m_kind_len);
00036 memcpy(m_kind, data + off, m_kind_len);
00037
00038 off += m_kind_len;
00039
00040 return off;
00041 }
00042
00043 BiopName::BiopName()
00044 {
00045 m_comp_count = 0;
00046 m_comps = NULL;
00047 }
00048
00049 BiopName::~BiopName()
00050 {
00051 delete[] m_comps;
00052 }
00053
00054 int BiopName::Process(const unsigned char *data)
00055 {
00056 int off = 0;
00057 m_comp_count = data[0];
00058 off++;
00059 m_comps = new BiopNameComp[m_comp_count];
00060
00061 for (int i = 0; i < m_comp_count; i++)
00062 {
00063 int ret = m_comps[i].Process(data + off);
00064 if (ret > 0)
00065 off += ret;
00066 else
00067 return off;
00068 }
00069
00070 return off;
00071 }
00072
00073 int BiopBinding::Process(const unsigned char *data)
00074 {
00075 int off = 0, ret;
00076 ret = m_name.Process(data);
00077
00078 if (ret > 0)
00079 off += ret;
00080 else
00081 return off;
00082
00083 m_binding_type = data[off++];
00084 ret = m_ior.Process(data + off);
00085
00086 if (ret > 0)
00087 off += ret;
00088 else
00089 return off;
00090
00091 m_objinfo_len = (data[off] << 8) | data[off + 1];
00092 off += 2;
00093
00094 if (m_objinfo_len > 0)
00095 {
00096 m_objinfo = (char*) malloc(m_objinfo_len);
00097 memcpy(m_objinfo, data + off, m_objinfo_len);
00098 }
00099 else
00100 m_objinfo = NULL;
00101
00102 off += m_objinfo_len;
00103
00104 return off;
00105 }
00106
00107 BiopBinding::~BiopBinding()
00108 {
00109 free(m_objinfo);
00110 }
00111
00112 bool BiopMessage::Process(DSMCCCacheModuleData *cachep, DSMCCCache *filecache,
00113 unsigned char *data, unsigned long *curp)
00114 {
00115
00116 if (! ProcessMsgHdr(data, curp))
00117 {
00118 VERBOSE(VB_DSMCC,"[biop] Invalid biop header, "
00119 "dropping rest of module");
00120
00121
00122 return false;
00123 }
00124
00125
00126 if (strcmp(m_objkind, "fil") == 0)
00127 {
00128 VERBOSE(VB_DSMCC,"[biop] Processing file");
00129 return ProcessFile(cachep, filecache, data, curp);
00130 }
00131 else if (strcmp(m_objkind, "dir") == 0)
00132 {
00133 VERBOSE(VB_DSMCC,"[biop] Processing directory");
00134 return ProcessDir(false, cachep, filecache, data, curp);
00135 }
00136 else if (strcmp(m_objkind, "srg") == 0)
00137 {
00138 VERBOSE(VB_DSMCC,"[biop] Processing gateway");
00139 return ProcessDir(true, cachep, filecache, data, curp);
00140 }
00141 else
00142 {
00143
00144 VERBOSE(VB_DSMCC, QString("Unknown or unsupported format %1%2%3%4")
00145 .arg(m_objkind[0]).arg(m_objkind[1])
00146 .arg(m_objkind[2]).arg(m_objkind[3]));
00147 return false;
00148 }
00149 }
00150
00151 BiopMessage::~BiopMessage()
00152 {
00153 free(m_objinfo);
00154 free(m_objkind);
00155 }
00156
00157 bool BiopMessage::ProcessMsgHdr(unsigned char *data, unsigned long *curp)
00158 {
00159 const unsigned char *buf = data + (*curp);
00160 int off = 0;
00161
00162 if (buf[0] !='B' || buf[1] !='I' || buf[2] !='O' || buf[3] !='P')
00163 {
00164 VERBOSE(VB_DSMCC, "BiopMessage - invalid header");
00165 return false;
00166 }
00167
00168 off += 4;
00169 m_version_major = buf[off++];
00170 m_version_minor = buf[off++];
00171 off += 2;
00172 m_message_size = ((buf[off + 0] << 24) | (buf[off+1] << 16) |
00173 (buf[off + 2] << 8) | (buf[off + 3]));
00174 off += 4;
00175 uint nObjLen = buf[off++];
00176 m_objkey.duplicate((const char*)buf + off, nObjLen);
00177 off += nObjLen;
00178 m_objkind_len = ((buf[off + 0] << 24) | (buf[off + 1] << 16) |
00179 (buf[off + 2] << 8) | (buf[off + 3]));
00180
00181 off += 4;
00182 m_objkind = (char*) malloc(m_objkind_len);
00183 memcpy(m_objkind, buf + off, m_objkind_len);
00184 off += m_objkind_len;
00185 m_objinfo_len = buf[off] << 8 | buf[off + 1];
00186 off += 2;
00187 m_objinfo = (char*) malloc(m_objinfo_len);
00188 memcpy(m_objinfo, buf + off, m_objinfo_len);
00189 off += m_objinfo_len;
00190 (*curp) += off;
00191
00192 return true;
00193 }
00194
00195
00204 bool BiopMessage::ProcessDir(
00205 bool isSrg, DSMCCCacheModuleData *cachep, DSMCCCache *filecache,
00206 unsigned char *data, unsigned long *curp)
00207 {
00208 int off = 0;
00209 const unsigned char *buf = data + (*curp);
00210 off++;
00211
00212 unsigned long msgbody_len = ((buf[off + 0] << 24) | (buf[off + 1] << 16) |
00213 (buf[off + 2] << 8) | (buf[off + 3]));
00214 (void) msgbody_len;
00215 off += 4;
00216
00217 unsigned int bindings_count = buf[off] << 8 | buf[off + 1];
00218 off += 2;
00219
00220 DSMCCCacheReference ref(cachep->CarouselId(), cachep->ModuleId(),
00221 cachep->StreamId(), m_objkey);
00222 DSMCCCacheDir *pDir;
00223 if (isSrg)
00224 pDir = filecache->Srg(ref);
00225 else
00226 pDir = filecache->Directory(ref);
00227
00228 VERBOSE(VB_DSMCC, QString("[Biop] Processing %1 reference %2")
00229 .arg(isSrg ? "gateway" : "directory").arg(ref.toString()));
00230
00231 for (uint i = 0; i < bindings_count; i++)
00232 {
00233 BiopBinding binding;
00234 int ret = binding.Process(buf + off);
00235 if (ret > 0)
00236 off += ret;
00237 else
00238 return false;
00239
00240
00241 binding.m_ior.AddTap(filecache->m_Dsmcc);
00242
00243 if (pDir)
00244 {
00245 if (strcmp("dir", binding.m_name.m_comps[0].m_kind) == 0)
00246 filecache->AddDirInfo(pDir, &binding);
00247 else if (strcmp("fil", binding.m_name.m_comps[0].m_kind) == 0)
00248 filecache->AddFileInfo(pDir, &binding);
00249 }
00250 }
00251
00252 (*curp) += off;
00253
00254 return true;
00255 }
00256
00257 bool BiopMessage::ProcessFile(DSMCCCacheModuleData *cachep, DSMCCCache *filecache,
00258 unsigned char *data, unsigned long *curp)
00259 {
00260 int off = 0;
00261 const unsigned char *buf = data + (*curp);
00262 unsigned long msgbody_len;
00263 unsigned long content_len;
00264
00265
00266
00267 off++;
00268 msgbody_len = ((buf[off ] << 24) | (buf[off + 1] << 16) |
00269 (buf[off + 2] << 8) | (buf[off + 3]));
00270 off += 4;
00271 content_len = ((buf[off ] << 24) | (buf[off + 1] << 16) |
00272 (buf[off + 2] << 8) | (buf[off + 3]));
00273 off += 4;
00274
00275 (*curp) += off;
00276
00277 DSMCCCacheReference ref(cachep->CarouselId(), cachep->ModuleId(),
00278 cachep->StreamId(), m_objkey);
00279
00280 QByteArray filedata;
00281 filedata.duplicate((const char *)data+(*curp), content_len);
00282 filecache->CacheFileData(ref, filedata);
00283
00284 (*curp) += content_len;
00285 return true;
00286 }
00287
00288 void ModuleDescriptorData::Process(const unsigned char *data, int length)
00289 {
00290 while (length > 0)
00291 {
00292 unsigned char tag = *data++;
00293 unsigned char len = *data++;
00294 length -= 2;
00295 switch (tag)
00296 {
00297 case 0x01:
00298 break;
00299 case 0x02:
00300 break;
00301 case 0x03:
00302 break;
00303 case 0x04:
00304 break;
00305 case 0x05:
00306 break;
00307 case 0x06:
00308 break;
00309 case 0x07:
00310 break;
00311 case 0x08:
00312 break;
00313 case 0x09:
00314
00315 isCompressed = true;
00316 originalSize = ((data[1] << 24) | (data[2] << 16) |
00317 (data[3] << 8) | (data[4]));
00318 break;
00319 default:
00320 break;
00321 }
00322 length -= len;
00323 data += len;
00324 }
00325 }
00326
00327 int BiopModuleInfo::Process(const unsigned char *data)
00328 {
00329 int off, ret;
00330 mod_timeout = ((data[0] << 24) | (data[1] << 16) |
00331 (data[2] << 8) | (data[3]));
00332 block_timeout = ((data[4] << 24) | (data[5] << 16) |
00333 (data[6] << 8) | (data[7]));
00334 min_blocktime = ((data[8] << 24) | (data[9] << 16) |
00335 (data[10] << 8) | (data[11]));
00336
00337 taps_count = data[12];
00338 off = 13;
00339
00340 if (taps_count > 0)
00341 {
00342
00343 ret = tap.Process(data + off);
00344 if (ret > 0)
00345 off += ret;
00346
00347 }
00348
00349 unsigned userinfo_len = data[off++];
00350
00351 if (userinfo_len > 0)
00352 {
00353 descriptorData.Process(data + off, userinfo_len);
00354 off += userinfo_len;
00355 }
00356 return off;
00357
00358 }
00359
00360 int BiopTap::Process(const unsigned char *data)
00361 {
00362 int off=0;
00363
00364 id = (data[0] << 8) | data[1];
00365 off += 2;
00366 use = (data[off] << 8) | data[off + 1];
00367 off += 2;
00368 assoc_tag = (data[off] << 8) | data[off + 1];
00369 off += 2;
00370 selector_len = data[off++];
00371 selector_data = (char*) malloc(selector_len);
00372 memcpy(selector_data, data + off, selector_len);
00373 off += selector_len;
00374
00375 return off;
00376 }
00377
00378 int BiopConnbinder::Process(const unsigned char *data)
00379 {
00380 int off = 0, ret;
00381
00382 component_tag = ((data[0] << 24) | (data[1] << 16) |
00383 (data[2] << 8) | (data[3]));
00384
00385 off += 4;
00386 component_data_len = data[off++];
00387 taps_count = data[off++];
00388 if (taps_count > 0)
00389 {
00390
00391 ret = tap.Process(data + off);
00392
00393 if (ret > 0)
00394 off += ret;
00395
00396 }
00397
00398 return off;
00399 }
00400
00401 int BiopObjLocation::Process(const unsigned char *data)
00402 {
00403 int off = 0;
00404
00405 component_tag = ((data[0] << 24) | (data[1] << 16) |
00406 (data[2] << 8) | (data[3]));
00407 off += 4;
00408 component_data_len = data[off++];
00409 m_Reference.m_nCarouselId =
00410 ((data[off ] << 24) | (data[off + 1] << 16) |
00411 (data[off + 2] << 8) | (data[off + 3]));
00412
00413 off += 4;
00414 m_Reference.m_nModuleId = (data[off] << 8) | data[off + 1];
00415 off += 2;
00416 version_major = data[off++];
00417 version_minor = data[off++];
00418 uint objKeyLen = data[off++];
00419 m_Reference.m_Key.duplicate((char*)data + off, objKeyLen);
00420 off += objKeyLen;
00421 return off;
00422 }
00423
00424
00425
00426 int ProfileBodyLite::Process(const unsigned char *)
00427 {
00428 VERBOSE(VB_DSMCC, "Found LiteProfileBody - Not Implemented Yet");
00429 return 0;
00430 }
00431
00432 int ProfileBodyFull::Process(const unsigned char *data)
00433 {
00434 int off = 0, ret;
00435
00436 data_len = ((data[off ] << 24) | (data[off + 1] << 16) |
00437 (data[off + 2] << 8) | (data[off + 3]));
00438 off += 4;
00439
00440 off += 1;
00441 lite_components_count = data[off++];
00442
00443 ret = obj_loc.Process(data + off);
00444 if (ret > 0)
00445 off += ret;
00446
00447
00448 ret = dsm_conn.Process(data + off);
00449 if (ret > 0)
00450 off += ret;
00451
00452
00453 obj_loc.m_Reference.m_nStreamTag = dsm_conn.tap.assoc_tag;
00454
00455
00456
00457 return off;
00458 }
00459
00460 int BiopIor::Process(const unsigned char *data)
00461 {
00462 int off = 0, ret;
00463 type_id_len = ((data[0] << 24) | (data[1] << 16) |
00464 (data[2] << 8) | (data[3]));
00465 type_id = (char*) malloc(type_id_len);
00466 off += 4;
00467 memcpy(type_id, data + off, type_id_len);
00468 off += type_id_len;
00469 tagged_profiles_count = ((data[off ] << 24) | (data[off + 1] << 16) |
00470 (data[off + 2] << 8) | (data[off + 3]));
00471 off += 4;
00472 profile_id_tag = ((data[off ] << 24) | (data[off + 1] << 16) |
00473 (data[off + 2] << 8) | (data[off + 3]));
00474 off += 4;
00475
00476 if ((profile_id_tag & 0xFF) == 0x06)
00477 {
00478 m_profile_body = new ProfileBodyFull;
00479 ret = m_profile_body->Process(data + off);
00480 if (ret > 0)
00481 off += ret;
00482
00483 }
00484 else if((profile_id_tag & 0xFF) == 0x05)
00485 {
00486 m_profile_body = new ProfileBodyLite;
00487 ret = m_profile_body->Process(data + off);
00488 if (ret > 0)
00489 off += ret;
00490
00491 }
00492
00493
00494
00495 return off;
00496 }
00497
00498
00499 void BiopIor::AddTap(Dsmcc *pStatus)
00500 {
00501 DSMCCCacheReference *ref = m_profile_body->GetReference();
00502 if (ref != NULL)
00503 pStatus->AddTap(ref->m_nStreamTag, ref->m_nCarouselId);
00504 }
00505
00506 BiopTap::~BiopTap()
00507 {
00508 free(selector_data);
00509 }