12 #include <sys/ioctl.h>
64 #define MIN_PRE_1_3_19_PRIVATESTREAM 10
112 esyslog(
"ERROR: too many devices!");
125 for (time_t t0 = time(NULL); time(NULL) - t0 < Timeout; ) {
153 esyslog(
"ERROR: invalid value in nextCardIndex(%d)", n);
188 isyslog(
"setting primary device to %d", n + 1);
197 esyslog(
"ERROR: invalid primary device number: %d", n + 1);
226 int MaxNumProvidedSystems = (1 << AvailableBits) - 1;
228 if (NumProvidedSystems > MaxNumProvidedSystems) {
229 esyslog(
"ERROR: device %d supports %d modulation systems but cDevice::GetDevice() currently only supports %d delivery systems which should be fixed", Device->
CardIndex() + 1, NumProvidedSystems, MaxNumProvidedSystems);
230 NumProvidedSystems = MaxNumProvidedSystems;
232 else if (NumProvidedSystems <= 0) {
233 esyslog(
"ERROR: device %d reported an invalid number (%d) of supported delivery systems - assuming 1", Device->
CardIndex() + 1, NumProvidedSystems);
234 NumProvidedSystems = 1;
236 return NumProvidedSystems;
243 int SlotPriority[NumCamSlots];
244 int NumUsableSlots = 0;
245 bool InternalCamNeeded =
false;
259 InternalCamNeeded =
true;
262 bool NeedsDetachReceivers =
false;
266 uint32_t Impact = 0xFFFFFFFF;
267 for (
int j = 0; j < NumCamSlots || !NumUsableSlots; j++) {
268 if (NumUsableSlots && SlotPriority[j] >
MAXPRIORITY)
274 if (InternalCamNeeded && !HasInternalCam)
296 imp <<= 1; imp |= ndr;
297 imp <<= 1; imp |= (NumUsableSlots || InternalCamNeeded) ? 0 :
device[i]->
HasCi();
305 NeedsDetachReceivers = ndr;
306 if (NumUsableSlots && !HasInternalCam)
315 if (NeedsDetachReceivers)
337 if (d->IsTunedToTransponder(Channel))
339 if (d->ProvidesTransponder(Channel)) {
340 if (d->MaySwitchTransponder(Channel))
342 else if (!d->Occupied() && d->MaySwitchTransponder(Channel)) {
343 if (d->Priority() < Priority && (!Device || d->
Priority() < Device->
Priority()))
380 int fd = open(FileName, O_WRONLY | O_CREAT | O_NOFOLLOW | O_TRUNC, DEFFILEMODE);
385 if (
safe_write(fd, Image, ImageSize) == ImageSize)
386 isyslog(
"grabbed image to %s", FileName);
411 switch (VideoDisplayFormat) {
421 default:
esyslog(
"ERROR: invalid value for VideoDisplayFormat '%d'", VideoDisplayFormat);
464 if (Pid || PidType ==
ptPcr) {
467 if (PidType !=
ptPcr) {
504 esyslog(
"ERROR: no free slot for PID %d on device %d", Pid,
CardIndex() + 1);
528 if (Pid || PidType ==
ptPcr) {
530 if (PidType ==
ptPcr)
603 return safe_read(Handle, Buffer, Length);
699 for (
int i = 3; i--;) {
701 case scrOk:
return true;
707 default:
esyslog(
"ERROR: invalid return value from SetChannel");
717 Direction =
sgn(Direction);
727 n = channel->
Number() + Direction;
732 dsyslog(
"skipped channel %d", first);
734 dsyslog(
"skipped channels %d..%d", first, n -
sgn(d));
756 bool NeedsTransferMode = Device !=
this;
763 if (NeedsTransferMode) {
799 if (Result ==
scrOk) {
812 if (!NeedsTransferMode)
834 return Seconds > 0 ? Seconds : 0;
903 return (0 <= c && c <= 2) ? c : 0;
908 if (0 <= AudioChannel && AudioChannel <= 2)
927 if (DescriptionsOnly) {
971 esyslog(
"ERROR: SetAvailableTrack called with invalid Type/Index (%d/%d)", Type, Index);
983 for (
int i = FirstTrack; i <= LastTrack; i++) {
1036 if (TrackId && TrackId->
id) {
1050 int PreferredAudioChannel = 0;
1051 int LanguagePreference = -1;
1054 for (
int i = StartCheck; i <= EndCheck; i++) {
1059 PreferredAudioChannel = pos;
1070 dsyslog(
"setting audio track to %d (%d)", PreferredTrack, PreferredAudioChannel);
1081 int LanguagePreference = INT_MAX;
1144 if (Data[0] == 0x47) {
1150 int Pid =
TsPid(Data);
1160 int NewSize = Size + l;
1161 if (
uchar *NewBuffer = (
uchar *)realloc(buf, NewSize)) {
1164 memcpy(buf + Offset, p, l);
1182 int NewSize = Size + l;
1183 if (
uchar *NewBuffer = (
uchar *)realloc(buf, NewSize)) {
1186 memcpy(buf + Offset, p, l);
1189 esyslog(
"ERROR: out of memory");
1232 if (Player &&
player == Player) {
1288 bool FirstLoop =
true;
1291 const uchar *End = Start + Length;
1292 while (Start < End) {
1293 int d = End -
Start;
1312 if (Data[8] == 0x24 && Data[45] >= 0x10 && Data[45] < 0x20) {
1317 int PayloadOffset = Data[8] + 9;
1320 if ((Data[7] & 0x01) && (Data[PayloadOffset - 3] & 0x81) == 0x01 && Data[PayloadOffset - 2] == 0x81)
1323 uchar SubStreamId = Data[PayloadOffset];
1324 uchar SubStreamType = SubStreamId & 0xF0;
1325 uchar SubStreamIndex = SubStreamId & 0x1F;
1328 pre_1_3_19_PrivateStreamDetected:
1331 SubStreamType = 0x80;
1336 switch (SubStreamType) {
1367 dsyslog(
"switching to pre 1.3.19 Dolby Digital compatibility mode - substream id = %02X", SubStreamId);
1370 goto pre_1_3_19_PrivateStreamDetected;
1383 esyslog(
"ERROR: incomplete PES packet write!");
1384 return Start == Data ? w : Start - Data;
1399 while (i <= Length - 6) {
1400 if (Data[i] == 0x00 && Data[i + 1] == 0x00 && Data[i + 2] == 0x01) {
1402 if (i + l > Length) {
1403 esyslog(
"ERROR: incomplete PES packet!");
1410 return i == 0 ? w : i;
1416 esyslog(
"ERROR: leftover PES data!");
1479 esyslog(
"ERROR: skipped %d bytes of TS fragment", Length);
1489 esyslog(
"ERROR: skipped %d bytes to sync on start of TS packet", Skipped);
1490 return Played + Skipped;
1492 int Pid =
TsPid(Data);
1495 if (PayloadOffset <
TS_SIZE) {
1504 return Played ? Played : w;
1512 return Played ? Played : w;
1527 if ((l > 45) && (p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] == 0xbd) && (p[8] == 0x24) && (p[45] >= 0x10) && (p[45] < 0x20))
1538 return Played ? Played : w;
1578 #define TS_SCRAMBLING_TIMEOUT 3 // seconds to wait until a TS becomes unscrambled
1579 #define TS_SCRAMBLING_TIME_OK 10 // seconds before a Channel/CAM combination is marked as known to decrypt
1591 bool DetachReceivers =
false;
1592 bool DescramblingOk =
false;
1593 int CamSlotNumber = 0;
1597 if (CamSlotNumber) {
1602 DetachReceivers =
true;
1605 DescramblingOk =
true;
1614 if (DetachReceivers) {
1652 if (Receiver->
device ==
this)
1656 #ifdef WAIT_FOR_TUNER_LOCK
1657 #define TUNER_LOCK_TIMEOUT 5000 // ms
1658 if (!
HasLock(TUNER_LOCK_TIMEOUT)) {
1659 esyslog(
"ERROR: device %d has no lock, can't attach receiver!",
CardIndex() + 1);
1666 for (
int n = 0; n < Receiver->
numPids; n++) {
1686 esyslog(
"ERROR: no free receiver slot!");
1692 if (!Receiver || Receiver->
device !=
this)
1694 bool receiversLeft =
false;
1703 for (
int n = 0; n < Receiver->
numPids; n++)
1707 receiversLeft =
true;
1721 if (Receiver && Receiver->
WantsPid(Pid))
1757 bool firstRead =
true;
1760 if (firstRead || Poller.
Poll(100)) {
1764 if (errno == EOVERFLOW)
1786 for (
int i = 1; i < Count; i++) {
1793 esyslog(
"ERROR: skipped %d bytes to sync on TS packet on device %d", Count,
cardIndex);