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):
125 size = getDesktop(0).size()
126 position_params = size.width() > 750 and (' ') or ('backgroundColor=\"blue\"')
128 <screen position="center,center" size="450,130" title="FPGA Upgrade">
129 <widget name="name" position="10,0" size="430,20" font="Regular;18" halign="left" valign="bottom"/>
130 <widget name="slider" position="10,25" size="430,30" borderWidth="2" borderColor="#cccccc"/>
131 <widget name="status" position="10,25" zPosition="1" size="430,30" font="Regular;18" halign="center" valign="center" foregroundColor="blue" %s transparent="1"/>
132 <widget source="info" render="Label" position="10,70" zPosition="1" size="430,60" font="Regular;22" halign="center" valign="center" backgroundColor="#a08500" transparent="1"/>
134 """ % position_params
136 def __init__(self, session, parent, timeout = 20):
137 Screen.__init__(self,session)
138 self.session = session
140 self["actions"] = ActionMap(["OkCancelActions"],
148 self.title_str = "FPGA Upgrade"
150 #self["name"] = Label(_("Upgrade status"))
151 self["name"] = Label(_(" "))
152 self["info"] = StaticText(_("Can't cancel during upgrade!!"))
154 self["status"] = Label(_("Status : 0%"))
155 self.status_bar = self["status"]
157 self.slider = Slider(0, 100)
158 self["slider"] = self.slider
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):
214 size = getDesktop(0).size()
215 position_params = size.width() > 750 and ('center', 440) or ('120', 420)
217 <screen position="center,%s" size="560,%d" title="FPGA Upgrade" >
218 <ePixmap pixmap="Vu_HD/buttons/red.png" position="0,7" size="80,40" alphatest="blend" />
219 <ePixmap pixmap="Vu_HD/buttons/green.png" position="186,7" size="80,40" alphatest="blend" />
220 <ePixmap pixmap="Vu_HD/buttons/blue.png" position="372,7" size="80,40" alphatest="blend" />
222 <widget source="key_red" render="Label" position="28,0" zPosition="1" size="160,40" font="Regular;20" halign="center" valign="center" transparent="1"/>
223 <widget source="key_green" render="Label" position="213,0" zPosition="1" size="160,40" font="Regular;20" halign="center" valign="center" transparent="1"/>
224 <widget source="key_blue" render="Label" position="400,0" zPosition="1" size="160,40" font="Regular;20" halign="center" valign="center" transparent="1"/>
226 <widget source="status" render="Label" position="15,45" zPosition="1" size="540,40" font="Regular;18" halign="left" valign="center" backgroundColor="#a08500" transparent="1" />
227 <widget name="file_list" position="0,100" size="555,325" scrollbarMode="showOnDemand" />
229 """ % position_params
231 def __init__(self, session):
232 Screen.__init__(self, session)
233 self.session = session
235 self["key_red"] = StaticText(_("Close"))
236 self["key_green"] = StaticText(_("Upgrade"))
237 self["key_blue"] = StaticText(_("Download"))
239 self["status"] = StaticText(_(" "))
240 self["file_list"] = FileList("/", matchingPattern = "^.*")
242 self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", ],
244 "red": self.onClickRed,
245 "green": self.onClickGreen,
246 "blue": self.onClickBlue,
247 "back": self.onClickRed,
248 "ok": self.onClickOk,
249 "up": self.onClickUp,
250 "down": self.onClickDown,
251 "left": self.onClickLeft,
252 "right": self.onClickRight,
254 self.onLayoutFinish.append(self.doLayoutFinish)
258 self.SOURCELIST = self["file_list"]
259 self.STATUS_BAR = self["status"]
260 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
262 self.DEVICE_LIST = '/dev/fpga_dp;/dev/misc/dp;'
263 self.DOWNLOAD_TAR_PATH = '/tmp/'
264 self.DOWNLOAD_FILE_NAME = 'TS_PRO.dat'
265 self.DOWNLOAD_URL = ''
267 self.FPGA = FPGAUpgradeManager()
268 print self.DEVICE_LIST
269 print self.DOWNLOAD_TAR_PATH
270 print self.DOWNLOAD_FILE_NAME
271 print self.DOWNLOAD_URL
273 def doLayoutFinish(self):
277 if fileExists(self.DOWNLOAD_TAR_PATH + self.DOWNLOAD_FILE_NAME):
278 os.remove(self.DOWNLOAD_TAR_PATH + self.DOWNLOAD_FILE_NAME)
281 def doLoadConf(self):
282 if fileExists("/proc/stb/info/vumodel"):
283 model = open("/proc/stb/info/vumodel").read().strip()
284 download_uri_header = open('/usr/lib/enigma2/python/Plugins/SystemPlugins/FPGAUpgrade/fpga.conf').readline().strip()
285 self.DOWNLOAD_URL = str(download_uri_header) + "vu" + str(model) + "/" + self.DOWNLOAD_FILE_NAME
287 def doHook(self, blockNumber, blockSize, totalSize) :
288 if blockNumber*blockSize > totalSize :
289 self.STATUS_BAR.setText(_("Downloaded " + self.DOWNLOAD_TAR_PATH + self.DOWNLOAD_FILE_NAME))
291 self.STATUS_BAR.setText(_("Downloading..."))
293 def onCallbackHandler(self, confirmed):
297 def doUpgradeHandler(self, confirmed):
298 if confirmed == False:
303 path = self.SOURCELIST.getCurrentDirectory() + self.SOURCELIST.getFilename()
305 #self.session.open(MessageBox, _("Can't select directory."), MessageBox.TYPE_INFO, timeout = 5)
309 device_list = self.DEVICE_LIST.split(";")
311 for d in device_list:
312 if os.path.exists(d):
316 if device == None or len(device) == 0:
317 message = "Fail to upgrade.\nCause : Can't found device.\nDo you want to exit?"
318 self.session.openWithCallback(self.onCallbackHandler, MessageBox, _(message), MessageBox.TYPE_YESNO, timeout = 10, default = True)
319 print "DEVICE_LIST : ", device_list
321 print "DEVICE : ", device
322 self.ERROR_CODE = self.FPGA.fpga_upgrade(path, device)
323 if self.ERROR_CODE > 0:
324 self.ERROR_MSG = self.FPGA.get_error_msg(self.ERROR_CODE, self.ERROR_MSG)
325 message = "Fail to upgrade.\nCause : " + self.ERROR_MSG + "\nDo you want to exit?"
326 self.session.openWithCallback(self.onCallbackHandler, MessageBox, _(message), MessageBox.TYPE_YESNO, timeout = 10, default = True)
327 print "DEVICE : ", device
328 print "FILE : ", path
330 #self.session.open(MessageBox, _("Success!!"), MessageBox.TYPE_INFO, timeout = 5)
331 self.session.open(UpgradeStatus, self, timeout = 20)
333 def onClickRed(self):
337 def onClickGreen(self):
338 #self.session.open(MessageBox, _("Upgrade will take about 5 minutes to finish."), MessageBox.TYPE_INFO, timeout = 10)
339 message = "Upgrade will take about 5 minutes to finish.\nDo you want to upgrade?"
340 self.session.openWithCallback(self.doUpgradeHandler, MessageBox, _(message), MessageBox.TYPE_YESNO, timeout = 10, default = True)
342 def onClickBlue(self):
345 test_opener = urllib.URLopener()
347 test_opener.open(self.DOWNLOAD_URL)
349 self.session.open(MessageBox, _('File not found'), MessageBox.TYPE_INFO, timeout = 5)
353 fname, header = urlretrieve(self.DOWNLOAD_URL, self.DOWNLOAD_TAR_PATH + self.DOWNLOAD_FILE_NAME, self.doHook)
355 self.session.open(MessageBox, _(str(msg)), MessageBox.TYPE_INFO, timeout = 5)
361 self.SOURCELIST.changeDir(self.DOWNLOAD_TAR_PATH)
362 self.SOURCELIST.moveToIndex(0)
363 while cmp(self.SOURCELIST.getFilename(), self.DOWNLOAD_FILE_NAME) != 0 :
364 self.SOURCELIST.down()
365 if cmp(before_name, self.SOURCELIST.getFilename()) == 0:
367 before_name = self.SOURCELIST.getFilename()
370 if self.SOURCELIST.canDescent() : # isDir
371 self.SOURCELIST.descent()
372 if self.SOURCELIST.getCurrentDirectory():
373 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
379 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
381 def onClickDown(self):
382 self.SOURCELIST.down()
383 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
385 def onClickLeft(self):
386 self.SOURCELIST.pageUp()
387 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
389 def onClickRight(self):
390 self.SOURCELIST.pageDown()
391 self.STATUS_BAR.setText(_(self.SOURCELIST.getCurrentDirectory()))
393 def main(session, **kwargs):
394 session.open(FPGAUpgrade)
396 def Plugins(**kwargs):
397 return PluginDescriptor(name=_("FPGA Upgrade"), description="Upgrade FPGA..", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main)