1 import os, fcntl, thread
3 from enigma import eTimer
5 from urllib import urlretrieve
8 from Screens.Screen import Screen
9 from Screens.MessageBox import MessageBox
11 from Plugins.Plugin import PluginDescriptor
13 from Tools.Directories import fileExists
15 from Components.Label import Label
16 from Components.Slider import Slider
17 from Components.Pixmap import Pixmap
18 from Components.FileList import FileList
19 from Components.ActionMap import ActionMap
20 from Components.PluginComponent import plugins
21 from Components.Sources.StaticText import StaticText
27 STATUS_PROGRAMMING = 4
29 class FPGAUpgradeCore() :
34 def __init__(self, firmwarefile, devicefile):
36 self.devicefile = devicefile
37 self.firmwarefile = firmwarefile
40 firmware,device = None,None
41 def closefpga(fp, fd):
42 if fd is not None: os.close(fd)
43 if fp is not None: fp.close()
45 size = os.path.getsize(self.firmwarefile)
46 if size == 0: raise Exception, 'data_size is zero'
47 #print '[FPGAUpgradeCore] data_size :',size
49 firmware = open(self.firmwarefile, 'rb')
50 device = os.open(self.devicefile, os.O_RDWR)
51 #print '[FPGAUpgradeCore] open >> [ok]'
53 rc = fcntl.ioctl(device, 0, size)
54 if rc < 0: raise Exception, 'fail to set size : %d'%(rc)
55 #print '[FPGAUpgradeCore] set size >> [ok]'
57 rc = fcntl.ioctl(device, 2, 5)
58 if rc < 0: raise Exception, 'fail to set programming mode : %d'%(rc)
59 #print '[FPGAUpgradeCore] programming mode >> [ok]'
60 self.status = STATUS_PREPARED
63 data = firmware.read(1024)
65 os.write(device, data)
66 #print '[FPGAUpgradeCore] write data >> [ok]'
68 self.status = STATUS_PROGRAMMING
69 rc = fcntl.ioctl(device, 1, 0)
70 if rc < 0: raise Exception, 'fail to programming : %d'%(rc)
71 #print '[FPGAUpgradeCore] upgrade done.'
72 if self.callcount < 100: raise Exception, 'wrong fpga file.'
73 except Exception, msg:
75 print '[FPGAUpgradeCore] ERROR >>',msg
76 closefpga(firmware, device)
78 closefpga(firmware, device)
81 def upgradeMain(self):
82 self.status = STATUS_READY
83 self.status = self.doUpgrade()
84 if self.status == STATUS_DONE:
85 print '[FPGAUpgrade] upgrade done.'
86 elif self.status == STATUS_ERROR:
87 print '[FPGAUpgrade] occur error.'
88 else: print '[FPGAUpgrade] occur unknown error.'
90 class FPGAUpgradeManager:
92 def get_interval(self):
95 def fpga_upgrade(self, datafile, device):
96 self.fu = FPGAUpgradeCore(firmwarefile=datafile, devicefile=device)
97 thread.start_new_thread(self.fu.upgradeMain, ())
100 if self.fu.status == STATUS_ERROR:
101 self.fu.callcount = 0
105 def get_status(self):
106 if self.fu.status == STATUS_READY:
108 elif self.fu.status == STATUS_ERROR:
110 elif self.fu.status == STATUS_PREPARED:
112 elif self.fu.status == STATUS_PROGRAMMING:
113 self.fu.callcount += 1
114 ret = (self.fu.callcount * 100) / self.fu.MAX_CALL_COUNT + 2
115 if ret >= 100: ret = 99
116 #print "callcount : [%d]"%(self.fu.callcount);
118 elif self.fu.status == STATUS_DONE:
121 def get_error_msg(self, errno, errmsg):
122 return str(self.fu.errmsg)
124 class UpgradeStatus(Screen):
126 <screen position="center,center" size="450,130" title="FPGA Upgrade">
127 <widget name="name" position="10,0" size="430,20" font="Regular;18" halign="left" valign="bottom"/>
128 <widget name="slider" position="10,25" size="430,30" backgroundColor="white"/>
129 <widget name="status" position="10,25" zPosition="1" size="430,30" font="Regular;18" halign="center" valign="center" foregroundColor="black" backgroundColor="black" transparent="1"/>
130 <widget source="info" render="Label" position="10,70" zPosition="1" size="430,60" font="Regular;22" halign="center" valign="center" backgroundColor="#a08500" transparent="1"/>
133 def __init__(self, session, parent, timeout = 20):
134 Screen.__init__(self,session)
135 self.session = session
137 self["actions"] = ActionMap(["OkCancelActions"],
145 self.title_str = "FPGA Upgrade"
147 #self["name"] = Label(_("Upgrade status"))
148 self["name"] = Label(_(" "))
149 self["info"] = StaticText(_("Can't cancel during upgrade!!"))
151 self["status"] = Label(_("Status : 0%"))
152 self.status_bar = self["status"]
154 self.slider = Slider(0, 100)
155 self["slider"] = self.slider
158 self.timer_check_progress = eTimer()
159 self.timer_check_progress.callback.append(self.callbackDoCheckProgress)
160 interval = self.parent.FPGA.get_interval()
161 self.timer_check_progress.start(interval)
162 self.need_restart = False
164 def callbackDoCheckProgress(self):
165 self.status = self.parent.FPGA.get_status()
168 self.slider.setValue(self.status)
170 if self.status == 100:
171 #print "fpga-upgrade done!!"
172 self.status_bar.setText(_("Succeed"))
173 #self.status_bar.setText(_("%d / 100" % (self.status)))
174 self.timer_check_progress.stop()
176 self.timer_exit = eTimer()
177 self.timer_exit.callback.append(self.callbackExit)
178 self.timer_exit.start(1000)
180 elif self.status < 0:#elif self.status == -1 or self.status == -2:
181 #print "fpga-upgrade error >> errno : [%d]" % (self.status)
183 ERROR_CODE = int(self.status) * -1
184 ERROR_MSG = self.parent.FPGA.get_error_msg(ERROR_CODE, ERROR_MSG)
185 self.status_bar.setText("Fail to update!!")
186 self["info"].setText(_("Error[%d] : %s.\nPress OK to exit." % (self.status, ERROR_MSG)))
187 self.timer_check_progress.stop()
191 #print "fpga-upgrade status : %d" % self.status
192 self.status_bar.setText(_("%d / 100" % (self.status)))
194 def callbackExit(self):
195 self.need_restart = True
196 if self.exit_count == self.timeout:
197 self.timer_exit.stop()
199 self.exit_count = self.exit_count + 1
200 #self.instance.setTitle("%s (%d)" % (self.title_str, (self.timeout-self.exit_count)))
201 self["info"].setText("Reboot after %d seconds.\nPress the OK to reboot now." %(self.timeout-self.exit_count))
204 if self.need_restart:
205 from Screens.Standby import TryQuitMainloop
206 self.session.open(TryQuitMainloop, 2)
210 class FPGAUpgrade(Screen):
212 <screen position="center,center" size="560,440" title="FPGA Upgrade" >
213 <ePixmap pixmap="Vu_HD/buttons/red.png" position="0,7" size="80,40" alphatest="blend" />
214 <ePixmap pixmap="Vu_HD/buttons/green.png" position="186,7" size="80,40" alphatest="blend" />
215 <ePixmap pixmap="Vu_HD/buttons/blue.png" position="372,7" size="80,40" alphatest="blend" />
217 <widget source="key_red" render="Label" position="28,0" zPosition="1" size="160,40" font="Regular;20" halign="center" valign="center" transparent="1"/>
218 <widget source="key_green" render="Label" position="213,0" zPosition="1" size="160,40" font="Regular;20" halign="center" valign="center" transparent="1"/>
219 <widget source="key_blue" render="Label" position="400,0" zPosition="1" size="160,40" font="Regular;20" halign="center" valign="center" transparent="1"/>
221 <widget source="status" render="Label" position="15,45" zPosition="1" size="540,40" font="Regular;18" halign="left" valign="center" backgroundColor="#a08500" transparent="1" />
222 <widget name="file_list" position="0,100" size="555,325" scrollbarMode="showOnDemand" />
226 def __init__(self, session):
227 Screen.__init__(self, session)
228 self.session = session
230 self["key_red"] = StaticText(_("Close"))
231 self["key_green"] = StaticText(_("Upgrade"))
232 self["key_blue"] = StaticText(_("Download"))
234 self["status"] = StaticText(_(" "))
235 self["file_list"] = FileList("/", matchingPattern = "^.*")
237 self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", ],
239 "red": self.onClickRed,
240 "green": self.onClickGreen,
241 "blue": self.onClickBlue,
242 "back": self.onClickRed,
243 "ok": self.onClickOk,
244 "up": self.onClickUp,
245 "down": self.onClickDown,
246 "left": self.onClickLeft,
247 "right": self.onClickRight,
249 self.onLayoutFinish.append(self.doLayoutFinish)
253 self.SOURCELIST = self["file_list"]
254 self.STATUS_BAR = self["status"]
255 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
257 self.DEVICE_LIST = '/dev/fpga_dp;/dev/misc/dp;'
258 self.DOWNLOAD_TAR_PATH = '/tmp/'
259 self.DOWNLOAD_FILE_NAME = 'TS_PRO.dat'
260 self.DOWNLOAD_URL = ''
262 self.FPGA = FPGAUpgradeManager()
263 print self.DEVICE_LIST
264 print self.DOWNLOAD_TAR_PATH
265 print self.DOWNLOAD_FILE_NAME
266 print self.DOWNLOAD_URL
268 def doLayoutFinish(self):
272 if fileExists(self.DOWNLOAD_TAR_PATH + self.DOWNLOAD_FILE_NAME):
273 os.remove(self.DOWNLOAD_TAR_PATH + self.DOWNLOAD_FILE_NAME)
276 def doLoadConf(self):
277 if fileExists("/proc/stb/info/vumodel"):
278 model = open("/proc/stb/info/vumodel").read().strip()
279 download_uri_header = open('/usr/lib/enigma2/python/Plugins/SystemPlugins/FPGAUpgrade/fpga.conf').readline().strip()
280 self.DOWNLOAD_URL = str(download_uri_header) + "vu" + str(model) + "/" + self.DOWNLOAD_FILE_NAME
282 def doHook(self, blockNumber, blockSize, totalSize) :
283 if blockNumber*blockSize > totalSize :
284 self.STATUS_BAR.setText(_("Downloaded " + self.DOWNLOAD_TAR_PATH + self.DOWNLOAD_FILE_NAME))
286 self.STATUS_BAR.setText(_("Downloading..."))
288 def onCallbackHandler(self, confirmed):
292 def doUpgradeHandler(self, confirmed):
293 if confirmed == False:
298 path = self.SOURCELIST.getCurrentDirectory() + self.SOURCELIST.getFilename()
300 #self.session.open(MessageBox, _("Can't select directory."), MessageBox.TYPE_INFO, timeout = 5)
304 device_list = self.DEVICE_LIST.split(";")
306 for d in device_list:
307 if os.path.exists(d):
311 if device == None or len(device) == 0:
312 message = "Fail to upgrade.\nCause : Can't found device.\nDo you want to exit?"
313 self.session.openWithCallback(self.onCallbackHandler, MessageBox, _(message), MessageBox.TYPE_YESNO, timeout = 10, default = True)
314 print "DEVICE_LIST : ", device_list
316 print "DEVICE : ", device
317 self.ERROR_CODE = self.FPGA.fpga_upgrade(path, device)
318 if self.ERROR_CODE > 0:
319 self.ERROR_MSG = self.FPGA.get_error_msg(self.ERROR_CODE, self.ERROR_MSG)
320 message = "Fail to upgrade.\nCause : " + self.ERROR_MSG + "\nDo you want to exit?"
321 self.session.openWithCallback(self.onCallbackHandler, MessageBox, _(message), MessageBox.TYPE_YESNO, timeout = 10, default = True)
322 print "DEVICE : ", device
323 print "FILE : ", path
325 #self.session.open(MessageBox, _("Success!!"), MessageBox.TYPE_INFO, timeout = 5)
326 self.session.open(UpgradeStatus, self, timeout = 20)
328 def onClickRed(self):
332 def onClickGreen(self):
333 #self.session.open(MessageBox, _("Upgrade will take about 5 minutes to finish."), MessageBox.TYPE_INFO, timeout = 10)
334 message = "Upgrade will take about 5 minutes to finish.\nDo you want to upgrade?"
335 self.session.openWithCallback(self.doUpgradeHandler, MessageBox, _(message), MessageBox.TYPE_YESNO, timeout = 10, default = True)
337 def onClickBlue(self):
340 test_opener = urllib.URLopener()
342 test_opener.open(self.DOWNLOAD_URL)
344 self.session.open(MessageBox, _('File not found'), MessageBox.TYPE_INFO, timeout = 5)
348 fname, header = urlretrieve(self.DOWNLOAD_URL, self.DOWNLOAD_TAR_PATH + self.DOWNLOAD_FILE_NAME, self.doHook)
350 self.session.open(MessageBox, _(str(msg)), MessageBox.TYPE_INFO, timeout = 5)
356 self.SOURCELIST.changeDir(self.DOWNLOAD_TAR_PATH)
357 self.SOURCELIST.moveToIndex(0)
358 while cmp(self.SOURCELIST.getFilename(), self.DOWNLOAD_FILE_NAME) != 0 :
359 self.SOURCELIST.down()
360 if cmp(before_name, self.SOURCELIST.getFilename()) == 0:
362 before_name = self.SOURCELIST.getFilename()
365 if self.SOURCELIST.canDescent() : # isDir
366 self.SOURCELIST.descent()
367 if self.SOURCELIST.getCurrentDirectory():
368 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
374 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
376 def onClickDown(self):
377 self.SOURCELIST.down()
378 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
380 def onClickLeft(self):
381 self.SOURCELIST.pageUp()
382 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
384 def onClickRight(self):
385 self.SOURCELIST.pageDown()
386 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
388 def main(session, **kwargs):
389 session.open(FPGAUpgrade)
391 def Plugins(**kwargs):
392 return PluginDescriptor(name=_("FPGA Upgrade"), description="Upgrade FPGA..", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main)