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