00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "Programs.h"
00023 #include "Ingredients.h"
00024 #include "Root.h"
00025 #include "BaseClasses.h"
00026 #include "ParseNode.h"
00027 #include "ASN1Codes.h"
00028 #include "Engine.h"
00029 #include "Logging.h"
00030 #include "freemheg.h"
00031
00032 #include <sys/timeb.h>
00033 #ifdef __FreeBSD__
00034 #include <sys/time.h>
00035 #else
00036 #include <time.h>
00037 #endif
00038
00039 #include "../../config.h"
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 MHProgram::MHProgram()
00050 {
00051 m_fInitiallyAvailable = true;
00052 }
00053
00054 void MHProgram::Initialise(MHParseNode *p, MHEngine *engine)
00055 {
00056 MHIngredient::Initialise(p, engine);
00057 p->GetNamedArg(C_NAME)->GetArgN(0)->GetStringValue(m_Name);
00058 MHParseNode *pAvail = p->GetNamedArg(C_INITIALLY_AVAILABLE);
00059 if (pAvail) m_fInitiallyAvailable = pAvail->GetArgN(0)->GetBoolValue();
00060
00061
00062 m_fInitiallyActive = false;
00063 }
00064
00065 void MHProgram::PrintMe(FILE *fd, int nTabs) const
00066 {
00067 MHIngredient::PrintMe(fd, nTabs);
00068 PrintTabs(fd, nTabs); fprintf(fd, ":Name "); m_Name.PrintMe(fd, 0); fprintf(fd, "\n");
00069 if (! m_fInitiallyAvailable) { PrintTabs(fd, nTabs); fprintf(fd, ":InitiallyAvailable false"); fprintf(fd, "\n"); }
00070 }
00071
00072
00073 void MHProgram::Activation(MHEngine *engine)
00074 {
00075 if (m_fRunning) return;
00076 MHIngredient::Activation(engine);
00077 m_fRunning = true;
00078 engine->EventTriggered(this, EventIsRunning);
00079 }
00080
00081
00082 void MHProgram::Deactivation(MHEngine *engine)
00083 {
00084 if (! m_fRunning) return;
00085
00086 MHIngredient::Deactivation(engine);
00087 }
00088
00089 void MHResidentProgram::PrintMe(FILE *fd, int nTabs) const
00090 {
00091 PrintTabs(fd, nTabs); fprintf(fd, "{:ResidentPrg ");
00092 MHProgram::PrintMe(fd, nTabs+1);
00093 PrintTabs(fd, nTabs); fprintf(fd, "}\n");
00094 }
00095
00096 static void SetSuccessFlag(const MHObjectRef &success, bool result, MHEngine *engine)
00097 {
00098 engine->FindObject(success)->SetVariableValue(result);
00099 }
00100
00101
00102 static int GetInt(MHParameter *parm, MHEngine *engine)
00103 {
00104 MHUnion un;
00105 un.GetValueFrom(*parm, engine);
00106 un.CheckType(MHUnion::U_Int);
00107 return un.m_nIntVal;
00108 }
00109
00110
00111 static void GetString(MHParameter *parm, MHOctetString &str, MHEngine *engine)
00112 {
00113 MHUnion un;
00114 un.GetValueFrom(*parm, engine);
00115 un.CheckType(MHUnion::U_String);
00116 str.Copy(un.m_StrVal);
00117 }
00118
00119 void MHResidentProgram::CallProgram(bool fIsFork, const MHObjectRef &success, const MHSequence<MHParameter *> &args, MHEngine *engine)
00120 {
00121 if (! m_fAvailable) Preparation(engine);
00122
00123 Activation(engine);
00124 MHLOG(MHLogDetail, QString("Calling program %1").arg(m_Name.Printable()));
00125 try {
00126
00127 if (m_Name.Equal("GCD")) {
00128 if (args.Size() == 2) {
00129 struct timeb timebuffer;
00130 #ifdef HAVE_FTIME
00131 ftime(&timebuffer);
00132 #else
00133 #ifdef HAVE_GETTIMEOFDAY
00134 struct timeval time;
00135 struct timezone zone;
00136
00137 if (gettimeofday(&time,&zone) == -1)
00138 MHLOG(MHLogDetail, QString("gettimeofday() failed"));
00139 timebuffer.time = time.tv_sec;
00140 timebuffer.timezone = zone.tz_minuteswest;
00141 timebuffer.dstflag = zone.tz_dsttime;
00142 #else
00143 #error Configuration error? No ftime() or gettimeofday()?
00144 #endif
00145 #endif
00146
00147 timebuffer.time -= timebuffer.timezone * 60;
00148
00149 int nTimeAsSecs = timebuffer.time % (24 * 60 * 60);
00150
00151
00152 int nModJulianDate = 40587 + timebuffer.time / (24 * 60 * 60);
00153
00154 engine->FindObject(*(args.GetAt(0)->GetReference()))->SetVariableValue(nModJulianDate);
00155 engine->FindObject(*(args.GetAt(1)->GetReference()))->SetVariableValue(nTimeAsSecs);
00156 SetSuccessFlag(success, true, engine);
00157 }
00158 else SetSuccessFlag(success, false, engine);
00159 }
00160
00161 else if (m_Name.Equal("FDa")) {
00162 if (args.Size() == 4) {
00163
00164 MHOctetString format;
00165 GetString(args.GetAt(0), format, engine);
00166 int date = GetInt(args.GetAt(1), engine);
00167 int time = GetInt(args.GetAt(2), engine);
00168
00169 time_t timet = (date - 40587) * (24 * 60 * 60) + time;
00170 struct tm *timeStr = gmtime(&timet);
00171 MHOctetString result;
00172 for (int i = 0; i < format.Size(); i++) {
00173 unsigned char ch = format.GetAt(i);
00174 char buffer[5];
00175 if (ch == '%') {
00176 i++;
00177 if (i == format.Size()) break;
00178 ch = format.GetAt(i);
00179 buffer[0] = 0;
00180 switch (ch)
00181 {
00182 case 'Y': sprintf(buffer, "%04d", timeStr->tm_year + 1900); break;
00183 case 'y': sprintf(buffer, "%02d", timeStr->tm_year % 100); break;
00184 case 'X': sprintf(buffer, "%02d", timeStr->tm_mon+1); break;
00185 case 'x': sprintf(buffer, "%1d", timeStr->tm_mon+1); break;
00186 case 'D': sprintf(buffer, "%02d", timeStr->tm_mday); break;
00187 case 'd': sprintf(buffer, "%1d", timeStr->tm_mday); break;
00188 case 'H': sprintf(buffer, "%02d", timeStr->tm_hour); break;
00189 case 'h': sprintf(buffer, "%1d", timeStr->tm_hour); break;
00190 case 'I':
00191 if (timeStr->tm_hour == 12 || timeStr->tm_hour == 0) strcpy(buffer, "12");
00192 else sprintf(buffer, "%02d", timeStr->tm_hour % 12);
00193 break;
00194 case 'i':
00195 if (timeStr->tm_hour == 12 || timeStr->tm_hour == 0) strcpy(buffer, "12");
00196 else sprintf(buffer, "%1d", timeStr->tm_hour % 12);
00197 break;
00198 case 'M': sprintf(buffer, "%02d", timeStr->tm_min); break;
00199 case 'm': sprintf(buffer, "%1d", timeStr->tm_min); break;
00200 case 'S': sprintf(buffer, "%02d", timeStr->tm_sec); break;
00201 case 's': sprintf(buffer, "%1d", timeStr->tm_sec); break;
00202
00203 case 'A': if (timeStr->tm_hour < 12) strcpy(buffer, "AM"); else strcpy(buffer, "PM"); break;
00204 case 'a': if (timeStr->tm_hour < 12) strcpy(buffer, "am"); else strcpy(buffer, "pm"); break;
00205 default: buffer[0] = ch; buffer[1] = 0;
00206 }
00207 result.Append(buffer);
00208 }
00209 else result.Append(MHOctetString(&ch, 1));
00210 }
00211 MHParameter *pResString = args.GetAt(3);
00212 engine->FindObject(*(pResString->GetReference()))->SetVariableValue(result);
00213 SetSuccessFlag(success, true, engine);
00214 }
00215 else SetSuccessFlag(success, false, engine);
00216 }
00217
00218 else if (m_Name.Equal("GDW")) {
00219 if (args.Size() == 2) {
00220 int date = GetInt(args.GetAt(0), engine);
00221
00222 time_t timet = (date - 40587) * (24 * 60 * 60);
00223 struct tm *timeStr = gmtime(&timet);
00224
00225 engine->FindObject(*(args.GetAt(1)->GetReference()))->SetVariableValue(timeStr->tm_wday);
00226 SetSuccessFlag(success, true, engine);
00227 } else SetSuccessFlag(success, false, engine);
00228 }
00229
00230 else if (m_Name.Equal("Rnd")) {
00231 if (args.Size() == 2) {
00232 int nLimit = GetInt(args.GetAt(0), engine);
00233 MHParameter *pResInt = args.GetAt(1);
00234 srand((unsigned)time( NULL ));
00235 engine->FindObject(*(pResInt->GetReference()))->SetVariableValue(rand() % nLimit +1);
00236 SetSuccessFlag(success, true, engine);
00237 }
00238 else SetSuccessFlag(success, false, engine);
00239 }
00240
00241 else if (m_Name.Equal("CTC")) {
00242
00243 if (args.Size() == 2) {
00244 MHOctetString string;
00245 GetString(args.GetAt(0), string, engine);
00246 MHContentRef result;
00247 result.m_ContentRef.Copy(string);
00248 engine->FindObject(*(args.GetAt(1)->GetReference()))->SetVariableValue(result);
00249 SetSuccessFlag(success, true, engine);
00250 }
00251 else SetSuccessFlag(success, false, engine);
00252 }
00253
00254 else if (m_Name.Equal("CTO")) {
00255
00256 if (args.Size() == 3) {
00257 MHObjectRef result;
00258 GetString(args.GetAt(0), result.m_GroupId, engine);
00259 result.m_nObjectNo = GetInt(args.GetAt(1), engine);
00260 engine->FindObject(*(args.GetAt(2)->GetReference()))->SetVariableValue(result);
00261 SetSuccessFlag(success, true, engine);
00262 }
00263 else SetSuccessFlag(success, false, engine);
00264 }
00265
00266 else if (m_Name.Equal("GSL")) {
00267 if (args.Size() == 2) {
00268
00269 MHOctetString string;
00270 GetString(args.GetAt(0), string, engine);
00271 MHParameter *pResInt = args.GetAt(1);
00272 SetSuccessFlag(success, true, engine);
00273 engine->FindObject(*(pResInt->GetReference()))->SetVariableValue(string.Size());
00274 }
00275 else SetSuccessFlag(success, false, engine);
00276 }
00277
00278 else if (m_Name.Equal("GSS")) {
00279 if (args.Size() == 4) {
00280 MHOctetString string;
00281 GetString(args.GetAt(0), string, engine);
00282 int nBeginExtract = GetInt(args.GetAt(1), engine);
00283 int nEndExtract = GetInt(args.GetAt(2), engine);
00284 if (nBeginExtract < 1) nBeginExtract = 1;
00285 if (nBeginExtract > string.Size()) nBeginExtract = string.Size();
00286 if (nEndExtract < 1) nEndExtract = 1;
00287 if (nEndExtract > string.Size()) nEndExtract = string.Size();
00288 MHParameter *pResString = args.GetAt(3);
00289
00290 engine->FindObject(*(pResString->GetReference()))->SetVariableValue(
00291 MHOctetString(string, nBeginExtract-1, nEndExtract-nBeginExtract+1));
00292 SetSuccessFlag(success, true, engine);
00293 }
00294 else SetSuccessFlag(success, false, engine);
00295 }
00296
00297 else if (m_Name.Equal("SSS")) {
00298 if (args.Size() == 4) {
00299
00300 MHOctetString string, searchString;
00301 GetString(args.GetAt(0), string, engine);
00302 int nStart = GetInt(args.GetAt(1), engine);
00303 if (nStart < 1) nStart = 1;
00304 GetString(args.GetAt(2), searchString, engine);
00305
00306 int nPos;
00307 for (nPos = nStart-1; nPos <= string.Size() - searchString.Size(); nPos++) {
00308 int i;
00309 for (i = 0; i < searchString.Size(); i++) {
00310 if (searchString.GetAt(i) != string.GetAt(i+nPos)) break;
00311 }
00312 if (i == searchString.Size()) break;
00313 }
00314
00315 MHParameter *pResInt = args.GetAt(3);
00316 SetSuccessFlag(success, true, engine);
00317 if (nPos <= string.Size() - searchString.Size()) {
00318
00319 engine->FindObject(*(pResInt->GetReference()))->SetVariableValue(nPos+1);
00320 }
00321 else {
00322 engine->FindObject(*(pResInt->GetReference()))->SetVariableValue(-1);
00323 }
00324 }
00325 else SetSuccessFlag(success, false, engine);
00326 }
00327
00328 else if (m_Name.Equal("SES")) {
00329 if (args.Size() == 5) {
00330
00331
00332 MHOctetString string, searchString;
00333 GetString(args.GetAt(0), string, engine);
00334 int nStart = GetInt(args.GetAt(1), engine);
00335 if (nStart < 1) nStart = 1;
00336 GetString(args.GetAt(2), searchString, engine);
00337
00338 int nPos;
00339 for (nPos = nStart-1; nPos <= string.Size() - searchString.Size(); nPos++) {
00340 int i;
00341 for (i = 0; i < searchString.Size(); i++) {
00342 if (searchString.GetAt(i) != string.GetAt(i+nPos)) break;
00343 }
00344 if (i == searchString.Size()) break;
00345 }
00346
00347 MHParameter *pResString = args.GetAt(3);
00348 MHParameter *pResInt = args.GetAt(4);
00349 SetSuccessFlag(success, true, engine);
00350 if (nPos <= string.Size() - searchString.Size()) {
00351
00352 engine->FindObject(*(pResInt->GetReference()))->SetVariableValue(nPos+1+searchString.Size());
00353
00354 MHOctetString resultString(string, nStart-1, nPos-nStart+1);
00355 engine->FindObject(*(pResString->GetReference()))->SetVariableValue(resultString);
00356 }
00357 else {
00358 engine->FindObject(*(pResInt->GetReference()))->SetVariableValue(-1);
00359 engine->FindObject(*(pResString->GetReference()))->SetVariableValue(MHOctetString(""));
00360 }
00361 }
00362 else SetSuccessFlag(success, false, engine);
00363 }
00364
00365 else if (m_Name.Equal("GSI")) {
00366
00367 if (args.Size() == 2) {
00368 MHOctetString string;
00369 GetString(args.GetAt(0), string, engine);
00370 MHParameter *pResInt = args.GetAt(1);
00371
00372
00373
00374 QString str = QString::fromUtf8((const char *)string.Bytes(), string.Size());
00375 int nResult = engine->GetContext()->GetChannelIndex(str);
00376 engine->FindObject(*(pResInt->GetReference()))->SetVariableValue(nResult);
00377 MHLOG(MHLogDetail, QString("Get service index for %1 - result %2").arg(string.Printable()).arg(nResult));
00378 SetSuccessFlag(success, true, engine);
00379 }
00380 else SetSuccessFlag(success, false, engine);
00381 }
00382
00383 else if (m_Name.Equal("TIn")) {
00384
00385 if (args.Size() == 1) {
00386 int nChannel = GetInt(args.GetAt(0), engine);
00387 bool res = engine->GetContext()->TuneTo(nChannel);
00388 SetSuccessFlag(success, res, engine);
00389 }
00390 else SetSuccessFlag(success, false, engine);
00391 }
00392 else if (m_Name.Equal("TII")) {
00393
00394 MHERROR("SI_TuneIndexInfo ResidentProgram is not implemented");
00395 }
00396 else if (m_Name.Equal("BSI")) {
00397
00398
00399
00400 if (args.Size() == 5) {
00401 int channelId = GetInt(args.GetAt(0), engine);
00402 int netId, origNetId, transportId, serviceId;
00403
00404 bool res = engine->GetContext()->GetServiceInfo(channelId, netId, origNetId,
00405 transportId, serviceId);
00406 if (res)
00407 {
00408 engine->FindObject(*(args.GetAt(1)->GetReference()))->SetVariableValue(netId);
00409 engine->FindObject(*(args.GetAt(2)->GetReference()))->SetVariableValue(origNetId);
00410 engine->FindObject(*(args.GetAt(3)->GetReference()))->SetVariableValue(transportId);
00411 engine->FindObject(*(args.GetAt(4)->GetReference()))->SetVariableValue(serviceId);
00412 }
00413 SetSuccessFlag(success, res, engine);
00414 }
00415 else SetSuccessFlag(success, false, engine);
00416 }
00417 else if (m_Name.Equal("GBI")) {
00418
00419 MHERROR("GetBootInfo ResidentProgram is not implemented");
00420 }
00421 else if (m_Name.Equal("CCR")) {
00422
00423
00424
00425
00426 if (args.Size() == 3) {
00427 MHUnion un;
00428 un.GetValueFrom(*(args.GetAt(0)), engine);
00429 un.CheckType(MHUnion::U_ContentRef);
00430 MHContentRef fileName;
00431 fileName.Copy(un.m_ContentRefVal);
00432 QString csPath = engine->GetPathName(fileName.m_ContentRef);
00433 bool result = false;
00434 QByteArray text;
00435
00436 if (! csPath.isEmpty())
00437 result = engine->GetContext()->GetCarouselData(csPath, text);
00438
00439 MHParameter *pResFlag = args.GetAt(1);
00440 engine->FindObject(*(pResFlag->GetReference()))->SetVariableValue(result);
00441 MHParameter *pResCR = args.GetAt(2);
00442
00443 engine->FindObject(*(pResCR->GetReference()))->SetVariableValue(fileName);
00444 SetSuccessFlag(success, true, engine);
00445 }
00446 else SetSuccessFlag(success, false, engine);
00447 }
00448 else if (m_Name.Equal("CGR")) {
00449
00450
00451 MHERROR("CheckGroupIDRef ResidentProgram is not implemented");
00452 }
00453 else if (m_Name.Equal("VTG")) {
00454
00455 MHERROR("VideoToGraphics ResidentProgram is not implemented");
00456 }
00457 else if (m_Name.Equal("SWA")) {
00458
00459
00460 MHERROR("SetWidescreenAlignment ResidentProgram is not implemented");
00461 }
00462 else if (m_Name.Equal("GDA")) {
00463
00464 MHERROR("GetDisplayAspectRatio ResidentProgram is not implemented");
00465 }
00466 else if (m_Name.Equal("CIS")) {
00467
00468 MHERROR("CI_SendMessage ResidentProgram is not implemented");
00469 }
00470 else if (m_Name.Equal("SSM")) {
00471
00472 MHERROR("SetSubtitleMode ResidentProgram is not implemented");
00473 }
00474
00475 else if (m_Name.Equal("WAI")) {
00476
00477
00478 if (args.Size() == 1)
00479 {
00480 MHOctetString result;
00481 result.Copy(engine->MHEGEngineProviderIdString);
00482 result.Append(" ");
00483 result.Append(engine->GetContext()->GetReceiverId());
00484 result.Append(" ");
00485 result.Append(engine->GetContext()->GetDSMCCId());
00486 engine->FindObject(*(args.GetAt(0)->GetReference()))->SetVariableValue(result);
00487 SetSuccessFlag(success, true, engine);
00488 }
00489 else SetSuccessFlag(success, false, engine);
00490 }
00491
00492 else if (m_Name.Equal("DBG")) {
00493 QString message = "DEBUG: ";
00494 for (int i = 0; i < args.Size(); i++) {
00495 MHUnion un;
00496 un.GetValueFrom(*(args.GetAt(i)), engine);
00497 switch (un.m_Type) {
00498 case MHUnion::U_Int:
00499 message.append(QString("%1").arg(un.m_nIntVal));
00500 break;
00501 case MHParameter::P_Bool:
00502 message.append(un.m_fBoolVal ? "True" : "False");
00503 break;
00504 case MHParameter::P_String:
00505 message.append(QString::fromUtf8((const char *)un.m_StrVal.Bytes(), un.m_StrVal.Size()));
00506 break;
00507 case MHParameter::P_ObjRef:
00508 message.append(un.m_ObjRefVal.Printable());
00509 break;
00510 case MHParameter::P_ContentRef:
00511 message.append(un.m_ContentRefVal.Printable());
00512 break;
00513 case MHParameter::P_Null:
00514 break;
00515 }
00516 }
00517 MHLOG(MHLogNotifications, message);
00518 }
00519
00520 else {
00521 MHERROR(QString("Unknown ResidentProgram %1").arg(m_Name.Printable()));
00522 }
00523 }
00524 catch (char const *) {
00525
00526 SetSuccessFlag(success, false, engine);
00527
00528 }
00529 Deactivation(engine);
00530
00531 if (fIsFork) engine->EventTriggered(this, EventAsyncStopped);
00532 }
00533
00534 MHRemoteProgram::MHRemoteProgram()
00535 {
00536
00537 }
00538
00539 MHRemoteProgram::~MHRemoteProgram()
00540 {
00541
00542 }
00543
00544 void MHRemoteProgram::Initialise(MHParseNode *p, MHEngine *engine)
00545 {
00546 MHProgram::Initialise(p, engine);
00547
00548 }
00549
00550 void MHRemoteProgram::PrintMe(FILE *fd, int nTabs) const
00551 {
00552 PrintTabs(fd, nTabs); fprintf(fd, "{:RemotePrg");
00553 MHProgram::PrintMe(fd, nTabs+1);
00554 fprintf(fd, "****TODO\n");
00555 PrintTabs(fd, nTabs); fprintf(fd, "}\n");
00556 }
00557
00558 MHInterChgProgram::MHInterChgProgram()
00559 {
00560
00561 }
00562
00563 MHInterChgProgram::~MHInterChgProgram()
00564 {
00565
00566 }
00567
00568 void MHInterChgProgram::Initialise(MHParseNode *p, MHEngine *engine)
00569 {
00570 MHProgram::Initialise(p, engine);
00571
00572 }
00573
00574 void MHInterChgProgram::PrintMe(FILE *fd, int nTabs) const
00575 {
00576 PrintTabs(fd, nTabs); fprintf(fd, "{:InterchgPrg");
00577 MHProgram::PrintMe(fd, nTabs+1);
00578 fprintf(fd, "****TODO\n");
00579 PrintTabs(fd, nTabs); fprintf(fd, "}\n");
00580 }
00581
00582
00583 void MHCall::Initialise(MHParseNode *p, MHEngine *engine)
00584 {
00585 MHElemAction::Initialise(p, engine);
00586 m_Succeeded.Initialise(p->GetArgN(1), engine);
00587
00588 MHParseNode *args = p->GetArgN(2);
00589 for (int i = 0; i < args->GetSeqCount(); i++) {
00590 MHParameter *pParm = new MHParameter;
00591 m_Parameters.Append(pParm);
00592 pParm->Initialise(args->GetSeqN(i), engine);
00593 }
00594 }
00595
00596 void MHCall::PrintArgs(FILE *fd, int nTabs) const
00597 {
00598 m_Succeeded.PrintMe(fd, nTabs);
00599 fprintf(fd, " ( ");
00600 for (int i = 0; i < m_Parameters.Size(); i++) m_Parameters.GetAt(i)->PrintMe(fd, 0);
00601 fprintf(fd, " )\n");
00602 }
00603
00604 void MHCall::Perform(MHEngine *engine)
00605 {
00606
00607 Target(engine)->CallProgram(m_fIsFork, m_Succeeded, m_Parameters, engine);
00608 }