Newer
Older
Import / projects / LGN-IP3870 / t / new / update.py
import uiconfig
import runtime
import utils
import config
import status
import evas
from setting import setting
from basemodel import Stage, NotifyStage, YesNoStage, ListStage
from baseui import NotifyUI, LargeWindowUI, BaloonMessageUI
from ui import UpdateProgressUI
import time, socket, evas, os, os.path
from profile import *
from roxiadebug import *
from dnsetting import down_setting

#message_13 = _('Software update failed.')
message_13 = _('Software update failed')


def Kill_IPC():
	if config.update_debug:print '### update.Kill_IPC...#status.critical_entered = False', runtime.updComm
	if runtime.updComm:
		if config.update_debug:print '### update.Kill_IPC...runtime.updComm.pid:',runtime.updComm.pid
	if runtime.updComm and runtime.updComm.pid:
		if config.update_debug:print 'Kill_IPC runtime.updComm.pid:',runtime.updComm.pid
		runtime.updComm.send_packet('disconnect')
		time.sleep(1)
		import signal
		try:
			os.kill(runtime.updComm.pid,signal.SIGKILL)

			# clean a zombie
			def hdl_sigchld(signum, frame):  # clean a zombie
				try:
				    	while 1:
	    					print 'os wait pid 4'
					        if os.waitpid(0, os.WNOHANG): raise OSError
					        if config.update_debug:print 'Some child is dying.. T_T byebye~'
				except OSError:
				   	#if config.update_debug: print 'signal.signal.error'
				   	pass
			signal.signal(signal.SIGCHLD, hdl_sigchld)
			runtime.updComm = None
		except OSError:
			if config.update_debug:print 'runtime.updComm',runtime.updComm
			runtime.updComm = None

class UpdateBase(NotifyStage):
	def __init__(self, message, cb = None, d=3000):
		icon = uiconfig.baloon_phone_setting_icon
		NotifyStage.__init__(self, message, icon, cb = cb, duration = d)
		self.job_tag = utils.Idle(self.job_cb)

		self.ui.set_right(_('END'))

	def job_cb(self):
		self.do_job()
		return False

	def do_job(self):
		# This should be re-implemented by derived class
		pass

	def cancel(self):
		runtime.manager.change_stage(UpdateInterrupted)

	def handle_key(self, key):
		key_manager(key)
		return True

class MessageNotify(NotifyStage):
#Roxia Begin smyook 06.03.16
	def __init__(self, message, duration=0, cb = None):
		icon = uiconfig.baloon_phone_setting_icon
		NotifyStage.__init__(self, message, icon, duration=duration, cb = cb)
#Roxia End smyook
	def destroy(self):
		NotifyStage.destroy(self)

class RetryYesNo(YesNoStage):
	def __init__(self):
		YesNoStage.__init__(self, _('Checking failed. Try again?'), self.yes_cb, self.no_cb, '', uiconfig.baloon_phone_setting_icon)

	def yes_cb(self):
		aa = runtime.manager.find_stage('check update')
		if aa:
			aa.sendpacket = 1
			runtime.manager.back_stage('check update')#check하는 곳으로 가자..
		else:
			runtime.manager.change_stage(CheckUpdateStage)
	def no_cb(self):
		# ka...show version 2006.10.24 (0:success 1:fail 2: cancel)
		setting.set_status_update(1)

#Roxia Begin smyook 06.06.23
		runtime.manager.sac3_timeout()
#Roxia End smyook
		if runtime.manager.find_stage('technical option'):
			runtime.manager.back_stage('technical option')
		else:
			runtime.manager.back_stage('idle')
	#ka...download 2006.11.01
	def handle_key(self, key):
		if key == config.Red:
			self.no_cb()
			return True
		else:
			return YesNoStage.handle_key(self, key)

class RetryDownloadYesNo(YesNoStage):
	def __init__(self):
		YesNoStage.__init__(self, _('Download failed. Try again?'), self.yes_cb, self.no_cb, '', uiconfig.baloon_phone_setting_icon)

	def yes_cb(self):
		aa = runtime.manager.find_stage('ftp update start')
		if aa:
			aa.sendpacket = 1
			runtime.manager.back_stage('ftp update start')
		else:
#Roxia Begin smyook 06.05.08
			runtime.manager.change_stage(DownloadStage)
#Roxia End smyook

	def no_cb(self):
		runtime.manager.sac3_timeout()
		#runtime.manager.sac3_retry += 1
		setting.show_update_stage_mode = ''
		#if config.update_debug: print 'runtime.manager.sac3_retry...',runtime.manager.sac3_retry
		#runtime.manager.sac3_timer = utils.Timer(60*config.min, runtime.manager.call_sac3, True)
		# ka...show version 2006.10.24 (0:success 1:fail 2: cancel)
		setting.set_status_update(1)
		if runtime.manager.find_stage('technical option'):
			runtime.manager.back_stage('technical option')
		else:
			runtime.manager.back_stage('idle')

	def handle_key(self, key):
		if key == config.Red:
			self.no_cb()
#Roxia Begin smyook 06.05.09
			return True
#Roxia End smyook
		else:
			return YesNoStage.handle_key(self, key)



tmpBool = False#다운로드중인지...
def check_ready_to_launch():
	if config.update_debug:print 'check_ready_to_launch'
	if config.update_debug:print 'setting.show_update_stage_mode:',setting.show_update_stage_mode
	global tmpBool
	tmpBool = True
	if runtime.manager.stage.name == 'idle':
		runtime.manager.stack_stage(UpdateStage(setting.show_update_stage_mode, bootUpdate = True))
	return True


class UpdateStage(Stage):
	name = 'update stage'
	agenda_forbidden = True
	def __init__(self, mode, bootUpdate = False):
		self.bootUpdate = bootUpdate
		# eicho modify for w.129 in NB. 06.10.31
		status.backup_status()
		# end.
		if mode == 'change sw':
			#msg = _('Old software version found. An update is suggested')
			msg = _('Using old Software. Update is needed.')
			left = _('UPDATE')
			menu4 = _('EXIT') #right = _('EXIT')
		elif mode == 'change sw lock video':
			#msg = _('Old software version found. To place a Video call an update is required.')
			msg = _('Using old Software. To support video call, update is needed')
			
			setting.enable_video_key = 0
			left = _('UPDATE')
			menu4 = _('EXIT') #right = _('EXIT')
		elif mode == 'change sw now':
			#msg = _('Old software version found. The software will be updated now!')
			msg = _('Software Updating.....')
			left = ''
			menu4 = '' #right = ''
		elif mode == 'change hw':
			#msg = _('Old hardware version found. An update is suggested')
			msg = _('Using old Software. Update is needed.')
			left = ''
			menu4 = _('EXIT') #right = _('EXIT')
		elif mode == 'change hw lock video':
			#msg = _('Old hardware version found. To place a Video call an update is required.')
			msg = _('Using old Software. To support video call, update is needed')
			setting.enable_video_key = 0
			left = ''
			menu4 = _('EXIT') #right = _('EXIT')
		else:
			if config.update_debug:print 'Unknown mode: [%s]' % mode
			#assert False

		setting.show_update_stage_mode = mode
		self.mode = mode
		if runtime.manager.sac3_timer:
			del(runtime.manager.sac3_timer)
			runtime.manager.sac3_timer = None
		self.ui = NotifyUI( msg, uiconfig.baloon_phone_setting_icon)
		self.ui.set_left(left)
		self.ui.set_right(right)

		if status.disp_update_tag:
			if config.update_debug:print 'remove timeout'
			runtime.evas.timeout_remove(status.disp_update_tag)
			status.disp_update_tag = None

	def destroy(self):
		if config.update_debug:print 'UpdateStage.destroy'
		Stage.destroy(self)
		if setting.show_update_stage_mode:
			#assert status.disp_update_tag == None
			if self.bootUpdate:
				status.disp_update_tag = runtime.evas.timeout_add(1000, check_ready_to_launch)

	def show(self):
		if config.update_debug:print 'UpdateStage.show',runtime.manager.stage.name
		Stage.show(self)

	def update_now(self):
		runtime.manager.stack_stage(UpdateStartStage(self.mode))
		return False

	def handle_key(self, key):
		runtime.manager.stage = self
		if config.update_debug: print 'UpdateStage.handle_key. key = ', key
		# ka...download 2006.11.10
		if key == config.Menu1:
			self.update_now()
			return False
		elif key == config.Menu2 or key == config.Red:
			setting.show_update_stage_mode = ''
			# ka...show version 2006.10.24 (0:success 1:fail 2: cancel)
			setting.set_status_update(2)
			if runtime.manager.find_stage('technical option'):
				runtime.manager.back_stage('technical option')
			else:
				runtime.manager.back_stage('idle')
			runtime.manager.call_sac3_retry = 4
			runtime.manager.init_timer_flag = True
			runtime.manager.sac3_timeout()
		elif key == config.OffHook or key == config.Green:
			runtime.manager.call_sac3_retry = 4
			runtime.manager.init_timer_flag = True
			runtime.manager.sac3_timeout()

		return False

