change plugins code.
[vuplus_dvbapp] / lib / python / Plugins / SystemPlugins / FirmwareUpgrade / plugin.py
1 import os, urllib
2 from urllib import urlretrieve
3
4 from Plugins.Plugin import PluginDescriptor
5
6 from Components.config import config, getConfigListEntry, ConfigSubsection, ConfigText, ConfigSelection, ConfigYesNo,ConfigText
7 from Components.ConfigList import ConfigListScreen
8 from Components.ActionMap import ActionMap
9 from Components.Sources.StaticText import StaticText
10 from Components.Pixmap import Pixmap
11 from Components.Label import Label
12
13 from Components.FileList import FileList 
14 from Components.Slider import Slider
15
16 from Screens.Screen import Screen
17 from Screens.MessageBox import MessageBox
18
19 from enigma import ePoint, eConsoleAppContainer, eTimer
20 from Tools.Directories import resolveFilename, SCOPE_PLUGINS
21
22 fwlist = None
23 fwdata = None
24 if os.path.exists("/proc/stb/info/vumodel"):
25         vumodel = open("/proc/stb/info/vumodel")
26         info = vumodel.read().strip()
27         vumodel.close()
28
29         if info == "ultimo":
30                 fwlist= [
31                          ("fpga", _("FPGA"))
32                         ,("fp", _("Front Processor"))
33                         ]
34                 fwdata= { 
35                          "fpga" : ["http://archive.vuplus.com/download/fpga", "fpga.files", "/dev/fpga_dp;/dev/misc/dp;"]
36                         ,"fp"   : ["http://archive.vuplus.com/download/fp", "fp.files", "/dev/bcm_mu;"]
37                         }
38         elif info == "uno":
39                 fwlist= [
40                         ("fpga", _("FPGA"))
41                         ]
42                 fwdata= { 
43                         "fpga" : ["http://archive.vuplus.com/download/fpga", "fpga.file", "/dev/fpga_dp;/dev/misc/dp;"]
44                         }
45
46 import os, fcntl, thread
47 STATUS_READY            = 0
48 STATUS_DONE             = 1
49 STATUS_ERROR            = 2
50 STATUS_PREPARED         = 3
51 STATUS_PROGRAMMING      = 4
52 STATUS_RETRY_UPGRADE    = 5
53
54 class FPUpgradeCore() :
55         status = STATUS_READY
56         errmsg = ''
57         MAX_CALL_COUNT = 120
58         def __init__(self, firmwarefile, devicefile):
59                 self.devicefile = devicefile
60                 self.firmwarefile = firmwarefile
61
62         def doUpgrade(self):
63                 firmware,device = None,None
64                 def closefpga(fp, fd):
65                         if fd is not None: os.close(fd)
66                         if fp is not None: fp.close()
67                 try:
68                         size = os.path.getsize(self.firmwarefile)
69                         if size == 0: raise Exception, 'data_size is zero'
70                         #print '[FPUpgradeCore] data_size :',size
71
72                         for xx in range(3):
73                                 self.callcount = 0
74                                 self.status = STATUS_READY
75
76                                 firmware = open(self.firmwarefile, 'rb')
77                                 device = os.open(self.devicefile, os.O_RDWR)
78                                 #print '[FPUpgradeCore] open >> [ok]'
79
80                                 rc = fcntl.ioctl(device, 0, size)
81                                 if rc < 0: raise Exception, 'fail to set size : %d'%(rc)
82                                 #print '[FPUpgradeCore] set size >> [ok]'
83                                 self.status = STATUS_PREPARED
84
85                                 while True:
86                                         data = firmware.read(1024)
87                                         if data == '': break
88                                         os.write(device, data)
89                                 #print '[FPUpgradeCore] write data >> [ok]'
90
91                                 self.status = STATUS_PROGRAMMING
92                                 rc = fcntl.ioctl(device, 1, 0)
93                                 if rc == 0: break
94                                 if xx == 2: raise Exception, 'fail to upgrade : %d'%(rc)
95                                 self.errmsg = 'fail to upgrade, retry..'
96                                 self.status = STATUS_RETRY_UPGRADE
97                                 closefpga(firmware, device)
98                         #print '[FPUpgradeCore] upgrade done.'
99                         if self.callcount < 20: raise Exception, 'wrong fpga file.'
100                 except Exception, msg:
101                         self.errmsg = msg
102                         print '[FPUpgradeCore] ERROR >>',msg
103                         closefpga(firmware, device)
104                         return STATUS_ERROR
105                 return STATUS_DONE
106
107         def upgradeMain(self):
108                 self.status = STATUS_READY
109                 self.status = self.doUpgrade()
110                 if self.status == STATUS_DONE:
111                         print 'upgrade done.'
112                 elif self.status == STATUS_ERROR:
113                         print 'error!!'
114                 else:   print 'unknown.'
115
116 class FPGAUpgradeCore() :
117         status = STATUS_READY
118         errmsg = ''
119         callcount       = 0
120         MAX_CALL_COUNT  = 1500
121         def __init__(self, firmwarefile, devicefile):
122                 print '[FPGAUpgrade]'
123                 self.devicefile = devicefile
124                 self.firmwarefile = firmwarefile
125
126         def doUpgrade(self):
127                 firmware,device = None,None
128                 def closefpga(fp, fd):
129                         if fd is not None: os.close(fd)
130                         if fp is not None: fp.close()
131                 try:
132                         size = os.path.getsize(self.firmwarefile)
133                         if size == 0: raise Exception, 'data_size is zero'
134                         #print '[FPGAUpgradeCore] data_size :',size
135
136                         firmware = open(self.firmwarefile, 'rb')
137                         device = os.open(self.devicefile, os.O_RDWR)
138                         #print '[FPGAUpgradeCore] open >> [ok]'
139
140                         rc = fcntl.ioctl(device, 0, size)
141                         if rc < 0: raise Exception, 'fail to set size : %d'%(rc)
142                         #print '[FPGAUpgradeCore] set size >> [ok]'
143
144                         rc = fcntl.ioctl(device, 2, 5)
145                         if rc < 0: raise Exception, 'fail to set programming mode : %d'%(rc)
146                         #print '[FPGAUpgradeCore] programming mode >> [ok]'
147                         self.status = STATUS_PREPARED
148
149                         while True:
150                                 data = firmware.read(1024)
151                                 if data == '': break
152                                 os.write(device, data)
153                         #print '[FPGAUpgradeCore] write data >> [ok]'
154
155                         self.status = STATUS_PROGRAMMING
156                         rc = fcntl.ioctl(device, 1, 0)
157                         if rc < 0: raise Exception, 'fail to programming : %d'%(rc)
158                         #print '[FPGAUpgradeCore] upgrade done.'
159                         if self.callcount < 20: raise Exception, 'wrong fpga file.'
160                 except Exception, msg:
161                         self.errmsg = msg
162                         print '[FPGAUpgradeCore] ERROR >>',msg
163                         closefpga(firmware, device)
164                         return STATUS_ERROR
165                 closefpga(firmware, device)
166                 return STATUS_DONE
167
168         def upgradeMain(self):
169                 self.status = STATUS_READY
170                 self.status = self.doUpgrade()
171                 if self.status == STATUS_DONE:
172                         print '[FPGAUpgrade] upgrade done.'
173                 elif self.status == STATUS_ERROR:
174                         print '[FPGAUpgrade] occur error.'
175                 else:   print '[FPGAUpgrade] occur unknown error.'
176
177 class FirmwareUpgradeManager:
178         fu = None
179         def getInterval(self):
180                 return 200
181
182         def startUpgrade(self, datafile, device, firmware):
183                 if firmware == 'fpga':
184                         self.fu = FPGAUpgradeCore(firmwarefile=datafile, devicefile=device)
185                 elif firmware == 'fp':
186                         self.fu = FPUpgradeCore(firmwarefile=datafile, devicefile=device)
187                 thread.start_new_thread(self.fu.upgradeMain, ())
188
189         def checkError(self):
190                 if self.fu.status == STATUS_ERROR:
191                         self.fu.callcount = 0
192                         return True
193                 return False
194
195         def getStatus(self):
196                 if self.fu.status in (STATUS_READY, STATUS_ERROR):
197                         return 0
198                 elif self.fu.status == STATUS_PREPARED:
199                         return 2
200                 elif self.fu.status == STATUS_PROGRAMMING:
201                         self.fu.callcount += 1
202                         ret = (self.fu.callcount * 100) / self.fu.MAX_CALL_COUNT + 2
203                         if ret >= 100: ret = 99
204                         #print "callcount : [%d]"%(self.fu.callcount);
205                         return ret
206                 elif self.fu.status == STATUS_DONE:
207                         return 100
208
209         def getErrorMessage(self, errno, errmsg):
210                 return str(self.fu.errmsg)
211
212 class UpgradeStatus(Screen):
213         skin =  """
214                 <screen position="center,center" size="450,100" title=" ">
215                         <widget name="name" position="10,0" size="430,20" font="Regular;18" halign="left" valign="bottom"/>
216                         <widget name="slider" position="10,25" size="430,30" backgroundColor="white"/>
217                         <widget name="status" position="10,25" zPosition="1" size="430,30" font="Regular;18" halign="center" valign="center" foregroundColor="black" backgroundColor="black" transparent="1"/>
218                         <widget source="info" render="Label" position="10,70" zPosition="1" size="430,30" font="Regular;22" halign="center" valign="center" backgroundColor="#a08500" transparent="1"/>
219                 </screen>
220                 """
221
222         def __init__(self, session, parent, firmware, datafile, device):
223                 Screen.__init__(self,session)
224                 self.session = session
225
226                 self["actions"] = ActionMap(["OkCancelActions"],
227                 {
228                         "ok": self.keyExit,
229                 }, -1)
230
231                 self.firmware = firmware
232                 self.datafile = datafile
233                 #print "[FirmwareUpgrade] - [%s][%s][%s]" % (self.datafile, firmware, device)
234
235                 self["name"] = Label(_(" "))
236                 self["info"] = StaticText(_("Can't cancel during upgrade!!"))
237
238                 self["status"] = Label(_("Status : 0%"))
239
240                 self.slider = Slider(0, 100)
241                 self["slider"] = self.slider
242
243                 self.callback = None
244
245                 self.setTitle(firmware.upper() + " Upgrade Status")
246
247                 self.FU = FirmwareUpgradeManager()
248
249                 self.old_status   = 0
250                 self.status_exit  = None
251                 self.check_status = eTimer()
252                 self.check_status.callback.append(self.cbCheckStatus)
253                 self.check_status.start(self.FU.getInterval())
254
255                 self.exitTimerCallCount = 0;
256                 self.upgradeLock = True
257                 self.FU.startUpgrade(self.datafile, device, firmware)
258
259         def cbCheckStatus(self):
260                 errmsg = ""
261                 errno  = self.FU.checkError()
262                 if errno:
263                         self.check_status.stop()
264                         errmsg = self.FU.getErrorMessage(errno, errmsg)
265                         print "[FirmwareUpgrade] - ERROR : [%d][%s]" % (errno, errmsg)
266                         self.session.open(MessageBox, _(errmsg), MessageBox.TYPE_INFO, timeout = 10)
267                         self.cbConfirmExit(False)
268                         return
269                 status = self.FU.getStatus()
270                 if self.old_status > status and status != -1:
271                         self.session.open(MessageBox, _("Fail to upgrade!! Retry!!"), MessageBox.TYPE_INFO, timeout = 10)
272                 self.slider.setValue(status)
273                 self["status"].setText(_("%d / 100" % (status)))
274                 if status == 100:
275                         self.check_status.stop()
276                         self["status"].setText(_("Success. Press OK to exit."))
277                         self.status_exit = eTimer()
278                         self.status_exit.callback.append(self.cbTimerExit)
279                         self.status_exit.start(1000)
280                         self.upgradeLock = False
281                 self.old_status = status
282
283         def setCallback(self, cb):
284                 self.callback = cb
285
286         def cbTimerExit(self):
287                 if self.exitTimerCallCount < 10: # exit after 10 sec.
288                         self.exitTimerCallCount = self.exitTimerCallCount + 1
289                         self.setTitle("%s Upgrade Status (%d)" % (self.firmware.upper(), 10-self.exitTimerCallCount))
290                         return
291                 if self.status_exit is not None:
292                         self.status_exit.stop()
293                 self.keyExit()
294
295         def cbConfirmExit(self, ret):
296                 if ret:
297                         os.system("rm -f %s %s.md5" % (self.datafile, self.datafile))
298                 self.close()
299
300         def keyExit(self):
301                 if self.upgradeLock:
302                         return
303                 if self.callback is not None:
304                         self.callback("Reboot now for a successful upgrade.", True)
305                 self.session.openWithCallback(self.cbConfirmExit, MessageBox, _("Do you want to remove binary data?"), MessageBox.TYPE_YESNO, timeout = 10, default = False)
306
307 class Filebrowser(Screen):
308         skin =  """
309                 <screen position="center,center" size="500,260" title="File Browser" >
310                         <ePixmap pixmap="Vu_HD/buttons/blue.png" position="5,7" size="80,40" alphatest="blend" />
311                         <widget source="key_blue" render="Label" position="40,0" zPosition="1" size="300,40" font="Regular;20" halign="left" valign="center" transparent="1"/>
312                         <widget name="file_list" position="0,50" size="500,160" scrollbarMode="showOnDemand" />
313
314                         <widget source="status" render="Label" position="0,220" zPosition="1" size="500,40" font="Regular;18" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
315                 </screen>
316                 """
317
318         def __init__(self, session, parent, firmware):
319                 Screen.__init__(self, session)
320                 self.session = session 
321                 
322                 self["key_blue"] = StaticText(_("Download  the  firmware (latest)"))
323
324                 self["status"]    = StaticText(_(" "))
325                 self["file_list"] = FileList("/", matchingPattern = "^.*")
326
327                 self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", ],
328                 {
329                         "ok":     self.onClickOk,
330                         "cancel": self.onClickCancel,
331                         "blue":   self.onClickBlue,
332                         "up":     self.onClickUp,
333                         "down":   self.onClickDown,
334                         "left":   self.onClickLeft,
335                         "right":  self.onClickRight,
336                 }, -1) 
337
338                 self.resetGUI()
339                 self.firmware = firmware
340
341                 self.callback = None
342                 self.timer_downloading = None
343
344                 self.downloadLock = False
345                 self.setTitle(firmware.upper() + " File Browser")
346
347         def resetGUI(self):
348                 self["status"].setText("Select to press OK, Exit to press Cancel.")
349
350         def setCallback(self, func):
351                 self.callback = func
352
353         def onClickOk(self):
354                 if self.downloadLock:
355                         return
356
357                 if self["file_list"].canDescent() : # isDir
358                         self["file_list"].descent()
359                         return
360
361                 # verify data
362                 self.gbin = self["file_list"].getCurrentDirectory() + self["file_list"].getFilename()
363                 if not os.path.exists(self.gbin):
364                         self.session.open(MessageBox, _("Can't found binary file."), MessageBox.TYPE_INFO, timeout = 10)
365                         return
366                 if not os.path.exists(self.gbin+".md5"):
367                         self.session.open(MessageBox, _("Can't found MD5 file."), MessageBox.TYPE_INFO, timeout = 10)
368                         return
369                 try:
370                         def checkExt(ext):
371                                 name_ext = os.path.splitext(self["file_list"].getFilename())
372                                 return len(name_ext)==2 and ext.startswith(name_ext[1])
373                         self.check_ext = False
374                         if (self.firmware == "fp" and checkExt(".bin")) or (self.firmware == "fpga" and checkExt(".dat")):
375                                 self.check_ext = True
376                         if self.check_ext == False:
377                                 self.session.open(MessageBox, _("You chose the incorrect file."), MessageBox.TYPE_INFO)
378                                 return
379                 except:
380                         self.session.open(MessageBox, _("You chose the incorrect file."), MessageBox.TYPE_INFO)
381                         return
382
383                 if os.path.exists("/usr/bin/md5sum") == False:
384                         self.session.open(MessageBox, _("Can't find /usr/bin/md5sum"), MessageBox.TYPE_INFO, timeout = 10)
385                         return
386                 md5sum_A = os.popen("md5sum %s | awk \'{print $1}\'"%(self.gbin)).readline().strip()
387                 md5sum_B = os.popen("cat %s.md5 | awk \'{print $1}\'"%(self.gbin)).readline().strip()
388                 #print "[FirmwareUpgrade] - Verify : file[%s], md5[%s]"%(md5sum_A,md5sum_B)
389
390                 if md5sum_A != md5sum_B:
391                         self.session.open(MessageBox, _("Fail to verify data file. \nfile[%s]\nmd5[%s]"%(md5sum_A,md5sum_B)), MessageBox.TYPE_INFO, timeout = 10)
392                         return 
393
394                 if self.callback is not None:
395                         self.callback(_(self.gbin))
396                 self.close()
397
398         def onClickCancel(self):
399                 self.close()
400
401         # uri : source file url(string)
402         # tf  : target file name(string)
403         # bd  : target base directory(string)
404         # cbfunc(string) : callback function(function)
405         def doDownload(self, uri, tf, bd='/tmp', cbfunc=None, errmsg="Fail to download."):
406                 tar = bd + "/" + tf
407                 #print "[FirmwareUpgrade] - Download Info : [%s][%s]" % (uri, tar)
408                 def doHook(blockNumber, blockSize, totalSize) :
409                         if blockNumber*blockSize > totalSize and cbfunc is not None:
410                                 cbfunc(tar)
411                 opener = urllib.URLopener()
412                 try:
413                         opener.open(uri)
414                 except:
415                         #self.session.open(MessageBox, _("File not found in this URL:\n%s"%(uri)), MessageBox.TYPE_INFO, timeout = 10)
416                         print "[FirmwareUpgrade] - Fail to download. URL :",uri
417                         self.session.open(MessageBox, _(errmsg), MessageBox.TYPE_INFO, timeout = 10)
418                         del opener
419                         return False
420                 try :
421                         f, h = urlretrieve(uri, tar, doHook)
422                 except IOError, msg:
423                         #self.session.open(MessageBox, _(str(msg)), MessageBox.TYPE_INFO, timeout = 10)
424                         print "[FirmwareUpgrade] - Fail to download. ERR_MSG :",str(msg)
425                         self.session.open(MessageBox, _(errmsg), MessageBox.TYPE_INFO, timeout = 10)
426                         del opener
427                         return False
428                 del opener
429                 return True
430
431         def runDownloading(self) :
432                 self.timer_downloading.stop()
433                 machine = str(open("/proc/stb/info/vumodel").read().strip())
434
435                 def cbDownloadDone(tar):
436                         try:
437                                 if os.path.splitext(tar)[1] != ".files":
438                                         self["status"].setText("Downloaded : %s\nSelect to press OK, Exit to press Cancel."%(tar))
439                         except:
440                                 pass
441                 # target
442                 global fwdata
443                 root_uri  = fwdata[self.firmware][0]
444                 root_file = fwdata[self.firmware][1]
445                 if not self.doDownload("%s/%s"%(root_uri, root_file), root_file, cbfunc=cbDownloadDone):
446                         self.resetGUI()
447                         self.downloadLock = False
448                         return
449
450                 target_path = ""
451                 for l in file("/tmp/"+root_file).readlines():
452                         if l.startswith(machine):
453                                 try:
454                                         target_path = l.split("=")[1].strip()
455                                 except:
456                                         target_path = ""
457                                         pass
458                 if target_path == "":
459                         self.session.open(MessageBox, _("Firmware does not exist."), MessageBox.TYPE_INFO)
460                         self.resetGUI()
461                         self.downloadLock = False
462                         return
463
464                 self.guri = "%s/vu%s/%s"%(root_uri, machine, target_path)
465                 self.gbin = os.path.basename(target_path)
466                 #print "[FirmwareUpgrade] - uri[%s], data[%s], data_path[%s]" % (self.gbin, self.guri, target_path)
467                 os.system("rm -f /tmp/" + root_file)
468
469                 # md5
470                 if not self.doDownload(self.guri+".md5", self.gbin+".md5", cbfunc=cbDownloadDone, errmsg="Can't download the checksum file."):
471                         self.resetGUI()
472                         self.downloadLock = False
473                         return
474                 # data
475                 if not self.doDownload(self.guri, self.gbin, cbfunc=cbDownloadDone, errmsg="Can't download the firmware file."):
476                         self.resetGUI()
477                         self.downloadLock = False
478                         return
479
480                 t = ''
481                 self["file_list"].changeDir("/tmp/")
482                 self["file_list"].moveToIndex(0)
483                 while cmp(self["file_list"].getFilename(), self.gbin) != 0 :
484                         self["file_list"].down()
485                         if cmp(t, self["file_list"].getFilename()) == 0:
486                                 break
487                         t = self["file_list"].getFilename()
488
489                 del self.timer_downloading
490                 self.timer_downloading = None
491                 self.downloadLock = False
492
493         def onClickBlue(self):
494                 if self.downloadLock:
495                         return
496                 self.downloadLock = True
497                 if not os.path.exists("/proc/stb/info/vumodel"):
498                         self.session.open(MessageBox, _("Can't found model name."), MessageBox.TYPE_INFO, timeout = 10)
499                         self.downloadLock = False
500                         return
501                 self["status"].setText("Please wait during download.")
502                 self.timer_downloading = eTimer()
503                 self.timer_downloading.callback.append(self.runDownloading)
504                 self.timer_downloading.start(1000)
505
506         def onClickUp(self):
507                 if self.downloadLock:
508                         return
509                 self.resetGUI()
510                 self["file_list"].up()
511
512         def onClickDown(self):
513                 if self.downloadLock:
514                         return
515                 self.resetGUI()
516                 self["file_list"].down()
517
518         def onClickLeft(self):
519                 if self.downloadLock:
520                         return
521                 self.resetGUI()
522                 self["file_list"].pageUp()
523
524         def onClickRight(self):
525                 if self.downloadLock:
526                         return
527                 self.resetGUI()
528                 self["file_list"].pageDown()
529
530         def keyNone(self):
531                 None
532
533 class FirmwareUpgrade(Screen, ConfigListScreen):
534         skin =  """
535                 <screen position="center,center" size="560,175" title="Firmware Upgrade" >
536                         <ePixmap pixmap="Vu_HD/buttons/red.png" position="125,7" size="80,40" alphatest="blend" />
537                         <ePixmap pixmap="Vu_HD/buttons/green.png" position="330,7" size="80,40" alphatest="blend" />
538
539                         <widget source="key_red" render="Label" position="160,0" zPosition="1" size="155,40" font="Regular;20" halign="left" valign="center" transparent="1" />
540                         <widget source="key_green" render="Label" position="365,0" zPosition="1" size="155,40" font="Regular;20" halign="left" valign="center" transparent="1" />
541
542                         <widget name="config" zPosition="2" position="0,50" itemHeight="36" size="540,40" scrollbarMode="showOnDemand" transparent="1" />
543                         <widget source="status" render="Label" position="0,100" zPosition="1" size="540,75" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
544                 </screen>
545                 """
546
547         def __init__(self, session): 
548                 Screen.__init__(self, session)
549                 self.session = session 
550
551                 self["shortcuts"] = ActionMap(["ShortcutActions", "SetupActions" ],
552                 {
553                         "ok":      self.keyGreen,
554                         "cancel":  self.keyRed,
555                         "red":     self.keyRed,
556                         "green":   self.keyGreen,
557                         "blue":    self.keyBlue,
558                 }, -2)
559
560                 self.list = []
561                 self.updateFilePath = ""
562
563                 self.finishedExit = False
564
565                 self.rebootLock = False
566                 self.rebootMessage = ""
567                 self.cbRebootCallCount = 0;
568
569                 ConfigListScreen.__init__(self, self.list, session=self.session)
570                 self["key_red"] = StaticText(_("Close"))
571
572                 self.logmode = None
573                 self.old_blue_clicked = 0
574                 self.fileopenmode = False
575                 self.upgrade_auto_run_timer = eTimer()
576                 self.upgrade_auto_run_timer.callback.append(self.keyGreen)
577
578                 global fwlist
579                 if fwlist is None:
580                         self["key_green"] = StaticText(_(" "))
581                         self["status"] = StaticText(_("This plugin is supported only the Ultimo/Uno."))
582                 else:
583                         self["key_green"] = StaticText(_("Upgrade"))
584                         self["status"] = StaticText(_(" "))
585                         self.setupUI()
586
587         def setupUI(self):
588                 global fwlist
589                 self.list = []
590                 self._item_firmware  = ConfigSelection(default=fwlist[0][0],  choices=fwlist)
591                 self._entry_firmware = getConfigListEntry(_("Firmware"), self._item_firmware)
592                 self.list.append(self._entry_firmware)
593                 self["config"].list = self.list
594                 self["config"].l.setList(self.list)
595                 self.setupStatus()
596
597         def setupStatus(self,message=None,reboot=False):
598                 self.updateFilePath = ""
599                 if message is not None:
600                         self.rebootLock = reboot
601                         self["status"].setText(message)
602                         if reboot:
603                                 self.rebootMessage = message
604                                 self.reboot_timer = eTimer()
605                                 self.reboot_timer.callback.append(self.cbReboot)
606                                 self.reboot_timer.start(1000)
607                         return
608                 if not self.rebootLock:
609                         self["status"].setText("Press the Green/OK button")
610
611         def doReboot(self):
612                 from Screens.Standby import TryQuitMainloop
613                 self.session.open(TryQuitMainloop, 2)
614
615         def cbReboot(self):
616                 max_call_count = 20
617                 self.finishedExit = True
618                 if self.cbRebootCallCount < max_call_count:
619                         self.cbRebootCallCount = self.cbRebootCallCount + 1
620                         #self["status"].setText("%s (%d)"%(self.rebootMessage, max_call_count-self.cbRebootCallCount))
621                         self["status"].setText("Reboot after %d seconds. Press the OK to reboot now."%(max_call_count-self.cbRebootCallCount))
622                         return
623                 self.doReboot()
624
625         # filebrowser window callback function
626         def cbSetStatus(self, data=None):
627                 if data is not None:
628                         self["status"].setText("Press the Green/OK button, if you want to upgrade to this file:\n%s\n" % (data))
629                         self.updateFilePath = data
630                         if self.fileopenmode == False:
631                                 self.upgrade_auto_run_timer.start(1000)
632
633         # upgrade window callback function
634         def cbFinishedUpgrade(self,message=None,reboot=False):
635                 self.setupStatus(message=message,reboot=reboot)
636
637         def cbRunUpgrade(self, ret):
638                 if ret == False:
639                         return
640
641                 if self.updateFilePath == "":
642                         self.session.open(MessageBox, _("No selected binary data!!"), MessageBox.TYPE_INFO, timeout = 10)
643                         return
644                 device = None
645                 for d in fwdata[self._item_firmware.value][2].split(';'):
646                         if os.path.exists(d):
647                                 device = d                      
648                 if device is None:
649                         self.session.open(MessageBox, _("Can't found device file!!"), MessageBox.TYPE_INFO, timeout = 10)
650                         return
651                 fbs = self.session.open(UpgradeStatus, self, self._item_firmware.value, self.updateFilePath, device)
652                 fbs.setCallback(self.cbFinishedUpgrade)
653         
654         def doFileOpen(self):
655                 fbs = self.session.open(Filebrowser, self, self._item_firmware.value)
656                 fbs.setCallback(self.cbSetStatus)
657
658         def keyLeft(self):
659                 if self.rebootLock:
660                         return
661                 global fwlist
662                 if fwlist is None:
663                         return
664                 ConfigListScreen.keyLeft(self)
665                 self.setupStatus()
666
667         def keyRight(self):
668                 global fwlist
669                 if fwlist is None:
670                         return
671                 ConfigListScreen.keyRight(self)
672                 self.setupStatus()
673
674         def keyGreen(self):
675                 if self.finishedExit:
676                         self.doReboot()
677                         return
678                 self.upgrade_auto_run_timer.stop()
679                 if self.rebootLock:
680                         return
681                 global fwlist
682                 if fwlist is None:
683                         return
684                 if self.updateFilePath == "":
685                         #self.session.open(MessageBox, _("No selected binary data!!"), MessageBox.TYPE_INFO)
686                         self.doFileOpen()
687                         return
688                 msg = "You should not be stop during the upgrade.\nDo you want to upgrade?"
689                 self.session.openWithCallback(self.cbRunUpgrade, MessageBox, _(msg), MessageBox.TYPE_YESNO, timeout = 15, default = True)
690                 self.fileopenmode = False
691
692         def keyYellow(self):
693                 if self.rebootLock:
694                         return
695                 global fwlist
696                 if fwlist is None:
697                         return
698                 self.fileopenmode = True
699                 self.doFileOpen()
700
701         def keyRed(self):
702                 if self.rebootLock:
703                         return
704                 self.close()
705
706         def cbLogMode(self):
707                 if self.old_blue_clicked:
708                         return
709                 self.logmode.stop()
710                 if os.path.exists("/tmp/onlogmode"):
711                         return
712                 os.system("touch /tmp/onlogmode")
713
714         def keyBlue(self):
715                 if self.rebootLock:
716                         return
717                 if self.logmode is not None and self.old_blue_clicked == 0:
718                         return
719                 if self.old_blue_clicked:
720                         self.old_blue_clicked = 0
721                         return
722                 self.old_blue_clicked = 1
723                 self.logmode = eTimer()
724                 self.logmode.callback.append(self.cbLogMode)
725                 self.logmode.start(1000)
726                 
727         def keyNone(self):
728                 None
729
730 def main(session, **kwargs):
731         session.open(FirmwareUpgrade)
732                                                            
733 def Plugins(**kwargs):            
734         return PluginDescriptor(name=_("Firmware Upgrade"), description="Upgrade Firmware..", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main)
735