|
SASC-NG
DVBSoftCAM
|
00001 /*************************************************************************** 00002 * Copyright (c) 2003 by Marcel Wiesweg * 00003 * * 00004 * This program is free software; you can redistribute it and/or modify * 00005 * it under the terms of the GNU General Public License as published by * 00006 * the Free Software Foundation; either version 2 of the License, or * 00007 * (at your option) any later version. * 00008 * * 00009 * $Id: si.c 1.16 2006/04/14 10:53:44 kls Exp $ 00010 * * 00011 ***************************************************************************/ 00012 00013 #include <string.h> 00014 #include "si.h" 00015 #include "descriptor.h" 00016 00017 namespace SI { 00018 00019 Object::Object() { 00020 } 00021 00022 Object::Object(CharArray &d) : data(d) { 00023 } 00024 00025 void Object::setData(const unsigned char*d, int size, bool doCopy) { 00026 data.assign(d, size, doCopy); 00027 } 00028 00029 void Object::setData(CharArray &d) { 00030 data=d; 00031 } 00032 00033 bool Object::checkSize(int offset) { 00034 return data.checkSize(offset); 00035 } 00036 00037 Section::Section(const unsigned char *data, bool doCopy) { 00038 setData(data, getLength(data), doCopy); 00039 } 00040 00041 TableId Section::getTableId() const { 00042 return getTableId(data.getData()); 00043 } 00044 00045 int Section::getLength() { 00046 return getLength(data.getData()); 00047 } 00048 00049 TableId Section::getTableId(const unsigned char *d) { 00050 return (TableId)((const SectionHeader *)d)->table_id; 00051 } 00052 00053 int Section::getLength(const unsigned char *d) { 00054 return HILO(((const SectionHeader *)d)->section_length)+sizeof(SectionHeader); 00055 } 00056 00057 bool CRCSection::isCRCValid() { 00058 return CRC32::isValid((const char *)data.getData(), getLength()/*, data.FourBytes(getLength()-4)*/); 00059 } 00060 00061 bool CRCSection::CheckCRCAndParse() { 00062 if (!isCRCValid()) 00063 return false; 00064 CheckParse(); 00065 return isValid(); 00066 } 00067 00068 int NumberedSection::getTableIdExtension() const { 00069 return getTableIdExtension(data.getData()); 00070 } 00071 00072 int NumberedSection::getTableIdExtension(const unsigned char *d) { 00073 return HILO(((const ExtendedSectionHeader *)d)->table_id_extension); 00074 } 00075 00076 bool NumberedSection::getCurrentNextIndicator() const { 00077 return data.getData<ExtendedSectionHeader>()->current_next_indicator; 00078 } 00079 00080 int NumberedSection::getVersionNumber() const { 00081 return data.getData<ExtendedSectionHeader>()->version_number; 00082 } 00083 00084 int NumberedSection::getSectionNumber() const { 00085 return data.getData<ExtendedSectionHeader>()->section_number; 00086 } 00087 00088 int NumberedSection::getLastSectionNumber() const { 00089 return data.getData<ExtendedSectionHeader>()->last_section_number; 00090 } 00091 00092 int Descriptor::getLength() { 00093 return getLength(data.getData()); 00094 } 00095 00096 DescriptorTag Descriptor::getDescriptorTag() const { 00097 return getDescriptorTag(data.getData()); 00098 } 00099 00100 int Descriptor::getLength(const unsigned char *d) { 00101 return ((const DescriptorHeader*)d)->descriptor_length+sizeof(DescriptorHeader); 00102 } 00103 00104 DescriptorTag Descriptor::getDescriptorTag(const unsigned char *d) { 00105 return (DescriptorTag)((const DescriptorHeader*)d)->descriptor_tag; 00106 } 00107 00108 Descriptor *DescriptorLoop::getNext(Iterator &it) { 00109 if (isValid() && it.i<getLength()) { 00110 return createDescriptor(it.i, true); 00111 } 00112 return 0; 00113 } 00114 00115 Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag tag, bool returnUnimplemetedDescriptor) { 00116 Descriptor *d=0; 00117 int len; 00118 if (isValid() && it.i<(len=getLength())) { 00119 const unsigned char *p=data.getData(it.i); 00120 const unsigned char *end=p+len-it.i; 00121 while (p < end) { 00122 if (Descriptor::getDescriptorTag(p) == tag) { 00123 d=createDescriptor(it.i, returnUnimplemetedDescriptor); 00124 if (d) 00125 break; 00126 } 00127 it.i+=Descriptor::getLength(p); 00128 p+=Descriptor::getLength(p); 00129 } 00130 } 00131 return d; 00132 } 00133 00134 Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag *tags, int arrayLength, bool returnUnimplementedDescriptor) { 00135 Descriptor *d=0; 00136 int len; 00137 if (isValid() && it.i<(len=getLength())) { 00138 const unsigned char *p=data.getData(it.i); 00139 const unsigned char *end=p+len-it.i; 00140 while (p < end) { 00141 for (int u=0; u<arrayLength;u++) 00142 if (Descriptor::getDescriptorTag(p) == tags[u]) { 00143 d=createDescriptor(it.i, returnUnimplementedDescriptor); 00144 break; 00145 } 00146 if (d) 00147 break; //length is added to it.i by createDescriptor, break here 00148 it.i+=Descriptor::getLength(p); 00149 p+=Descriptor::getLength(p); 00150 } 00151 } 00152 return d; 00153 } 00154 00155 Descriptor *DescriptorLoop::createDescriptor(int &i, bool returnUnimplemetedDescriptor) { 00156 if (!checkSize(Descriptor::getLength(data.getData(i)))) 00157 return 0; 00158 Descriptor *d=Descriptor::getDescriptor(data+i, domain, returnUnimplemetedDescriptor); 00159 if (!d) 00160 return 0; 00161 i+=d->getLength(); 00162 d->CheckParse(); 00163 return d; 00164 } 00165 00166 int DescriptorLoop::getNumberOfDescriptors() { 00167 const unsigned char *p=data.getData(); 00168 const unsigned char *end=p+getLength(); 00169 int count=0; 00170 while (p < end) { 00171 count++; 00172 p+=Descriptor::getLength(p); 00173 } 00174 return count; 00175 } 00176 00177 DescriptorGroup::DescriptorGroup(bool del) { 00178 array=0; 00179 length=0; 00180 deleteOnDesctruction=del; 00181 } 00182 00183 DescriptorGroup::~DescriptorGroup() { 00184 if (deleteOnDesctruction) 00185 Delete(); 00186 delete[] array; 00187 } 00188 00189 void DescriptorGroup::Delete() { 00190 for (int i=0;i<length;i++) 00191 if (array[i]!=0) { 00192 delete array[i]; 00193 array[i]=0; 00194 } 00195 } 00196 00197 void DescriptorGroup::Add(GroupDescriptor *d) { 00198 if (!array) { 00199 length=d->getLastDescriptorNumber()+1; 00200 array=new GroupDescriptor*[length]; //numbering is zero-based 00201 for (int i=0;i<length;i++) 00202 array[i]=0; 00203 } else if (length != d->getLastDescriptorNumber()+1) 00204 return; //avoid crash in case of misuse 00205 array[d->getDescriptorNumber()]=d; 00206 } 00207 00208 bool DescriptorGroup::isComplete() { 00209 for (int i=0;i<length;i++) 00210 if (array[i]==0) 00211 return false; 00212 return true; 00213 } 00214 00215 char *String::getText() { 00216 int len=getLength(); 00217 if (len < 0 || len > 4095) 00218 return strdup("text error"); // caller will delete it! 00219 char *data=new char(len+1); 00220 decodeText(data, len+1); 00221 return data; 00222 } 00223 00224 char *String::getText(char *buffer, int size) { 00225 int len=getLength(); 00226 if (len < 0 || len >= size) { 00227 strncpy(buffer, "text error", size); 00228 buffer[size-1] = 0; 00229 return buffer; 00230 } 00231 decodeText(buffer, size); 00232 return buffer; 00233 } 00234 00235 //taken from VDR, Copyright Klaus Schmidinger <kls@cadsoft.de> 00236 char *String::getText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion) { 00237 int len=getLength(); 00238 if (len < 0 || len >= sizeBuffer) { 00239 strncpy(buffer, "text error", sizeBuffer); 00240 buffer[sizeBuffer-1] = 0; 00241 *shortVersion = 0; 00242 return buffer; 00243 } 00244 decodeText(buffer, shortVersion, sizeBuffer, sizeShortVersion); 00245 return buffer; 00246 } 00247 00248 //taken from libdtv, Copyright Rolf Hakenes <hakenes@hippomi.de> 00249 void String::decodeText(char *buffer, int size) { 00250 const unsigned char *from=data.getData(0); 00251 char *to=buffer; 00252 00253 /* Disable detection of coding tables - libdtv doesn't do it either 00254 if ( (0x01 <= *from) && (*from <= 0x1f) ) { 00255 codeTable=*from 00256 } 00257 */ 00258 00259 if (*from == 0x10) 00260 from += 3; // skips code table info 00261 00262 int len=getLength(); 00263 for (int i = 0; i < len; i++) { 00264 if (*from == 0) 00265 break; 00266 if ( ((' ' <= *from) && (*from <= '~')) 00267 || (*from == '\n') 00268 || (0xA0 <= *from) 00269 || (*from == 0x86 || *from == 0x87) 00270 ) 00271 *to++ = *from; 00272 else if (*from == 0x8A) 00273 *to++ = '\n'; 00274 from++; 00275 if (to - buffer >= size - 1) 00276 break; 00277 } 00278 *to = '\0'; 00279 } 00280 00281 void String::decodeText(char *buffer, char *shortVersion, int sizeBuffer, int sizeShortVersion) { 00282 const unsigned char *from=data.getData(0); 00283 char *to=buffer; 00284 char *toShort=shortVersion; 00285 int IsShortName=0; 00286 00287 if (*from == 0x10) 00288 from += 3; // skips code table info 00289 00290 int len=getLength(); 00291 for (int i = 0; i < len; i++) { 00292 if ( ((' ' <= *from) && (*from <= '~')) 00293 || (*from == '\n') 00294 || (0xA0 <= *from) 00295 ) 00296 { 00297 *to++ = *from; 00298 if (IsShortName) 00299 *toShort++ = *from; 00300 } 00301 else if (*from == 0x8A) 00302 *to++ = '\n'; 00303 else if (*from == 0x86) 00304 IsShortName++; 00305 else if (*from == 0x87) 00306 IsShortName--; 00307 else if (*from == 0) 00308 break; 00309 from++; 00310 if (to - buffer >= sizeBuffer - 1 || toShort - shortVersion >= sizeShortVersion - 1) 00311 break; 00312 } 00313 *to = '\0'; 00314 *toShort = '\0'; 00315 } 00316 00317 Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, bool returnUnimplemetedDescriptor) { 00318 Descriptor *d=0; 00319 switch (domain) { 00320 case SI: 00321 switch ((DescriptorTag)da.getData<DescriptorHeader>()->descriptor_tag) { 00322 case CaDescriptorTag: 00323 d=new CaDescriptor(); 00324 break; 00325 case CarouselIdentifierDescriptorTag: 00326 d=new CarouselIdentifierDescriptor(); 00327 break; 00328 case NetworkNameDescriptorTag: 00329 d=new NetworkNameDescriptor(); 00330 break; 00331 case ServiceListDescriptorTag: 00332 d=new ServiceListDescriptor(); 00333 break; 00334 case SatelliteDeliverySystemDescriptorTag: 00335 d=new SatelliteDeliverySystemDescriptor(); 00336 break; 00337 case CableDeliverySystemDescriptorTag: 00338 d=new CableDeliverySystemDescriptor(); 00339 break; 00340 case TerrestrialDeliverySystemDescriptorTag: 00341 d=new TerrestrialDeliverySystemDescriptor(); 00342 break; 00343 case BouquetNameDescriptorTag: 00344 d=new BouquetNameDescriptor(); 00345 break; 00346 case ServiceDescriptorTag: 00347 d=new ServiceDescriptor(); 00348 break; 00349 case NVODReferenceDescriptorTag: 00350 d=new NVODReferenceDescriptor(); 00351 break; 00352 case TimeShiftedServiceDescriptorTag: 00353 d=new TimeShiftedServiceDescriptor(); 00354 break; 00355 case ComponentDescriptorTag: 00356 d=new ComponentDescriptor(); 00357 break; 00358 case StreamIdentifierDescriptorTag: 00359 d=new StreamIdentifierDescriptor(); 00360 break; 00361 case SubtitlingDescriptorTag: 00362 d=new SubtitlingDescriptor(); 00363 break; 00364 case MultilingualNetworkNameDescriptorTag: 00365 d=new MultilingualNetworkNameDescriptor(); 00366 break; 00367 case MultilingualBouquetNameDescriptorTag: 00368 d=new MultilingualBouquetNameDescriptor(); 00369 break; 00370 case MultilingualServiceNameDescriptorTag: 00371 d=new MultilingualServiceNameDescriptor(); 00372 break; 00373 case MultilingualComponentDescriptorTag: 00374 d=new MultilingualComponentDescriptor(); 00375 break; 00376 case PrivateDataSpecifierDescriptorTag: 00377 d=new PrivateDataSpecifierDescriptor(); 00378 break; 00379 case ServiceMoveDescriptorTag: 00380 d=new ServiceMoveDescriptor(); 00381 break; 00382 case FrequencyListDescriptorTag: 00383 d=new FrequencyListDescriptor(); 00384 break; 00385 case ServiceIdentifierDescriptorTag: 00386 d=new ServiceIdentifierDescriptor(); 00387 break; 00388 case CaIdentifierDescriptorTag: 00389 d=new CaIdentifierDescriptor(); 00390 break; 00391 case ShortEventDescriptorTag: 00392 d=new ShortEventDescriptor(); 00393 break; 00394 case ExtendedEventDescriptorTag: 00395 d=new ExtendedEventDescriptor(); 00396 break; 00397 case TimeShiftedEventDescriptorTag: 00398 d=new TimeShiftedEventDescriptor(); 00399 break; 00400 case ContentDescriptorTag: 00401 d=new ContentDescriptor(); 00402 break; 00403 case ParentalRatingDescriptorTag: 00404 d=new ParentalRatingDescriptor(); 00405 break; 00406 case TeletextDescriptorTag: 00407 case VBITeletextDescriptorTag: 00408 d=new TeletextDescriptor(); 00409 break; 00410 case ApplicationSignallingDescriptorTag: 00411 d=new ApplicationSignallingDescriptor(); 00412 break; 00413 case LocalTimeOffsetDescriptorTag: 00414 d=new LocalTimeOffsetDescriptor(); 00415 break; 00416 case LinkageDescriptorTag: 00417 d=new LinkageDescriptor(); 00418 break; 00419 case ISO639LanguageDescriptorTag: 00420 d=new ISO639LanguageDescriptor(); 00421 break; 00422 case PDCDescriptorTag: 00423 d=new PDCDescriptor(); 00424 break; 00425 case AncillaryDataDescriptorTag: 00426 d=new AncillaryDataDescriptor(); 00427 break; 00428 00429 //note that it is no problem to implement one 00430 //of the unimplemented descriptors. 00431 00432 //defined in ISO-13818-1 00433 case VideoStreamDescriptorTag: 00434 case AudioStreamDescriptorTag: 00435 case HierarchyDescriptorTag: 00436 case RegistrationDescriptorTag: 00437 case DataStreamAlignmentDescriptorTag: 00438 case TargetBackgroundGridDescriptorTag: 00439 case VideoWindowDescriptorTag: 00440 case SystemClockDescriptorTag: 00441 case MultiplexBufferUtilizationDescriptorTag: 00442 case CopyrightDescriptorTag: 00443 case MaximumBitrateDescriptorTag: 00444 case PrivateDataIndicatorDescriptorTag: 00445 case SmoothingBufferDescriptorTag: 00446 case STDDescriptorTag: 00447 case IBPDescriptorTag: 00448 00449 //defined in ETSI EN 300 468 00450 case StuffingDescriptorTag: 00451 case VBIDataDescriptorTag: 00452 case CountryAvailabilityDescriptorTag: 00453 case MocaicDescriptorTag: 00454 case TelephoneDescriptorTag: 00455 case CellListDescriptorTag: 00456 case CellFrequencyLinkDescriptorTag: 00457 case ServiceAvailabilityDescriptorTag: 00458 case ShortSmoothingBufferDescriptorTag: 00459 case PartialTransportStreamDescriptorTag: 00460 case DataBroadcastDescriptorTag: 00461 case DataBroadcastIdDescriptorTag: 00462 case CaSystemDescriptorTag: 00463 case AC3DescriptorTag: 00464 case DSNGDescriptorTag: 00465 case AnnouncementSupportDescriptorTag: 00466 case AdaptationFieldDataDescriptorTag: 00467 case TransportStreamDescriptorTag: 00468 default: 00469 if (!returnUnimplemetedDescriptor) 00470 return 0; 00471 d=new UnimplementedDescriptor(); 00472 break; 00473 } 00474 break; 00475 case MHP: 00476 switch ((DescriptorTag)da.getData<DescriptorHeader>()->descriptor_tag) { 00477 // They once again start with 0x00 (see page 234, MHP specification) 00478 case MHP_ApplicationDescriptorTag: 00479 d=new MHP_ApplicationDescriptor(); 00480 break; 00481 case MHP_ApplicationNameDescriptorTag: 00482 d=new MHP_ApplicationNameDescriptor(); 00483 break; 00484 case MHP_TransportProtocolDescriptorTag: 00485 d=new MHP_TransportProtocolDescriptor(); 00486 break; 00487 case MHP_DVBJApplicationDescriptorTag: 00488 d=new MHP_DVBJApplicationDescriptor(); 00489 break; 00490 case MHP_DVBJApplicationLocationDescriptorTag: 00491 d=new MHP_DVBJApplicationLocationDescriptor(); 00492 break; 00493 // 0x05 - 0x0A is unimplemented this library 00494 case MHP_ExternalApplicationAuthorisationDescriptorTag: 00495 case MHP_IPv4RoutingDescriptorTag: 00496 case MHP_IPv6RoutingDescriptorTag: 00497 case MHP_DVBHTMLApplicationDescriptorTag: 00498 case MHP_DVBHTMLApplicationLocationDescriptorTag: 00499 case MHP_DVBHTMLApplicationBoundaryDescriptorTag: 00500 case MHP_ApplicationIconsDescriptorTag: 00501 case MHP_PrefetchDescriptorTag: 00502 case MHP_DelegatedApplicationDescriptorTag: 00503 case MHP_ApplicationStorageDescriptorTag: 00504 default: 00505 if (!returnUnimplemetedDescriptor) 00506 return 0; 00507 d=new UnimplementedDescriptor(); 00508 break; 00509 } 00510 break; 00511 case PCIT: 00512 switch ((DescriptorTag)da.getData<DescriptorHeader>()->descriptor_tag) { 00513 case ContentDescriptorTag: 00514 d=new ContentDescriptor(); 00515 break; 00516 case ShortEventDescriptorTag: 00517 d=new ShortEventDescriptor(); 00518 break; 00519 case ExtendedEventDescriptorTag: 00520 d=new ExtendedEventDescriptor(); 00521 break; 00522 case PremiereContentTransmissionDescriptorTag: 00523 d=new PremiereContentTransmissionDescriptor(); 00524 break; 00525 default: 00526 if (!returnUnimplemetedDescriptor) 00527 return 0; 00528 d=new UnimplementedDescriptor(); 00529 break; 00530 } 00531 break; 00532 } 00533 d->setData(da); 00534 return d; 00535 } 00536 00537 } //end of namespace