class UpdateInterrupted(UpdateBase):
	def __init__(self, msg=message_13, key_action=False):
		#ka...download 2006.10.31 - Key Action에 의한 Interrupt만 15days Timer를 돌린다. 
		self.key_action=key_action
		if profile.get_profile() == 0:
			runtime.evas.idle_add(self.stop_ppp)

		self.chkstatus_timer = None
		self.onhooked = False
		if runtime.updComm:
			Kill_IPC()

		UpdateBase.__init__(self, msg, self.notify_timeout, d=3000)
		self.ui.set_right('')
		#self.ui.set_title(_('UPDATE SOFTWARE'))
		self.ui.set_title(_('Software update'))

	def cancel(self):
		pass

	def stop_ppp(self):
		if runtime.ppp:
			runtime.ppp.stop_ppp(True)
			runtime.ppp = None

	def notify_timeout(self):
		def check_phone_status():
			import model
			if status.phone_status != status.Disconnected:
#Roxia Begin smyook 06.02.02
				print '~~~~~~~~~~~~~~~ phone status is not disconnected : ' , status.Disconnected
				if profile.get_profile() == 0:
					if runtime.ppp:
						print '~~~~~~~~~~~~~~~ runtime.ppp alive !!! '
						#runtime.ppp.stop_ppp()
						#runtime.ppp = None
						self.stop_ppp()
					else:
						print '~~~~~~~~~~~~~~~ phone status is changed to Disconnected'
						status.phone_status = status.Disconnected
#Roxia End smyook
				return True

			if runtime.manager:
#Roxia Begin smyook 06.06.23
				#runtime.manager.sac3_retry = 4
#Roxia End smyook
				#ka...download
				if self.key_action:
					runtime.manager.call_sac3_retry = 4
					runtime.manager.init_timer_flag = True
					# ka...show version 2006.10.24 (0:success 1:fail 2: cancel)
					setting.set_status_update(2)
				else:
					# ka...show version 2006.10.24 (0:success 1:fail 2: cancel)
					setting.set_status_update(1)
				runtime.manager.sac3_timeout()
			#ka...handle_key 2006.11.26
			if status.modem_audio_state == status.HS or status.modem_audio_state == status.SPK:
				if config.update_debug:print 'jwoo:update:status.HS'
				if profile.get_profile() == 0:
					stage = model.OffHookStage
				else:
					stage = model.EnblockEditStage
				runtime.manager.change_stage(stage,True)
			elif self.onhooked:
				if config.update_debug:print 'jwoo:update:onhooked'
				runtime.manager.change_stage(model.IdleStage,True)
			else:
				if config.update_debug:print 'jwoo:update:unknown'
				if runtime.manager.find_stage('technical option'):
					runtime.manager.back_stage('technical option')
				else:
					runtime.manager.back_stage('idle')

			if self.chkstatus_timer:
				runtime.evas.timeout_remove(self.chkstatus_timer)
				self.chkstatus_timer = None
			return False

		self.chkstatus_timer = runtime.evas.timeout_add(1000,check_phone_status)

	def handle_key(self,key):

		if key == config.OffHook:
			self.onhooked = False
			status.set_modem_audio_state(status.HS) # change the order vpark
			if profile.get_profile()  == 0:
				runtime.dspg.set_state(runtime.dspg.ST_HS_OFFHK)
			else:
				runtime.dspg.set_state(runtime.dspg.ST_V_HS_OFFHK_LPLAY) # vpark
		elif key == config.OnHook:
			self.onhooked = True
			runtime.dspg.set_state(runtime.dspg.ST_IDLE)
			status.set_modem_audio_state(status.IDLE)

		return True


#Roxia End smyook
class UpdateStartStage(UpdateBase):
	def __init__(self, mode='change sw'):
		#msg = _('Software update in progress. Wait the end of the procedure.')
		msg = _('Software Updating. Please wait.')
		if profile.get_profile() == 0:
		#	msg =  msg + '\n' + _('Incoming calls can\'t be received.')
			msg =  msg + '\n' + _('Cannot answer the call.')
		UpdateBase.__init__(self, msg, self.timeout)
		#self.ui.set_title(_('UPDATE SOFTWARE'))
		self.ui.set_title(_('Software update'))
		self.mode = mode

	def timeout(self):
		if runtime.manager.find_stage('update connection'):
			runtime.manager.back_stage('update connection')
		else:
			runtime.manager.change_stage(ConnectionStage(self.mode))
		return False

	def handle_key(self, key):
		if key in '0123456789#*' or key in (config.Green, config.Video, config.OffHook, config.OnHook):
			if profile.get_profile() == 0:
				if key == config.OnHook:
					#runtime.manager.change_stage(UpdateInterrupted( _('Software update interrupted'), key_action=True))
					runtime.manager.change_stage(UpdateInterrupted( _('Software update interrupted'), key_action=True))
					return True
				else:
					return True
			else:
				pass # IP mode일 경우, 원래 처리대로

		key_manager(key)
		return True
	
class UpdateDownloadPopStage(UpdateBase):
	def __init__(self, mode='change sw'):
		#msg = _('Software update in progress. Wait the end of the procedure.')
		msg = _('Software Updating. Please wait.')
		if profile.get_profile() == 0:
			#msg = msg + '\n' + _('Incoming calls can\'t be received.')			
			msg = msg + '\n' + _('Cannot answer the call.')

		self.mode = mode
		UpdateBase.__init__(self, msg, self.timeout,1000)
		#self.ui.set_title(_('UPDATE SOFTWARE'))
		self.ui.set_title(_('Software update'))


	def timeout(self):
		if runtime.manager.find_stage('download stage'):
			runtime.manager.back_stage('download stage')
		else:
			print '~~~~ print here?? let Roxia know, please... ~~~~~'
			#runtime.manage

