eb477c66ca0c745a3659f5f6d9e3465701f0f758
[vuplus_xbmc] / xbmc / utils / TuxBoxUtil.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 //
22 // GeminiServer
23 //
24
25 #include "TuxBoxUtil.h"
26 #include "URIUtils.h"
27 #include "filesystem/CurlFile.h"
28 #include "dialogs/GUIDialogContextMenu.h"
29 #include "Application.h"
30 #include "ApplicationMessenger.h"
31 #include "GUIInfoManager.h"
32 #include "video/VideoInfoTag.h"
33 #include "guilib/GUIWindowManager.h"
34 #include "dialogs/GUIDialogOK.h"
35 #include "dialogs/GUIDialogYesNo.h"
36 #include "filesystem/File.h"
37 #include "URL.h"
38 #include "settings/AdvancedSettings.h"
39 #include "FileItem.h"
40 #include "guilib/LocalizeStrings.h"
41 #include "StringUtils.h"
42 #include "utils/XBMCTinyXML.h"
43 #include "log.h"
44
45 using namespace XFILE;
46 using namespace std;
47
48 CTuxBoxUtil g_tuxbox;
49 CTuxBoxService g_tuxboxService;
50
51 CTuxBoxService::CTuxBoxService() : CThread("TuxBoxService")
52 {
53 }
54 CTuxBoxService::~CTuxBoxService()
55 {
56 }
57 CTuxBoxUtil::CTuxBoxUtil(void)
58 {
59   sCurSrvData.requested_audio_channel = 0;
60   sZapstream.initialized = false;
61   sZapstream.available = false;
62 }
63 CTuxBoxUtil::~CTuxBoxUtil(void)
64 {
65 }
66 bool CTuxBoxService::Start()
67 {
68   if(g_advancedSettings.m_iTuxBoxEpgRequestTime != 0)
69   {
70     StopThread();
71     Create(false);
72     return true;
73   }
74   else
75     return false;
76 }
77 void CTuxBoxService::Stop()
78 {
79   CLog::Log(LOGDEBUG, "%s - Stopping CTuxBoxService thread", __FUNCTION__);
80   StopThread();
81 }
82 void CTuxBoxService::OnStartup()
83 {
84   CLog::Log(LOGDEBUG, "%s - Starting CTuxBoxService thread", __FUNCTION__);
85   SetPriority( GetMinPriority() );
86 }
87 void CTuxBoxService::OnExit()
88 {
89   CThread::m_bStop = true;
90 }
91 bool CTuxBoxService::IsRunning()
92 {
93   return !CThread::m_bStop;
94 }
95 void CTuxBoxService::Process()
96 {
97   CStdString strCurrentServiceName = g_tuxbox.sCurSrvData.service_name;
98   CStdString strURL;
99
100   while(!CThread::m_bStop && g_application.m_pPlayer->IsPlaying())
101   {
102     strURL = g_application.CurrentFileItem().GetPath();
103     if(!URIUtils::IsTuxBox(strURL))
104       break;
105
106     int iRequestTimer = g_advancedSettings.m_iTuxBoxEpgRequestTime *1000; //seconds
107     Sleep(iRequestTimer);
108
109     CURL url(strURL);
110     if(g_tuxbox.GetHttpXML(url,"currentservicedata"))
111     {
112       CLog::Log(LOGDEBUG, "%s - receive current service data was successful", __FUNCTION__);
113       if(!strCurrentServiceName.IsEmpty()&&
114         !strCurrentServiceName.Equals("NULL") &&
115         !g_tuxbox.sCurSrvData.service_name.IsEmpty() &&
116         !g_tuxbox.sCurSrvData.service_name.Equals("-") &&
117         !g_tuxbox.vVideoSubChannel.mode)
118       {
119         //Detect Channel Change
120         //We need to detect the channel on the TuxBox Device!
121         //On changing the channel on the device we will loose the stream and mplayer seems not able to detect it to stop
122         if (strCurrentServiceName != g_tuxbox.sCurSrvData.service_name && g_application.m_pPlayer->IsPlaying() && !g_tuxbox.sZapstream.available)
123         {
124           CLog::Log(LOGDEBUG," - ERROR: Non controlled channel change detected! Stopping current playing stream!");
125           CApplicationMessenger::Get().MediaStop();
126           break;
127         }
128       }
129       //Update infomanager from tuxbox client
130       g_infoManager.UpdateFromTuxBox();
131     }
132     else
133       CLog::Log(LOGDEBUG, "%s - Could not receive current service data", __FUNCTION__);
134   }
135 }
136 bool CTuxBoxUtil::CreateNewItem(const CFileItem& item, CFileItem& item_new)
137 {
138   //Build new Item
139   item_new.SetLabel(item.GetLabel());
140   item_new.SetPath(item.GetPath());
141   item_new.SetArt("thumb", item.GetArt("thumb"));
142
143   if(g_tuxbox.GetZapUrl(item.GetPath(), item_new))
144   {
145     if(vVideoSubChannel.mode)
146       vVideoSubChannel.current_name = item_new.GetLabel()+" ("+vVideoSubChannel.current_name+")";
147     return true;
148   }
149   else
150   {
151     if(!sBoxStatus.recording.Equals("1")) //Don't Show this Dialog, if the Box is in Recording mode! A previos YN Dialog was send to user!
152     {
153       CLog::Log(LOGDEBUG, "%s ---------------------------------------------------------", __FUNCTION__);
154       CLog::Log(LOGDEBUG, "%s - WARNING: Zaping Failed no Zap Point found!", __FUNCTION__);
155       CLog::Log(LOGDEBUG, "%s ---------------------------------------------------------", __FUNCTION__);
156       CStdString strText;
157       strText.Format(g_localizeStrings.Get(21334).c_str(), item.GetLabel());
158       CGUIDialogOK::ShowAndGetInput(21331, strText, 21333, 0);
159     }
160   }
161   return false;
162 }
163 bool CTuxBoxUtil::ParseBouquets(TiXmlElement *root, CFileItemList &items, CURL &url, CStdString strFilter, CStdString strChild)
164 {
165   CStdString strOptions, strPort;
166   TiXmlElement *pRootElement =root;
167   TiXmlNode *pNode = NULL;
168   TiXmlNode *pIt = NULL;
169   items.m_idepth =1;
170   // Get Options
171   strOptions = url.GetOptions();
172
173   if (!pRootElement)
174   {
175     CLog::Log(LOGWARNING, "%s - No %s found", __FUNCTION__, strChild.c_str());
176     return false;
177   }
178   if (strFilter.IsEmpty())
179   {
180     pNode = pRootElement->FirstChild(strChild.c_str());
181     if (!pNode)
182     {
183       CLog::Log(LOGWARNING, "%s - No %s found", __FUNCTION__,strChild.c_str());
184       return false;
185     }
186     while(pNode)
187     {
188         pIt = pNode->FirstChild("name");
189         if (pIt)
190         {
191           CStdString strItemName = pIt->FirstChild()->Value();
192
193           pIt = pNode->FirstChild("reference");
194           if (pIt)
195           {
196             CStdString strItemPath = pIt->FirstChild()->Value();
197             // add. bouquets to item list!
198             CFileItemPtr pItem(new CFileItem);
199             pItem->m_bIsFolder = true;
200             pItem->SetLabel(strItemName);
201             {
202               CURL fileUrl;
203               fileUrl.SetProtocol("tuxbox");
204               fileUrl.SetUserName(url.GetUserName());
205               fileUrl.SetPassword(url.GetPassWord());
206               fileUrl.SetHostName(url.GetHostName());
207               if (url.GetPort() != 0 && url.GetPort() != 80)
208                 fileUrl.SetPort(url.GetPort());
209               fileUrl.SetOptions(url.GetOptions());
210               fileUrl.SetOption("reference", strItemPath);
211               pItem->SetPath(fileUrl.Get());
212             }
213             items.Add(pItem);
214             //DEBUG Log
215             CLog::Log(LOGDEBUG, "%s - Name:    %s", __FUNCTION__,strItemName.c_str());
216             CLog::Log(LOGDEBUG, "%s - Adress:  %s", __FUNCTION__,pItem->GetPath().c_str());
217           }
218         }
219         pNode = pNode->NextSibling(strChild.c_str());
220     }
221   }
222   return true;
223 }
224 bool CTuxBoxUtil::ParseBouquetsEnigma2(TiXmlElement *root, CFileItemList &items, CURL &url, CStdString& strFilter, CStdString& strChild)
225 {
226   CStdString strPort;
227   TiXmlElement *pRootElement = root;
228   TiXmlNode *pNode = NULL;
229   TiXmlNode *pIt = NULL;
230   items.m_idepth = 1;
231
232   if (!pRootElement)
233   {
234     CLog::Log(LOGWARNING, "%s - No %s found", __FUNCTION__, strChild.c_str());
235     return false;
236   }
237   if (strFilter.IsEmpty())
238   {
239     pNode = pRootElement->FirstChildElement("e2bouquet");
240     if (!pNode)
241     {
242       CLog::Log(LOGWARNING, "%s - No %s found", __FUNCTION__,strChild.c_str());
243       return false;
244     }
245     while(pNode)
246     {
247       CFileItemPtr pItem(new CFileItem);
248       pIt = pNode->FirstChildElement("e2servicereference");
249       CStdString strItemPath = pIt->FirstChild()->Value();
250       pIt = pNode->FirstChildElement("e2servicename");
251       CStdString strItemName = pIt->FirstChild()->Value();
252       pItem->m_bIsFolder = true;
253       pItem->SetLabel(strItemName);
254       {
255         CURL fileUrl;
256         fileUrl.SetProtocol("tuxbox");
257         fileUrl.SetHostName(url.GetHostName());
258         if (url.GetPort() != 0 && url.GetPort() != 80)
259           fileUrl.SetPort(url.GetPort());
260         fileUrl.SetFileName(strItemName + "/");
261         pItem->SetPath(fileUrl.Get());
262       }
263       items.Add(pItem);
264       pNode = pNode->NextSiblingElement("e2bouquet");
265     }
266   }
267   return true;
268 }
269 bool CTuxBoxUtil::ParseChannels(TiXmlElement *root, CFileItemList &items, CURL &url, CStdString strFilter, CStdString strChild)
270 {
271   CStdString strPort;
272   TiXmlElement *pRootElement =root;
273   TiXmlNode *pNode = NULL;
274   TiXmlNode *pIt = NULL;
275   TiXmlNode *pIta = NULL;
276   items.m_idepth =2;
277
278   if (!pRootElement)
279   {
280     CLog::Log(LOGWARNING, "%s - No %ss found", __FUNCTION__,strChild.c_str());
281     return false;
282   }
283   if(!strFilter.IsEmpty())
284   {
285     pNode = pRootElement->FirstChild(strChild.c_str());
286     if (!pNode)
287     {
288       CLog::Log(LOGWARNING, "%s - No %s found", __FUNCTION__,strChild.c_str());
289       return false;
290     }
291     while(pNode)
292     {
293         pIt = pNode->FirstChild("name");
294         if (pIt)
295         {
296           CStdString strItemName = pIt->FirstChild()->Value();
297
298           pIt = pNode->FirstChild("reference");
299           if (strFilter.Equals(pIt->FirstChild()->Value()))
300           {
301             pIt = pNode->FirstChild("service");
302             if (!pIt)
303             {
304               CLog::Log(LOGWARNING, "%s - No service found", __FUNCTION__);
305               return false;
306             }
307             while(pIt)
308             {
309                 pIta = pIt->FirstChild("name");
310                 if (pIta)
311                 {
312                   strItemName = pIta->FirstChild()->Value();
313
314                   pIta = pIt->FirstChild("reference");
315                   if (pIta)
316                   {
317                     CStdString strItemPath = pIta->FirstChild()->Value();
318                     // channel listing add. to item list!
319                     CFileItemPtr pbItem(new CFileItem);
320                     pbItem->m_bIsFolder = false;
321                     pbItem->SetLabel(strItemName);
322                     pbItem->SetLabelPreformated(true);
323                     {
324                       CURL fileUrl;
325                       fileUrl.SetProtocol("tuxbox");
326                       fileUrl.SetUserName(url.GetUserName());
327                       fileUrl.SetPassword(url.GetPassWord());
328                       fileUrl.SetHostName(url.GetHostName());
329                       if (url.GetPort() != 0 && url.GetPort() != 80)
330                         fileUrl.SetPort(url.GetPort());
331                       fileUrl.SetFileName("cgi-bin/zapTo");
332                       fileUrl.SetOption("path", strItemPath+".ts");
333                       pbItem->SetPath(fileUrl.Get());
334                     }
335                     pbItem->SetArt("thumb", GetPicon(strItemName)); //Set Picon Image
336
337                     //DEBUG Log
338                     CLog::Log(LOGDEBUG, "%s - Name:    %s", __FUNCTION__,strItemName.c_str());
339                     CLog::Log(LOGDEBUG, "%s - Adress:  %s", __FUNCTION__,pbItem->GetPath().c_str());
340
341                     //add to the list
342                     items.Add(pbItem);
343                   }
344                 }
345                 pIt = pIt->NextSibling("service");
346             }
347           }
348         }
349         pNode = pNode->NextSibling(strChild.c_str());
350     }
351     return true;
352   }
353   return false;
354 }
355 bool CTuxBoxUtil::ParseChannelsEnigma2(TiXmlElement *root, CFileItemList &items, CURL &url, CStdString& strFilter, CStdString& strChild)
356 {
357   TiXmlElement *pRootElement = root;
358   TiXmlNode *pNode = NULL;
359   TiXmlNode *pIt = NULL;
360   TiXmlNode *pIta = NULL;
361   TiXmlNode *pItb = NULL;
362   items.m_idepth = 2;
363
364   if (!pRootElement)
365   {
366     CLog::Log(LOGWARNING, "%s - No %ss found", __FUNCTION__,strChild.c_str());
367     return false;
368   }
369   if(!strFilter.IsEmpty())
370   {
371     pNode = pRootElement->FirstChild(strChild.c_str());
372     if (!pNode)
373     {
374       CLog::Log(LOGWARNING, "%s - No %s found", __FUNCTION__,strChild.c_str());
375       return false;
376     }
377     while(pNode)
378     {
379       pIt = pNode->FirstChildElement("e2servicename");
380       CStdString bqtName = pIt->FirstChild()->Value();
381       pIt = pNode->FirstChildElement("e2servicelist");
382       pIta = pIt->FirstChildElement("e2service");
383       while(pIta)
384       {
385         pItb = pIta->FirstChildElement("e2servicereference");
386         CStdString strItemPath = pItb->FirstChild()->Value();
387         pItb = pIta->FirstChildElement("e2servicename");
388         CStdString strItemName = pItb->FirstChild()->Value();
389         if(bqtName == url.GetShareName())
390         {
391           CFileItemPtr pbItem(new CFileItem);
392           pbItem->m_bIsFolder = false;
393           pbItem->SetLabel(strItemName);
394           {
395             CURL fileUrl;
396             fileUrl.SetProtocol("http");
397             fileUrl.SetHostName(url.GetHostName());
398             fileUrl.SetPort(8001);
399             fileUrl.SetFileName(strItemPath);
400             pbItem->SetPath(fileUrl.Get());
401           }
402           pbItem->SetMimeType("video/mpeg2");
403           items.Add(pbItem);
404           CLog::Log(LOGDEBUG, "%s - Name:    %s", __FUNCTION__,strItemName.c_str());
405           CLog::Log(LOGDEBUG, "%s - Adress:  %s", __FUNCTION__,pbItem->GetPath().c_str());
406         }
407         pIta = pIta->NextSiblingElement("e2service");
408       }
409       pNode = pNode->NextSiblingElement("e2bouquet");
410     }
411   }
412   return true;
413 }
414 bool CTuxBoxUtil::ZapToUrl(CURL url, const CStdString &pathOption)
415 {
416   // send Zap
417   CStdString strZapUrl, strPostUrl, strZapName, strFilter;
418   //Extract the ZAP to Service String
419   //Remove the ".ts"
420   strFilter = pathOption.Left(pathOption.size()-3);
421   //Get the Service Name
422
423   // Create ZAP URL
424   CURL urlx;
425   urlx.SetProtocol("http");
426   urlx.SetUserName(url.GetUserName());
427   urlx.SetPassword(url.GetPassWord());
428   urlx.SetHostName(url.GetHostName());
429   if (url.GetPort() != 0 && url.GetPort() != 80)
430     urlx.SetPort(url.GetPort());
431   CURL postUrl(urlx);
432   postUrl.SetFileName("cgi-bin/zapTo");
433   postUrl.SetOption("path", strFilter);
434
435   //Check Recording State!
436   if(GetHttpXML(urlx,"boxstatus"))
437   {
438     if(sBoxStatus.recording.Equals("1"))
439     {
440       CLog::Log(LOGDEBUG, "%s ---------------------------------------------------------", __FUNCTION__);
441       CLog::Log(LOGDEBUG, "%s - WARNING: Device is Recording! Record Mode is: %s", __FUNCTION__,sBoxStatus.recording.c_str());
442       CLog::Log(LOGDEBUG, "%s ---------------------------------------------------------", __FUNCTION__);
443       CGUIDialogYesNo* dialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
444       if (dialog)
445       {
446         //Target TuxBox is in Recording mode! Are you sure to stream ?YN
447         dialog->SetHeading(21331);
448         dialog->SetLine( 0, 21332);
449         dialog->SetLine( 1, 21335);
450         dialog->SetLine( 2, "" );
451         dialog->DoModal();
452         if (!dialog->IsConfirmed())
453         {
454           //DialogYN = NO -> Return false!
455           return false;
456         }
457       }
458     }
459   }
460
461   //Send ZAP Command
462   CCurlFile http;
463   if(http.Open(postUrl))
464   {
465     //DEBUG LOG
466     CLog::Log(LOGDEBUG, "%s - Zapped to: %s", __FUNCTION__,postUrl.Get().c_str());
467
468     //Request StreamInfo
469     GetHttpXML(urlx,"streaminfo");
470
471     //Extract StreamInformations
472     int iRetry=0;
473     //PMT must be a valid value to be sure that the ZAP is OK and we can stream!
474     while(sStrmInfo.pmt.Equals("ffffffffh") && iRetry!=10) //try 10 Times
475     {
476       CLog::Log(LOGDEBUG, "%s - Requesting STREAMINFO! TryCount: %i!", __FUNCTION__,iRetry);
477       GetHttpXML(urlx,"streaminfo");
478       iRetry=iRetry+1;
479       Sleep(200);
480     }
481
482     // PMT Not Valid? Try Time 10 reached, checking for advancedSettings m_iTuxBoxZapWaitTime
483     if(sStrmInfo.pmt.Equals("ffffffffh") && g_advancedSettings.m_iTuxBoxZapWaitTime > 0 )
484     {
485       iRetry = 0;
486       CLog::Log(LOGDEBUG, "%s - Starting TuxBox ZapWaitTimer!", __FUNCTION__);
487       while(sStrmInfo.pmt.Equals("ffffffffh") && iRetry!=10) //try 10 Times
488       {
489         CLog::Log(LOGDEBUG, "%s - Requesting STREAMINFO! TryCount: %i!", __FUNCTION__,iRetry);
490         GetHttpXML(urlx,"streaminfo");
491         iRetry=iRetry+1;
492         if(sStrmInfo.pmt.Equals("ffffffffh"))
493         {
494           CLog::Log(LOGERROR, "%s - STREAMINFO ERROR! Could not receive all data, TryCount: %i!", __FUNCTION__,iRetry);
495           CLog::Log(LOGERROR, "%s - PMT is: %s (not a Valid Value)! Waiting %i sec.", __FUNCTION__,sStrmInfo.pmt.c_str(), g_advancedSettings.m_iTuxBoxZapWaitTime);
496           Sleep(g_advancedSettings.m_iTuxBoxZapWaitTime*1000);
497         }
498       }
499     }
500
501     //PMT Failed! No StreamInformations availible.. closing stream
502     if (sStrmInfo.pmt.Equals("ffffffffh"))
503     {
504       CLog::Log(LOGERROR, "%s-------------------------------------------------------------", __FUNCTION__);
505       CLog::Log(LOGERROR, "%s - STREAMINFO ERROR! Could not receive all data, TryCount: %i!", __FUNCTION__,iRetry);
506       CLog::Log(LOGERROR, "%s - PMT is: %s (not a Valid Value)! There is nothing to Stream!", __FUNCTION__,sStrmInfo.pmt.c_str());
507       CLog::Log(LOGERROR, "%s - The Stream will stopped!", __FUNCTION__);
508       CLog::Log(LOGERROR, "%s-------------------------------------------------------------", __FUNCTION__);
509       return false;
510     }
511     //Currentservicedata
512     GetHttpXML(urlx,"currentservicedata");
513     //boxstatus
514     GetHttpXML(urlx,"boxstatus");
515     //boxinfo
516     GetHttpXML(urlx,"boxinfo");
517     //serviceepg
518     GetHttpXML(urlx,"serviceepg");
519     return true;
520   }
521   return false;
522 }
523 bool CTuxBoxUtil::GetZapUrl(const CStdString& strPath, CFileItem &items )
524 {
525   CURL url(strPath);
526   CStdString strOptions = url.GetOptions();
527   if (strOptions.IsEmpty())
528     return false;
529
530   if (url.HasOption("path"))
531   {
532     if(ZapToUrl(url, url.GetOption("path")))
533     {
534       //Check VideoSubChannels
535       if(GetHttpXML(url,"currentservicedata")) //Update Currentservicedata
536       {
537         //Detect VideoSubChannels
538         CStdString strVideoSubChannelName, strVideoSubChannelPID;
539         if(GetVideoSubChannels(strVideoSubChannelName,strVideoSubChannelPID ))
540         {
541           // new videosubchannel selected! settings options to new video zap id
542           // zap again now to new videosubchannel
543           if(ZapToUrl(url, strVideoSubChannelPID + ".ts"))
544           {
545             vVideoSubChannel.mode = true;
546             vVideoSubChannel.current_name = strVideoSubChannelName;
547           }
548         }
549         else
550           vVideoSubChannel.mode= false;
551       }
552
553       CStdString strStreamURL, strVideoStream;
554       CStdString strLabel, strLabel2;
555       CStdString strAudioChannelName, strAudioChannelPid;
556       CStdString strAPids;
557       sAudioChannel sRequestedAudioChannel;
558
559       if (!GetGUIRequestedAudioChannel(sRequestedAudioChannel))
560       {
561         if (g_advancedSettings.m_bTuxBoxSendAllAPids && sCurSrvData.audio_channels.size() > 1)
562         {
563           for (vector<sAudioChannel>::iterator sChannel = sCurSrvData.audio_channels.begin(); sChannel!=sCurSrvData.audio_channels.end(); ++sChannel)
564           {
565             if (sChannel->pid != sRequestedAudioChannel.pid)
566               strAPids += "," + sChannel->pid.Right(4);
567           }
568           CLog::Log(LOGDEBUG, "%s - Sending all audio pids: %s%s", __FUNCTION__, strAudioChannelPid.c_str(), strAPids.c_str());
569
570           strVideoStream.Format("0,%s,%s,%s%s",sStrmInfo.pmt.Left(4).c_str(), sStrmInfo.vpid.Left(4).c_str(), sStrmInfo.apid.Left(4).c_str(), strAPids.c_str());
571         }
572         else
573           strVideoStream.Format("0,%s,%s,%s",sStrmInfo.pmt.Left(4).c_str(), sStrmInfo.vpid.Left(4).c_str(), sStrmInfo.apid.Left(4).c_str());
574       }
575       else
576         strVideoStream.Format("0,%s,%s,%s",sStrmInfo.pmt.Left(4).c_str(), sStrmInfo.vpid.Left(4).c_str(), strAudioChannelPid.Left(4).c_str());
577
578       CURL streamURL;
579       streamURL.SetProtocol("http");
580       streamURL.SetUserName(url.GetUserName());
581       streamURL.SetPassword(url.GetPassWord());
582       streamURL.SetHostName(url.GetHostName());
583       streamURL.SetPort(g_advancedSettings.m_iTuxBoxStreamtsPort);
584       streamURL.SetFileName(strVideoStream.c_str());
585
586       if (!g_tuxbox.sZapstream.initialized)
587         g_tuxbox.InitZapstream(strPath);
588
589       // Use the Zapstream service when available.
590       if (g_tuxbox.sZapstream.available)
591       {
592         sAudioChannel sSelectedAudioChannel;
593         if (GetRequestedAudioChannel(sSelectedAudioChannel))
594         {
595           if (sSelectedAudioChannel.pid != sStrmInfo.apid)
596           {
597             if (SetAudioChannel(strPath, sSelectedAudioChannel))
598               CLog::Log(LOGDEBUG, "%s - Zapstream: Requested audio channel is %s, pid %s.", __FUNCTION__, sSelectedAudioChannel.name.c_str(), sSelectedAudioChannel.pid.c_str());
599           }
600         }
601         streamURL.SetFileName("");
602         streamURL.SetPort(g_advancedSettings.m_iTuxBoxZapstreamPort);
603       }
604
605       if (g_application.m_pPlayer->IsPlaying() && !g_tuxbox.sZapstream.available)
606         CApplicationMessenger::Get().MediaStop();
607
608       strLabel.Format("%s: %s %s-%s",items.GetLabel().c_str(), sCurSrvData.current_event_date.c_str(),sCurSrvData.current_event_start.c_str(), sCurSrvData.current_event_start.c_str());
609       strLabel2.Format("%s", sCurSrvData.current_event_description.c_str());
610
611       // Set Event details
612       CStdString strGenre, strTitle;
613       strGenre.Format("%s %s  -  (%s: %s)",g_localizeStrings.Get(143),sCurSrvData.current_event_description, g_localizeStrings.Get(209),sCurSrvData.next_event_description);
614       strTitle.Format("%s",sCurSrvData.current_event_details);
615       int iDuration = atoi(sCurSrvData.current_event_duration.c_str());
616
617       items.GetVideoInfoTag()->m_genre = StringUtils::Split(strGenre, g_advancedSettings.m_videoItemSeparator);  // VIDEOPLAYER_GENRE: current_event_description (Film Name)
618       items.GetVideoInfoTag()->m_strTitle = strTitle; // VIDEOPLAYER_TITLE: current_event_details     (Film beschreibung)
619       items.GetVideoInfoTag()->m_duration = iDuration; //VIDEOPLAYER_DURATION: current_event_duration (laufzeit in sec.)
620
621       items.SetPath(streamURL.Get());
622       items.m_iDriveType = url.GetPort(); // Dirty Hack! But i need to hold the Port ;)
623       items.SetLabel(items.GetLabel()); // VIDEOPLAYER_DIRECTOR: service_name (Program Name)
624       items.SetLabel2(sCurSrvData.current_event_description); // current_event_description (Film Name)
625       items.m_bIsFolder = false;
626       items.SetMimeType("video/x-mpegts");
627       return true;
628     }
629   }
630   return false;
631 }
632
633 // Notice: Zapstream is a streamts enhancement from PLi development team.
634 // If you are using a non-PLi based image you might not have Zapstream installed.
635 bool CTuxBoxUtil::InitZapstream(const CStdString& strPath)
636 {
637   CURL url(strPath);
638   CCurlFile http;
639   int iTryConnect = 0;
640   int iTimeout = 2;
641
642   g_tuxbox.sZapstream.initialized = true;
643
644   if (!g_advancedSettings.m_bTuxBoxZapstream)
645   {
646     CLog::Log(LOGDEBUG, "%s - Zapstream is disabled in advancedsettings.xml.", __FUNCTION__);
647     return g_tuxbox.sZapstream.available = false;
648   }
649
650   url.SetProtocol("http");
651   url.SetFileName("");
652   url.SetOptions("");
653   url.SetPort(g_advancedSettings.m_iTuxBoxZapstreamPort);
654
655   while (iTryConnect < 3)
656   {
657     http.SetTimeout(iTimeout);
658
659     if (http.Open(url))
660     {
661       http.Close();
662       CHttpHeader h = http.GetHttpHeader();
663       CStdString strValue = h.GetValue("server");
664
665       if (strValue.Find("zapstream") >= 0 )
666       {
667         CLog::Log(LOGDEBUG, "%s - Zapstream is available on port %i.", __FUNCTION__, g_advancedSettings.m_iTuxBoxZapstreamPort);
668         return g_tuxbox.sZapstream.available = true;
669       }
670     }
671
672     iTryConnect++;
673     iTimeout+=5;
674   }
675
676   CLog::Log(LOGDEBUG, "%s - Zapstream is not available on port %i.", __FUNCTION__, g_advancedSettings.m_iTuxBoxZapstreamPort);
677   return false;
678 }
679 bool CTuxBoxUtil::SetAudioChannel( const CStdString& strPath, const AUDIOCHANNEL& sAC )
680 {
681   CURL url(strPath);
682   CCurlFile http;
683   int iTryConnect = 0;
684   int iTimeout = 2;
685
686   url.SetProtocol("http");
687   url.SetFileName("cgi-bin/setAudio");
688   url.SetOptions("?channel=1&language=" + sAC.pid);
689   url.SetPort(80);
690
691   g_tuxbox.sZapstream.initialized = true;
692
693   while (iTryConnect < 3)
694   {
695     http.SetTimeout(iTimeout);
696
697     if (http.Open(url))
698     {
699       http.Close();
700       return true;
701     }
702
703     iTryConnect++;
704     iTimeout+=5;
705   }
706
707   return false;
708 }
709 bool CTuxBoxUtil::GetHttpXML(CURL url,CStdString strRequestType)
710 {
711   // Check and Set URL Request Option
712   if(!strRequestType.IsEmpty())
713   {
714     if(strRequestType.Equals("streaminfo"))
715     {
716       url.SetOptions("xml/streaminfo");
717     }
718     else if(strRequestType.Equals("currentservicedata"))
719     {
720       url.SetOptions("xml/currentservicedata");
721     }
722     else if(strRequestType.Equals("boxstatus"))
723     {
724       url.SetOptions("xml/boxstatus");
725     }
726     else if(strRequestType.Equals("boxinfo"))
727     {
728       url.SetOptions("xml/boxinfo");
729     }
730     else if(strRequestType.Equals("serviceepg"))
731     {
732       url.SetOptions("xml/serviceepg");
733     }
734     else
735     {
736       CLog::Log(LOGERROR, "%s - Request Type is not defined! You requested: %s", __FUNCTION__,strRequestType.c_str());
737       return false;
738     }
739   }
740   else
741   {
742     CLog::Log(LOGERROR, "%s - strRequestType Request Type is Empty!", __FUNCTION__);
743     return false;
744   }
745
746   // Clean Up the URL, so we have a clean request!
747   url.SetFileName("");
748
749   //Open
750   CCurlFile http;
751   http.SetTimeout(20);
752   if(http.Open(url))
753   {
754     int size_read = 0;
755     int data_size = 0;
756     int size_total = (int)http.GetLength();
757
758     if(size_total > 0)
759     {
760       // read response from server into string buffer
761       CStdString strTmp;
762       strTmp.reserve(size_total);
763       char buffer[16384];
764       while( (size_read = http.Read( buffer, sizeof(buffer)-1) ) > 0 )
765       {
766         buffer[size_read] = 0;
767         strTmp += buffer;
768         data_size += size_read;
769       }
770
771       // parse returned xml
772       CXBMCTinyXML doc;
773       TiXmlElement *XMLRoot=NULL;
774       strTmp.Replace("></",">-</"); //FILL EMPTY ELEMENTS WITH "-"!
775       doc.Parse(strTmp, http.GetServerReportedCharset());
776       strTmp.Empty();
777
778       XMLRoot = doc.RootElement();
779       CStdString strRoot = XMLRoot->Value();
780       if( strRoot.Equals("streaminfo"))
781         return StreamInformations(XMLRoot);
782       if(strRoot.Equals("currentservicedata"))
783         return CurrentServiceData(XMLRoot);
784       if(strRoot.Equals("boxstatus"))
785         return BoxStatus(XMLRoot);
786       if(strRoot.Equals("boxinfo"))
787         return BoxInfo(XMLRoot);
788       if(strRoot.Equals("serviceepg") || strRoot.Equals("service_epg"))
789         return ServiceEPG(XMLRoot);
790
791       CLog::Log(LOGERROR, "%s - Unable to parse xml", __FUNCTION__);
792       CLog::Log(LOGERROR, "%s - Request String: %s", __FUNCTION__,strRoot.c_str());
793       return false;
794     }
795     else
796     {
797       CLog::Log(LOGERROR, "%s - http length is invalid!", __FUNCTION__);
798       return false;
799     }
800   }
801   CLog::Log(LOGERROR, "%s - Open URL Failed! Unable to get XML structure", __FUNCTION__);
802   return false;
803 }
804 bool CTuxBoxUtil::StreamInformations(TiXmlElement *pRootElement)
805 {
806   /*
807   Sample:
808   http://192.168.0.110:31339/0,0065,01ff,0200,0201,0203,01ff
809
810   http://getIP:31339/0,pmtpid,vpid,apid,apids,apids,pcrpid;
811
812   vpid,pmtpid,pcrpid,apid  --> xml/streaminfo
813   apids --> /xml/currentservicedata
814
815   apid: is the defined audio stream!
816   Normal Stereo: http://192.168.0.110:31339/0,0065,01ff,0200,0201,0203,01ff
817   Normal English: http://192.168.0.110:31339/0,0065,01ff,0201,,,01ff
818   Normal DD5.1/AC3: http://192.168.0.110:31339/0,0065,01ff,0203,,,01ff
819   */
820
821   TiXmlNode *pNode = NULL;
822   TiXmlNode *pIt = NULL;
823   if(pRootElement != NULL)
824   {
825     CStdString strRoot = pRootElement->Value();
826     pNode = pRootElement->FirstChild("frontend");
827     if (pNode)
828     {
829       sStrmInfo.frontend = pNode->FirstChild()->Value();
830       CLog::Log(LOGDEBUG, "%s - Frontend: %s", __FUNCTION__, sStrmInfo.frontend.c_str());
831     }
832     pNode = pRootElement->FirstChild("service");
833     if (pNode)
834     {
835       CLog::Log(LOGDEBUG, "%s - Service", __FUNCTION__);
836       pIt = pNode->FirstChild("name");
837       if (pIt)
838       {
839         sStrmInfo.service_name = pIt->FirstChild()->Value();
840         CLog::Log(LOGDEBUG, "%s - Name: %s", __FUNCTION__, sStrmInfo.service_name.c_str());
841       }
842       pIt = pNode->FirstChild("reference");
843       if (pIt)
844       {
845         sStrmInfo.service_reference = pIt->FirstChild()->Value();
846         CLog::Log(LOGDEBUG, "%s - Reference: %s", __FUNCTION__, sStrmInfo.service_reference.c_str());
847       }
848     }
849
850     pNode = pRootElement->FirstChild("provider");
851     if(pNode && pNode->FirstChild())
852     {
853       sStrmInfo.provider= pNode->FirstChild()->Value();
854       CLog::Log(LOGDEBUG, "%s - Provider: %s", __FUNCTION__, sStrmInfo.provider.c_str());
855     }
856     pNode = pRootElement->FirstChild("vpid");
857     if (pNode)
858     {
859       sStrmInfo.vpid = pNode->FirstChild()->Value();
860       CLog::Log(LOGDEBUG, "%s - Vpid: %s", __FUNCTION__, sStrmInfo.vpid.c_str());
861     }
862     pNode = pRootElement->FirstChild("apid");
863     if (pNode)
864     {
865       sStrmInfo.apid = pNode->FirstChild()->Value();
866       CLog::Log(LOGDEBUG, "%s - Apid: %s", __FUNCTION__, sStrmInfo.apid.c_str());
867     }
868     pNode = pRootElement->FirstChild("pcrpid");
869     if (pNode)
870     {
871       sStrmInfo.pcrpid = pNode->FirstChild()->Value();
872       CLog::Log(LOGDEBUG, "%s - PcrPid: %s", __FUNCTION__, sStrmInfo.pcrpid.c_str());
873     }
874     pNode = pRootElement->FirstChild("tpid");
875     if (pNode)
876     {
877       sStrmInfo.tpid = pNode->FirstChild()->Value();
878       CLog::Log(LOGDEBUG, "%s - Tpid: %s", __FUNCTION__, sStrmInfo.tpid.c_str());
879     }
880     pNode = pRootElement->FirstChild("tsid");
881     if (pNode)
882     {
883       sStrmInfo.tsid = pNode->FirstChild()->Value();
884       CLog::Log(LOGDEBUG, "%s - Tsid: %s", __FUNCTION__, sStrmInfo.tsid.c_str());
885     }
886     pNode = pRootElement->FirstChild("onid");
887     if (pNode)
888     {
889       sStrmInfo.onid = pNode->FirstChild()->Value();
890       CLog::Log(LOGDEBUG, "%s - Onid: %s", __FUNCTION__, sStrmInfo.onid.c_str());
891     }
892     pNode = pRootElement->FirstChild("sid");
893     if (pNode)
894     {
895       sStrmInfo.sid = pNode->FirstChild()->Value();
896       CLog::Log(LOGDEBUG, "%s - Sid: %s", __FUNCTION__, sStrmInfo.sid.c_str());
897     }
898     pNode = pRootElement->FirstChild("pmt");
899     if (pNode)
900     {
901       sStrmInfo.pmt = pNode->FirstChild()->Value();
902       CLog::Log(LOGDEBUG, "%s - Pmt: %s", __FUNCTION__, sStrmInfo.pmt.c_str());
903     }
904     pNode = pRootElement->FirstChild("video_format");
905     if (pNode)
906     {
907       sStrmInfo.video_format = pNode->FirstChild()->Value();
908       CLog::Log(LOGDEBUG, "%s - Video Format: %s", __FUNCTION__, sStrmInfo.video_format.c_str());
909     }
910     pNode = pRootElement->FirstChild("supported_crypt_systems");
911     if (pNode)
912     {
913       sStrmInfo.supported_crypt_systems = pNode->FirstChild()->Value();
914       CLog::Log(LOGDEBUG, "%s - Supported Crypt Systems: %s", __FUNCTION__, sStrmInfo.supported_crypt_systems.c_str());
915     }
916     pNode = pRootElement->FirstChild("used_crypt_systems");
917     if (pNode)
918     {
919       sStrmInfo.used_crypt_systems = pNode->FirstChild()->Value();
920       CLog::Log(LOGDEBUG, "%s - Used Crypt Systems: %s", __FUNCTION__, sStrmInfo.used_crypt_systems.c_str());
921     }
922     pNode = pRootElement->FirstChild("satellite");
923     if (pNode)
924     {
925       sStrmInfo.satellite = pNode->FirstChild()->Value();
926       CLog::Log(LOGDEBUG, "%s - Satellite: %s", __FUNCTION__, sStrmInfo.satellite.c_str());
927     }
928     pNode = pRootElement->FirstChild("frequency");
929     if (pNode)
930     {
931       sStrmInfo.frequency = pNode->FirstChild()->Value();
932       CLog::Log(LOGDEBUG, "%s - Frequency: %s", __FUNCTION__, sStrmInfo.frequency.c_str());
933     }
934     pNode = pRootElement->FirstChild("symbol_rate");
935     if (pNode)
936     {
937       sStrmInfo.symbol_rate = pNode->FirstChild()->Value();
938       CLog::Log(LOGDEBUG, "%s - Symbol Rate: %s", __FUNCTION__, sStrmInfo.symbol_rate.c_str());
939     }
940     pNode = pRootElement->FirstChild("polarisation");
941     if (pNode)
942     {
943       sStrmInfo.polarisation = pNode->FirstChild()->Value();
944       CLog::Log(LOGDEBUG, "%s - Polarisation: %s", __FUNCTION__, sStrmInfo.polarisation.c_str());
945     }
946     pNode = pRootElement->FirstChild("inversion");
947     if (pNode)
948     {
949       sStrmInfo.inversion = pNode->FirstChild()->Value();
950       CLog::Log(LOGDEBUG, "%s - Inversion: %s", __FUNCTION__, sStrmInfo.inversion.c_str());
951     }
952     pNode = pRootElement->FirstChild("fec");
953     if (pNode)
954     {
955       sStrmInfo.fec = pNode->FirstChild()->Value();
956       CLog::Log(LOGDEBUG, "%s - Fec: %s", __FUNCTION__, sStrmInfo.fec.c_str());
957     }
958     pNode = pRootElement->FirstChild("snr");
959     if (pNode)
960     {
961       sStrmInfo.snr = pNode->FirstChild()->Value();
962       CLog::Log(LOGDEBUG, "%s - Snr: %s", __FUNCTION__, sStrmInfo.snr.c_str());
963     }
964     pNode = pRootElement->FirstChild("agc");
965     if (pNode)
966     {
967       sStrmInfo.agc = pNode->FirstChild()->Value();
968       CLog::Log(LOGDEBUG, "%s - Agc: %s", __FUNCTION__,  sStrmInfo.agc.c_str());
969     }
970     pNode = pRootElement->FirstChild("ber");
971     if (pNode)
972     {
973       sStrmInfo.ber = pNode->FirstChild()->Value();
974       CLog::Log(LOGDEBUG, "%s - ber: %s", __FUNCTION__, sStrmInfo.ber.c_str());
975     }
976     pNode = pRootElement->FirstChild("lock");
977     if (pNode)
978     {
979       sStrmInfo.lock = pNode->FirstChild()->Value();
980       CLog::Log(LOGDEBUG, "%s - Lock: %s", __FUNCTION__, sStrmInfo.lock.c_str());
981     }
982     pNode = pRootElement->FirstChild("sync");
983     if (pNode)
984     {
985       sStrmInfo.sync = pNode->FirstChild()->Value();
986       CLog::Log(LOGDEBUG, "%s - Sync: %s", __FUNCTION__, sStrmInfo.sync.c_str());
987     }
988     return true;
989   }
990   return false;
991 }
992 bool CTuxBoxUtil::CurrentServiceData(TiXmlElement *pRootElement)
993 {
994   TiXmlNode *pNode = NULL;
995   TiXmlNode *pIt = NULL;
996   TiXmlNode *pVal = NULL;
997   if(pRootElement)
998   {
999     CLog::Log(LOGDEBUG, "%s - Current Service Data", __FUNCTION__);
1000     pNode = pRootElement->FirstChild("service");
1001     if (pNode)
1002     {
1003       CLog::Log(LOGDEBUG, "%s - Service", __FUNCTION__);
1004       pIt = pNode->FirstChild("name");
1005       if (pIt)
1006       {
1007         sCurSrvData.service_name = pIt->FirstChild()->Value();
1008         CLog::Log(LOGDEBUG, "%s - Service Name: %s", __FUNCTION__, pIt->FirstChild()->Value());
1009       }
1010       pIt = pNode->FirstChild("reference");
1011       if (pIt)
1012       {
1013         sCurSrvData.service_reference = pIt->FirstChild()->Value();
1014         CLog::Log(LOGDEBUG, "%s - Service Reference: %s", __FUNCTION__, pIt->FirstChild()->Value());
1015       }
1016     }
1017
1018     pNode = pRootElement->FirstChild("audio_channels");
1019     if (pNode)
1020     {
1021       CLog::Log(LOGDEBUG, "%s - Audio Channels", __FUNCTION__);
1022       int i = 0;
1023
1024       pIt = pNode->FirstChild("channel");
1025       sCurSrvData.audio_channels.clear();
1026
1027       while(pIt)
1028       {
1029         sAudioChannel newChannel;
1030
1031         pVal = pIt->FirstChild("pid");
1032         if(pVal)
1033           newChannel.pid = pVal->FirstChild()->Value();
1034
1035         pVal = pIt->FirstChild("selected");
1036         if(pVal)
1037           newChannel.selected = pVal->FirstChild()->Value();
1038
1039         pVal = pIt->FirstChild("name");
1040         if(pVal)
1041           newChannel.name = pVal->FirstChild()->Value();
1042
1043         CLog::Log(LOGDEBUG, "%s - Audio Channels: Channel %i -> PID: %s Selected: %s Name: %s", __FUNCTION__, i, newChannel.pid.c_str(), newChannel.selected.c_str(), newChannel.name.c_str() );
1044
1045         i=i+1;
1046         sCurSrvData.audio_channels.push_back( newChannel );
1047         pIt = pIt->NextSibling("channel");
1048       }
1049     }
1050     pNode = pRootElement->FirstChild("audio_track");
1051     if (pNode)
1052     {
1053       sCurSrvData.audio_track = pNode->FirstChild()->Value();
1054       CLog::Log(LOGDEBUG, "%s - Audio Track: %s", __FUNCTION__, pNode->FirstChild()->Value() );
1055     }
1056     pNode = pRootElement->FirstChild("video_channels");
1057     if (pNode)
1058     {
1059       CLog::Log(LOGDEBUG, "%s - Video Channels", __FUNCTION__);
1060       pIt = pNode->FirstChild("service");
1061       if (pIt)
1062       {
1063         vVideoSubChannel.name.clear();
1064         vVideoSubChannel.reference.clear();
1065         vVideoSubChannel.selected.clear();
1066         int i = 0;
1067         while(pIt)
1068         {
1069           pVal = pIt->FirstChild("name");
1070           if(pVal)
1071           {
1072             vVideoSubChannel.name.push_back(pVal->FirstChild()->Value());
1073             CLog::Log(LOGDEBUG, "%s - Video Sub Channel %i:      Name: %s", __FUNCTION__, i,pVal->FirstChild()->Value());
1074           }
1075           pVal = pIt->FirstChild("reference");
1076           if(pVal)
1077           {
1078             vVideoSubChannel.reference.push_back(pVal->FirstChild()->Value());
1079             CLog::Log(LOGDEBUG, "%s - Video Sub Channel %i: Reference: %s", __FUNCTION__, i,pVal->FirstChild()->Value());
1080           }
1081           pVal = pIt->FirstChild("selected");
1082           if(pVal)
1083           {
1084             vVideoSubChannel.selected.push_back(pVal->FirstChild()->Value());
1085             CLog::Log(LOGDEBUG, "%s - Video Sub Channel %i: Selected: %s", __FUNCTION__, i,pVal->FirstChild()->Value());
1086           }
1087           pIt = pIt->NextSibling("service");
1088           i++;
1089         }
1090       }
1091       else
1092       {
1093         vVideoSubChannel.name.clear();
1094         vVideoSubChannel.reference.clear();
1095         vVideoSubChannel.selected.clear();
1096       }
1097     }
1098     pNode = pRootElement->FirstChild("current_event");
1099     if (pNode)
1100     {
1101       CLog::Log(LOGDEBUG, "%s - Current Event", __FUNCTION__);
1102       pIt = pNode->FirstChild("date");
1103       if (pIt)
1104       {
1105         sCurSrvData.current_event_date = pIt->FirstChild()->Value();
1106         CLog::Log(LOGDEBUG, "%s - Date: %s", __FUNCTION__, pIt->FirstChild()->Value());
1107       }
1108       pIt = pNode->FirstChild("time");
1109       if (pIt)
1110       {
1111         sCurSrvData.current_event_time = pIt->FirstChild()->Value();
1112         CLog::Log(LOGDEBUG, "%s - Time: %s", __FUNCTION__, pIt->FirstChild()->Value());
1113       }
1114
1115       pIt = pNode->FirstChild("start");
1116       if (pIt)
1117       {
1118         sCurSrvData.current_event_start = pIt->FirstChild()->Value();
1119         CLog::Log(LOGDEBUG, "%s - Start: %s", __FUNCTION__, pIt->FirstChild()->Value());
1120       }
1121
1122       pIt = pNode->FirstChild("duration");
1123       if (pIt)
1124       {
1125         sCurSrvData.current_event_duration = pIt->FirstChild()->Value();
1126         CLog::Log(LOGDEBUG, "%s - Duration: %s", __FUNCTION__, pIt->FirstChild()->Value());
1127       }
1128
1129       pIt = pNode->FirstChild("description");
1130       if (pIt)
1131       {
1132         sCurSrvData.current_event_description = pIt->FirstChild()->Value();
1133         CLog::Log(LOGDEBUG, "%s - Description: %s", __FUNCTION__, pIt->FirstChild()->Value());
1134       }
1135       pIt = pNode->FirstChild("details");
1136       if (pIt)
1137       {
1138         sCurSrvData.current_event_details = pIt->FirstChild()->Value();
1139         CLog::Log(LOGDEBUG, "%s - Details: %s", __FUNCTION__, pIt->FirstChild()->Value());
1140       }
1141     }
1142     pNode = pRootElement->FirstChild("next_event");
1143     if (pNode)
1144     {
1145       CLog::Log(LOGDEBUG, "%s - Next Event", __FUNCTION__);
1146       pIt = pNode->FirstChild("date");
1147       if (pIt)
1148       {
1149         sCurSrvData.next_event_date = pIt->FirstChild()->Value();
1150         CLog::Log(LOGDEBUG, "%s - Date: %s", __FUNCTION__, pIt->FirstChild()->Value());
1151       }
1152       pIt = pNode->FirstChild("time");
1153       if (pIt)
1154       {
1155         sCurSrvData.next_event_time = pIt->FirstChild()->Value();
1156         CLog::Log(LOGDEBUG, "%s - Time: %s", __FUNCTION__, pIt->FirstChild()->Value());
1157       }
1158
1159       pIt = pNode->FirstChild("start");
1160       if (pIt)
1161       {
1162         sCurSrvData.next_event_start = pIt->FirstChild()->Value();
1163         CLog::Log(LOGDEBUG, "%s - Start: %s", __FUNCTION__, pIt->FirstChild()->Value());
1164       }
1165
1166       pIt = pNode->FirstChild("duration");
1167       if (pIt)
1168       {
1169         sCurSrvData.next_event_duration = pIt->FirstChild()->Value();
1170         CLog::Log(LOGDEBUG, "%s - Duration: %s", __FUNCTION__, pIt->FirstChild()->Value());
1171       }
1172
1173       pIt = pNode->FirstChild("description");
1174       if (pIt)
1175       {
1176         sCurSrvData.next_event_description = pIt->FirstChild()->Value();
1177         CLog::Log(LOGDEBUG, "%s - Description: %s", __FUNCTION__, pIt->FirstChild()->Value());
1178       }
1179       pIt = pNode->FirstChild("details");
1180       if (pIt)
1181       {
1182         sCurSrvData.next_event_details = pIt->FirstChild()->Value();
1183         CLog::Log(LOGDEBUG, "%s - Details: %s", __FUNCTION__, pIt->FirstChild()->Value());
1184       }
1185     }
1186     return true;
1187   }
1188   return false;
1189
1190 }
1191 bool CTuxBoxUtil::BoxStatus(TiXmlElement *pRootElement)
1192 {
1193   //Tuxbox Controll Commands
1194   /*
1195     /cgi-bin/admin?command=wakeup
1196     /cgi-bin/admin?command=standby
1197     /cgi-bin/admin?command=shutdown
1198     /cgi-bin/admin?command=reboot
1199     /cgi-bin/admin?command=restart
1200   */
1201
1202   TiXmlNode *pNode = NULL;
1203
1204   if(pRootElement)
1205   {
1206     CLog::Log(LOGDEBUG, "%s - BoxStatus", __FUNCTION__);
1207     pNode = pRootElement->FirstChild("current_time");
1208     if (pNode)
1209     {
1210       sBoxStatus.current_time = pNode->FirstChild()->Value();
1211       CLog::Log(LOGDEBUG, "%s - Current Time: %s", __FUNCTION__, pNode->FirstChild()->Value());
1212     }
1213     pNode = pRootElement->FirstChild("standby");
1214     if (pNode)
1215     {
1216       sBoxStatus.standby = pNode->FirstChild()->Value();
1217       CLog::Log(LOGDEBUG, "%s - Standby: %s", __FUNCTION__, pNode->FirstChild()->Value());
1218     }
1219     pNode = pRootElement->FirstChild("recording");
1220     if (pNode)
1221     {
1222       sBoxStatus.recording = pNode->FirstChild()->Value();
1223       CLog::Log(LOGDEBUG, "%s - Recording: %s", __FUNCTION__, pNode->FirstChild()->Value());
1224     }
1225     pNode = pRootElement->FirstChild("mode");
1226     if (pNode)
1227     {
1228       sBoxStatus.mode = pNode->FirstChild()->Value();
1229       CLog::Log(LOGDEBUG, "%s - Mode: %s", __FUNCTION__, pNode->FirstChild()->Value());
1230     }
1231     pNode = pRootElement->FirstChild("ip");
1232     if (pNode)
1233     {
1234       if (sBoxStatus.ip != pNode->FirstChild()->Value() )
1235       {
1236         g_tuxbox.sZapstream.initialized = false;
1237         g_tuxbox.sZapstream.available = false;
1238       }
1239       sBoxStatus.ip = pNode->FirstChild()->Value();
1240       CLog::Log(LOGDEBUG, "%s - Ip: %s", __FUNCTION__, pNode->FirstChild()->Value());
1241     }
1242     return true;
1243   }
1244   return false;
1245 }
1246 bool CTuxBoxUtil::BoxInfo(TiXmlElement *pRootElement)
1247 {
1248   TiXmlNode *pNode = NULL;
1249   TiXmlNode *pIt = NULL;
1250
1251   if(pRootElement)
1252   {
1253     CLog::Log(LOGDEBUG, "%s - BoxInfo", __FUNCTION__);
1254     pNode = pRootElement->FirstChild("image");
1255     if (pNode)
1256     {
1257       CLog::Log(LOGDEBUG, "%s - Image", __FUNCTION__);
1258       pIt = pNode->FirstChild("version");
1259       if (pIt)
1260       {
1261         sBoxInfo.image_version = pIt->FirstChild()->Value();
1262         CLog::Log(LOGDEBUG, "%s - Image Version: %s", __FUNCTION__, pIt->FirstChild()->Value());
1263       }
1264       pIt = pNode->FirstChild("url");
1265       if (pIt)
1266       {
1267         sBoxInfo.image_url = pIt->FirstChild()->Value();
1268         CLog::Log(LOGDEBUG, "%s - Image Url: %s", __FUNCTION__, pIt->FirstChild()->Value());
1269       }
1270       pIt = pNode->FirstChild("comment");
1271       if (pIt)
1272       {
1273         sBoxInfo.image_comment = pIt->FirstChild()->Value();
1274         CLog::Log(LOGDEBUG, "%s - Image Comment: %s", __FUNCTION__, pIt->FirstChild()->Value());
1275       }
1276       pIt = pNode->FirstChild("catalog");
1277       if (pIt)
1278       {
1279         sBoxInfo.image_catalog = pIt->FirstChild()->Value();
1280         CLog::Log(LOGDEBUG, "%s - Image Catalog: %s", __FUNCTION__, pIt->FirstChild()->Value());
1281       }
1282     }
1283     pNode = pRootElement->FirstChild("firmware");
1284     if (pNode)
1285     {
1286       sBoxInfo.firmware = pNode->FirstChild()->Value();
1287       CLog::Log(LOGDEBUG, "%s - Firmware: %s", __FUNCTION__, pNode->FirstChild()->Value());
1288     }
1289     pNode = pRootElement->FirstChild("fpfirmware");
1290     if (pNode)
1291     {
1292       sBoxInfo.fpfirmware = pNode->FirstChild()->Value();
1293       CLog::Log(LOGDEBUG, "%s - FP Firmware: %s", __FUNCTION__, pNode->FirstChild()->Value());
1294     }
1295     pNode = pRootElement->FirstChild("webinterface");
1296     if (pNode)
1297     {
1298       sBoxInfo.webinterface = pNode->FirstChild()->Value();
1299       CLog::Log(LOGDEBUG, "%s - Web Interface: %s", __FUNCTION__, pNode->FirstChild()->Value());
1300     }
1301     pNode = pRootElement->FirstChild("model");
1302     if (pNode)
1303     {
1304       sBoxInfo.model = pNode->FirstChild()->Value();
1305       CLog::Log(LOGDEBUG, "%s - Model: %s", __FUNCTION__, pNode->FirstChild()->Value());
1306     }
1307     pNode = pRootElement->FirstChild("manufacturer");
1308     if (pNode)
1309     {
1310       sBoxInfo.manufacturer = pNode->FirstChild()->Value();
1311       CLog::Log(LOGDEBUG, "%s - Manufacturer: %s", __FUNCTION__, pNode->FirstChild()->Value());
1312     }
1313     pNode = pRootElement->FirstChild("processor");
1314     if (pNode)
1315     {
1316       sBoxInfo.processor = pNode->FirstChild()->Value();
1317       CLog::Log(LOGDEBUG, "%s - Processor: %s", __FUNCTION__, pNode->FirstChild()->Value());
1318     }
1319     pNode = pRootElement->FirstChild("usbstick");
1320     if (pNode)
1321     {
1322       sBoxInfo.usbstick = pNode->FirstChild()->Value();
1323       CLog::Log(LOGDEBUG, "%s - USB Stick: %s", __FUNCTION__, pNode->FirstChild()->Value());
1324     }
1325     pNode = pRootElement->FirstChild("disk");
1326     if (pNode)
1327     {
1328       sBoxInfo.disk = pNode->FirstChild()->Value();
1329       CLog::Log(LOGDEBUG, "%s - Disk: %s", __FUNCTION__, pNode->FirstChild()->Value());
1330     }
1331     return true;
1332   }
1333   return false;
1334 }
1335 bool CTuxBoxUtil::ServiceEPG(TiXmlElement *pRootElement)
1336 {
1337   TiXmlNode *pNode = NULL;
1338   TiXmlNode *pIt = NULL;
1339
1340   if(pRootElement)
1341   {
1342     CLog::Log(LOGDEBUG, "%s - Service EPG", __FUNCTION__);
1343     pNode = pRootElement->FirstChild("service");
1344     if (pNode)
1345     {
1346       CLog::Log(LOGDEBUG, "%s - Service", __FUNCTION__);
1347       pIt = pNode->FirstChild("reference");
1348       if (pIt)
1349       {
1350         sServiceEPG.service_reference = pIt->FirstChild()->Value();
1351         CLog::Log(LOGDEBUG, "%s - Service Reference: %s", __FUNCTION__, pIt->FirstChild()->Value());
1352       }
1353       pIt = pNode->FirstChild("name");
1354       if (pIt)
1355       {
1356         sServiceEPG.service_name = pIt->FirstChild()->Value();
1357         CLog::Log(LOGDEBUG, "%s - Service Name: %s", __FUNCTION__, pIt->FirstChild()->Value());
1358       }
1359     }
1360     //Todo there is more then 1 event! Create a Event List!
1361     pNode = pRootElement->FirstChild("event");
1362     if (pNode)
1363     {
1364       CLog::Log(LOGDEBUG, "%s - Event", __FUNCTION__);
1365       pIt = pNode->FirstChild("date");
1366       if (pIt)
1367       {
1368         sServiceEPG.date = pIt->FirstChild()->Value();
1369         CLog::Log(LOGDEBUG, "%s - Date: %s", __FUNCTION__, pIt->FirstChild()->Value());
1370       }
1371       pIt = pNode->FirstChild("time");
1372       if (pIt)
1373       {
1374         sServiceEPG.time = pIt->FirstChild()->Value();
1375         CLog::Log(LOGDEBUG, "%s - Time: %s", __FUNCTION__, pIt->FirstChild()->Value());
1376       }
1377       pIt = pNode->FirstChild("duration");
1378       if (pIt)
1379       {
1380         sServiceEPG.duration = pIt->FirstChild()->Value();
1381         CLog::Log(LOGDEBUG, "%s - Duration: %s", __FUNCTION__, pIt->FirstChild()->Value());
1382       }
1383       pIt = pNode->FirstChild("descritption");
1384       if (pIt)
1385       {
1386         sServiceEPG.descritption = pIt->FirstChild()->Value();
1387         CLog::Log(LOGDEBUG, "%s - Descritption: %s", __FUNCTION__, pIt->FirstChild()->Value());
1388       }
1389       pIt = pNode->FirstChild("genre");
1390       if (pIt)
1391       {
1392         sServiceEPG.genre = pIt->FirstChild()->Value();
1393         CLog::Log(LOGDEBUG, "%s - Genre: %s", __FUNCTION__, pIt->FirstChild()->Value());
1394       }
1395       pIt = pNode->FirstChild("genrecategory");
1396       if (pIt)
1397       {
1398         sServiceEPG.genrecategory = pIt->FirstChild()->Value();
1399         CLog::Log(LOGDEBUG, "%s - Genrecategory: %s", __FUNCTION__, pIt->FirstChild()->Value());
1400       }
1401       pIt = pNode->FirstChild("start");
1402       if (pIt)
1403       {
1404         sServiceEPG.start = pIt->FirstChild()->Value();
1405         CLog::Log(LOGDEBUG, "%s - Start: %s", __FUNCTION__, pIt->FirstChild()->Value());
1406       }
1407       pIt = pNode->FirstChild("details");
1408       if (pIt)
1409       {
1410         sServiceEPG.details = pIt->FirstChild()->Value();
1411         CLog::Log(LOGDEBUG, "%s - Details: %s", __FUNCTION__, pIt->FirstChild()->Value());
1412       }
1413     }
1414     return true;
1415   }
1416   return false;
1417 }
1418 //PopUp and request the AudioChannel
1419 //No PopUp: On 1x detected AudioChannel
1420 bool CTuxBoxUtil::GetGUIRequestedAudioChannel(AUDIOCHANNEL& sRequestedAC)
1421 {
1422   sRequestedAC = sCurSrvData.audio_channels[0];
1423
1424   // Audio Selection is Disabled! Return false to use default values!
1425   if(!g_advancedSettings.m_bTuxBoxAudioChannelSelection)
1426   {
1427     CLog::Log(LOGDEBUG, "%s - Audio Channel Selection is Disabled! Returning False to use the default values!", __FUNCTION__);
1428     return false;
1429   }
1430
1431   // We have only one Audio Channel return false to use default values!
1432   if(sCurSrvData.audio_channels.size() == 1)
1433     return false;
1434
1435   // popup the context menu
1436   CContextButtons buttons;
1437
1438   // add the needed Audio buttons
1439   for (unsigned int i = 0; i < sCurSrvData.audio_channels.size(); ++i)
1440     buttons.Add(i, sCurSrvData.audio_channels[i].name);
1441
1442   int channel = CGUIDialogContextMenu::ShowAndGetChoice(buttons);
1443   if (channel >= 0)
1444   {
1445     sRequestedAC = sCurSrvData.audio_channels[channel];
1446     sCurSrvData.requested_audio_channel = channel;
1447     CLog::Log(LOGDEBUG, "%s - Audio channel %s requested.", __FUNCTION__, sRequestedAC.name.c_str());
1448     return true;
1449   }
1450   return false;
1451 }
1452 bool CTuxBoxUtil::GetRequestedAudioChannel(AUDIOCHANNEL& sRequestedAC)
1453 {
1454   sRequestedAC = sCurSrvData.audio_channels[sCurSrvData.requested_audio_channel];
1455
1456   return true;
1457 }
1458 bool CTuxBoxUtil::GetVideoSubChannels(CStdString& strVideoSubChannelName, CStdString& strVideoSubChannelPid)
1459 {
1460   // no video sub channel return false!
1461   if(vVideoSubChannel.name.size() <= 0 || vVideoSubChannel.reference.size() <= 0)
1462     return false;
1463
1464   // IsPlaying, Stop it..
1465   if(g_application.m_pPlayer->IsPlaying())
1466     CApplicationMessenger::Get().MediaStop();
1467
1468   // popup the context menu
1469   CContextButtons buttons;
1470
1471   // add the needed Audio buttons
1472   for (unsigned int i = 0; i < vVideoSubChannel.name.size(); ++i)
1473     buttons.Add(i, vVideoSubChannel.name[i]);
1474
1475   // get selected Video Sub Channel name and reference zap
1476   int channel = CGUIDialogContextMenu::ShowAndGetChoice(buttons);
1477   if (channel >= 0)
1478   {
1479     strVideoSubChannelName = vVideoSubChannel.name[channel];
1480     strVideoSubChannelPid = vVideoSubChannel.reference[channel];
1481     vVideoSubChannel.name.clear();
1482     vVideoSubChannel.reference.clear();
1483     vVideoSubChannel.selected.clear();
1484     return true;
1485   }
1486   return false;
1487 }
1488 //Input: Service Name (Channel Namne)
1489 //Output: picon url (on ERROR the default icon path will be returned)
1490 CStdString CTuxBoxUtil::GetPicon(CStdString strServiceName)
1491 {
1492   if(!g_advancedSettings.m_bTuxBoxPictureIcon)
1493   {
1494     CLog::Log(LOGDEBUG, "%s PictureIcon Detection is Disabled! Using default icon", __FUNCTION__);
1495     return "";
1496   }
1497   if (strServiceName.IsEmpty())
1498   {
1499     CLog::Log(LOGDEBUG, "%s Service Name is Empty! Can not detect a PictureIcon. Using default icon!", __FUNCTION__);
1500     return "";
1501   }
1502   else
1503   {
1504     CStdString piconXML, piconPath, defaultPng;
1505     CStdString strName, strPng;
1506     piconPath = "special://xbmc/userdata/PictureIcon/Picon/";
1507     defaultPng = piconPath+"tuxbox.png";
1508     piconXML = "special://xbmc/userdata/PictureIcon/picon.xml";
1509     CXBMCTinyXML piconDoc;
1510
1511     if (!CFile::Exists(piconXML))
1512       return defaultPng;
1513
1514     if (!piconDoc.LoadFile(piconXML))
1515     {
1516       CLog::Log(LOGERROR, "Error loading %s, Line %d\n%s", piconXML.c_str(), piconDoc.ErrorRow(), piconDoc.ErrorDesc());
1517       return defaultPng;
1518     }
1519
1520     TiXmlElement *pRootElement = piconDoc.RootElement();
1521     if (!pRootElement || strcmpi(pRootElement->Value(),"picon") != 0)
1522     {
1523       CLog::Log(LOGERROR, "Error loading %s, no <picon> node", piconXML.c_str());
1524       return defaultPng;
1525     }
1526
1527     TiXmlElement* pServices = pRootElement->FirstChildElement("services");
1528     TiXmlElement* pService;
1529     pService = pServices->FirstChildElement("service");
1530     while(pService)
1531     {
1532       if(pService->Attribute("name"))
1533         strName.Format("%s",pService->Attribute("name"));
1534
1535       if(pService->Attribute("png"))
1536         strPng.Format("%s",pService->Attribute("png"));
1537
1538       if(strName.Equals(strServiceName))
1539       {
1540         strPng.Format("%s%s",piconPath.c_str(), strPng.c_str());
1541         strPng.ToLower();
1542         CLog::Log(LOGDEBUG, "%s %s: Path is: %s", __FUNCTION__,strServiceName.c_str(), strPng.c_str());
1543         return strPng;
1544       }
1545       pService = pService->NextSiblingElement("service");
1546     }
1547     return defaultPng;
1548   }
1549 }
1550
1551 // iMODE: 0 = TV, 1 = Radio, 2 = Data, 3 = Movies, 4 = Root
1552 // SUBMODE: 0 = n/a, 1 = All, 2 = Satellites, 2 = Providers, 4 = Bouquets
1553 CStdString CTuxBoxUtil::GetSubMode(int iMode, CStdString& strXMLRootString, CStdString& strXMLChildString)
1554 {
1555   //Todo: add a setting: "Don't Use Request mode" to advanced.xml
1556
1557   // MODE: 0 = TV, 1 = Radio, 2 = Data, 3 = Movies, 4 = Root
1558   // SUBMODE: 0 = n/a, 1 = All, 2 = Satellites, 2 = Providers, 4 = Bouquets
1559   // Default Submode
1560   CStdString strSubMode;
1561
1562   if(iMode <0 || iMode >4)
1563   {
1564     strSubMode.Format("xml/services?mode=0&submode=4");
1565     strXMLRootString.Format("bouquets");
1566     strXMLChildString.Format("bouquet");
1567     return strSubMode;
1568   }
1569
1570   // popup the context menu
1571
1572   // FIXME: Localize these
1573   CContextButtons choices;
1574   choices.Add(1, "All");
1575   choices.Add(2, "Satellites");
1576   choices.Add(3, "Providers");
1577   choices.Add(4, "Bouquets");
1578
1579   int iSubMode = CGUIDialogContextMenu::ShowAndGetChoice(choices);
1580   if (iSubMode == 1)
1581   {
1582     strXMLRootString.Format("services");
1583     strXMLChildString.Format("service");
1584   }
1585   else if (iSubMode == 2)
1586   {
1587     strXMLRootString.Format("satellites");
1588     strXMLChildString.Format("satellite");
1589   }
1590   else if (iSubMode == 3)
1591   {
1592     strXMLRootString.Format("providers");
1593     strXMLChildString.Format("provider");
1594   }
1595   else // if (iSubMode == 4 || iSubMode < 0)
1596   {
1597     iSubMode = 4;
1598     strXMLRootString.Format("bouquets");
1599     strXMLChildString.Format("bouquet");
1600   }
1601   strSubMode.Format("xml/services?mode=%i&submode=%i",iMode,iSubMode);
1602   return strSubMode;
1603 }
1604 //Input: url/path of share/item file/folder
1605 //Output: the detected submode root and child string
1606 CStdString CTuxBoxUtil::DetectSubMode(CStdString strSubMode, CStdString& strXMLRootString, CStdString& strXMLChildString)
1607 {
1608   //strSubMode = "xml/services?mode=0&submode=1"
1609   CStdString strFilter;
1610   int ipointMode = strSubMode.Find("?mode=");
1611   int ipointSubMode = strSubMode.Find("&submode=");
1612   if (ipointMode >=0)
1613     strFilter = strSubMode.GetAt(ipointMode+6);
1614
1615   if (ipointSubMode >=0)
1616   {
1617     CStdString strTemp;
1618     strTemp = strSubMode.GetAt(ipointSubMode+9);
1619     if(strTemp.Equals("1"))
1620     {
1621       strXMLRootString.Format("unknowns");
1622       strXMLChildString.Format("unknown");
1623     }
1624     else if(strTemp.Equals("2"))
1625     {
1626       strXMLRootString.Format("satellites");
1627       strXMLChildString.Format("satellite");
1628     }
1629     else if(strTemp.Equals("3"))
1630     {
1631       strXMLRootString.Format("providers");
1632       strXMLChildString.Format("provider");
1633     }
1634     else if(strTemp.Equals("4"))
1635     {
1636       strXMLRootString.Format("bouquets");
1637       strXMLChildString.Format("bouquet");
1638     }
1639
1640   }
1641   return strFilter;
1642 }