Newer
Older
Import / projects / LGN-IP3870 / t / orig / dectHandler.py
# -*- coding: euc-kr -*-

#-------------------------------------------------------------------------------
# Name:		dectHandler
# Purpose:	 MMI와 DECT간에 사용되는 함수를 정의한다.
#
# Author:	  류호창
#
# Created:	 15-12-2007
# Copyright:   (c) LG-Nortel 2007
# Licence:	 <Ryoo Ho Chang GGU!>
#-------------------------------------------------------------------------------
import os
import socket
import dectConfig
from dectConfig import MessageCode
import runtime
from runtime import mmiDebug as MD 
import config
import struct
import status
import utils
from setting import setting 
from vdcisetting import vdci_setting
from mmiSoundPath import Device, SP_State, SP_Context
import profile
import calldb
import time, ntptime

dectDebug = True

def getNetworkStatus():
	return True

def getLinkStatus():
	return True
		
class DectHandler:
	# member

	ACCEPTABLE = 0
	NOT_ACCEPTABLE = 1

	SUCCESS = 0
	FAILURE = 1
	RANGE_OUT = 2
	
	IDLE = 0
	SUBSCRIPTION = 1
	DE_SUBSCRIPTION = 2
	PAGING = 1

	ZERO_PAD = 0

	DIAL_TONE = 0
	WAITING_TONE = 1
	NO_TONE = 2

	DEFAULT = 0
	BASE_TO_HANDSET_AND_NETWORK = 1
	BASE_TO_HANDSET = 2
	BASE_TO_NETWORK = 3

	SMS_SENDING_TIMER = 20 * 1000 # 20 second
	SMS_RECEIVING_TIMER = 25 * 1000 # 25 second
	
	def __init__(self):
		self.dectHandler_pid = None
		self.dectClientSocket = None
		self.dectReceveHandler = None

		self.overlap = False
		self.playingDialTone = False

		self.with_error = False

		self.subsRequsetType = None
		self.pagingRequestType = None

		self.dectSendingSms = False
		self.H2B_SMS_SEND_NOTIFY_TIMER = None

		self.B2H_SMS_RECV_NOTIFY_ACK_TIMER = None	
		
		self.isProcessingCidType2 = False

		# 임시 sms 전송을 위해 사용
		self.retrySendingSmsToDectTimer = None
		
		self.runDectHandler()

	def isDectSendingSms(self):
		return self.dectSendingSms
		
	def runDectHandler(self):
		MD.mmiTrace('DectHandler.runDectHandler()')

		self.dectClientSocket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
		self.dectClientSocket.setblocking( 1 )

		import time
		try_connect = 0
		while try_connect < 5:
			try_connect += 1
			connected = True
			try:
				self.dectClientSocket.connect(config.dect_socket_path)
			except:
				connected = False

			if connected:
				MD.mmiTrace('**  dect_sock_app socket connected! **')
				import evas
				self.dectReceveHandler=runtime.evas.input_add(self.dectClientSocket.fileno(), evas.INPUT_READ, self.messageHandlerFromDect)
				break
			else: # sock connect error, retry..
				MD.mmiTrace('** dect_sock_app socket connect failed, retry', try_connect, '**')
				time.sleep(1)

	def H2B_ACK(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, msg_id, response, call_index = struct.unpack('=bBbH', data)

		MD.mmiTrace('line number = ', lnNo)
		MD.mmiTrace('msg_id = ', msg_id)
		MD.mmiTrace('response = ', response)
		MD.mmiTrace('call_index = ', call_index)

		MD.mmiTrace('CALL H2B_ACK FUNCTION = ', dectConfig.DICT_B2H_ACK_FUNCTION[msg_id])
		self.H2B_ACK_Run(dectConfig.DICT_B2H_ACK_FUNCTION[msg_id], lnNo, response, call_index)

	def H2B_ACK_Run(self, cmd, *param):
		if hasattr(self, cmd):
			func = getattr(self, cmd)
			func(param)

	def H2B_CONFIG_ACK(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, msg_id, response, call_index = struct.unpack('=bBbH', data)

		MD.mmiTrace('line number = ', lnNo)
		MD.mmiTrace('msg_id = ', msg_id)
		MD.mmiTrace('response = ', response)
		MD.mmiTrace('call_index = ', call_index)

		MD.mmiTrace('CALL H2B_CONFIG_ACK FUNCTION = ', dectConfig.DICT_B2H_CONFIG_ACK_FUNCTION[msg_id])
		self.H2B_ACK_Run(dectConfig.DICT_B2H_CONFIG_ACK_FUNCTION[msg_id], lnNo, response, call_index)

	def H2B_CONFIG_ACK_Run(self, cmd, *param):
		if hasattr(self, cmd):
			func = getattr(self, cmd)
			func(param)

	def H2B_UPGRADE_ACK(self):
		pass
		
	def H2B_MAKE_CALL_NOTIFY(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, dial_number = struct.unpack('=B26s', data)
		dial_number = dial_number.split('\x00')[0]		
		MD.mmiTrace('line number = ', lnNo)
		MD.mmiTrace('dial_number = ', dial_number)

		callIndex = runtime.dectCallManager.makeCallIndex()
		
		response = self.ZERO_PAD
		self.B2H_ACK(lnNo, messageId, response, callIndex) 

		status.currentCallDuration = (0, 0, 0)
		status.currentCallDuration_copy = (0, 0, 0)
		status.serviceStatusType = None

		runtime.dectCallManager.startOutGoingCall(lnNo, number=dial_number)

		#runtime.dectCallManager.setDectStatus(DectCallManager.RINGBACK)

	def H2B_CANCEL_CALL_NOTIFY(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, call_index, cause = struct.unpack('=BHH', data)

		MD.mmiTrace('line number = ', lnNo)
		MD.mmiTrace('call_index = ', call_index)
		MD.mmiTrace('cause = ', cause)

		response = self.ZERO_PAD
		self.B2H_ACK(lnNo, messageId, response, call_index) 

		# 통화로 정리
		if lnNo == 1:
			ts1OnHook = runtime.SP_context.TS1_OnHook()
			if ts1OnHook.next():
				ts1OnHook.next()
		elif lnNo == 2:
			ts2OnHook = runtime.SP_context.TS2_OnHook()
			if ts2OnHook.next():
				ts2OnHook.next()
		else:
			MD.mmiTrace('Line Number Error!')
		
		runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
		
	def H2B_ACCEPT_CALL_NOTIFY(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, call_index, hsNo = struct.unpack('=BHB', data)
		MD.mmiTrace('line number = ', lnNo)
		MD.mmiTrace('call_index = ', call_index)
		MD.mmiTrace('handset number = ', hsNo)

		response = self.ZERO_PAD
		self.B2H_ACK(lnNo, messageId, response, call_index) 

		if status.DECT_PATH_TEST:
			runtime.manager.stage.connect()
		else:
			runtime.dectCallManager.setDectStatus(DectCallManager.CONNECTED)
			
			# 200 OK 에 대한 응답 송출
			if lnNo == 1:
				runtime.dectCallManager.setLineNumber(lnNo)
				runtime.manager.handle_key(True, config.TS1_OFF_HOOK)
			elif lnNo == 2:
				runtime.dectCallManager.setLineNumber(lnNo)
				runtime.manager.handle_key(True, config.TS2_OFF_HOOK)
			else:
				MD.mmiException('lnNo Error!!')
				
			# dect 가 응답을 주는 경우
			# 1. incoming 에 대한 응답
			if runtime.manager.stage.get_name() == 'incomingcall':
				pass
			# 2. transfer에 대한 응답
			elif runtime.manager.stage.get_name() == 'VideoCallConnected':
				pass
			else:
				#if runtime.eaHandler.isAppInUse():
				#	runtime.eaHandler.endCall()
				pass	
		
	def H2B_DROP_CALL_NOTIFY(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, call_index, cause = struct.unpack('=BHH', data)

		MD.mmiTrace('line number = ', lnNo)
		MD.mmiTrace('call_index = ', call_index)
		MD.mmiTrace('cause = ', cause)

		if runtime.manager.stage.get_name() == 'InUseByDect':
			runtime.SP_context.stopTonePlay()

		if lnNo == 1:
			ts1OnHook = runtime.SP_context.TS1_OnHook()
			if ts1OnHook.next():
				ts1OnHook.next()

				response = 0x00 # success
				self.B2H_ACK(lnNo, messageId, response, call_index) 

				if runtime.SP_context.getBaseStatus() == SP_Context.TRANSFER_RINGING:
					runtime.manager.stage.transferDroppedByDect()
					
				runtime.dectCallManager.stopCall()

				if runtime.manager.stage.get_name() == 'InUseByDect':
					devices = runtime.SP_context.getCurrentDevice()
					for device in devices:
						if device == SP_State.DEVICE_HS:						
							hsOnHook = runtime.SP_context.HS_OnHook()
							if hsOnHook.next():
								hsOnHook.next()
						elif device == SP_State.DEVICE_SPK:
							spkOnHook = runtime.SP_context.SPK_OnHook()
							if spkOnHook.next():
								spkOnHook.next()
								spkOnHook.next()
					runtime.manager.back_stage()
			else:
				response = 0x01 # Failure
				self.B2H_ACK(lnNo, messageId, response, call_index) 
				
		elif lnNo == 2:
			ts2OnHook = runtime.SP_context.TS2_OnHook()
			if ts2OnHook.next():
				ts2OnHook.next()

				response = 0x00 # success
				self.B2H_ACK(lnNo, messageId, response, call_index) 
				runtime.dectCallManager.stopCall()
			else:
				response = 0x01 # Failure
				self.B2H_ACK(lnNo, messageId, response, call_index) 
		else:
			MD.mmiTodo('lnNo is abnormal value!!!')
		
	def H2B_DTMF_NOTIFY(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, call_index, dtmf_string_length, dtmf_string = struct.unpack('=BHB26s', data)
		dtmf_string = dtmf_string.split('\x00')[0]
		
		MD.mmiTrace('line number = ', lnNo)
		MD.mmiTrace('call_index = ', call_index)
		MD.mmiTrace('dtmf_string_length = ', dtmf_string_length)
		MD.mmiTrace('dtmf_string = ', dtmf_string)

		# exchange this position with B2H_ACK for too long response time after pressing DTMF in DECT
		for dtmf in dtmf_string:
			runtime.vdciapp.send_dtmf(dtmf)

		response = self.ZERO_PAD
		self.B2H_ACK(lnNo, messageId, response, call_index) 

	def H2B_REG_ACK(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, msg_id, response, call_index = struct.unpack('=bBbH', data)

		MD.mmiTrace('line number = ', lnNo)
		MD.mmiTrace('msg_id = ', msg_id)
		MD.mmiTrace('response = ', response)
		MD.mmiTrace('call_index = ', call_index)

		if status.DECT_PATH_TEST:
			runtime.manager.stage.ringing()
		else:
			runtime.dectCallManager.sendTimeAndTelephoneInformation()
		'''
		if response in (DectCallManager.REG_SUCCESS, DectCallManager.REG_FAILURE):
			runtime.dectCallManager.sendTimeAndTelephoneInformation()
		else:		
			MD.mmiTrace('Nothing to do right now')
		'''
		
	def H2B_VP_ACK(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, msg_id, response, call_index = struct.unpack('=bBbH', data)

		MD.mmiTrace('line number = ', lnNo)
		MD.mmiTrace('msg_id = ', msg_id)
		MD.mmiTrace('response = ', response)
		MD.mmiTrace('call_index = ', call_index)

		MD.mmiTrace('CALL DICT_B2H_VP_ACK FUNCTION = ', dectConfig.DICT_B2H_VP_ACK_FUNCTION[msg_id])
		self.H2B_VP_ACK_Run(dectConfig.DICT_B2H_VP_ACK_FUNCTION[msg_id], lnNo, response, call_index)

	def H2B_VP_ACK_Run(self, cmd, *param):
		if hasattr(self, cmd):
			func = getattr(self, cmd)
			func(param)

	def H2B_VP_TRANS_REQUEST(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, call_index, type, hs_num = struct.unpack('=BHBB', data)

		IDLE = 0
		TRANSFER_FORM_HS_TO_VP = 1
		
		if type == IDLE:
			from mmiSoundPath import SP_Context
			if runtime.SP_context.getBaseStatus() == SP_Context.TRANSFER_RINGING:
				response = self.ACCEPTABLE
				self.B2H_VP_ACK(lnNo, messageId, response, call_index) 

				from mmiSoundPath import SP_Context
				baseCallStatus = runtime.SP_context.getBaseCallStatus()
				if baseCallStatus in [SP_Context.OUTGOING_VIDEO, SP_Context.INCOMING_VIDEO]:
					runtime.manager.stage.transferCancelledByDect()
				else:
					runtime.manager.stage.transferCancelledByDect()
					runtime.manager.back_stage()
				
		elif type == TRANSFER_FORM_HS_TO_VP:
			response = self.ACCEPTABLE
			self.B2H_VP_ACK(lnNo, messageId, response, call_index) 

			# [20080904_2] : hcryoo : [QA 6-07] 2G로의 3인통화 시도시 전환을 하면 베이스의 영상 화면이 IDLE로 된다.
			from mmiSoundPath import SP_Context
			from dectHandler import DectCallManager
			baseCallStatus, baseStatus, dectCallStatus, dectStatus = status.getCurrentCallStatus()
			# [20080904_7] : hcryoo : [QE 29078] 음성호 통화중에 Second call착신도중 본체전환하여 본체응답시 LCD중첩됨
			if runtime.eaHandler.isAppInUse() or dectStatus == DectCallManager.RINGBACK or \
				runtime.manager.stage.get_name() == 'InUseByDect' or \
				status.serviceStatusType in ['RB', 'BR', 'RW', 'WR'] or \
				(status.serviceStatusType in ['WB', 'BW'] and 	\
				baseCallStatus in [SP_Context.OUTGOING_VIDEO, SP_Context.INCOMING_VIDEO] and \
				runtime.manager.stage.get_name() == 'AudioCallConnected'):
				self.B2H_VP_TRANS_RESULT(lnNo, call_index, type=1, result=1) 
			else:
				from mmiSoundPath import SP_Context
				baseCallStatus = runtime.SP_context.getBaseCallStatus()
				if baseCallStatus in [SP_Context.OUTGOING_VIDEO, SP_Context.INCOMING_VIDEO]:
					runtime.manager.stage.transferCallbyDect(hs_num)
				else:
					from model import H2B_TransferStage
					runtime.manager.change_stage(H2B_TransferStage(hs_num), True)				
			# [20080904_2] : hcryoo : [QA 6-07] 2G로의 3인통화 시도시 전환을 하면 베이스의 영상 화면이 IDLE로 된다.==
			# [20080904_7] : hcryoo : [QE 29078] 음성호 통화중에 Second call착신도중 본체전환하여 본체응답시 LCD중첩됨 ==
		
	def H2B_VP_PAGING_RESULT(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, call_index, type, result = struct.unpack('=BHBB', data)

		response = self.ZERO_PAD
		self.B2H_VP_ACK(lnNo, messageId, response, call_index) 

		if type == self.PAGING:
			if result == self.SUCCESS:
				runtime.dectCallManager.pagingSucceeded()
			elif result == self.FAILURE:
				runtime.dectCallManager.pagingFailed()
			else:
				MD.mmiException('ERROR in PAGING Result')
		elif type == self.IDLE:
			MD.mmiTrace('CURRENTLY NOT PROVIDED') 


	def H2B_VP_SUBS_RESULT(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, call_index, type, result = struct.unpack('=BHBB', data)
		MD.mmiTrace('type = ', type)
		MD.mmiTrace('result = ', result)

		response = self.ZERO_PAD
		self.B2H_VP_ACK(lnNo, messageId, response, call_index) 

		if type == self.SUBSCRIPTION:
			if result == self.SUCCESS:
				runtime.dectCallManager.subscriptionSucceeded()
			elif result == self.FAILURE:
				runtime.dectCallManager.subscriptonFailed()
			else:
				MD.mmiException('ERROR in Subscription Result')
		elif type == self.IDLE:
			MD.mmiTrace('CURRENTLY NOT PROVIDED') 


	def H2B_UPGRADE_REQUEST(self):
		pass
		
	def H2B_SMS_SEND_NOTIFY(self, H2B_message):
		messageId, dataLength, data = H2B_message
		for i in range(9):
			MD.mmiTrace(i, ' = ', hex(ord(data[i])))

		lnNo, call_index, data_length, data = struct.unpack('=BHH650s', data)
		data_length = struct.pack('H', data_length)
		data_length = struct.unpack('<H', data_length)[0]

		MD.mmiTrace('line number = ', lnNo)
		MD.mmiTrace('call_index = ', call_index)
		MD.mmiTrace('data_length = ', data_length)

		response = self.ZERO_PAD
		self.B2H_SMS_ACK(lnNo, messageId, response, call_index) 

		# 임시로 HS에서 올라온 call_index를 저장한다.
		runtime.dectCallManager.setCallIndex(call_index)
		
		data = data[:data_length]
		
		for i in range(data_length):
			MD.mmiTrace(i, ' = ', hex(ord(data[i])))
		
		runtime.dectCallManager.sendSmsFromDect(data_length, data)

		self.dectSendingSms = True
		
		def H2B_SMS_SEND_NOTIFY_CB():
			self.dectSendingSms = False
			self.H2B_SMS_SEND_NOTIFY_TIMER = None
			MD.mmiTodo('타임 아웃이 되면 뭘 하나 ?')
			
		import utils	
		self.H2B_SMS_SEND_NOTIFY_TIMER = utils.Timer(self.SMS_SENDING_TIMER, H2B_SMS_SEND_NOTIFY_CB)

	def isNetworkAlive(self):
		isAlive = True
		cur_profile = profile.profile.get_profile()
		if cur_profile == 1:
			if profile.lan_profile.dhcp == 'yes' and not os.path.exists('/tmp/dhcpcd-eth0.info') or not status.LanConnected:
				isAlive = False
		elif cur_profile == 2:
			if profile.wifi_profile.dhcp == 'yes' and not os.path.exists('/tmp/dhcpcd-wlan0.info') or not status.wifi_connected:
				isAlive = False

		return isAlive

	def H2B_TONE_START_REQUEST(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, type, direction, hsNo = struct.unpack('=BBBB', data)

		if not self.isNetworkAlive():
			runtime.dectCallManager.cancelCall(MessageCode.LGN_Define.LAN_CABLE_NOT_CONNECTED)
			runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
			return

		response = 0x00 # success
		callIndex = runtime.dectCallManager.makeCallIndex()
		self.B2H_ACK(lnNo, messageId, response, callIndex) 

		# VC02를 사용하는 교통정보 사용중인 경우에도 busy처리한다. 2008.06.23
		if runtime.eaHandler.isShowingTraffic():
			MD.mmiTrace('*** BASE IN USE: Traffic service ***')
			runtime.dectCallManager.cancelCall(MessageCode.VP_STATUS.COMMON_NOTIFICATION)
			return
		# status는 사용중이 아닌데, 정리는 안된 상태를 위해
		runtime.eaHandler.stopTraffic()
		
		baseCallStatus, baseStatus, dectCallStatus, dectStatus = status.getCurrentCallStatus()
		if baseStatus == SP_Context.IDLE: # base 가 사용중이 아닌 경우
			if dectStatus ==DectCallManager.IDLE:
				runtime.SP_context.dect1.setStatus(Device.OFF_HOOK)
				runtime.dectCallManager.setDectCallStatus(DectCallManager.OUTGOING_AUDIO)
				runtime.dectCallManager.setDectStatus(DectCallManager.DIALING)	
				runtime.dectCallManager.openPcmChannel(lnNo)
				#runtime.vdci_play_tone(config.PLAY_DIAL_TONE)
				#runtime.SP_context.dect1.setTone(config.PLAY_RINGBACK_TONE)
				#runtime.SP_context.startTonePlay(SP_State.DEVICE_HSS1_TS1)
				runtime.dectCallManager.startDialTone()

			elif dectStatus ==DectCallManager.CONNECTED:
				if direction == self.DEFAULT:
					MD.mmiTrace('self.DEFAULT')
				elif direction == self.BASE_TO_HANDSET_AND_NETWORK:
					MD.mmiTrace('self.BASE_TO_HANDSET_AND_NETWORK')				
				elif direction == self.BASE_TO_HANDSET:
					MD.mmiTrace('self.BASE_TO_HANDSET')
				elif direction == self.BASE_TO_NETWORK:
					MD.mmiTrace('self.BASE_TO_NETWORK')
					runtime.dectCallManager.setInterCom(True)
					runtime.dectCallManager.playTransferMoh()
					runtime.SP_context.SP_setMicDisable()
					runtime.vdciapp.send_mesg(code1=config.MESG_SET_PARAMS, code2=config.MESG_SET_AUDIO_MUTE, mesg1=1, mesg2=1)
		else: # base가 사용중인 경우(영상 광고의 경우도 포 함)
			if (baseCallStatus in [SP_Context.INCOMING_VIDEO, SP_Context.OUTGOING_VIDEO] or (baseCallStatus == SP_Context.OUTGOING_AUDIO and status.pushVideoAd)) and dectStatus != DectCallManager.IDLE:
				if direction == self.DEFAULT:
					MD.mmiTrace('self.DEFAULT')
				elif direction == self.BASE_TO_HANDSET_AND_NETWORK:
					MD.mmiTrace('self.BASE_TO_HANDSET_AND_NETWORK')				
				elif direction == self.BASE_TO_HANDSET:
					MD.mmiTrace('self.BASE_TO_HANDSET')
				elif direction == self.BASE_TO_NETWORK:
					MD.mmiTrace('self.BASE_TO_NETWORK')
					runtime.dectCallManager.setInterCom(True)
					runtime.dectCallManager.playTransferMoh()
					runtime.SP_context.SP_setMicDisable()
					runtime.vdciapp.send_mesg(code1=config.MESG_SET_PARAMS, code2=config.MESG_SET_AUDIO_MUTE, mesg1=1, mesg2=1)
			else:
				MD.mmiTrace('DectHandler::H2B_TONE_START_REQUEST() ==================================') 
				baseCallStatus, baseStatus, dectCallStatus, dectStatus = status.getCurrentCallStatus()
				if baseCallStatus in [SP_Context.INCOMING_VIDEO, SP_Context.OUTGOING_VIDEO]:
					runtime.dectCallManager.cancelCall(MessageCode.VP_STATUS.VIDEO_CALL)
				else:
					runtime.dectCallManager.cancelCall(MessageCode.VP_STATUS.AUDIO_CALL)
				
		
	def H2B_TONE_STOP_REQUEST(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, hsNo = struct.unpack('=BB', data)

		response = 0x00 # success
		callIndex = runtime.dectCallManager.getCallIndex()

		if runtime.dectCallManager.isInterCom():
			runtime.dectCallManager.setInterCom(False)
			runtime.dectCallManager.stopTransferMoh()
			runtime.SP_context.SP_setMicEnable()
			runtime.vdciapp.send_mesg(code1=config.MESG_SET_PARAMS, code2=config.MESG_SET_AUDIO_MUTE, mesg1=0, mesg2=1)

		# 재부팅 시 핸드셋에서 종료할 경우 생기는 오류를 막기 위한 것.
		if not callIndex:
			callIndex = runtime.dectCallManager.makeCallIndex()
			
		self.B2H_ACK(lnNo, messageId, response, callIndex) 

		runtime.dectCallManager.stopDialTone()

	def H2B_RELEASED_NOTIFY(self, H2B_message):
		runtime.dectCallManager.setDectCallStatus(DectCallManager.IDLE)
		runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
	
		messageId, dataLength, data = H2B_message

		lnNo, call_index = struct.unpack('=BH', data)

		MD.mmiTrace('line number = ', lnNo)
		MD.mmiTrace('call_index = ', call_index)

		if status.DECT_PATH_TEST:
			runtime.manager.stage.close()

		#runtime.dectCallManager.setReleaseFromDect(False)
		

	def H2B_INFO_NOTIFY(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, call_index, information = struct.unpack('=BH10s', data)

		response = self.ZERO_PAD
		self.B2H_ACK(lnNo, messageId, response, call_index) 

		runtime.dectCallManager.sendFlash()
				
	def H2B_CONFIG_INFO_REQUEST(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo = struct.unpack('=B', data)

		runtime.dectCallManager.sendConfigInfo()
		
	def H2B_CONFIG_SET(self, H2B_message):
		pass

	def H2B_SMS_RECV_RESULT(self, H2B_message):
		self.B2H_SMS_RECV_NOTIFY_ACK_TIMER = None

		messageId, dataLength, data = H2B_message

		# parsing 오류로 인해 2byte를 1byte로 처리하기 위해 아래와 같이 수정함.
		lnNo, call_index, result1, result2 = struct.unpack('=BHBB', data)

		MD.mmiTrace('line number = ', lnNo)
		MD.mmiTrace('call_index = ', call_index)
		MD.mmiTrace('result = ', result1)
		
		response = self.ZERO_PAD
		self.B2H_SMS_ACK(lnNo, messageId, response, call_index)

		status.isSmsProcessing = False
	
		channel = runtime.dectCallManager.getChannel()
		print 'status.TEMP_MSG_CONDITION = ', status.TEMP_MSG_CONDITION
		
		if status.TEMP_MSG_CONDITION:
			print '>>>>>>>>>>>>> TEMP_MSG_CONDITION PROCESSED...'
			#runtime.vdciapp.send_mesg(code1=config.MESG_INCOMING_CALL, code2=config.MESG_MSG_REJECT, chan1=channel, mesg1='200')	
			#runtime.vmHandler.sendMessageWithDectConfirm()

			if result1 == self.FAILURE or result1 == self.RANGE_OUT:
				# 무조건 200 OK 주고 VM에 전송 후에 retry하는 걸로 수정
				print '>>>>>>>>>>>>> FAIL / RANGE OUT PROCESSED...'
				if status.tempMessagingTimer:
					def retrySendingSmsToDect():
						self.retrySendingSmsToDectTimer = None
						
						baseStatus, toAddress, contentType, subject, filePath, replyUser = runtime.vmHandler.getMMSInfoForMessageTest()
						runtime.dectCallManager.receiveSmsFromIsmc(channel, toAddress, contentType, subject, filePath, replyUser)

					print 'RETRY SENDING SMS TO DECT IN 5 SECOND LATER!!!'
					self.retrySendingSmsToDectTimer = utils.Timer(5*1000, retrySendingSmsToDect)
						
				else:
					print '>>>>>>>>>>>>>>>> End of Timer : FAIL!!!!!!!!!!!!!!!!'
			else:
				print 'RESULT IS 0 (OK!!)'
				status.tempMessagingTimer = None
		else:
			if result1 == self.FAILURE:
				runtime.vdciapp.send_mesg(code1=config.MESG_INCOMING_CALL, code2=config.MESG_MSG_REJECT, chan1=channel, mesg1=config.REASON_BUSY_HERE)	
			else:
				runtime.vdciapp.send_mesg(code1=config.MESG_INCOMING_CALL, code2=config.MESG_MSG_REJECT, chan1=channel, mesg1='200')	
				runtime.vmHandler.sendMessageWithDectConfirm()
		
	def H2B_SMS_ACK(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, msg_id, response, call_index = struct.unpack('=BBBH', data)

		MD.mmiTrace('line number = ', lnNo)
		MD.mmiTrace('msg_id = ', msg_id)
		MD.mmiTrace('response = ', response)
		MD.mmiTrace('call_index = ', call_index)

		MD.mmiTrace('CALL H2B_SMS_ACK FUNCTION = ', dectConfig.DICT_B2H_SMS_ACK_FUNCTION[msg_id])
		self.H2B_SMS_ACK_Run(dectConfig.DICT_B2H_SMS_ACK_FUNCTION[msg_id], lnNo, response, call_index)

	def H2B_SMS_ACK_Run(self, cmd, *param):
		if hasattr(self, cmd):
			func = getattr(self, cmd)
			func(param)

	def H2B_SYNCML_ACK(self, H2B_message):
		pass
		
	def H2B_SYNCML_START_NOTIFY(self, H2B_message):
		pass
		
	def H2B_SYNCML_DATA_NOTIFY(self, H2B_message):
		pass

	def H2B_SYNCML_END_NOTIFY(self, H2B_message):
		pass

	def H2B_SYNCML_DATA_ACK(self, H2B_message):
		pass

	def H2B_SYNCML_CANCEL_NOTIFY(self, H2B_message):
		pass

	def H2B_SYNCML_QUERY(self, H2B_message):
		pass

	def H2B_SYNCML_FILE_INFO(self, H2B_message):
		pass

	def H2B_SNMP_INFO_NOTIFY(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, hsInfo = struct.unpack('=B32s', data)
		hsInfos = struct.unpack('8s8s8s8s', hsInfo)

		response = self.ZERO_PAD
		callIndex = runtime.dectCallManager.makeCallIndex()
		self.B2H_SNMP_ACK(lnNo, messageId, response, callIndex) 

		hsInfos = hsInfos[:3] # 현재 dect는 4개를 보내고 KT 스펙은 3개를 요구함.
		MD.mmiTrace('*********************')
		for handsetInfo in hsInfos:
			for i in range(8):
				MD.mmiTrace(i, ' = ', hex(ord(handsetInfo[i])))
		
		dectInfos = []
		for handsetInfo in hsInfos:
			subs_info, vega_base_ver, vega_dect_ver, tcc_ver, serial_num = struct.unpack('=BBBB4s', handsetInfo)
			dectInfo = str(subs_info) + ':' + str(vega_base_ver) + ':' + str(vega_dect_ver) + ':' +str(tcc_ver) + ':' + serial_num 
			dectInfos.append(dectInfo)

		MD.mmiTrace('dectInfos = ', dectInfos)
		
		runtime.dectCallManager.setDectInformationList(dectInfos)


	def H2B_SNMP_INFO(self, H2B_message):
		messageId, dataLength, data = H2B_message

		lnNo, hsInfo = struct.unpack('=B32s', data)
		hsInfos = struct.unpack('8s8s8s8s', hsInfo)

		hsInfos = hsInfos[:3] # 현재 dect는 4개를 보내고 KT 스펙은 3개를 요구함.
		MD.mmiTrace('*********************')
		for handsetInfo in hsInfos:
			for i in range(8):
				MD.mmiTrace(i, ' = ', hex(ord(handsetInfo[i])))
		
		dectInfos = []
		for handsetInfo in hsInfos:
			subs_info, vega_base_ver, vega_dect_ver, tcc_ver, serial_num= struct.unpack('=BBBB4s', handsetInfo)
			dectInfo = str(subs_info) + ':' + str(vega_base_ver) + ':' + str(vega_dect_ver) + ':' +str(tcc_ver) + ':' + serial_num 
			dectInfos.append(dectInfo)

		MD.mmiTrace('dectInfos = ', dectInfos)
		
		runtime.dectCallManager.setDectInformationList(dectInfos)

	def H2B_REGISTER_REQUEST(self, H2B_message):
		messageId, dataLength, data = H2B_message

		#lnNo = struct.unpack('=B', data)

		response = self.ZERO_PAD
		callIndex = runtime.dectCallManager.makeCallIndex()
		self.B2H_REGISTER_ACK(1, messageId, response, callIndex) 

		if status.get_regstatus_mmi():
			runtime.dectCallManager.sendRegistrationReport(DectCallManager.REG_SUCCESS)
		else:
			# Ack
			runtime.manager.linkmonitor.restart_net_monitor(callnow=True)
			#runtime.manager.linkmonitor.del_do_monitor_cool_flag()
			#runtime.manager.linkmonitor.do_monitor(background=True, force=True)
			#runtime.manager.stage.handle_key(config.Green)

	def H2B_DEREGISTER_REQUEST(self, H2B_message):
		messageId, dataLength, data = H2B_message

		#lnNo = struct.unpack('B', data)

		response = self.ZERO_PAD
		callIndex = runtime.dectCallManager.makeCallIndex()
		self.B2H_DEREGISTER_ACK(1, messageId, response, callIndex) 

		if status.get_regstatus_mmi():
			import phonesetting
			runtime.manager.change_stage(phonesetting.DeRegisteringStage, True)
		else:
			runtime.dectCallManager.sendRegistrationReport(DectCallManager.REG_FAILURE)

	def H2B_DIAL_DTMF_NOTIFY(self, H2B_message):
		messageId, dataLength, data = H2B_message
	
		lnNo, dtmf_string_length, dtmf_string = struct.unpack('=BB26s', data)
		dtmf_string = dtmf_string.split('\x00')[0]

		MD.mmiTrace('line number = ', lnNo)
		MD.mmiTrace('dtmf string length = ', dtmf_string_length)
		MD.mmiTrace('dtmf string = ', dtmf_string)

		if dtmf_string_length == 1:
			MD.mmiTodo('해당 DTMF에 대한 톤을 발생해야 함.')
			runtime.SP_context.startKeyTonePlay(SP_State.DEVICE_HSS1_TS1, dtmf_string, dectConfig.DECT_TONE_DURATION)
		else:
			MD.mmiTodo('연속적인 DTMF 플레이 할것.--> 링고와 관련하여 오류를 발생시킴.')
			#for dtmf in range(dtmf_string_length):
			#	runtime.SP_context.startKeyTonePlay(SP_State.DEVICE_HSS1_TS1, dtmf_string[dtmf], dectConfig.DECT_TONE_DURATION)
				#import time
				#time.sleep(dectConfig.DECT_TONE_INTER_DIGIT_TIME)
				#import time
				#time.sleep(dectConfig.DECT_TONE_DURATION + dectConfig.DECT_TONE_INTER_DIGIT_TIME)

	def H2B_REJECT_CALL_NOTIFY(self, H2B_message):
		messageId, dataLength, data = H2B_message
	
		lnNo, call_index, hsNo = struct.unpack('=BHB', data)

		response = self.ZERO_PAD
		self.B2H_ACK(lnNo, messageId, response, call_index) 

		runtime.dectCallManager.sendTemporarilyUnavailable()

	def H2B_VP_RFPI_RESULT(self, H2B_message):
		messageId, dataLength, data = H2B_message
	
		lnNo, call_index, RFPI_0, RFPI_1, RFPI_2, RFPI_3, RFPI_4 = struct.unpack('=BHBBBBB', data)

		response = self.ZERO_PAD
		self.B2H_VP_ACK(lnNo, messageId, response, call_index) 

		runtime.manager.stage.showResult((RFPI_0, RFPI_1, RFPI_2, RFPI_3, RFPI_4))
	
	def B2H_ACK(self, lineNumber, messageId, response, callIndex):
		# header part
		msgId = dectConfig.B2H_ACK
		dataLength = 5

		# data part
		lnNo = struct.pack('b', lineNumber)
		msg_id = struct.pack('B', messageId)
		response = struct.pack('b', response)
		call_index = struct.pack('H', callIndex) 
		data = lnNo + msg_id + response + call_index
		#data = struct.pack('bbbh', lineNumber, messageId, response, callIndex)
		self.B2H_sendMessage(msgId, dataLength, data)
		
	def B2H_CONFIG_ACK(self):
		pass
		
	def B2H_STATUS_REPORT(self, lineNumber, statusType, networkLink, registrationStatus):
		messageId = dectConfig.B2H_STATUS_REPORT
		dataLength = 5

		lnNo = struct.pack('B', lineNumber)
		type = struct.pack('B', statusType) 
		net_link = struct.pack('<H', networkLink)
		reg_status = struct.pack('B', registrationStatus)
		
		data = lnNo + type + net_link + reg_status
		
		self.B2H_sendMessage(messageId, dataLength, data)
		

	def B2H_STATUS_REPORT_ACK(self, response):
		pass

	def B2H_VP_ACK(self, lineNumber, messageId, response, callIndex):
		# header part
		msgId = dectConfig.B2H_VP_ACK
		dataLength = 5

		# data part
		lnNo = struct.pack('b', lineNumber)
		msg_id = struct.pack('B', messageId)
		response = struct.pack('b', response)
		call_index = struct.pack('H', callIndex) 
		data = lnNo + msg_id + response + call_index
		#data = struct.pack('bbbh', lineNumber, messageId, response, callIndex)
		self.B2H_sendMessage(msgId, dataLength, data)
				
	def B2H_CONNECTED_CALL_NOTIFY(self, lineNumber, callIndex):
		messageId = dectConfig.B2H_CONNECTED_CALL_NOTIFY
		dataLength = 3

		lnNo = struct.pack('b', lineNumber)
		call_index = struct.pack('H', callIndex) 

		data = lnNo + call_index
		
		self.B2H_sendMessage(messageId, dataLength, data)

	def B2H_CONNECTED_CALL_NOTIFY_ACK(self, response):
		pass

	def B2H_VP_PAGING_REQUEST(self, lineNumber, callIndex, requestType):
		messageId = dectConfig.B2H_VP_PAGING_REQUEST
		dataLength = 4

		self.pagingRequestType = requestType
		
		lnNo = struct.pack('b', lineNumber)
		call_index = struct.pack('H', callIndex) 
		requestType = struct.pack('b', requestType)
		
		data = lnNo + call_index + requestType
		
		self.B2H_sendMessage(messageId, dataLength, data)

	def B2H_VP_PAGING_REQUEST_ACK(self, H2B_ACK_message):
		lineNumber, response, callIndex = H2B_ACK_message

		if self.pagingRequestType == self.IDLE: # cancel
			if response == self.ACCEPTABLE:
				MD.mmiTodo('PAGING CANCEL Request OK, maintain the current screen.')
			elif response == NOT_ACCEPTABLE:
				MD.mmiTodo('cancel paging rejected')
				runtime.dectCallManager.cancellingPagingRejected()
			else:
				MD.mmiException('ERROR in return value')
		elif self.pagingRequestType == self.PAGING:
			if response == self.ACCEPTABLE:
				MD.mmiTodo('PAGING Request OK, maintain the current screen.')
			elif response == NOT_ACCEPTABLE:
				MD.mmiTodo('cancel paging')
				runtime.dectCallManager.cancelReadyToPaging()
			else:
				MD.mmiException('ERROR in return value')
		self.pagingRequestType = None

	def B2H_NEW_CALL_NOTIFY(self, lineNumber, callIndex, absenceReason, destNumberLength, destNumber, destNameLength, destName, callForward=0):
		runtime.dectCallManager.setDectCallStatus(DectCallManager.INCOMING_AUDIO)
	
		messageId = dectConfig.B2H_NEW_CALL_NOTIFY
		dataLength = 68

		lnNo = struct.pack('b', lineNumber)
		call_index = struct.pack('H', callIndex) 
		import time, ntptime
		year, month, day, hour, min, sec, date = time.localtime(ntptime.ntime())[0:7]
		currentTime = struct.pack('<7H', year, month, day, hour, min, sec, date)
		absence_reason = struct.pack('s', absenceReason)
		dest_number_length = struct.pack('b', destNumberLength)
		dest_number = struct.pack('26s', destNumber)
		dest_name_length = struct.pack('b', destNameLength)
		dest_name = struct.pack('21s', destName)
		call_forward = struct.pack('B', callForward)
		
		data = lnNo + call_index + currentTime + absence_reason + dest_number_length + dest_number + dest_name_length+ dest_name + call_forward
		
		self.B2H_sendMessage(messageId, dataLength, data)

	def B2H_NEW_CALL_NOTIFY_ACK(self, H2B_ACK_message):
		lineNumber, response, callIndex = H2B_ACK_message

		MD.mmiTodo('lineNumber에 response의 결과를 저장하여 최종 수신 여부 결정')
		if response == 1:
			MD.mmiTrace('수신 가능한 상태')			
			if not self.isProcessingCidType2 and runtime.manager.stage.get_name() == 'B2H_Transfer':
				runtime.manager.stage.startTransferTimer()
			else:
				self.isProcessingCidType2 = False
		elif response == 2:
			MD.mmiTrace('BUSY : 수신 불가능한 상태')
			if not self.isProcessingCidType2 and runtime.manager.stage.get_name() == 'B2H_Transfer':
				runtime.manager.stage.transferCancelledByDectBusy()
			else:
				self.isProcessingCidType2 = False
		else:
			MD.mmiTodo('B2H_NEW_CALL_NOTIFY_ACK exception process')
			self.isProcessingCidType2 = False
		
	def B2H_CANCEL_CALL_NOTIFY(self, lineNumber, callIndex, cause):
		messageId = dectConfig.B2H_CANCEL_CALL_NOTIFY
		dataLength = 5

		lnNo = struct.pack('b', lineNumber)
		call_index = struct.pack('H', callIndex) 
		cause = struct.pack('<H', cause)
		
		data = lnNo + call_index + cause
		
		self.B2H_sendMessage(messageId, dataLength, data)

	def B2H_CANCEL_CALL_NOTIFY_ACK(self, H2B_ACK_message):
		lineNumber, response, callIndex = H2B_ACK_message

		self.B2H_RELEASED_NOTIFY(lineNumber, callIndex)
		
	def B2H_DROP_CALL_NOTIFY(self, lineNumber, callIndex, cause=200):
		messageId = dectConfig.B2H_DROP_CALL_NOTIFY
		dataLength = 5

		lnNo = struct.pack('b', lineNumber)
		call_index = struct.pack('H', callIndex) 
		cause = struct.pack('<H', 200)
		
		data = lnNo + call_index + cause
		
		self.B2H_sendMessage(messageId, dataLength, data)

	def B2H_DROP_CALL_NOTIFY_ACK(self, H2B_ACK_message):
		lineNumber, response, callIndex = H2B_ACK_message

		self.B2H_RELEASED_NOTIFY(lineNumber, callIndex)
				
	def B2H_VP_SUBS_REQUEST(self, lineNumber, callIndex, type, hsNumber=0xFF):
		messageId = dectConfig.B2H_VP_SUBS_REQUEST
		dataLength = 5

		self.subsRequestType = type
		
		lnNo = struct.pack('b', lineNumber)
		call_index = struct.pack('H', callIndex) 
		type = struct.pack('b', type)
		hs_num = struct.pack('B', hsNumber)
		
		data = lnNo + call_index + type + hs_num
		
		self.B2H_sendMessage(messageId, dataLength, data)

	def B2H_VP_SUBS_REQUEST_ACK(self, H2B_ACK_message):
		lineNumber, response, callIndex = H2B_ACK_message

		if self.subsRequestType == self.IDLE: # cancel
			if response == self.ACCEPTABLE:
				MD.mmiTodo('SUBSCRIBE CANCEL Request OK, maintain the current screen.')
			elif response == NOT_ACCEPTABLE:
				MD.mmiTodo('cancel subscriptoin rejected')
				runtime.dectCallManager.cancellingSubscriptionRejected()
			else:
				MD.mmiException('ERROR in return value')
		elif self.subsRequestType == self.SUBSCRIPTION:
			if response == self.ACCEPTABLE:
				MD.mmiTodo('SUBSCRIBE Request OK, maintain the current screen.')
			elif response == self.NOT_ACCEPTABLE:
				MD.mmiTodo('fail subscriptoin')
				runtime.dectCallManager.failReadyToSubscribe()
			else:
				MD.mmiException('ERROR in return value')
		elif self.subsRequestType == self.DE_SUBSCRIPTION:
			if response == self.ACCEPTABLE:
				MD.mmiTodo('DE_SUBSCRIBE Request OK, maintain the current screen.')
				runtime.dectCallManager.sendUnsubscribeKeyEvent(config.SUCCEED)
			elif response == self.NOT_ACCEPTABLE:
				MD.mmiTodo('fail de-subscriptoin')
				runtime.dectCallManager.sendUnsubscribeKeyEvent(config.FAIL)
			else:
				MD.mmiException('ERROR in return value')
			
		self.subsRequestType = None
		
	def B2H_VP_TRANS_RESULT(self, lineNumber, callIndex, type, result):
		messageId = dectConfig.B2H_VP_TRANS_RESULT
		#msgId = struct.pack('B', messageId)
		dataLength = 5
		
		lnNo = struct.pack('B', lineNumber)
		call_index = struct.pack('H', callIndex) 
		type = struct.pack('B', type)
		result = struct.pack('B', result)
		data = lnNo + call_index + type + result

		self.B2H_sendMessage(messageId, dataLength, data)

	def B2H_VP_TRANS_RESULT_ACK(self, response):
		pass
		
	def B2H_SMS_RECV_NOTIFY(self, lineNumber, callIndex, packetLength, smsData):
		messageId = dectConfig.B2H_SMS_RECV_NOTIFY
		dataLength = 655

		lnNo = struct.pack('B', lineNumber)
		call_index = struct.pack('H', callIndex) 
		data_length = struct.pack('<H', packetLength)
		
		SMS_data = struct.pack('650s', smsData)
		
		data = lnNo + call_index + data_length + SMS_data
		
		self.B2H_sendMessage(messageId, dataLength, data)

		def B2H_SMS_RECV_NOTIFY_CB():
			print 'ACK ================================>>>>>>>>>>>'
			print 'ACK ================================>>>>>>>>>>>'
			print 'ACK ================================>>>>>>>>>>>'

			if status.TEMP_MSG_CONDITION:
				status.tempMessagingTimer = None
	
			status.isSmsProcessing = False
			self.B2H_SMS_RECV_NOTIFY_ACK_TIMER = None
			# 메시지 수신에 대한 실패를 처리하기 위해 vdci에 메시지를 내린다.
			channel = runtime.dectCallManager.getChannel()
			runtime.vdciapp.send_mesg(code1=config.MESG_INCOMING_CALL, code2=config.MESG_MSG_REJECT, chan1=channel, mesg1=config.REASON_BUSY_HERE)	

		self.H2B_SMS_SEND_NOTIFY_ACK_TIMER = utils.Timer(self.SMS_RECEIVING_TIMER, B2H_SMS_RECV_NOTIFY_CB)

	def B2H_SMS_RECV_NOTIFY_ACK(self, H2B_ACK_message):
		lineNumber, response, callIndex = H2B_ACK_message

		# 현재 dect에서는 B2H_SMS_RECV_NOTIFY에 대한 reponse로 무조건 Success를 준다.
		import utils
		if response == self.SUCCESS:
			self.H2B_SMS_SEND_NOTIFY_ACK_TIMER = None
			MD.mmiTrace('SMS delivery OK from BASE to DECT :: Nothing To Do')			
		else:
			status.isSmsProcessing = False
			if status.TEMP_MSG_CONDITION:
				status.tempMessagingTimer = None
			self.B2H_SMS_RECV_NOTIFY_ACK_TIMER = None
		
			channel = runtime.dectCallManager.getChannel()
			runtime.vdciapp.send_mesg(code1=config.MESG_INCOMING_CALL, code2=config.MESG_MSG_REJECT, chan1=channel, mesg1=config.REASON_BUSY_HERE)	
		
	def B2H_SMS_SEND_RESULT(self, lineNumber, callIndex, result):
		self.dectSendingSms = False
		self.H2B_SMS_SEND_NOTIFY_TIMER = None

		messageId = dectConfig.B2H_SMS_SEND_RESULT
		dataLength = 5

		lnNo = struct.pack('B', lineNumber)
		call_index = struct.pack('H', callIndex) 
		result = struct.pack('<H', result)
		
		data = lnNo + call_index + result
		
		self.B2H_sendMessage(messageId, dataLength, data)

	def B2H_SMS_SEND_RESULT_ACK(self, response):
		pass
		
	def B2H_RELEASED_NOTIFY(self, lineNumber, callIndex):
		#runtime.mmedia.HAL_mixer_pause()
		ts1OnHook = runtime.SP_context.TS1_OnHook()
		if ts1OnHook.next():
			ts1OnHook.next()
		#runtime.mmedia.HAL_mixer_resume()

		runtime.dectCallManager.setDectCallStatus(DectCallManager.IDLE)
		runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
		
		messageId = dectConfig.B2H_RELEASED_NOTIFY
		dataLength = 3

		lnNo = struct.pack('b', lineNumber)
		call_index = struct.pack('H', callIndex) 
		
		data = lnNo + call_index
		
		self.B2H_sendMessage(messageId, dataLength, data)

	def B2H_RELEASED_NOTIFY_ACK(self, response):
		pass

	def B2H_CONFIG_INFO(self):
		msgId = dectConfig.B2H_CONFIG_INFO
		dataLength = 477
	
		from vdcisetting import vdci_setting
		import profile
		import phonesetting

		
		telNo = vdci_setting.tel_num
		user_pw = vdci_setting.auth_pwd
		ip_pstn = 1
		p_cscf_addr_1 = vdci_setting.proxy_addr
		p_cscf_addr_2 = vdci_setting.backup_proxy_addr
		sbc_addr_1 = vdci_setting.primary_sbc_addr
		sbc_addr_2 = vdci_setting.secondary_sbc_addr
		sode_addr = 'http://upgrade.ktsode.com:9080/'
		tos_mode = 1
		uri_mode = setting.urlPolicy
		subs_info, vega_base_ver, vega_dect_ver, tcc_ver, serial_num = setting.dect_information_list[0].split(':')
		VoIP_version = '0000.0000.0000'
		vega_BS_version = int(vega_base_ver)
		vega_HS_version = int(vega_dect_ver)
		TCC_version = int(tcc_ver)
		session_timer = vdci_setting.subscriber_expires
		dtmf_mode = status.get_current_dtmf_type()
		p2p_mode = 0

		terminalIp = '0.0.0.0'
		ipMode = 1
		terminalIpInfo = phonesetting.getIpAddress()
		if terminalIpInfo:
			terminalIp = terminalIpInfo[0]
			ipMode = terminalIpInfo[1]
		if ipMode:
			ip_mode_ = 1
		else:
			ip_mode_ = 3
		own_ip = terminalIp

		ipaddress_not_used, netmask, gateway, dns_addr_1, dns_addr_2 = phonesetting.getNetworkInfo()
		
		ppp_user_id= ''
		ppp_user_pwd = ''
		sms_svc_no = '1549'
		sms_host = ''

		'''
		defaultmac = "00:40:5a:00:00:00"
		try:
			p = os.popen("/sbin/ifconfig eth0")
			t=p.read()
			p.close()
			mac_addr= re.search("HWaddr ([0-9a-fA-F:]+)",t).group(1)
		
		except:
			mac_addr = defaultmac
		mac_addr = mac_addr.replace(':', '')
		'''
		mac_addr = phonesetting.getMACNumber().replace(':', '')
		
		area_code = setting.prefix[1:]
		p_cscf_port_1 = vdci_setting.proxy_port
		s_cscf_port_2 = vdci_setting.backup_proxy_port
		p_sbc_port_1 = vdci_setting.primary_sbc_port
		s_sbc_port_2 = vdci_setting.secondary_sbc_port
		auth_id = vdci_setting.auth_name
		user_addr = vdci_setting.domain
		sip_uri = ''

		print 'phonesetting.getWiFiMAC() = ', phonesetting.getWiFiMAC()
		WIFI_mac_addr = phonesetting.getWiFiMAC().replace(':', '')

		_telNo = struct.pack('15s', telNo)
		_user_pw = struct.pack('11s', user_pw)
		_ip_pstn = struct.pack('B', ip_pstn)
		_p_cscf_addr_1 = struct.pack('40s', p_cscf_addr_1)
		_p_cscf_addr_2 = struct.pack('40s', p_cscf_addr_2)
		_sbc_addr_1 = struct.pack('40s', sbc_addr_1)
		_sbc_addr_2 = struct.pack('40s', sbc_addr_2)
		_sode_addr = struct.pack('40s', sode_addr)
		_tos_mode = struct.pack('B', tos_mode)
		_uri_mode = struct.pack('B', uri_mode)
		_VoIP_version = struct.pack('15s', VoIP_version)
		_version = struct.pack('BBBs', vega_BS_version, vega_HS_version, TCC_version, '')
		_session_timer = struct.pack('L', int(session_timer))
		_dtmf_mode = struct.pack('B', dtmf_mode)
		_p2p_mode = struct.pack('B', p2p_mode)
		_ip_mode = struct.pack('B', ip_mode_)
		own_ip_address1, own_ip_address2, own_ip_address3, own_ip_address4 = own_ip.split('.')
		_own_ip = struct.pack('4B', int(own_ip_address1), int(own_ip_address2), int(own_ip_address3), int(own_ip_address4))
		netmask_address1, netmask_address2, netmask_address3, netmask_address4 = netmask.split('.')
		_netmask = struct.pack('4B', int(netmask_address1), int(netmask_address2), int(netmask_address3), int(netmask_address4))
		gateway_address1, gateway_address2, gateway_address3, gateway_address4 = gateway.split('.')
		_gateway = struct.pack('4B', int(gateway_address1), int(gateway_address2), int(gateway_address3), int(gateway_address4))
		dns_addr_1_address1, dns_addr_1_address2, dns_addr_1_address3, dns_addr_1_address4 = dns_addr_1.split('.')
		_dns_addr_1 = struct.pack('4B', int(dns_addr_1_address1), int(dns_addr_1_address2), int(dns_addr_1_address3), int(dns_addr_1_address4))
		dns_addr_2_address1, dns_addr_2_address2, dns_addr_2_address3, dns_addr_2_address4 = dns_addr_2.split('.')
		_dns_addr_2 = struct.pack('4B', int(dns_addr_2_address1), int(dns_addr_2_address2), int(dns_addr_2_address3), int(dns_addr_2_address4))
		_ppp_user_id = struct.pack('21s', ppp_user_id)
		_ppp_user_pwd = struct.pack('11s', ppp_user_pwd)
		_sms_svc_no = struct.pack('11s', sms_svc_no)
		_sms_host = struct.pack('21s', sms_host)
		_mac_addr = struct.pack('13s', mac_addr)
		_area_code = struct.pack('3s', area_code)
		_p_cscf_port_1 = struct.pack('6s', p_cscf_port_1)
		_s_cscf_port_2 = struct.pack('6s', s_cscf_port_2)
		_p_sbc_port_1 = struct.pack('6s', p_sbc_port_1)
		_s_sbc_port_2 = struct.pack('6s', s_sbc_port_2)
		_auth_id = struct.pack('33s', auth_id)
		_user_addr = struct.pack('21s', user_addr)
		_sip_uri = struct.pack('21s', sip_uri)
		_WIFI_mac_addr = struct.pack('13s', WIFI_mac_addr)

		data = _telNo + _user_pw + _ip_pstn + _p_cscf_addr_1 + _p_cscf_addr_2 + _sbc_addr_1 + _sbc_addr_2 + \
			_sode_addr + _tos_mode + _uri_mode + _VoIP_version + _version + _session_timer + _dtmf_mode + \
			_p2p_mode + _ip_mode + _own_ip + _netmask + _gateway + _dns_addr_1 + _dns_addr_2 + _ppp_user_id + \
			_ppp_user_pwd + _sms_svc_no + _sms_host + _mac_addr + _area_code + _p_cscf_port_1 + _s_cscf_port_2 + _p_sbc_port_1 + \
			_s_sbc_port_2 + _auth_id + _user_addr + _sip_uri + _WIFI_mac_addr

		self.B2H_sendMessage(msgId, dataLength, data)
		
	def B2H_CONFIG_INFO_ACK(self, response):
		pass

	def B2H_SMS_ACK(self, lineNumber, messageId, response, callIndex):
		# header part
		msgId = dectConfig.B2H_SMS_ACK
		dataLength = 5

		# data part
		lnNo = struct.pack('b', lineNumber)
		msg_id = struct.pack('B', messageId)
		response = struct.pack('b', response)
		call_index = struct.pack('H', callIndex) 
		data = lnNo + msg_id + response + call_index
		self.B2H_sendMessage(msgId, dataLength, data)
		
	def B2H_SYNCML_ACK(self):
		pass
		
	def B2H_VP_PASSWORD_CHANGE(self, lineNumber, callIndex, pwd):
		messageId = dectConfig.B2H_VP_PASSWORD_CHANGE
		dataLength = 7		
		
		lnNo = struct.pack('b', lineNumber)
		call_index = struct.pack('H', callIndex) 
		password = struct.pack('4s', pwd)
		
		data = lnNo + call_index + password
		
		self.B2H_sendMessage(messageId, dataLength, data)


	def B2H_VP_PASSWORD_CHANGE_ACK(self, response):
		pass
		
	def B2H_SYNCML_DATA_NOTIFY(self):
		pass
		
	def B2H_SYNCML_END_NOTIFY(self):
		pass
		
	def B2H_SYNCML_RESULT(self):
		pass
		
	def B2H_SYNCML_CANCEL_NOTIFY(self):
		pass
		
	def B2H_TIME_TEL_INFO(self, lineNumber, telephoneNumber):
		msgId = dectConfig.B2H_TIME_TEL_INFO
		dataLength = 36
		
		lnNo = struct.pack('b', lineNumber)
		import time, ntptime
		year, month, day, hour, min, sec, date = time.localtime(ntptime.ntime())[0:7]
		currentTime = struct.pack('<7H', year, month, day, hour, min, sec, date)
		tel_num = struct.pack('21s', telephoneNumber)
		data = lnNo + currentTime + tel_num

		self.B2H_sendMessage(msgId, dataLength, data)

	def B2H_TIME_TEL_INFO_ACK(self, H2B_ACK_message):
		lineNumber, response, callIndex = H2B_ACK_message

		MD.mmiTrace('B2H_TIME_TEL_INFO_ACK : Nothing To do ')
		
	def B2H_UPGRADE_REPORT(self):
		pass
		
	def B2H_UPGRADE_ACK(self):
		pass

	def B2H_SNMP_ACK(self, lineNumber, messageId, response, callIndex):
		# header part
		msgId = dectConfig.B2H_SNMP_ACK
		dataLength = 5

		# data part
		lnNo = struct.pack('b', lineNumber)
		msg_id = struct.pack('B', messageId)
		response = struct.pack('b', response)
		call_index = struct.pack('H', callIndex) 
		data = lnNo + msg_id + response + call_index

		self.B2H_sendMessage(msgId, dataLength, data)

	def B2H_SNMP_INFO_REQUEST(self, lineNumber):
		msgId = dectConfig.B2H_SNMP_INFO_REQUEST
		dataLength = 1

		lnNo = struct.pack('b', lineNumber)
		
		data = lnNo
		
		self.B2H_sendMessage(msgId, dataLength, data)

	def B2H_REGISTER_ACK(self, lineNumber, messageId, response, callIndex):
		# header part
		msgId = dectConfig.B2H_REGISTER_ACK
		dataLength = 5

		# data part
		lnNo = struct.pack('B', lineNumber)
		msg_id = struct.pack('B', messageId)
		response = struct.pack('B', response)
		call_index = struct.pack('H', callIndex) 
		data = lnNo + msg_id + response + call_index

		self.B2H_sendMessage(msgId, dataLength, data)

	def B2H_VP_RESET_REQUEST(self, lineNumber, type):
		# header part
		msgId = dectConfig.B2H_VP_RESET_REQUEST
		dataLength = 4

		# data part
		lnNo = struct.pack('b', lineNumber)
		callIndex = runtime.dectCallManager.makeCallIndex() # one time
		call_index = struct.pack('H', callIndex) 
		type = struct.pack('b', type)
		data = lnNo + call_index + type

		self.B2H_sendMessage(msgId, dataLength, data)

	def B2H_DEREGISTER_ACK(self, lineNumber, messageId, response, callIndex):
		# header part
		msgId = dectConfig.B2H_DEREGISTER_ACK
		dataLength = 5

		# data part
		lnNo = struct.pack('B', lineNumber)
		msg_id = struct.pack('B', messageId)
		response = struct.pack('B', response)
		call_index = struct.pack('H', callIndex) 
		data = lnNo + msg_id + response + call_index

		self.B2H_sendMessage(msgId, dataLength, data)

	def B2H_VP_RESET_REQUEST_ACK(self, H2B_VP_ACK_message):
		lineNumber, response, callIndex = H2B_VP_ACK_message

		if status.DECT_RESET_TEST:
			runtime.manager.stage.changeMessage()
		else:
			runtime.manager.stage.resultSucceed()

	def B2H_VP_RFPI_REQUEST(self, lineNumber, type):
		# header part
		msgId = dectConfig.B2H_VP_RFPI_REQUEST
		dataLength = 4

		# data part
		lnNo = struct.pack('b', lineNumber)
		callIndex = runtime.dectCallManager.makeCallIndex() # one time
		call_index = struct.pack('H', callIndex) 
		type = struct.pack('b', type)
		data = lnNo + call_index + type

		self.B2H_sendMessage(msgId, dataLength, data)

	def B2H_sendMessage(self, messageId=None, dataLength=None, data=''):
		MD.mmiTrace('==> B2H_sendMessage')

		# 덱트와의 동기화를 위해 sleep을 20ms준다.
		import time
		time.sleep(0.03)

		packedMessageId = struct.pack('B', messageId)
		packedDataLength = struct.pack('H', dataLength)
		B2H_message = [packedMessageId, packedDataLength, data]
		B2H_messageString = ''.join(B2H_message)

		MD.mmiTrace('SEND BASE ==> TS')
		msgLen = len(B2H_messageString)
		for i in range(msgLen):
			if i ==10:
				break
			MD.mmiTrace(i, '=', hex(ord(B2H_messageString[i])))
			
		if self.dectClientSocket != None:
			try:
				self.dectClientSocket.send(B2H_messageString)
			except:
				pass

	def messageHandlerFromDect(self,dectClientSocket,type):
		import status
		try:
			socketMessage = self.dectClientSocket.recv( 2054 )
			MD.mmiTrace('MSG length from DECT = ', len(socketMessage))
		except:
			MD.mmiException('messageHandlerFromDect()')
			MD.mmiTodo('processing dect exception')
			return

		if len( socketMessage ) == 0:	# Disconnected from unix socket
			if self.dectReceveHandler != None:
				runtime.evas.input_remove(self.dectReceveHandler)
				self.dectReceveHandler = None
			return

		if ord(socketMessage[0]) != 0:
			socketMessages = [socketMessage]
			if len(socketMessage) > 1027:
				socketMessages = [socketMessage[:1027], socketMessage[1027:]]
			for socketMessage in socketMessages:
				try:
					MD.mmiTrace('RECEIVE DECT ==> BASE')
					for i in range(11):
						MD.mmiTrace(i, ' = ', hex(ord(socketMessage[i])))
				except:
					MD.mmiTrace('PRINT INDEX ERROR ')			
					
					
				messageId = socketMessage[0]
				networkDataLength = socketMessage[1:3]
				dataLength = struct.unpack('H', networkDataLength)[0]
				
				MD.mmiTrace('data length = ', dataLength)

				if dataLength:
					data = socketMessage[3:3+dataLength]
				else:
					data = None

				MD.mmiTrace('CALL DECT FUNCTION = ', dectConfig.DICT_H2B_FUNCTION[ord(messageId)])
				self.H2B_messageRun(dectConfig.DICT_H2B_FUNCTION[ord(messageId)], ord(messageId), dataLength, data)
		else:
			print 'ERROR : MSG ID = 0'
			
		return True

	def H2B_messageRun(self, cmd, *param):
		if hasattr(self, cmd):
			func = getattr(self, cmd)
			func(param)

class DectCallManager:
	IDLE = 0
	
	OUTGOING_AUDIO = 1
	OUTGOING_VIDEO = 2
	INCOMING_AUDIO = 3
	INCOMING_VIDEO = 4

	# DECT STATUS
	# IDLE = 0
	RINGING = 1
	DIALING = 2
	RINGBACK = 3
	CONNECTING = 4
	CONNECTED = 5
	BUSY = 6
	TRANSFER_RINGING = 7
	REJECT = 8
	
	BASE_IN_USE = 1
	
	SUBSCRIPTION = 1
	DE_SUBSCRIPTION = 2

	PAGING = 1
	
	NETWORK = 1
	REG_STATUS = 2
	VP_STATUS = 3

	NETWORK_OK = 0
	NETWORK_ERROR = 701
	LINK_DOWN = 702

	PROVISION_SUCCESS = 0
	REG_START = 1
	REG_SUCCESS = 2
	REG_FAILURE = 3

	EEPROM_RESET = 0
	TBR_6 = 1
	TBR_10 = 2
	FACTORY_RESET = 3

	SUCCESS = 0
	FAILURE = 1

	SMS_SEND_FILE_NAME = '/tmp/smsFromDect'
	
	def __init__(self, lineNumber):
		self.dectCallStatus = self.IDLE # DECT 
		self.dialNumber = None
		self.inviteFlag = None
		self.callTime = 0
		
		self.lineNumber = lineNumber
		self.callIndex = None

		#self.releaseFromDect = False

		self.dectInformationList = setting.dect_information_list
		
		self.firstRegistration = False
		self.registrationStatus = self.REG_SUCCESS

		self.dectStatus = self.IDLE

		self.vpStatus = MessageCode.VP_STATUS.IDLE

		self.interCom = False
		# DECT 정보를 조회한다.
		self.getSnmpInfo()

		self.channel = None # int

	def getChannel(self):
		return self.channel
		
	def setInterCom(self, interCom):
		self.interCom = interCom

	def isInterCom(self):
		return self.interCom
		
	def sendTemporarilyUnavailable(self):
		runtime.vdciapp.send_mesg(code1=config.MESG_INCOMING_CALL, code2=config.MESG_CALL_REJECT, \
			mesg1=config.REASON_TEMPORARILY_UNAVAILABLE)	
		runtime.dectCallManager.setDectStatus(self.REJECT)

	def sendFlash(self):
		runtime.vdciapp.send_hook_flash()

	def getVpStatus(self):
		return self.vpStatus

	def setVpStatus(self, vpStatus):
		self.vpStatus = vpStatus
		
	def getDectStatus(self):
		return self.dectStatus

	def setDectStatus(self, dectStatus):
		MD.mmiTrace('DECT STATUS = ', dectStatus)
		self.dectStatus = dectStatus
		
	def isSubcribedDect(self):
		if len(self.dectInformationList):
			isSubscribed = False
			self.dectInformationList = setting.dect_information_list
			for dectInformation in self.dectInformationList:
				subs_info = dectInformation.split(':')[0]
				if subs_info == '1':
					isSubscribed = True
					break
			return isSubscribed				
		else:
			return False
			
	def getDectInformationList(self):
		return self.dectInformationList

	def setDectInformationList(self, dectInformationList):
		self.dectInformationList = dectInformationList
		setting.set_dect_information_list(self.dectInformationList)

	def cleardectInformationList(self):
		self.dectInformationList = setting.dect_information_list
		newDectInformationList = []
		for dectInformation in self.dectInformationList:
			newDectInformation = '0' + dectInformation[1:]
			newDectInformationList.append(newDectInformation)
		self.dectInformationList = newDectInformationList
		setting.set_dect_information_list(newDectInformationList)
		
	def isSubscriptionFull(self):
		self.dectInformationList = setting.dect_information_list
		for dectInformation in self.dectInformationList:
			subs_info = dectInformation.split(':')[0]
			if subs_info == '0':
				return False
		return True				
		
	def isSubscription(self):
		if len(self.dectInformationList):
			return True
		else:
			return False

	def makeCallIndex(self):
		if self.callIndex:
			return self.callIndex
		else:
			import random
			callIndex = random.randrange(1000, 30000)
			self.callIndex = callIndex

			return callIndex

	def cleanDectCallManager(self):
		self.callIndex = None

	def sendFirstRegistrationStartReport(self):
		if self.isSubscription():
			self.firstRegistration = True
			self.sendRegistrationReport(self.REG_START)

	def sendRegistrationStartReport(self):
		if self.isSubscription():
			self.sendRegistrationReport(self.REG_START)

	def sendRegistrationResultReport(self, registrationStatus):
		if status.DECT_PATH_TEST:
			self.sendRegistrationReport(registrationStatus)
			return

		if self.isSubcribedDect(): 
			if self.firstRegistration:
				self.firstRegistration = False
				self.sendRegistrationReport(registrationStatus)
				self.registrationStatus = registrationStatus
			else:
				if self.registrationStatus != registrationStatus:
					self.registrationStatus = registrationStatus
					self.sendRegistrationReport(registrationStatus)

	# 등록 상태도 검사해서 보내야 하나?
	def sendNetworkStatusReportToDect(self, status):
		runtime.dectHandler.B2H_STATUS_REPORT(self.lineNumber, self.NETWORK, status, self.PROVISION_SUCCESS)

	# 403, 404, 410 처리
	def sendRegistrationStatusReportToDect(self, reg_status):
		runtime.dectHandler.B2H_STATUS_REPORT(self.lineNumber, self.REG_STATUS, MessageCode.LGN_Define.NETWORK_OK, reg_status)

	def sendVideophoneStatusReportToDect(self, status):
		runtime.dectHandler.B2H_STATUS_REPORT(self.lineNumber, self.VP_STATUS, status, self.PROVISION_SUCCESS)

	# 최종적으로 각 상태의 리포트로 수정 후 삭제해야 함.
	def sendStatusReportToDect(self, status):
		runtime.dectHandler.B2H_STATUS_REPORT(self.lineNumber, self.VP_STATUS, status, self.PROVISION_SUCCESS)
		
	def sendLinkUpReport(self):
		statusType = self.NETWORK
		networkLink = self.NETWORK_OK
		registrationStatus = self.REG_FAILURE

		runtime.dectHandler.B2H_STATUS_REPORT(self.lineNumber, statusType, networkLink, registrationStatus)

	def sendLinkDownReport(self):
		statusType = self.NETWORK
		networkLink = MessageCode.LGN_Define.LAN_CABLE_NOT_CONNECTED
		registrationStatus = self.REG_FAILURE
#MMW	2007.0702 bug fix, after link down and link up, it does not send registration status because after registration succeed once, self.registrationStatus never changed
		self.registrationStatus = registrationStatus
#end of MMW
		runtime.dectHandler.B2H_STATUS_REPORT(self.lineNumber, statusType, networkLink, registrationStatus)

#MMW	2007.0702 to change wifi register status for registration
	def unregisterstatusReport(self):
		self.registrationStatus = self.REG_FAILURE

	def unregisterstatusReport2(self):
		self.firstRegistration = False
		self.registrationStatus = self.REG_FAILURE

#end of MMW

	def sendRegistrationReport(self, registrationStatus, statusReset=False):
		statusType = self.REG_STATUS
		networkLink = self.NETWORK_OK
		if statusReset:
			self.registrationStatus = self.REG_FAILURE
		import time
		time.sleep(0.5)
		runtime.dectHandler.B2H_STATUS_REPORT(self.lineNumber, statusType, networkLink, registrationStatus)
		time.sleep(0.5)

	def sendVpStatusReport(self, vpStatus, registrationStatus):
		statusType = self.VP_STATUS
		networkLink = vpStatus

		runtime.dectHandler.B2H_STATUS_REPORT(self.lineNumber, statusType, networkLink, registrationStatus)

	def sendTransResult(self, result):
		type = 1 # Trans from HS to VP
		runtime.dectHandler.B2H_VP_TRANS_RESULT(self.lineNumber, self.callIndex, type, result)
		
	def sendTimeAndTelephoneInformation(self):
		runtime.dectHandler.B2H_TIME_TEL_INFO(self.lineNumber, vdci_setting.tel_num)

	def getSnmpInfo(self):
		MD.mmiTrace('SEND B2H_SNMP_INFO_REQUEST')

		runtime.dectHandler.B2H_SNMP_INFO_REQUEST(self.lineNumber)

	def sendUnsubscribeKeyEvent(self, result):
		MD.mmiTrace('sendUnsubscribeKeyEvent')

		runtime.manager.handle_key(True, result)

	def desubscribe(self, handsetNumber):
		callIndex = self.makeCallIndex()
		runtime.dectHandler.B2H_VP_SUBS_REQUEST(self.lineNumber, callIndex, self.DE_SUBSCRIPTION, handsetNumber)		

	def readyToSubscribe(self):
		callIndex = self.makeCallIndex()
		runtime.dectHandler.B2H_VP_SUBS_REQUEST(self.lineNumber, callIndex, self.SUBSCRIPTION)

	def failReadyToSubscribe(self):
		self.cleanDectCallManager()
		runtime.manager.handle_key(True, config.FAIL)

	def cancellingSubscriptionRejected(self):
		self.cleanDectCallManager()
		runtime.manager.handle_key(True, config.CANCEL)
		
	def subscriptionSucceeded(self):
		self.cleanDectCallManager()
		runtime.manager.handle_key(True, config.SUCCEED)

	def subscriptonFailed(self):
		self.cleanDectCallManager()
		runtime.manager.handle_key(True, config.FAIL)

	def cancelSubscription(self):
		runtime.dectHandler.B2H_VP_SUBS_REQUEST(self.lineNumber, self.callIndex, self.IDLE)

	def readyToPaging(self):
		self.makeCallIndex()
		runtime.dectHandler.B2H_VP_PAGING_REQUEST(self.lineNumber, self.callIndex, self.PAGING)

	def cancelReadyToPaging(self):
		self.cleanDectCallManager()
		runtime.manager.handle_key(True, config.CANCEL)

	def cancellingPagingRejected(self):
		self.cleanDectCallManager()
		runtime.manager.handle_key(True, config.CANCEL)
		
	def pagingSucceeded(self):
		self.cleanDectCallManager()
		runtime.manager.handle_key(True, config.SUCCEED)

	def pagingFailed(self):
		self.cleanDectCallManager()
		runtime.manager.handle_key(True, config.FAIL)

	def cancelPaging(self):
		runtime.dectHandler.B2H_VP_PAGING_REQUEST(self.lineNumber, self.callIndex, self.IDLE)

	'''
	def getReleaseFromDect(self):
		return self.releaseFromDect

	def setReleaseFromDect(self, releaseFromDect):
		self.releaseFromDect = releaseFromDect
	'''
	
	def getDectCallStatus(self):
		return self.dectCallStatus

	def setDectCallStatus(self, dectCallStatus):
		self.dectCallStatus = dectCallStatus

	def getBaseCallStatus(self):
		return self.baseCallStatus

	def setBaseCallStatus(self, baseCallStatus):
		self.baseCallStatus = baseCallStatus
		
	def getLineNumber(self):
		return lineNumber

	def setLineNumber(self, lineNumber):
		self.lineNumber = lineNumber

	def getCallIndex(self):
		return self.callIndex

	def setCallIndex(self, callIndex):
		self.callIndex = callIndex

	def start_B2H_Transfer(self, destName, destNumber):
		destNumberLength = len(destNumber)

		absenceReason = 'T'

		destNameLength = len(destName)

		self.makeCallIndex()
		runtime.dectHandler.B2H_NEW_CALL_NOTIFY(self.lineNumber, self.callIndex, absenceReason, \
			destNumberLength, destNumber, destNameLength, destName)

	def sendCidType2(self, destName, destNumber):
		self.isProcessingCidType2 = True
		
		destNumberLength = len(destNumber)
		destNameLength = len(destName)

		absenceReason = 'A'

		if destName.find('anonymous') != -1 or destNumber.find('anonymous') != -1:
			destName = ''
			destNumber = ''
			destNumberLength = 0
			destNameLength = 0

		self.makeCallIndex()
		runtime.dectHandler.B2H_NEW_CALL_NOTIFY(self.lineNumber, self.callIndex, absenceReason, \
			destNumberLength, destNumber, destNameLength, destName)
	
	def sendRestrictedNumberSign(self, destName, destNumber):
		destNumberLength = len(destNumber)

		absenceReason = 'Q'

		destNameLength = len(destName)

		self.makeCallIndex()
		runtime.dectHandler.B2H_NEW_CALL_NOTIFY(self.lineNumber, self.callIndex, absenceReason, \
			destNumberLength, destNumber, destNameLength, destName)

	def startIncomingCall(self, destName, destNumber):
		destNumberLength = len(destNumber)
		destNameLength = len(destName)

		absenceReason = 'A'

		if destName.find('anonymous') != -1 or destNumber.find('anonymous') != -1:
			destName = ''
			destNumber = ''
			destNumberLength = 0
			destNameLength = 0
			
		self.makeCallIndex()
		runtime.dectHandler.B2H_NEW_CALL_NOTIFY(self.lineNumber, self.callIndex, absenceReason, \
			destNumberLength, destNumber, destNameLength, destName)
		
	def startOutGoingCall(self, lineNumber, number=None):
		MD.mmiTrace('DectCallManager.startOutGoingCall()')

		if runtime.vdciapp == None:
			MD.mmiTrace('vdciapp not running..')
		
		self.lineNumber = lineNumber
		if number:
			self.dialNumber = number

		'''
		# emergency call 처리
		from vdcisetting import vdci_setting
		telNo = vdci_setting.tel_num
		user_pw = vdci_setting.auth_pwd
		if telNo == '' or user_pw == '':
			self.cancelCall(MessageCode.VP_STATUS.NEED_REGISTRATION)
			return
		
		localPrefix = ['02',  '031', '032', '033', '041', '042', '043', '051', '052', '053', '054', '055', '061', '062', '063', '064', '070']
		numberLength = len(self.dialNumber)
		
		if (numberLength == 3 and self.dialNumber[0] == '1') or \
			(self.dialNumber[:2]=='02' and len(self.dialNumber)==5 and self.dialNumber[2]=='1') or \
			(self.dialNumber[:3] in localPrefix and and len(self.dialNumber)==6 and self.dialNumber[3] == '1') :
			pass
		else:
			self.cancelCall(MessageCode.VP_STATUS.NEED_REGISTRATION)
			return
		'''	
		def cancelInvite():
			self.inviteFlag = 0
			self.stopCall()

			return False

		self.dectCallStatus = self.OUTGOING_AUDIO
		runtime.dectCallManager.setDectStatus(DectCallManager.CONNECTING)	
		status.set_video_mode(status.AudioRequesting)

		import utils
		uriPolicy, number = utils.checkUrlPolicy(self.dialNumber)
		if number == '+':
			number = '+0'

		status.dial_number = number
		
		runtime.vdci_send_mesg(code1=config.MESG_OUTGOING_CALL, \
								code2=config.MESG_CALL_AUDIO, \
								mesg1=number, mesg9=uriPolicy)

		return self.callIndex

	def startRing(self):
		#runtime.vdci_play_tone(config.PLAY_RINGBACK_TONE)
		runtime.SP_context.startTonePlay()

	def stopRing(self):
		#runtime.vdci_stop_tone()
		runtime.SP_context.stopTonePlay()
	
	def connectCall(self):
		if self.inviteFlag:
			self.inviteFlag = 0

		if self.dectCallStatus == self.OUTGOING_AUDIO:			
			callIndex = self.makeCallIndex()
			runtime.dectHandler.B2H_CONNECTED_CALL_NOTIFY(self.lineNumber, callIndex)
		else:
			MD.mmiTrace('INCOMING_AUDIO or VIDEO')
			return
		
	def stopCall(self, releaseFromDect=True):
		self.releaseFromDect = releaseFromDect

		runtime.mmiDebug.mmiTrace('==================================')
		runtime.mmiDebug.mmiTrace('status.call_time = ', status.call_time)
		runtime.mmiDebug.mmiTrace('status.dial_number = ', status.dial_number)
		runtime.mmiDebug.mmiTrace('status.caller_number = ', status.caller_number)		

		if status.first_info_number:
			if status.first_info_number[0:4] == '*010':						
				status.first_info_number = status.first_info_number[1:]					
		if status.second_info_number:
			if status.second_info_number[0:4] == '*010':						
				status.second_info_number = status.second_info_number[1:]					

		baseCallStatus, baseStatus, dectCallStatus, dectStatus = status.getCurrentCallStatus()
		
		if status.dial_number: # 발신
			caller = True
			number = status.dial_number
			if status.call_time > 0:
				if number[0:4] == '*010':
					number = number[1:]
				runtime.mmiDebug.mmiTrace('9status.currentCallDuration = ', status.currentCallDuration)
				runtime.mmiDebug.mmiTrace('status.currentCallDuration_copy = ', status.currentCallDuration_copy)
				calldb.add_call_log('dialed', number, status.call_time,\
						ntptime.ntime() - status.call_time, 0, 0)

			if status.serviceStatusType in ['BB']:
				if status.dial_number == status.first_info_number:
					calldb.add_call_log('dialed', status.second_info_number ,\
						status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
				else:
					calldb.add_call_log('dialed', status.first_info_number ,\
						status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
				status.first_info_number = ''
				status.second_info_number = ''
				status.second_info_call_duration_start = 0
			elif status.serviceStatusType in ['BW', 'WB']:
				if status.isConferenceCall:
					if status.dial_number == status.first_info_number:
						calldb.add_call_log('dialed', status.second_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
					else:
						calldb.add_call_log('dialed', status.first_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
				else:
					if status.dial_number == status.first_info_number:
						calldb.add_call_log('received', status.second_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
					else:
						calldb.add_call_log('received', status.first_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
				
				status.first_info_number = ''
				status.second_info_number = ''
				status.second_info_call_duration_start = 0
			elif status.serviceStatusType in ['WR', 'RW']:
				if status.dial_number == status.first_info_number:
					if status.firstCallType == 1: # audio
						calldb.add_call_log('dialed', status.second_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
					else: # video
						calldb.add_call_log('dialed', status.second_info_number ,\
							0, 0, status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start)
					status.second_info_number = ''
					status.second_info_call_duration_start = 0
				else:
					if status.firstCallType == 1: # audio
						calldb.add_call_log('dialed', status.first_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
					else: # video
						calldb.add_call_log('dialed', status.first_info_number ,\
							0, 0, status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start)
					status.second_info_number = ''
					status.second_info_call_duration_start = 0

		#elif status.caller_number and status.caller_number not in ('P', 'O'):
		# [20080919_2]: hcryoo : [QE 29099] 통화시간 339179분으로 표시되는 부재 Call Log 저장됨
		#else: # 수신
		elif status.caller_number:
		# [20080919_2]: hcryoo : [QE 29099] 통화시간 339179분으로 표시되는 부재 Call Log 저장됨==
			if status.AutoAnswering:
				status.call_time = 0
			if status.call_time > 0:
				if status.serviceStatusType in ['BN', 'NB'] and not status.caller_number in [status.first_info_number, status.second_info_number]:
					runtime.mmiDebug.mmiTrace('10-111 status.currentCallDuration = ', status.currentCallDuration)
					runtime.mmiDebug.mmiTrace('status.currentCallDuration_copy = ', status.currentCallDuration_copy)
					if status.first_info_number:
						calldb.add_call_log('received', status.first_info_number, status.call_time, ntptime.ntime() - status.call_time, 0, 0)
					else:
						calldb.add_call_log('received', status.second_info_number, status.call_time, ntptime.ntime() - status.call_time, 0, 0)
				else:
					runtime.mmiDebug.mmiTrace('11status.currentCallDuration = ', status.currentCallDuration)
					runtime.mmiDebug.mmiTrace('status.currentCallDuration_copy = ', status.currentCallDuration_copy)
					if baseCallStatus == SP_Context.INCOMING_VIDEO and baseStatus == SP_Context.CONNECTED:
						pass
					else:
						calldb.add_call_log('received', status.caller_number, status.call_time, ntptime.ntime() - status.call_time, 0, 0)

				# 수신 음성 호의 경우에는 수신시 무조건 second는 음성 호이고 missed 인 경우는 원래 호 type을 고려한다. 
				if status.serviceStatusType in ['BW', 'WB']:
					if status.caller_number == status.first_info_number:
						calldb.add_call_log('received', status.second_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
					else:
						calldb.add_call_log('received', status.first_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
					status.first_info_number = ''
					status.second_info_number = ''
					status.second_info_call_duration_start = 0
				elif status.serviceStatusType in ['BR', 'RB']:
					if status.caller_number == status.first_info_number:
						if status.second_info_call_mode == 0: # audio
							calldb.add_call_log('missed', status.second_info_number ,\
								status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
						else: # video
							calldb.add_call_log('missed', status.second_info_number ,\
								0, 0, status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start)
					else:
						if status.second_info_call_mode == 0: # audio
							calldb.add_call_log('missed', status.first_info_number ,\
								status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
						else: # video
							calldb.add_call_log('missed', status.first_info_number ,\
								0, 0, status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start)

					status.missed_call_count += 1

					# 현재 스펙 상 missed call message 처리는 하지 않음
					status.first_info_number = ''
					status.second_info_number = ''
					status.second_info_call_duration_start = 0
				
			else:
				if status.call_time == 0:
					status.call_time = ntptime.ntime()
				callLogTime = ntptime.ntime()
				runtime.mmiDebug.mmiTrace('12status.currentCallDuration = ', status.currentCallDuration)
				runtime.mmiDebug.mmiTrace('status.currentCallDuration_copy = ', status.currentCallDuration_copy)
				calldb.add_call_log('missed', status.caller_number, status.call_time, ntptime.ntime() - status.call_time, 0, 0)
				status.missed_call_count += 1
				# 자동 응답시 한글 이름이 잘 못 보여지는 오류 수정.
				if setting.missedCallAlarm:
					from phonedb import phonedb
					callerNumber = status.caller_number
					callerName = phonedb.get_name_by_number(callerNumber)
					missedCallAlarmNumber = '%s;%s;%s' % (setting.missedCallAlarmNumber1, setting.missedCallAlarmNumber2, setting.missedCallAlarmNumber3)
					if status.video_mode == status.VideoIncoming:
						callType = 1
					else:
						callType = 0
					runtime.eaHandler.sendMissedCallAlarm(callType, missedCallAlarmNumber, callerName, callerNumber, 0)
		
		runtime.vdci_send_mesg(code1=config.MESG_HANGUP)

		MD.mmiTrace('stopCall::sendCallInfoTrap $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$')
		def sendCallInfoTrap():
			runtime.trapHandler.callInfoTrap(status.sipResponseCodeForTrap)
			status.sipResponseCodeForTrap = None
			self.callInfoTrapTimer = None
			status.trapChecked = False
		DELAYED_SENDING_TRAP_TIME = 2000
		import utils
		self.callInfoTrapTimer = utils.Timer(DELAYED_SENDING_TRAP_TIME, sendCallInfoTrap)

		MD.mmiTrace('stopCall: release channel and reset')
		status.release_channel()
		status.clear_current_call_status()
		status.reset_call_status()
		status.wideband_codec = 0
		status.waiting = 0
		status.business_option_status = status.NotSelected
		status.business_call_status = status.OneCallConnected
		status.videocall_mode = status.VideoCallDisconnected
		status.phone_status = status.Disconnected
		status.WhatFrom = status.from_none
		status.indirect_cid = 0
		status.special_cid = False
		status.videocall_byuser = False

		runtime.SP_context.stopTonePlay(SP_State.DEVICE_HSS1_TS1)
		status.setClearCallStatus()
		
	def cancelCall(self, cause=MessageCode.Normal.NORMAL_RELEASE):
		MD.mmiTrace('DectCallManager::cancelCall')

		if not self.callIndex:
			self.makeCallIndex()
		runtime.dectHandler.B2H_CANCEL_CALL_NOTIFY(self.lineNumber, self.callIndex, cause)

		'''
		baseCallStatus, baseStatus, dectCallStatus, dectStatus = status.getCurrentCallStatus()
		if dectStatus == DectCallManager.TRANSFER_RINGING:
			if not self.callIndex:
				self.makeCallIndex()
			runtime.dectHandler.B2H_CANCEL_CALL_NOTIFY(self.lineNumber, self.callIndex, cause)

			return
		else:
			MD.mmiTrace('cancelCall::sendCallInfoTrap $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$')
			def sendCallInfoTrap():
				runtime.trapHandler.callInfoTrap(status.sipResponseCodeForTrap)
				status.sipResponseCodeForTrap = None
				self.callInfoTrapTimer = None
				status.trapChecked = False
			DELAYED_SENDING_TRAP_TIME = 2000
			import utils
			self.callInfoTrapTimer = utils.Timer(DELAYED_SENDING_TRAP_TIME, sendCallInfoTrap)
			
			MD.mmiTrace('cancelCall: release channel and reset')
			if not self.callIndex:
				self.makeCallIndex()
			runtime.dectHandler.B2H_CANCEL_CALL_NOTIFY(self.lineNumber, self.callIndex, cause)

			status.release_channel()
			status.clear_current_call_status()
			status.reset_call_status()
			status.wideband_codec = 0
			status.waiting = 0
			status.business_option_status = status.NotSelected
			status.business_call_status = status.OneCallConnected
			status.videocall_mode = status.VideoCallDisconnected
			status.phone_status = status.Disconnected
			status.WhatFrom = status.from_none
			status.indirect_cid = 0
			status.special_cid = False
			status.videocall_byuser = False
		
			self.setDectCallStatus(DectCallManager.IDLE)
			self.setDectStatus(DectCallManager.IDLE)
		'''
		
	def dropCall(self, cause=200):
		MD.mmiTrace('DectCallManager::dropCall / cause = ', cause)

		runtime.dectHandler.B2H_DROP_CALL_NOTIFY(self.lineNumber, self.callIndex, cause)

		runtime.vdci_send_mesg(code1=config.MESG_HANGUP)

		'''
		MD.mmiTrace('dropCall::sendCallInfoTrap $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$')
		def sendCallInfoTrap():
			runtime.trapHandler.callInfoTrap(status.sipResponseCodeForTrap)
			status.sipResponseCodeForTrap = None
			self.callInfoTrapTimer = None
			status.trapChecked = False
		DELAYED_SENDING_TRAP_TIME = 2000
		import utils
		self.callInfoTrapTimer = utils.Timer(DELAYED_SENDING_TRAP_TIME, sendCallInfoTrap)
		'''
		
		MD.mmiTrace('dropCall: release channel and reset')
		status.release_channel()
		status.clear_current_call_status()
		status.reset_call_status()
		status.wideband_codec = 0
		status.waiting = 0
		status.business_option_status = status.NotSelected
		status.business_call_status = status.OneCallConnected
		status.videocall_mode = status.VideoCallDisconnected
		status.phone_status = status.Disconnected
		status.WhatFrom = status.from_none
		status.indirect_cid = 0
		status.special_cid = False
		status.videocall_byuser = False

		runtime.SP_context.stopTonePlay(SP_State.DEVICE_HSS1_TS1)
		status.setClearCallStatus()

	def rejectCallByBase(self):
		MD.mmiTrace('DectCallManager::rejectCallByBase')

		runtime.dectHandler.B2H_DROP_CALL_NOTIFY(self.lineNumber, self.callIndex)
	
	def rejectCall(self):
		MD.mmiTrace('rejectCall::sendCallInfoTrap $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$')
		def sendCallInfoTrap():
			runtime.trapHandler.callInfoTrap(status.sipResponseCodeForTrap)
			status.sipResponseCodeForTrap = None
			self.callInfoTrapTimer = None
			status.trapChecked = False
		DELAYED_SENDING_TRAP_TIME = 2000
		import utils
		self.callInfoTrapTimer = utils.Timer(DELAYED_SENDING_TRAP_TIME, sendCallInfoTrap)
		
		MD.mmiTrace('rejectCall: release channel and reset')
		runtime.dectHandler.B2H_DROP_CALL_NOTIFY(self.lineNumber, self.callIndex)
		status.release_channel()
		status.clear_current_call_status()
		status.reset_call_status()
		status.wideband_codec = 0
		status.waiting = 0
		status.business_option_status = status.NotSelected
		status.business_call_status = status.OneCallConnected
		status.videocall_mode = status.VideoCallDisconnected
		status.phone_status = status.Disconnected
		status.WhatFrom = status.from_none
		status.indirect_cid = 0
		status.special_cid = False
		status.videocall_byuser = False
	
		self.setDectCallStatus(DectCallManager.IDLE)
		self.setDectStatus(DectCallManager.IDLE)
			
	def serverStopCall(self):
		MD.mmiTrace('serverStopCall()')

		runtime.mmiDebug.mmiTrace('==================================')
		runtime.mmiDebug.mmiTrace('status.call_time = ', status.call_time)
		runtime.mmiDebug.mmiTrace('status.dial_number = ', status.dial_number)
		runtime.mmiDebug.mmiTrace('status.caller_number = ', status.caller_number)		

		if status.first_info_number:
			if status.first_info_number[0:4] == '*010':						
				status.first_info_number = status.first_info_number[1:]					
		if status.second_info_number:
			if status.second_info_number[0:4] == '*010':						
				status.second_info_number = status.second_info_number[1:]					

		baseCallStatus, baseStatus, dectCallStatus, dectStatus = status.getCurrentCallStatus()
		
		if status.dial_number: # 발신
			caller = True
			number = status.dial_number
			if status.call_time > 0:
				if number[0:4] == '*010':
					number = number[1:]
				runtime.mmiDebug.mmiTrace('229status.currentCallDuration = ', status.currentCallDuration)
				runtime.mmiDebug.mmiTrace('status.currentCallDuration_copy = ', status.currentCallDuration_copy)
				calldb.add_call_log('dialed', number, status.call_time,\
						ntptime.ntime() - status.call_time, 0, 0)

			if status.serviceStatusType in ['BB']:
				if status.dial_number == status.first_info_number:
					calldb.add_call_log('dialed', status.second_info_number ,\
						status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
				else:
					calldb.add_call_log('dialed', status.first_info_number ,\
						status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
				status.first_info_number = ''
				status.second_info_number = ''
				status.second_info_call_duration_start = 0
			elif status.serviceStatusType in ['BW', 'WB']:
				if status.isConferenceCall:
					if status.dial_number == status.first_info_number:
						calldb.add_call_log('dialed', status.second_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
					else:
						calldb.add_call_log('dialed', status.first_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
				else:
					if status.dial_number == status.first_info_number:
						calldb.add_call_log('received', status.second_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
					else:
						calldb.add_call_log('received', status.first_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
				
				status.first_info_number = ''
				status.second_info_number = ''
				status.second_info_call_duration_start = 0
			elif status.serviceStatusType in ['WR', 'RW']:
				if status.dial_number == status.first_info_number:
					if status.firstCallType == 1: # audio
						calldb.add_call_log('dialed', status.second_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
					else: # video
						calldb.add_call_log('dialed', status.second_info_number ,\
							0, 0, status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start)
					status.second_info_number = ''
					status.second_info_call_duration_start = 0
				else:
					if status.firstCallType == 1: # audio
						calldb.add_call_log('dialed', status.first_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
					else: # video
						calldb.add_call_log('dialed', status.first_info_number ,\
							0, 0, status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start)
					status.second_info_number = ''
					status.second_info_call_duration_start = 0

		#elif status.caller_number and status.caller_number not in ('P', 'O'):
		# [20080919_2]: hcryoo : [QE 29099] 통화시간 339179분으로 표시되는 부재 Call Log 저장됨
		#else: # 수신
		elif status.caller_number:
		# [20080919_2]: hcryoo : [QE 29099] 통화시간 339179분으로 표시되는 부재 Call Log 저장됨==
			if status.AutoAnswering:
				status.call_time = 0
			if status.call_time > 0:
				if status.serviceStatusType in ['BN', 'NB'] and not status.caller_number in [status.first_info_number, status.second_info_number]:
					runtime.mmiDebug.mmiTrace('2210-111 status.currentCallDuration = ', status.currentCallDuration)
					runtime.mmiDebug.mmiTrace('status.currentCallDuration_copy = ', status.currentCallDuration_copy)
					if status.first_info_number:
						calldb.add_call_log('received', status.first_info_number, status.call_time, ntptime.ntime() - status.call_time, 0, 0)
					else:
						calldb.add_call_log('received', status.second_info_number, status.call_time, ntptime.ntime() - status.call_time, 0, 0)
				else:
					runtime.mmiDebug.mmiTrace('11status.currentCallDuration = ', status.currentCallDuration)
					runtime.mmiDebug.mmiTrace('status.currentCallDuration_copy = ', status.currentCallDuration_copy)
					if baseCallStatus == SP_Context.INCOMING_VIDEO and baseStatus == SP_Context.CONNECTED:
						pass
					else:
						calldb.add_call_log('received', status.caller_number, status.call_time, ntptime.ntime() - status.call_time, 0, 0)

				# 수신 음성 호의 경우에는 수신시 무조건 second는 음성 호이고 missed 인 경우는 원래 호 type을 고려한다. 
				if status.serviceStatusType in ['BW', 'WB']:
					if status.caller_number == status.first_info_number:
						calldb.add_call_log('received', status.second_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
					else:
						calldb.add_call_log('received', status.first_info_number ,\
							status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
					status.first_info_number = ''
					status.second_info_number = ''
					status.second_info_call_duration_start = 0
				elif status.serviceStatusType in ['BR', 'RB']:
					if status.caller_number == status.first_info_number:
						if status.second_info_call_mode == 0: # audio
							calldb.add_call_log('missed', status.second_info_number ,\
								status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
						else: # video
							calldb.add_call_log('missed', status.second_info_number ,\
								0, 0, status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start)
					else:
						if status.second_info_call_mode == 0: # audio
							calldb.add_call_log('missed', status.first_info_number ,\
								status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start, 0, 0)
						else: # video
							calldb.add_call_log('missed', status.first_info_number ,\
								0, 0, status.second_info_call_duration_start, ntptime.ntime() - status.second_info_call_duration_start)

					status.missed_call_count += 1

					# 현재 스펙 상 missed call message 처리는 하지 않음
					status.first_info_number = ''
					status.second_info_number = ''
					status.second_info_call_duration_start = 0
				
			else:
				if status.call_time == 0:
					status.call_time = ntptime.ntime()
				callLogTime = ntptime.ntime()
				runtime.mmiDebug.mmiTrace('2212status.currentCallDuration = ', status.currentCallDuration)
				runtime.mmiDebug.mmiTrace('status.currentCallDuration_copy = ', status.currentCallDuration_copy)
				calldb.add_call_log('missed', status.caller_number, status.call_time, ntptime.ntime() - status.call_time, 0, 0)
				status.missed_call_count += 1
				# 자동 응답시 한글 이름이 잘 못 보여지는 오류 수정.
				if setting.missedCallAlarm:
					from phonedb import phonedb
					callerNumber = status.caller_number
					callerName = phonedb.get_name_by_number(callerNumber)
					missedCallAlarmNumber = '%s;%s;%s' % (setting.missedCallAlarmNumber1, setting.missedCallAlarmNumber2, setting.missedCallAlarmNumber3)
					if status.video_mode == status.VideoIncoming:
						callType = 1
					else:
						callType = 0
					runtime.eaHandler.sendMissedCallAlarm(callType, missedCallAlarmNumber, callerName, callerNumber, 0)

		def sendCallInfoTrap():
			MD.mmiTrace('serverStopCall::sendCallInfoTrap $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$')		
			runtime.trapHandler.callInfoTrap(status.sipResponseCodeForTrap)
			status.sipResponseCodeForTrap = None
			self.callInfoTrapTimer = None
			status.trapChecked = False
		DELAYED_SENDING_TRAP_TIME = 2000
		import utils
		self.callInfoTrapTimer = utils.Timer(DELAYED_SENDING_TRAP_TIME, sendCallInfoTrap)

		MD.mmiTrace('serverStopCall: release channel and reset')
		runtime.dectHandler.B2H_DROP_CALL_NOTIFY(self.lineNumber, self.callIndex)
		status.release_channel()
		status.clear_current_call_status()
		status.reset_call_status()
		status.wideband_codec = 0
		status.waiting = 0
		status.business_option_status = status.NotSelected
		status.business_call_status = status.OneCallConnected
		status.videocall_mode = status.VideoCallDisconnected
		status.phone_status = status.Disconnected
		status.WhatFrom = status.from_none
		status.indirect_cid = 0
		status.special_cid = False
		status.videocall_byuser = False
	
		self.setDectCallStatus(DectCallManager.IDLE)
		self.setDectStatus(DectCallManager.IDLE)
		
	def openPcmChannel(self, lnNo):
		MD.mmiTrace('openPcmChannel()')
		#runtime.mmedia.HAL_mixer_pause()
		if lnNo == 1:
			ts1OffHook = runtime.SP_context.TS1_OffHook()
			if ts1OffHook.next():
				ts1OffHook.next()
		elif lnNo == 2:
			ts2OffHook = runtime.SP_context.TS2_OffHook()
			if ts2OffHook.next():
				ts2OffHook.next()
		#runtime.mmedia.HAL_mixer_resume()
		
	def closePcmChannel(self, lnNo):
		MD.mmiTrace('closePcmChannel()')
		#runtime.mmedia.HAL_mixer_pause()
		if lnNo == 1:
			ts1OnHook = runtime.SP_context.TS1_OnHook()
			if ts1OnHook.next():
				ts1OnHook.next()
		if lnNo == 2:
			ts2OnHook = runtime.SP_context.TS2_OnHook()
			if ts2OnHook.next():
				ts2OnHook.next()
		#runtime.mmedia.HAL_mixer_resume()
				
	def startDialTone(self):
		MD.mmiTrace('SP_context :: START DIAL TONE')
		#runtime.SP_context.dect1.setStatus(Device.OFF_HOOK)
		runtime.SP_context.dect1.setTone(config.PLAY_DIAL_TONE)
		runtime.SP_context.startTonePlay()
		
	def stopDialTone(self):
		MD.mmiTrace('SP_context :: STOP DIAL TONE')
		#runtime.vdci_stop_tone()
		runtime.SP_context.stopTonePlay(SP_State.DEVICE_HSS1_TS1)

	def startRingbackTone(self):
		MD.mmiTrace('START RINGBACK TONE')
		#runtime.SP_context.SP_startPlayback()
		#runtime.vdci_play_tone(config.PLAY_RINGBACK_TONE)
		runtime.SP_context.dect1.setStatus(Device.OFF_HOOK)
		runtime.SP_context.dect1.setTone(config.PLAY_RINGBACK_TONE)
		runtime.SP_context.startTonePlay()

	def stopRingbackTone(self):
		MD.mmiTrace('STOP RINGBACK TONE')
		#runtime.vdci_stop_tone()
		#runtime.SP_context.stopTonePlay()
		#runtime.SP_context.SP_stopPlayback()
		runtime.SP_context.stopTonePlay(SP_State.DEVICE_HSS1_TS1)

	def send_VegaEepromReset(self):
		MD.mmiTrace('DECT EEPROM RESET')
		
		runtime.dectHandler.B2H_VP_RESET_REQUEST(self.lineNumber, self.EEPROM_RESET)
	
	def send_TBR_6(self):
		MD.mmiTrace('DECT TBR6 RESET')
		
		runtime.dectHandler.B2H_VP_RESET_REQUEST(self.lineNumber, self.TBR_6)

	def send_TBR_10(self):
		MD.mmiTrace('DECT TBR10 RESET')
		
		runtime.dectHandler.B2H_VP_RESET_REQUEST(self.lineNumber, self.TBR_10)	

	def sendFactoryReset(self):
		MD.mmiTrace('DECT FACTORY RESET')
		
		runtime.dectHandler.B2H_VP_RESET_REQUEST(self.lineNumber, self.FACTORY_RESET)

	def sendRfpiView(self):
		MD.mmiTrace('DECT RFPI View')

		RFPI_REQUEST = 1
		runtime.dectHandler.B2H_VP_RFPI_REQUEST(self.lineNumber, RFPI_REQUEST)

	# DECT SMS SEND
	def sendSmsFromDect(self, dataLength, data):
		tlvList = self.parseDectData(dataLength, data)

		subjectList = []
		firstToAddress = True
		toAddresses = []
		for tlvItem in tlvList:
			if tlvItem[0] == dectConfig.PARAM_TYPE:
				contentType = tlvItem[2] 
			elif tlvItem[0] == dectConfig.PARAM_SERVER_ADDR:
				pass
			elif tlvItem[0] == dectConfig.PARAM_SERVER_PORT:
				pass
			elif tlvItem[0] == dectConfig.PARAM_FROM:
				pass
			elif tlvItem[0] == dectConfig.PARAM_TO:
				if firstToAddress:
					toAddress = tlvItem[2]
					firstToAddress = False
				else:
					toAddresses.append(tlvItem[2])
			elif tlvItem[0] == dectConfig.PARAM_REPLY_TO:
				replyUser = tlvItem[2]
			elif tlvItem[0] in [dectConfig.PARAM_SDATE, dectConfig.PARAM_FNAME, dectConfig.PARAM_FPWD]:
				if tlvItem[0] == dectConfig.PARAM_SDATE:
					sdate = 'sdate=' + tlvItem[2]
					subjectList.append(sdate)
				elif tlvItem[0] == dectConfig.PARAM_FNAME:
					sdate = 'fname=' + tlvItem[2]
					subjectList.append(sdate)
				elif tlvItem[0] == dectConfig.PARAM_FPWD:
					sdate = 'fpwd=' + tlvItem[2]
					subjectList.append(sdate)
			elif tlvItem[0] == dectConfig.PARAM_MESSAGE:
				smsMessage = tlvItem[2] 
			elif tlvItem[0] == dectConfig.PARAM_CALLBACK_URL:
				pass
			elif tlvItem[0] == dectConfig.PARAM_TRANSFER_NUM:
				pass
		subject = ','.join(subjectList)	
		
		filePath = self.SMS_SEND_FILE_NAME
		smsFile = open(filePath, 'w')
		if len(toAddresses) == 0:
			contentType = 'text/plain'
			smsFile.write(smsMessage)
		else:
			contentType = 'text/xml'
			toAddressString = ','.join(toAddresses)
			smsFile.write('<?xml version="1.0"?>')
			smsFile.write('<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">')
			smsFile.write('<env:Body>')
			smsFile.write('<DeliverReq>')
			smsFile.write('<RecipientList>')
			smsFile.write('<Recipient>%s</Recipient>' % toAddressString)
			smsFile.write('</RecipientList>')
			smsFile.write('<smsMessage>%s</smsMessage>' % smsMessage)
			smsFile.write('</DeliverReq>')
			smsFile.write('</env:Body>')
			smsFile.write('</env:Envelope>')
		smsFile.close()

		domainAddress = 'ismc.ann.com'
		
		uriPolicy, number = utils.checkUrlPolicy(toAddress)
		runtime.vdciapp.send_mesg(code1='m', code2='m', \
			mesg1=number, \
			mesg2=domainAddress, \
			mesg3=contentType, \
			mesg4=subject, \
			mesg5=filePath, \
			mesg6=replyUser, \
			#mesg7=reserved,\
			#mesg8=reserved,\
			mesg9=uriPolicy)			

	def parseDectData(self, dataLength, data):
		tlvLength = struct.unpack('H', data[:2])[0]
		tlvData = data[2:dataLength-1]
		checksum = data[dataLength-1:]

		MD.mmiTrace('tlvLength = ', tlvLength)

		for i in range(tlvLength):
			MD.mmiTrace(i, ' = ', hex(ord(tlvData[i])))

		tlvList = []
		totalLength = 0
		while totalLength < tlvLength:
			parameterType = struct.unpack('B', tlvData[0])[0]
			valueLength = struct.unpack('B', tlvData[1])[0]
			value = tlvData[2:valueLength+2]

			totalLength = totalLength + valueLength + 2
			MD.mmiTrace('valueLength = ', valueLength)

			for i in range(valueLength):
				MD.mmiTrace(i, ' = ', hex(ord(value[i])))

			tlvItem = [parameterType, valueLength, value]
			tlvList.append(tlvItem)

			tlvData = tlvData[valueLength+2:]
			MD.mmiTrace('totalLength = ', totalLength)

		return tlvList

	def sendSmsSendResultToDect(self, code, reason):
		if code == MessageCode.SMS.ACCEPT:
			MD.mmiTrace('OK =======================>')
			#runtime.dectHandler.B2H_SMS_SEND_RESULT(self.lineNumber, self.callIndex, MessageCode.SMS.ACCEPT)
			runtime.dectHandler.B2H_SMS_SEND_RESULT(self.lineNumber, self.callIndex, 200)
			return
		elif code == MessageCode.SMS.BAD_REQUEST:
			MD.mmiTrace('SMS Send Result : BAD_REQUEST : ', reason)
			runtime.dectHandler.B2H_SMS_SEND_RESULT(self.lineNumber, self.callIndex, MessageCode.SMS.BAD_REQUEST)
			return
		elif code == MessageCode.SMS.INVALID_MEDIA_TYPE:
			MD.mmiTrace('SMS Send Result : INVALID_MEDIA_TYPE : ', reason)
			runtime.dectHandler.B2H_SMS_SEND_RESULT(self.lineNumber, self.callIndex, MessageCode.SMS.INVALID_MEDIA_TYPE)
			return
		elif code == MessageCode.SMS.UNKNOWN:
			MD.mmiTrace('SMS Send Result : UNKNOWN : ', reason)
			runtime.dectHandler.B2H_SMS_SEND_RESULT(self.lineNumber, self.callIndex, MessageCode.SMS.UNKNOWN)
			return
		elif code == MessageCode.SMS.SMS_UNSUBSCRIBED:
			MD.mmiTrace('SMS Send Result : SMS_UNSUBSCRIBED : ', reason)
			runtime.dectHandler.B2H_SMS_SEND_RESULT(self.lineNumber, self.callIndex, MessageCode.SMS.SMS_UNSUBSCRIBED)
			return
		elif code == MessageCode.SMS.SERVER_ERROR:
			MD.mmiTrace('SMS Send Result : SERVER_ERROR : ', reason)
			runtime.dectHandler.B2H_SMS_SEND_RESULT(self.lineNumber, self.callIndex, MessageCode.SMS.SERVER_ERROR)
			return

		MD.mmiTrace('FAIL =======================>')
		runtime.dectHandler.B2H_SMS_SEND_RESULT(self.lineNumber, self.callIndex, self.FAILURE)

	# DECT SMS RECEIVE
	def receiveSmsFromIsmc(self, channel, toAddress, contentType, subject, filePath, replyUser):
		self.channel = channel
		
		tlvList = []

		tlvItem = [dectConfig.PARAM_TYPE, 1, '\x00']
		tlvList.append(tlvItem)

		if toAddress:
			fromLength = len(toAddress)
			tlvItem = [dectConfig.PARAM_TO, fromLength, toAddress]
			tlvList.append(tlvItem)
		else:
			MD.mmiTrace('receiveSmsFromIsmc : ERROR in received SMS')

		if replyUser:
			replyUserLength = len(replyUser)
			tlvItem = [dectConfig.PARAM_FROM, replyUserLength, replyUser]
			tlvList.append(tlvItem)
		else:
			MD.mmiTrace('receiveSmsFromIsmc : ERROR in received SMS')

		messageFile = open(filePath, 'r')
		message = messageFile.read()
		messageFile.close()
		messageLength = len(message)
		print 'messageLength = ', messageLength
		#tlvItem = [dectConfig.PARAM_MESSAGE, messageLength, message[:-1]]
		tlvItem = [dectConfig.PARAM_MESSAGE, messageLength, message]
		tlvList.append(tlvItem)

		dectPacket, packetLength = self.makeDectPacket(tlvList)

		callIndex = self.makeCallIndex()
		runtime.dectHandler.B2H_SMS_RECV_NOTIFY(self.lineNumber, callIndex, packetLength, dectPacket)
		
	def makeDectPacket(self, tlvList):
		dectPacket = ''
		
		for item in tlvList:
			packetType = struct.pack('B', item[0])
			packetLength = struct.pack('B', item[1])
			packetValue = item[2]

			packet = packetType + packetLength + packetValue

			dectPacket = dectPacket + packet

		dectPacketLength = len(dectPacket)
		print 'dectPacketLength = ', dectPacketLength
		dectPacket = struct.pack('H', dectPacketLength) + dectPacket
		dectPacketChecksum = self.calculateChecksum(dectPacket)
		dectPacket = dectPacket + struct.pack('B', dectPacketChecksum)

		finalDectPacketLength = len(dectPacket)
		
		return [dectPacket, finalDectPacketLength]

	def calculateChecksum(self, s):
		check_sum = 0
		for x in s:
			check_sum += ord(x)
		check_sum &= 0xFF
		return (0x100 - check_sum) & 0xFF # two's complement

	def playTransferMoh(self):
		runtime.vdci_send_mesg(code1=config.MESG_AUTO_ANSWER_INFO, \
								code2=config.MESG_AUTO_ANSWER_PLAY, \
								mesg1=config.transferMOH)

	def stopTransferMoh(self):
		runtime.vdci_send_mesg(code1=config.MESG_AUTO_ANSWER_INFO, \
								code2=config.MESG_AUTO_ANSWER_STOP, \
								mesg1=config.transferMOH)

	def sendConfigInfo(self):
		runtime.dectHandler.B2H_CONFIG_INFO()

	def sendToDectPWD(self, pwd):
		callIndex = self.makeCallIndex()
		runtime.dectHandler.B2H_VP_PASSWORD_CHANGE(self.lineNumber, callIndex, pwd)