class DownloadUI(UpdateProgressUI):
	def __init__(self, mesg = _('Download in progress...'), percent = 0):
		UpdateProgressUI.__init__(self, mesg, '', '', '', '')
		self.set_percent(percent)

downloading= False
#TMP_FILE='/tmp/snmp_ftp_tmp_file'

def proc_down_status(val):
	# sending trap and save manual download status...
	debugLogN('proc_down_status: (%d)'%val)
	runtime.manual_down_status = val
	#cmd = 'upgrade_noti.sh %d &'%val
	#os.system(cmd)
	
class VersionCheckStage(Stage):
	# manual download step 1: check software version.
	name = 'vcheck stage'
	agenda_forbidden = True
	domonitor_forbidden = True

	def __init__(self,direct = False):
		self.ui = DownloadUI(_('Version checking...'), percent = 0)
		self.direct = direct
		self.is_downloading = True
		self.timer = None
		self.hundred_percent_ok = False

		self.pro=0
		if not self.timer:
			self.timer = utils.Timer(3000, self.check_percent)
			downloading = True

		import manual
		runtime.down = manual.manual_download()
		self.post_timer = utils.Timer(1000, self.post_init)
		
	def post_init(self):
		if len(down_setting.get_download_server_ip()) == 0 or  not (0 < down_setting.get_download_server_port() < 65535):
			#os.system('upgrade_noti.sh 11 &')
			proc_down_status(11)
			runtime.manager.change_stage(MessageNotify( _('Download server setting is not valid'), 3000))
			return
			
		software_type = setting.download_type
		version = runtime.down.get_fw_ver(software_type)

		server_url = 'http://%s:%d/'%(down_setting.get_download_server_ip(), down_setting.get_download_server_port())
		debugLogC( 'STEP1-start: VCheck swtype(%s), version(%s), server_url(%s)'%(software_type, version, server_url) )
		
		runtime.down.get_update_request(server_url, software_type, version,  fin_cb=self.fin_cb)

	def fin_cb(self, ret):
		self.pro = 100
		if self.ui:
			self.ui.set_percent(self.pro)

		str = open('/tmp/request_response').read()
		debugLogC('STEP1-end: VCheck (%d)\n%s\n'%(ret, str) )

		if ret == 21: # time out 
			#os.system('upgrade_noti.sh 12 &')
			proc_down_status(12)
			runtime.manager.change_stage(MessageNotify(_('Cannot connect download server'), 3000))
		elif ret == 22: # time out 
			#os.system('upgrade_noti.sh 12 &')
			proc_down_status(12)
			runtime.manager.change_stage(MessageNotify(_('Cannot connect download server'), 3000))
		elif ret == 0 and len(str) == 0: # time out - DNS error case 
			#os.system('upgrade_noti.sh 12 &')
			proc_down_status(12)
			runtime.manager.change_stage(MessageNotify(_('Cannot connect download server'), 3000))			
		elif ret == 23:
			#os.system('upgrade_noti.sh 20 &')
			proc_down_status(20)
			runtime.manager.change_stage(MessageNotify(_('Download server auth fail'), 3000))	
		else:
			self.download_finished()
			
	def destroy(self):
		self.timer = None
		self.post_timer = None
		Stage.destroy(self)
			
	def check_percent(self):
		self.pro += 50
		if self.pro > 100:
			self.pro = 100
		self.pro = runtime.down.get_progress_poll()
		if self.ui:
			self.ui.set_percent(self.pro)
		#if self.pro >= 100:
			#self.download_finished()
			#runtime.evas.idle_add(self.download_finished)
	
		return True

	def download_finished(self):
		if self.timer:
			self.timer.__del__()
			self.timer = None
		try:
			ret, message = runtime.down.parser()
			print 'step1', ret, message
			debugLogC('STEP1-res: VCheck ret(%s), message(%s)'%(ret, message))

			#u8message = unicode(message, 'euc-kr').encode('utf-8')
			if (ret == '200'):
				print 'ret == 200 going to Download stage'
				runtime.manager.change_stage(DownloadStage)
			elif (ret == "201"):
				# no trap required
				#runtime.manager.change_stage(MessageNotify(u8message, 3000))
				runtime.manager.change_stage(MessageNotify(_('You are using latest version'), 3000))
			elif (ret == "202"):
				#os.system('upgrade_noti.sh 13 &')
				proc_down_status(13)
				#runtime.manager.change_stage(MessageNotify(u8message, 3000))
				runtime.manager.change_stage(MessageNotify(_('Fill required field'), 3000))
			elif (ret == "203"):
				#os.system('upgrade_noti.sh 13 &')
				proc_down_status(13)
				#runtime.manager.change_stage(MessageNotify(u8message, 3000))
				runtime.manager.change_stage(MessageNotify(_('Terminal identification failed'), 3000))
			elif (ret == "204"):
				#os.system('upgrade_noti.sh 13 &')
				proc_down_status(13)
				#runtime.manager.change_stage(MessageNotify(u8message, 3000))
				runtime.manager.change_stage(MessageNotify(_('Invalid PkgId'), 3000))
			else:
				print ret, message	
				runtime.manager.change_stage(MessageNotify(_('Unknown server error'), 3000))
		except:
			debugLogC('STEP1-except: Download error')
			runtime.manager.change_stage(MessageNotify(_('Download error'), 3000))
		
		# change_stage to next phase...

	def handle_key(self, key):
		if key == config.key_link_down:  
			if config.update_debug: print '~~~~~~ Link down event: It will be dissconnected 60 seconds later if there is no response ~~~'
 		return True
		


