1 import os, fcntl, thread
3 from enigma import eTimer, getDesktop
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=" ">
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" borderWidth="2" borderColor="#cccccc"/>
129 <widget name="status" position="10,25" zPosition="1" size="430,30" font="Regular;18" halign="center" valign="center" foregroundColor="#9f1313" transparent="1"/>
130 <widget source="info" render="Label" position="10,70" zPosition="1" size="430,60" font="Regular;22" halign="center" valign="center" transparent="1"/>
134 def __init__(self, session, parent, timeout = 20):
135 Screen.__init__(self,session)
136 self.session = session
138 self["actions"] = ActionMap(["OkCancelActions"],
146 self.title_str = "FPGA Upgrade"
148 #self["name"] = Label(_("Upgrade status"))
149 self["name"] = Label(_(" "))
150 self["info"] = StaticText(_("Can't cancel during upgrade!!"))
152 self["status"] = Label(_("Status : 0%"))
153 self.status_bar = self["status"]
155 self.slider = Slider(0, 100)
156 self["slider"] = self.slider
158 self.setTitle("FPGA Upgrade Status")
161 self.timer_check_progress = eTimer()
162 self.timer_check_progress.callback.append(self.callbackDoCheckProgress)
163 interval = self.parent.FPGA.get_interval()
164 self.timer_check_progress.start(interval)
165 self.need_restart = False
167 def callbackDoCheckProgress(self):
168 self.status = self.parent.FPGA.get_status()
171 self.slider.setValue(self.status)
173 if self.status == 100:
174 #print "fpga-upgrade done!!"
175 self.status_bar.setText(_("Succeed"))
176 #self.status_bar.setText(_("%d / 100" % (self.status)))
177 self.timer_check_progress.stop()
179 self.timer_exit = eTimer()
180 self.timer_exit.callback.append(self.callbackExit)
181 self.timer_exit.start(1000)
183 elif self.status < 0:#elif self.status == -1 or self.status == -2:
184 #print "fpga-upgrade error >> errno : [%d]" % (self.status)
186 ERROR_CODE = int(self.status) * -1
187 ERROR_MSG = self.parent.FPGA.get_error_msg(ERROR_CODE, ERROR_MSG)
188 self.status_bar.setText("Fail to update!!")
189 self["info"].setText(_("Error[%d] : %s.\nPress OK to exit." % (self.status, ERROR_MSG)))
190 self.timer_check_progress.stop()
194 #print "fpga-upgrade status : %d" % self.status
195 self.status_bar.setText(_("%d / 100" % (self.status)))
197 def callbackExit(self):
198 self.need_restart = True
199 if self.exit_count == self.timeout:
200 self.timer_exit.stop()
202 self.exit_count = self.exit_count + 1
203 #self.instance.setTitle("%s (%d)" % (self.title_str, (self.timeout-self.exit_count)))
204 self["info"].setText("Reboot after %d seconds.\nPress the OK to reboot now." %(self.timeout-self.exit_count))
207 if self.need_restart:
208 from Screens.Standby import TryQuitMainloop
209 self.session.open(TryQuitMainloop, 2)
213 class FPGAUpgrade(Screen):
215 <screen position="center,center" size="560,430" title="FPGA Upgrade" >
216 <ePixmap pixmap="skin_default/buttons/red.png" position="40,10" size="140,40" alphatest="blend" />
217 <ePixmap pixmap="skin_default/buttons/green.png" position="210,10" size="140,40" alphatest="blend" />
218 <ePixmap pixmap="skin_default/buttons/blue.png" position="380,10" size="140,40" alphatest="blend" />
220 <widget source="key_red" render="Label" position="40,10" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1"/>
221 <widget source="key_green" render="Label" position="210,10" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1"/>
222 <widget source="key_blue" render="Label" position="380,10" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" foregroundColor="#ffffff" transparent="1"/>
224 <widget source="status" render="Label" position="15,60" zPosition="1" size="540,40" font="Regular;18" halign="left" valign="center" transparent="1" />
225 <widget name="file_list" position="0,100" size="555,320" scrollbarMode="showOnDemand" />
229 def __init__(self, session):
230 Screen.__init__(self, session)
231 self.session = session
233 self["key_red"] = StaticText(_("Close"))
234 self["key_green"] = StaticText(_("Upgrade"))
235 self["key_blue"] = StaticText(_("Download"))
237 self["status"] = StaticText(_(" "))
238 self["file_list"] = FileList("/", matchingPattern = "^.*")
240 self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", ],
242 "red": self.onClickRed,
243 "green": self.onClickGreen,
244 "blue": self.onClickBlue,
245 "back": self.onClickRed,
246 "ok": self.onClickOk,
247 "up": self.onClickUp,
248 "down": self.onClickDown,
249 "left": self.onClickLeft,
250 "right": self.onClickRight,
252 self.onLayoutFinish.append(self.doLayoutFinish)
256 self.SOURCELIST = self["file_list"]
257 self.STATUS_BAR = self["status"]
258 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
260 self.DEVICE_LIST = '/dev/fpga_dp;/dev/misc/dp;'
261 self.DOWNLOAD_TAR_PATH = '/tmp/'
262 self.DOWNLOAD_FILE_NAME = 'TS_PRO.dat'
263 self.DOWNLOAD_URL = ''
265 self.FPGA = FPGAUpgradeManager()
266 print self.DEVICE_LIST
267 print self.DOWNLOAD_TAR_PATH
268 print self.DOWNLOAD_FILE_NAME
269 print self.DOWNLOAD_URL
271 def doLayoutFinish(self):
275 if fileExists(self.DOWNLOAD_TAR_PATH + self.DOWNLOAD_FILE_NAME):
276 os.remove(self.DOWNLOAD_TAR_PATH + self.DOWNLOAD_FILE_NAME)
279 def doLoadConf(self):
280 if fileExists("/proc/stb/info/vumodel"):
281 model = open("/proc/stb/info/vumodel").read().strip()
282 download_uri_header = open('/usr/lib/enigma2/python/Plugins/SystemPlugins/FPGAUpgrade/fpga.conf').readline().strip()
283 self.DOWNLOAD_URL = str(download_uri_header) + "vu" + str(model) + "/" + self.DOWNLOAD_FILE_NAME
285 def doHook(self, blockNumber, blockSize, totalSize) :
286 if blockNumber*blockSize > totalSize :
287 self.STATUS_BAR.setText(_("Downloaded " + self.DOWNLOAD_TAR_PATH + self.DOWNLOAD_FILE_NAME))
289 self.STATUS_BAR.setText(_("Downloading..."))
291 def onCallbackHandler(self, confirmed):
295 def doUpgradeHandler(self, confirmed):
296 if confirmed == False:
301 path = self.SOURCELIST.getCurrentDirectory() + self.SOURCELIST.getFilename()
303 #self.session.open(MessageBox, _("Can't select directory."), MessageBox.TYPE_INFO, timeout = 5)
307 device_list = self.DEVICE_LIST.split(";")
309 for d in device_list:
310 if os.path.exists(d):
314 if device == None or len(device) == 0:
315 message = "Fail to upgrade.\nCause : Can't found device.\nDo you want to exit?"
316 self.session.openWithCallback(self.onCallbackHandler, MessageBox, _(message), MessageBox.TYPE_YESNO, timeout = 10, default = True)
317 print "DEVICE_LIST : ", device_list
319 print "DEVICE : ", device
320 self.ERROR_CODE = self.FPGA.fpga_upgrade(path, device)
321 if self.ERROR_CODE > 0:
322 self.ERROR_MSG = self.FPGA.get_error_msg(self.ERROR_CODE, self.ERROR_MSG)
323 message = "Fail to upgrade.\nCause : " + self.ERROR_MSG + "\nDo you want to exit?"
324 self.session.openWithCallback(self.onCallbackHandler, MessageBox, _(message), MessageBox.TYPE_YESNO, timeout = 10, default = True)
325 print "DEVICE : ", device
326 print "FILE : ", path
328 #self.session.open(MessageBox, _("Success!!"), MessageBox.TYPE_INFO, timeout = 5)
329 self.session.open(UpgradeStatus, self, timeout = 20)
331 def onClickRed(self):
335 def onClickGreen(self):
336 #self.session.open(MessageBox, _("Upgrade will take about 5 minutes to finish."), MessageBox.TYPE_INFO, timeout = 10)
337 message = "Upgrade will take about 5 minutes to finish.\nDo you want to upgrade?"
338 self.session.openWithCallback(self.doUpgradeHandler, MessageBox, _(message), MessageBox.TYPE_YESNO, timeout = 10, default = True)
340 def onClickBlue(self):
343 test_opener = urllib.URLopener()
345 test_opener.open(self.DOWNLOAD_URL)
347 self.session.open(MessageBox, _('File not found'), MessageBox.TYPE_INFO, timeout = 5)
351 fname, header = urlretrieve(self.DOWNLOAD_URL, self.DOWNLOAD_TAR_PATH + self.DOWNLOAD_FILE_NAME, self.doHook)
353 self.session.open(MessageBox, _(str(msg)), MessageBox.TYPE_INFO, timeout = 5)
359 self.SOURCELIST.changeDir(self.DOWNLOAD_TAR_PATH)
360 self.SOURCELIST.moveToIndex(0)
361 while cmp(self.SOURCELIST.getFilename(), self.DOWNLOAD_FILE_NAME) != 0 :
362 self.SOURCELIST.down()
363 if cmp(before_name, self.SOURCELIST.getFilename()) == 0:
365 before_name = self.SOURCELIST.getFilename()
368 if self.SOURCELIST.canDescent() : # isDir
369 self.SOURCELIST.descent()
370 if self.SOURCELIST.getCurrentDirectory():
371 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
377 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
379 def onClickDown(self):
380 self.SOURCELIST.down()
381 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
383 def onClickLeft(self):
384 self.SOURCELIST.pageUp()
385 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
387 def onClickRight(self):
388 self.SOURCELIST.pageDown()
389 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
391 def main(session, **kwargs):
392 session.open(FPGAUpgrade)
394 def Plugins(**kwargs):
395 return PluginDescriptor(name=_("FPGA Upgrade"), description="Upgrade FPGA..", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main)