class DownloadStage(Stage):
	# manual download step 2: download software firmware.
	name = 'download stage'
	agenda_forbidden = True
	domonitor_forbidden = True

	def __init__(self, site = None, direct = False):
		self.ui = DownloadUI(_('Download in progress...'))
		self.direct = direct
		self.is_downloading = True
		self.timer = None
		self.hundred_percent_ok = False
		self.ret = 0
		self.pro=0
		self.site = site
		import manual
		runtime.down = manual.manual_download()
		self.progress=0

		#self.post_init()
		#runtime.lfname = '/tmp/down_file'
		#runtime.down.get_download_request(self.site, runtime.lfname, fin_cb=self.fin_cb)

		if not self.timer:
			self.timer = utils.Timer(2000, self.check_percent)
			downloading = True
		self.post_timer = utils.Timer(1000, self.post_init)

		
	def post_init(self):
		if self.post_timer != None :
			self.post_timer = None
		'''
		self.software_type = setting.download_type
		self.version = runtime.down.get_fw_ver(self.software_type)
		
		debugLogC( 'STEP2-start: Download swtype(%s), version(%s), fsize(%s)'%(self.software_type, self.version, runtime.down.pkgFileSize.strip()) )

		fsize = int(runtime.down.pkgFileSize)
		'''
		runtime.lfname = '/tmp/down_file'
		runtime.down.get_download_request(self.site, runtime.lfname, fin_cb=self.fin_cb)
		
	def fin_cb(self, ret):
		if self.timer != None:
			self.timer = None

		debugLogC('STEP2-end: Download ret (%d)'% ret)
		self.ret = ret
		print 'cb ret =', ret
		self.pro = 100

		if self.ui:
			self.ui.set_percent(self.pro)

		self.download_finished()		
		"""
		if ret == 20: # server connnection fail....
			#server_url = 'http://%s:%d/'%(setting.download_server_ip, setting.download_server_port)
			'''
			server_url = down_setting.get_download_server_url()
			proc_down_status(20)
			runtime.down.send_response(server_url, self.software_type, runtime.down.pkgVersion, 20)
			#runtime.manager.change_stage(MessageNotify(_('Download server login fail'), 3000))					
			'''
			runtime.manager.change_stage(MessageNotify(_('Cannot log in download server'),  3000))		
			# telio provision download fail
			if config.provision_debug :
				print 'download fail!!!!!!!!!!!#2'
			runtime.manager.provision_manager.download_fail_retry()

		elif ret == 21: # server connnection fail....
			#server_url = 'http://%s:%d/'%(setting.download_server_ip, setting.download_server_port)
			'''
			server_url = down_setting.get_download_server_url()
			proc_down_status(21)
			runtime.down.send_response(server_url, self.software_type, runtime.down.pkgVersion, 21)
			'''
			runtime.manager.change_stage(MessageNotify(_('Cannot connect download server'), 3000))	
			# telio provision download fail
			if config.provision_debug :
				print 'download fail!!!!!!!!!!!#3'
			runtime.manager.provision_manager.download_fail_retry()
			
		elif ret == 22: # time out 
			'''
			#server_url = 'http://%s:%d/'%(setting.download_server_ip, setting.download_server_port)
			server_url = down_setting.get_download_server_url()
			proc_down_status(22)
			runtime.down.send_response(server_url, self.software_type, runtime.down.pkgVersion, 22)
			#runtime.manager.change_stage(MessageNotify(_('Download timeout'), 3000))
			'''
			runtime.manager.change_stage(MessageNotify(_('Download Timeout.'), 3000))
			# telio provision download fail
			if config.provision_debug :
				print 'download fail!!!!!!!!!!!#4'
			runtime.manager.provision_manager.download_fail_retry()


		elif ret == 23: # login fail
			#os.system('upgrade_noti.sh 20 &')
			'''
			proc_down_status(20)
			#server_url = 'http://%s:%d/'%(setting.download_server_ip, setting.download_server_port)
			server_url = down_setting.get_download_server_url()
			runtime.down.send_response(server_url, self.software_type,runtime.down.pkgVersion, 20)
			#runtime.manager.change_stage(MessageNotify(_('Download server login fail'), 3000))		
			'''
			runtime.manager.change_stage(MessageNotify(_('Cannot log in download server'),  3000))		
			# telio provision download fail
			if config.provision_debug :
				print 'download fail!!!!!!!!!!!#5'
			runtime.manager.provision_manager.download_fail_retry()


		else:
			self.download_finished()	
		"""
			
 	def destroy(self):
		if self.timer:
			self.timer.__del__()
			self.timer = None
		Stage.destroy(self)
					
	def check_percent(self):
		if self.timer != None:
			self.timer = None
			self.timer = utils.Timer(1000, self.check_percent)	
		self.pro = runtime.down.get_progress_poll()
		print '### STEP2: check_percent =', self.pro
		if self.ui:
			self.progress = self.progress + 20
			if self.progress > 100:
				self.progress = 0
			self.ui.set_percent(self.progress)
#			self.ui.set_percent(self.pro)
		#if self.pro >= 100:
		#	runtime.evas.render_now()
		#	runtime.evas.idle_add(self.download_finished)
			
		return True

	def download_finished(self):
		if self.timer:
			self.timer.__del__()
			self.timer = None
		# change_stage to next phase...
		if self.ret == 0 :  # download OK
			# report downloading file finished.
			pass
		else:
			print "download fail", self.ret
			# telio provision download fail
			if config.provision_debug :
				print 'download fail!!!!!!!!!!!#1'
			runtime.manager.provision_manager.download_fail_retry()
#			runtime.manager.change_stage(MessageNotify(_('Download server setting is not valid'), 3000))
			runtime.manager.change_stage(MessageNotify(_('Download fail'), 3000))
			return
		runtime.manager.change_stage(DoCopyStage)
		
	def handle_key(self, key):
		if key == config.key_link_down:  
			if config.update_debug: print '~~~~~~ Link down event: It will be dissconnected 60 seconds later if there is no response ~~~'
		return True
	'''
class DownloadStage(Stage):
	# manual download step 2: download software firmware.
	name = 'download stage'
	agenda_forbidden = True
	domonitor_forbidden = True

	def __init__(self,direct = False):
		self.ui = DownloadUI(_('Download in progress...'))
		self.direct = direct
		self.is_downloading = True
		self.timer = None
		self.hundred_percent_ok = False
		self.ret = 0
		self.pro=0
		if not self.timer:
			self.timer = utils.Timer(1000, self.check_percent)
			downloading = True
		self.post_timer = utils.Timer(1000, self.post_init)
		
	def post_init(self):			
		
		self.software_type = setting.download_type
		self.version = runtime.down.get_fw_ver(self.software_type)
		
		debugLogC( 'STEP2-start: Download swtype(%s), version(%s), fsize(%s)'%(self.software_type, self.version, runtime.down.pkgFileSize.strip()) )

		fsize = int(runtime.down.pkgFileSize)
		runtime.lfname = '/tmp/down_file'
		runtime.down.get_download_request(runtime.lfname, fsize, fin_cb=self.fin_cb)
		
	def fin_cb(self, ret):

		debugLogC('STEP2-end: Download ret (%d)'% ret)
		self.ret = ret
		self.pro = 100

		if self.ui:
			self.ui.set_percent(self.pro)
			
		if ret == 20: # server connnection fail....
			#server_url = 'http://%s:%d/'%(setting.download_server_ip, setting.download_server_port)
			server_url = down_setting.get_download_server_url()
			proc_down_status(20)
			runtime.down.send_response(server_url, self.software_type, runtime.down.pkgVersion, 20)
			#runtime.manager.change_stage(MessageNotify(_('Download server login fail'), 3000))					
			runtime.manager.change_stage(MessageNotify(_('Cannot log in download server'),  3000))		

		elif ret == 21: # server connnection fail....
			#server_url = 'http://%s:%d/'%(setting.download_server_ip, setting.download_server_port)
			server_url = down_setting.get_download_server_url()
			proc_down_status(21)
			runtime.down.send_response(server_url, self.software_type, runtime.down.pkgVersion, 21)
			runtime.manager.change_stage(MessageNotify(_('Cannot connect download server'), 3000))		
		elif ret == 22: # time out 
			#server_url = 'http://%s:%d/'%(setting.download_server_ip, setting.download_server_port)
			server_url = down_setting.get_download_server_url()
			proc_down_status(22)
			runtime.down.send_response(server_url, self.software_type, runtime.down.pkgVersion, 22)
			#runtime.manager.change_stage(MessageNotify(_('Download timeout'), 3000))
			runtime.manager.change_stage(MessageNotify(_('Download Timeout.'), 3000))

		elif ret == 23: # login fail
			#os.system('upgrade_noti.sh 20 &')
			proc_down_status(20)
			#server_url = 'http://%s:%d/'%(setting.download_server_ip, setting.download_server_port)
			server_url = down_setting.get_download_server_url()
			runtime.down.send_response(server_url, self.software_type,runtime.down.pkgVersion, 20)
			#runtime.manager.change_stage(MessageNotify(_('Download server login fail'), 3000))		
			runtime.manager.change_stage(MessageNotify(_('Cannot log in download server'),  3000))		

		else:
			self.download_finished()		
			
 	def destroy(self):
		if self.timer:
			self.timer.__del__()
			self.timer = None
		Stage.destroy(self)
					
	def check_percent(self):
		self.pro = runtime.down.get_progress_poll()
		print '### STEP2: check_percent =', self.pro
		if self.ui:
			self.ui.set_percent(self.pro)
		#if self.pro >= 100:
		#	runtime.evas.render_now()
		#	runtime.evas.idle_add(self.download_finished)
			
		return True

	def download_finished(self):
		if self.timer:
			self.timer.__del__()
			self.timer = None
		# change_stage to next phase...
		if self.ret == 0 :  # download OK
			# report downloading file finished.
			pass
		else:
			print "download fail", self.ret
			runtime.manager.change_stage(MessageNotify(_('Download server setting is not valid'), 3000))
			return
		runtime.manager.change_stage(DoCopyStage)
		
	def handle_key(self, key):
		if key == config.key_link_down:  
			if config.update_debug: print '~~~~~~ Link down event: It will be dissconnected 60 seconds later if there is no response ~~~'
		return True
	'''	

class DoCopyStage(Stage):
	# manual download step 3: do copy - md5sum check.
	name = 'download copy stage'
	agenda_forbidden = True
	domonitor_forbidden = True

	def __init__(self,direct = False):
		#self.ui = DownloadUI(_('Check firmware checksum...'), percent = 100)
		self.ui = DownloadUI(_('File integrity check'), percent = 0)

		self.direct = direct
		self.is_downloading = True
		self.timer = None
		self.timer2 = None	# update helper timer
		self.hundred_percent_ok = False
		self.pid = 0
	
		self.software_type = setting.download_type
		self.version = runtime.down.get_fw_ver(self.software_type)
		debugLogC( 'STEP3-start: DoCopy swtype(%s), version(%s)'%(self.software_type, self.version) )
		
		self.pro=0
		if not self.timer:
			self.timer = utils.Timer(1000, self.check_percent)
			downloading = True
			
		self.post_timer = utils.Timer(1000, self.post_init)

	def post_init(self):
		cmd = 'update-helper copy %s'%runtime.lfname
#		print "run os.system: ", cmd
		ret = self.fork_update_helper(cmd)
		if config.provision_debug :
			print 'update  helper fork', ret
		if ret == 'True' :
			self.timer2 = utils.Timer(config.provision_process_watch_time * 1000,\
			self.updatehelper_watch)
		elif ret == 'False' :	# fork fail, some time later fork again, temporary 3 sec later
			self.timer2 = utils.Timer(config.provision_process_watch_time  * 1000,\
			self.post_init)
		else :
			if config.provision_debug :
				print 'ret, what should I need to do... nothing??', ret 
			self.timer2 = utils.Timer(config.provision_process_watch_time * 1000,\
			self.updatehelper_watch)
			
		"""
		import dnloader
		self.ret = os.system(cmd)
		debugLogC('STEP3-end: DoCopy ret (%d)'% self.ret)
		print 'doc ret = ', self.ret 
		if self.ret == 0: # success
			#os.system('upgrade_noti.sh 40 &')
			'''
			proc_down_status(40)
			#server_url = 'http://%s:%d/'%(setting.download_server_ip, setting.download_server_port)
			server_url = down_setting.get_download_server_url()
			runtime.down.send_response(server_url, self.software_type, runtime.down.pkgVersion,40)
			'''
			#show reboot message
			cmd = 'touch /usr/local/update/lock'
			os.system(cmd)
			print "run os.system: ", cmd
			os.system("sync")
			stage = DownloadNoti(message = _('Check integrity Ok'), icon=None, noexit=True, duration = 3*1000, cb=self.go_to_reboot_stage)
			runtime.manager.stack_stage(stage)
			print 'reboot'
		else: # fail
			'''
			#server_url = 'http://%s:%d/'%(setting.download_server_ip, setting.download_server_port)
			server_url = down_setting.get_download_server_url()
			runtime.down.send_response(server_url, self.software_type, runtime.down.pkgVersion,27)
			#os.system('upgrade_noti.sh 27 &')
			proc_down_status(27)
#			runtime.manager.change_stage(MessageNotify(_('Download file checksum error'), 3000))
			'''
			# telio provision download fail
			if config.provision_debug :
				print 'download fail!!!!!!!!!!!#6'
			self.pro =100		
			self.ui.set_percent(self.pro)	
			runtime.manager.provision_manager.download_fail_retry()			
			runtime.manager.change_stage(MessageNotify(_('Download  file Error.'), 3000))
		"""
		
		'''		
	def post_init(self):
		cmd = 'update-helper copy %s'%runtime.lfname
		print "run os.system: ", cmd

		import dnloader
		self.ret = os.system(cmd)
		debugLogC('STEP3-end: DoCopy ret (%d)'% self.ret)
		if self.ret == 0: # success
			#os.system('upgrade_noti.sh 40 &')
			proc_down_status(40)
			#server_url = 'http://%s:%d/'%(setting.download_server_ip, setting.download_server_port)
			server_url = down_setting.get_download_server_url()
			runtime.down.send_response(server_url, self.software_type, runtime.down.pkgVersion,40)
		else: # fail
			#server_url = 'http://%s:%d/'%(setting.download_server_ip, setting.download_server_port)
			server_url = down_setting.get_download_server_url()
			runtime.down.send_response(server_url, self.software_type, runtime.down.pkgVersion,27)
			#os.system('upgrade_noti.sh 27 &')
			proc_down_status(27)
#			runtime.manager.change_stage(MessageNotify(_('Download file checksum error'), 3000))
			runtime.manager.change_stage(MessageNotify(_('Download Checksum Error.'), 3000))
		self.pro =100
		'''

	def fork_update_helper(self, cmd)  :
		if self.pid != 0 :
			ret = self.updatehelper_child_process_check()
			if ret == 256 :
				if config.provision_debug :
					print 'update helper keck!!!'
			if config.provision_debug :
				print 'update helper return', ret
			return ret

		try :
			self.pid = os.fork()
		except :
			print 'update helper fork except error'
			return 'False'			

		if self.pid != 0 : # parent
			if config.provision_debug :
				print 'parent process gogo!!'
				print 'parent pid', os.getpid()
				print 'child pid', self.pid	
			return 'True'
		
		else :	#child process
			if config.provision_debug :		
				print 'child process'
				print 'child pid', os.getpid()
				print 'parent pid', os.getppid()
	
			cmds = cmd.strip()
			cmd = cmds.split(' ')
			print 'cmd=', cmd
			os.execlp('/usr/local/bin/update-helper', *cmd)

	def 	updatehelper_watch(self) :
		if self.timer2 != None :
			self.timer2 = None	
		if config.provision_debug :
			print 'updatehelper_watch'
		ret = self.updatehelper_child_process_check()
		if ret == 'True' :	# success
			if config.provision_debug :
				print 'download file check success'
			#show reboot message
			cmd = 'touch /usr/local/update/lock'
			os.system(cmd)
			print "run os.system: ", cmd
			os.system("sync")
			stage = DownloadNoti(message = _('Check integrity Ok'), icon=None, noexit=True, duration = 3*1000, cb=self.go_to_reboot_stage)
			runtime.manager.stack_stage(stage)
			print 'reboot'				
		elif ret == 'False' : 	# fail
			if config.provision_debug :
				print 'download file check fail'
			self.pro =100		
			self.ui.set_percent(self.pro)	
			runtime.manager.provision_manager.download_fail_retry()			
			runtime.manager.change_stage(MessageNotify(_('Download file Error'), 3000))				
		else :
			if config.provision_debug :
				print 'URL_file_get_watch wait??, ret =', ret
			self.timer2 = utils.Timer(config.provision_process_watch_time * 1000,\
			self.updatehelper_watch)			


	def updatehelper_child_process_check(self) :		
		if config.provision_debug :
			print 'provision_child_process_check pid =', self.pid
		#print 'parent pid', os.getpid()
		#print 'child pid', self.pid		
		
		if self.pid != 0 :
			wpid, ret = os.waitpid(self.pid, os.WNOHANG)
			if config.provision_debug :
				print 'wait pid = ', wpid
				print 'wait pid ret = ', ret 
				print 'self.pid = ', self.pid

			if self.pid != wpid :
				if ret == 256 :
					if config.provision_debug :
						print 'keck!!!'
					return ret
				elif wpid == 0 and ret == 0 :
					if config.provision_debug :
						print 'what the heck!!!'
					procstat = self.get_proc_status()
					if config.provision_debug :
						print 'procstat =', procstat 
					if procstat == 'S' or procstat == 'Z' :
						return ret
					elif 	procstat == 'E' :
						self.pid = 0
						return 'False'
				else :
					if config.provision_debug :
						print 'e wait pid = ', wpid
						print 'e wait pid ret = ', ret 
						print 'e self.pid = ', self.pid
					return ret
			else :
				if ret != 0 :
					if config.provision_debug :
						print 'wpid= %d, self pid = %d, ret=%d'%(wpid, self.pid, ret)
					self.pid = 0
					return 'False'
				os.system('sync')		
				os.system('sync')
				os.system('sync')	
				self.pid = 0

				return 'True'			
		else :
			self.pid = 0		
			return 'False'

	def get_proc_status(self):
		try:
			strs = open('/proc/%d/stat'%self.pid).read().split(' ')
			#print 'GET PROC_STATUS', strs
			return strs[2]
		except:
			print 'exception : get_proc_status', self.pid  # the process finished or file name error
			return 'E'				
				
 	def destroy(self):
		if config.provision_debug :
			print 'DoCopyStage.destroy'
		self.timer = None
		self.timer2 = None
		Stage.destroy(self)

	def check_percent(self):
		if self.timer != None:
			self.timer = None
			self.timer = utils.Timer(1000, self.check_percent)	
		if config.provision_debug :
			print '### update helper: check_percent =', self.pro
		if self.ui:
			self.pro = self.pro + 20
			if self.pro > 100:
				self.pro = 0
			self.ui.set_percent(self.pro)

#		if self.pro >= 100:
#			self.download_finished()	
		return True

	def go_to_reboot_stage(self):
		if self.timer != None :
			self.timer = None
		def reset_cb():
			import utils, time
			if runtime.vdciapp:
				runtime.vdciapp.req_deregister()
			time.sleep(1)			
			utils.releaseDhcp()
#MMW 2008.06.25 when reboot is called, reset vega and DCP related GPIO pin				
			utils.vega_reset_together()
#end of MMW		
#MMW	2008.07.07	when reboot send disassoc to AP and then unload the driver
			os.system('wlstop')
#end of MMW
			time.sleep(1)
			os.system('reboot')

		stage = DownloadNoti(message = _('The phone will be reboot shortly') + '\n' + _('and install New SW'), icon =uiconfig.baloon_setting_system_reset_icon,  noexit=True, duration = 3*1000, cb=reset_cb)
		runtime.manager.stack_stage(stage)


	def handle_key(self, key):
		print 'DoCopyStage.handle_key', key
		if key == config.key_link_down:  
			if config.update_debug: print '~~~~~~ Link down event: It will be dissconnected 60 seconds later if there is no response ~~~'
 		return True


class DownloadNoti(NotifyStage):
	name = 'download notify'
	def __init__(self, message, icon = None, noexit=True, duration=0,cb=None, exit_cb=None):
		self.noexit = noexit
		self.exit_cb = exit_cb

		NotifyStage.__init__(self, message, icon, cb, duration)
		if not self.noexit:
			self.ui.set_menu4(_('CANCEL'))
		self.ui.show_bg=True
		
	def handle_key(self,key):
		if self.noexit:
			if key in (config.Red, config.Green, config.OffHook, config.OnHook):
				if config.provision_debug :
					print 'Ignore key(1) - ', key
				return True

		else:
			# exit key is available...
			if key in (config.Menu4, config.Red): # Exit
				if self.exit_cb:
					self.exit_cb()
					return True
				runtime.manager.back_stage()
				return True
			elif key in (config.Green, config.OffHook, config.OnHook, config.Video):
				if config.provision_debug :
					print '** Ignore key(2) - ', key
				return True

		NotifyStage.handle_key(self,key)		
		
class DoUpdateStage(Stage):
	# manual download step 4: do install
	name = 'download update stage'
	agenda_forbidden = True
	domonitor_forbidden = True
	def __init__(self,direct = False):
		#self.ui = DownloadUI(_('firmware installing...'))
		self.ui = DownloadUI(_('Starting install'))
		
		self.direct = direct
		self.is_downloading = True
		self.timer = None
		self.hundred_percent_ok = False
	
		self.software_type = setting.download_type
		self.version = runtime.down.get_fw_ver(self.software_type)
		debugLogC( 'STEP4-start: DoInstall swtype(%s), version(%s)'%(self.software_type, self.version) )
		
		self.pro=0
		if not self.timer:
			self.timer = utils.Timer(10000, self.check_percent)
			downloading = True

		self.post_timer = utils.Timer(1000, self.post_init)
		
	def post_init(self):

		os.system("touch /usr/local/update/lock")
		os.system("touch /usr/local/update/updated")
		cmd = 'update-helper install'
		print "run os.system: ", cmd

		server_url = down_setting.get_download_server_url()
		runtime.down.send_response(server_url, self.software_type, runtime.down.pkgVersion, 100)

		os.system("sync")
		def reset_cb():
			import utils, time
			if runtime.vdciapp:
				runtime.vdciapp.req_deregister()
			time.sleep(1)			
			utils.releaseDhcp()
#MMW 2008.06.25 when reboot is called, reset vega and DCP related GPIO pin				
			utils.vega_reset_together()
#end of MMW		
#MMW	2008.07.07	when reboot send disassoc to AP and then unload the driver
			os.system('wlstop')
#end of MMW
			time.sleep(1)
			os.system('reboot')

		stage = NotifyStage( _('The phone will be reboot shortly'), uiconfig.baloon_setting_system_reset_icon, reset_cb)
		runtime.manager.stack_stage(stage)
		
#		self.ret = os.system(cmd)
#		if self.ret == 0: # success
#			#os.system('upgrade_noti.sh 100 &')
#			proc_down_status(100)
#			#server_url = 'http://%s:%d/'%(setting.download_server_ip, setting.download_server_port)
#			server_url = down_setting.get_download_server_url()			
#			runtime.down.send_response(server_url, self.software_type, runtime.down.pkgVersion,100)
#		else: # fail
#			#server_url = 'http://%s:%d/'%(setting.download_server_ip, setting.download_server_port)
#			server_url = down_setting.get_download_server_url()
#			runtime.down.send_response(server_url, self.software_type, runtime.down.pkgVersion,27)
#			#os.system('upgrade_noti.sh 27 &')
#			proc_down_status(27)
#			runtime.manager.change_stage(MessageNotify(_('Install fail'), 3000))
#		self.pro=100

 	def destroy(self):
		if self.timer:
			self.timer.__del__()
			self.timer = None
		Stage.destroy(self)

	def check_percent(self):
		self.pro += 10
		self.ui.set_percent(self.pro)
		if self.pro >= 100:
			self.download_finished()		
		return True

	def download_finished(self):
		debugLogC( 'STEP4 - ATTENTION - NOT USED CODE just return' )

		return
		# obselete
		if self.ret == 0 :  # install OK
			def noti_reset_cb():
				def reset_cb():
					print 'reboot!!!'
					import utils, time
					if runtime.vdciapp:
						runtime.vdciapp.req_deregister()
					time.sleep(1)					
					utils.releaseDhcp()
#MMW 2008.06.25 when reboot is called, reset vega and DCP related GPIO pin				
					utils.vega_reset_together()
#end of MMW		
#MMW	2008.07.07	when reboot send disassoc to AP and then unload the driver
					os.system('wlstop')
#end of MMW
					time.sleep(1)
					os.system('reboot')
					
				stage = NotifyStage( _('The phone will be reboot shortly'), uiconfig.baloon_setting_system_reset_icon, reset_cb)
				runtime.manager.stack_stage(stage)

			server_url = down_setting.get_download_server_url()
			#print '### server_url: ', server_url
			runtime.down.send_response(server_url, self.software_type, runtime.down.pkgVersion, 100)
			#runtime.manager.change_stage(MessageNotify(_('Installing finished.'), 3000, cb=noti_reset_cb))
			runtime.manager.change_stage(MessageNotify(_('Installation is finished successfully.'), 3000, cb=noti_reset_cb))
			
			#stage = NotifyStage(_('Installing finished.'), uiconfig.baloon_setting_system_reset_icon, reset_cb, duration=1)
			#runtime.manager.change_stage(stage)

		else:
			#runtime.manager.change_stage(MessageNotify(_('Installing failed.'), 3000))
			runtime.manager.change_stage(MessageNotify(_('Software Installation Failed.'), 3000))

		# change_stage to next phase...

	def handle_key(self, key):
		if key == config.key_link_down:  
			if config.update_debug: print '~~~~~~ Link down event: It will be dissconnected 60 seconds later if there is no response ~~~'
 		return True

class InstallingUIStage(UpdateBase):
	name = 'installinguistage'
	def __init__(self):
		if config.update_debug:print 'InstallingUIStage.init'
		icon = uiconfig.baloon_phone_setting_icon
		self.installOK = False
		#msg = _('Please, wait a moment. Installing new software...')
		msg = _('Installing new Software. Please wait...')
		UpdateBase.__init__(self, msg, self.timeout,500)
		self.ui.set_right('')
		setting.enable_video_key = 1

	def setInstallOK(self, ok):
		self.installOK = ok
		if self.installOK:
			runtime.manager.change_stage(ReadyToReboot)
		else:
			if runtime.manager.find_stage('check update'):
				if self.bootUpdate:
					# ka...show version 2006.10.24 (0:success 1:fail 2: cancel)
					setting.set_status_update(1)
					#runtime.manager.stack_stage(MessageNotify(_('Checking failed.'), 3000))
					runtime.manager.stack_stage(MessageNotify(_('Software update failed'), 3000))
					runtime.manager.back_stage('idle')
				else:
					runtime.manager.change_stage(RetryYesNo)
			else:
				runtime.manager.stack_stage(RetryYesNo)

	def timeout(self):
		if runtime.updComm:
			runtime.updComm.send_packet("install_downloaded_files")
#Roxia Begin smyook 06.02.27
	def handle_key(self, key):
		return True
#Roxia End smyook

class ReadyToReboot(UpdateBase):

	def __init__(self):
		if config.update_debug:print 'ReadyToReboot.init'
		icon = uiconfig.baloon_phone_setting_icon
#Roxia Begin smyook 06.06.23
# eicho modify sentence for wording 06.07.25
		#msg = _('Download finished. After rebooting, installation will go on.')
		msg = _('Installation will continue after rebooting...')
		
		#msg = _('Software update completed. After rebooting, update will go on.')
#Roxia End smyook
		UpdateBase.__init__(self, msg, self.timeout)
		self.ui.set_right('')
		setting.enable_video_key = 1

		# ka...show version 2006.10.24 (0:success 1:fail 2: cancel)
		setting.set_status_update(0)

	def timeout(self):
#Roxia Begin smyook 06.03.16
		if runtime.vdciapp:
			runtime.vdciapp.req_deregister()
			time.sleep(2)

			runtime.vdciapp.kill_vdciapp()
			runtime.vdciapp = None
#Roxia End smyook
		time.sleep(1)
		Kill_IPC()
		import utils, time
		if runtime.vdciapp:
			runtime.vdciapp.req_deregister()
		time.sleep(1)
		utils.releaseDhcp()
#MMW 2008.06.25 when reboot is called, reset vega and DCP related GPIO pin				
		utils.vega_reset_together()
#end of MMW	
#MMW	2008.07.07	when reboot send disassoc to AP and then unload the driver
		os.system('wlstop')
#end of MMW
		time.sleep(1)
		os.system('reboot')
		return False
#Roxia Begin smyook 06.02.27
	def handle_key(self, key):
		return True
#Roxia End smyook

class NotiStage(NotifyStage):
	if config.update_debug:print 'NotiStage'
	def __init__(self, dequeue_num):
		icon = uiconfig.baloon_phone_setting_icon
		if dequeue_num == 1:
			#msg = _('During software update Incoming calls can\'t be received.')
			msg = uiconifg.WD_0265
		else:
			#msg = _('Wait the end of the procedure.')
			msg = uiconifg.WD_0265
			
		NotifyStage.__init__(self, msg, icon)

		self.dequeue_num = dequeue_num
		self.ui.set_left( '' )
		self.ui.set_right( _('END') )
		#self.ui.set_title(_('UPDATE SOFTWARE'))
		self.ui.set_title(_('Software update'))

	def cancel(self):
		runtime.manager.pop_stage().destroy()
		runtime.manager.pop_stage().destroy()
		runtime.manager.change_stage(UpdateInterrupted)

	def handle_key(self, key):

		if key in (config.Menu2, config.Red):
			for i in range(self.dequeue_num):
				runtime.manager.pop_stage().destroy()
				runtime.manager.pop_stage().destroy()

		elif key in '0123456789#*' or key in (config.Green, config.Video, config.OffHook, config.OnHook):
			if profile.get_profile() == 0:
				if key == config.OnHook:
					#runtime.manager.change_stage(UpdateInterrupted( _('Software update interrupted'), key_action=True))
					runtime.manager.change_stage(UpdateInterrupted( _('Software update interrupted'), key_action=True))
					return True
				else:
					return True
			else:
				pass # IP mode일 경우, 원래 처리대로

		key_manager(key)
		return True
		
# shchun : firmware download...
class ConfirmManualDownloadYesNo(YesNoStage):
	domonitor_forbidden = True
	def __init__(self):
		YesNoStage.__init__(self, _('Do you want update to latest version?'), self.yes_cb, self.no_cb, '', uiconfig.baloon_phone_setting_icon)

	def yes_cb(self):
		runtime.manager.change_stage(VersionCheckStage)

	def no_cb(self):
		runtime.manager.back_stage()
		
	def handle_key(self, key):
		if key == config.Red:
			self.no_cb()
			return True
		else:
			return YesNoStage.handle_key(self, key)

class ConfigManualDownload(ListStage):
	name = 'mDownload'	
	icon = uiconfig.setting_system_technical_icon
	domonitor_forbidden = True

	def __init__(self):
		self.title = _('DOWNLOAD OPTIONS')
	
		#self.choice =  _('Server Address'), _('Server Port'), _('SW Type')
		self.choice = _('Server address'), _('Port')
		ListStage.__init__(self, self.choice)
		
	def set_cb(self, ui):
		import menu
		text = ui.get_text()
		if len(text) == 0:
			#runtime.manager.stack_stage(menu.VoIPSettingNotifyStage(_('No text inserted.')))
			runtime.manager.stack_stage(menu.VoIPSettingNotifyStage(_('Input a value')))

		else:
			down_setting.set_download_server_ip(text.strip())
			#runtime.manager.change_stage(menu.VoIPSettingNotifyStage(_('Menual download server set')))
			runtime.manager.change_stage(menu.VoIPSettingNotifyStage(_('Download server set')))


	def activate(self, index):		
		if index == 0:
			#stage = ConfigManualDownloadServerAddress
			value = down_setting.get_download_server_ip()
			title = _('manual download address')
			subtitle = _('manual download address')
			max = 50

			import menu
			stage = menu.VoIPEditor(title, subtitle, self.set_cb, text=value, textmax = max, ischr=True, need_hangul=False,  only_num = 0)
			runtime.manager.stack_stage(stage)

		elif index == 1:
			stage = ConfigManualDownloadServerPort
			runtime.manager.stack_stage(stage)
		#elif index == 2:
		#	stage = ConfigManualDownloadSWType
		#	runtime.manager.stack_stage(stage)

class ConfigManualDownloadServerPort(Stage):
	icon = uiconfig.setting_system_technical_icon
	domonitor_forbidden = True
	def __init__(self):
		import ui
		#self.ui = ui.NormalDigitEditUI('', _('SERVER PORT'), _('port'), 5)
		self.ui = ui.NormalDigitEditUI('', _('SERVER PORT'), _('Port'), 5)
		#if setting.download_server_port:
		#	self.ui.set_text(str(setting.download_server_port))

		server_port = down_setting.get_download_server_port()
		self.ui.set_text(str(server_port))

		self.icon = uiconfig.baloon_phone_setting_icon
			
	def handle_key(self, key):
		import basemodel
		if key == config.Menu1:
			str_port = self.ui.get_text()
			#setting.download_server_port = int(str_port)
			#setting.save()
			try:
				int_port = int(str_port)
			except:
				int_port = 0

			down_setting.set_download_server_port(int_port)
			
			if len(str_port) > 0:
				#message = _('Download server port set')
				message = _('Download Port is Set')
			else:
				#message = _('Download server port deleted')
				message = _('Download Port is deleted.')
				
			stage = NotifyStage(message, self.icon)
			runtime.manager.change_stage(stage)			
		else:
			return self.ui.handle_key(key)

			
class ConfigManualDownloadServerAddress(Stage): # obselete
	icon = uiconfig.setting_system_technical_icon
	def __init__(self):
		
		import ui
		self.ui = ui.NormalDigitEditUI('', _('SERVER ADDRESS'), _('IP address'), 50)
		self.ui.set_text(down_setting.get_download_server_ip())
		icon = uiconfig.setting_system_technical_icon
		self.flag = 0
		
	def insert_symbol(self, s):
		before_text = self.ui.get_text()
		self.ui.insert_text(s)
		after_text = self.ui.get_text()
		if before_text == after_text:
			#runtime.manager.change_stage(NotifyStage(_('Max length exceeded'), uiconfig.baloon_phone_setting_icon))
			runtime.manager.change_stage(NotifyStage(_('Invalid Value'), uiconfig.baloon_phone_setting_icon))

		else:
			runtime.manager.back_stage()
			
	def handle_key(self, key):
		import basemodel
		if key == config.Menu1:
			iserror = False
			str_ip = self.ui.get_text()

			ipadd = str_ip.split('.') #coming number > 255
			if len(ipadd) == 4:
				for z in range(len(ipadd)):
					if not ipadd[z]:
						iserror = True
						break
					if int(ipadd[z].strip())>255:
						iserror = True
						break
			else:
				iserror = True

			if iserror:
				#stage = basemodel.NotifyStage(_('Invalid address'), self.icon)
				stage = basemodel.NotifyStage(_('Invalid Address'), self.icon)
				runtime.manager.stack_stage(stage)
				return True

			for z in range(len(ipadd)):
				ipadd[z] = int(ipadd[z].strip())
			str_ip = '%d.%d.%d.%d' % (ipadd[0], ipadd[1], ipadd[2], ipadd[3])

# eicho 06.07.08
			#cur_profile.copy_old_values()
			#setting.download_server_ip = str_ip
			#setting.save()
 			down_setting.set_download_server_ip(str_ip)

			if str_ip:
				message = _('Download server address set')
			else:
				message = _('Download server address deleted')
			stage = NotifyStage(message, self.icon)
			runtime.manager.change_stage(stage)
###
		elif key in '#':
			if self.flag == 0:
				self.ui.set_automata('multitap', 'lower')
				self.flag = 1
			elif self.flag == 1:
				self.ui.set_automata('123', False)
				self.flag = 0
			else:
				self.automata_idx = utils.get_automata_idx(*self.ui.automata)
				self.automata_idx += 1
				if self.automata_idx >= len(config.automata_list):
					self.automata_idx = 3
				name, casemode = config.automata_list[self.automata_idx]
				self.ui.set_automata(name, casemode)
		elif key == '*':
			self.ui.reset_automata()
			if self.ui.entry.ascii_mode_case0:
				runtime.manager.stack_stage(basemodel.SymbolSelectionStage(self, case=0))
			elif self.ui.entry.ascii_mode_case1:
				runtime.manager.stack_stage(basemodel.SymbolSelectionStage(self, case=1))
			elif self.ui.entry.ascii_mode_case2:
				runtime.manager.stack_stage(basemodel.SymbolSelectionStage(self, case=2))
			else:
				runtime.manager.stack_stage(basemodel.SymbolSelectionStage(self, True))
			return True
###
		else:
			return self.ui.handle_key(key)

class ConfigManualDownloadSWType(ListStage):
	name = 'mDownload'	
	icon = uiconfig.setting_system_technical_icon
	module_info ='/usr/local/lgvp/var/module.info'
	def __init__(self):
		self.title = _('SW Type')
		self.choice = []
		# extract module info from /usr/local/lgvp/var/module.info 1st column.....
		f = open(self.module_info, 'r')
		line = f.readline()
		while len(line) > 0:
			print 'read line : ', line 
			self.choice.append(line.split(' ')[0])
			line = f.readline()
			
		#self.choice =  _('All'), _('App'), _('Configuration'), _('Misc')
		ListStage.__init__(self, self.choice)

		for i in range(len(self.choice)):
			if self.choice[i] == setting.download_type:
				self.ui.set_focus(i)

		#self.ui.set_focus(setting.download_type)
	def activate(self, index):		
		setting.download_type = self.choice[index]
		setting.save()
 		#message = _('SW type set.')
		message = _('Software type is set')
		
		stage = NotifyStage(message, self.icon)
		runtime.manager.change_stage(stage)