package controller

/*
#include <uvdbus/smart_sound.h>
#include <uvdbus/ota.h>
*/
import "C"
import (
	"encoding/base64"
	"encoding/json"
	. "netease_control_center/globals"
	"netease_control_center/interfaces"
	"netease_control_center/interfaces/SRevent"
	"netease_control_center/interfaces/eventPoint"
	"netease_control_center/interfaces/log"
	"netease_control_center/interfaces/schedule"
	"netease_control_center/interfaces/vui"
	. "netease_control_center/modules/player"
	"netease_control_center/utils/godbus/dbus"
	"strconv"
	"time"
	"netease_control_center/modules/hardware/led_mcu"
	"netease_control_center/modules/hardware/mcu_leds/atservice"
)

var (
	Methodtable = map[string]interface{}{
		"GOAPI": goapi,
		"API":   capi,
	}
	SigChan chan *dbus.Signal

	dbusSerialChan chan *dbus.Message
)

const (
	DBUS_PATH           = "/netease/ihw/controller"
	DBUS_INTERFACE_NAME = "netease.ihw.SmartAudio"
)

func initEntry() {
	SigChan = make(chan *dbus.Signal, 10)
	go sigProcess(SigChan)

	Modules[MODULE_CONTROLLER] = &ModInfo{
		Path:       "/netease/ihw/controller",
		Aliase:     "netease.ihw.controller",
		MethodMap:  &Methodtable,
		SignalChan: SigChan,
		Init:       true,
	}

	Modules[MODULE_PLAYER].NeedSeqHandle = true
	Modules[MODULE_PLAYER].SeqSigHandFunc = _sigProcess

	Modules[MODULE_WIFI].NeedSeqHandle = true
	Modules[MODULE_WIFI].SeqSigHandFunc = nil

	Modules[MODULE_BT].NeedSeqHandle = true
	Modules[MODULE_BT].SeqSigHandFunc = nil

	Modules[MODULE_AIRPLAY].NeedSeqHandle = true
	Modules[MODULE_AIRPLAY].SeqSigHandFunc = nil

	Modules[MODULE_DLNA].NeedSeqHandle = true
	Modules[MODULE_DLNA].SeqSigHandFunc = nil

	Modules[MODULE_MANUFACTURE_CONTROLLER].NeedSeqHandle = true
}

func capi(modname uint32, msgmsk uint32, buscmd uint32, dataLen uint32, data string) *dbus.Error {
	return goapi(modname, msgmsk, 0, 0, buscmd, dataLen, []byte(data))
}

func goapi(modId uint32, msgmsk uint32, sec uint32, usec uint32, buscmd uint32, msglen uint32, data []byte) *dbus.Error {
	if CMD_PLAYER_RET_STATUS != buscmd {
		cur := time.Now().UnixNano()
		cur = cur / 1e6
		//var sendedtime int64 = int64(sec)*1e3 + int64(usec)/1e3
		//log.Println(log.DebugLog, "Jump into api,send time:", sec, usec, sendedtime, cur, "  cast:", cur-sendedtime)

		log.Println(log.DebugLog, "modId msgmsk buscmd msglen: ", modId, msgmsk, buscmd, msglen, string(data))
		//log.Println(log.DebugLog, "Data len:", len(data))
	}

	if msglen != uint32(len(data)) {
		log.Println(log.ErrorLog, "Recv data len not equal!", msglen, len(data))
		if len(data) > int(msglen) {
			data = data[0:int(msglen)]
		}
		msglen = uint32(len(data))
	}

	SetModOnlineByModid(modId)

	//by modid
	switch modId {
	case MODULE_ALARM:
		DbusAlarmCmdDeal(buscmd, data)
		return nil
	case MODULE_OTA:
		DbusOtaCmdDeal(data)
		return nil
	}

	switch buscmd {
	case uint32(C.CMD_MISC_PING):
		log.Println(log.DebugLog, "Recv: ", string(data))
		return nil
	case CMD_SE_PLAYER_STATE_NTF: //se player 状态处理
		seplayerMsgProcess(string(data))
	case CMD_PLAYER_RET_STATUS:
		playerMsgProcess(string(data))
		UpdateActiveTime()

		//Voice status: recognition success!
	case uint32(C.CMD_TEST_GET_VER_REQ),
		uint32(C.CMD_TEST_KNOB_REQ),
		uint32(C.CMD_TEST_BUTTON_REQ),
		uint32(C.CMD_TEST_SET_VOLUME_REQ),
		uint32(C.CMD_TEST_GET_VOLUME_REQ):
		processManfactureMsg(buscmd, msglen, data)

	case uint32(C.CMD_MSC_MSG_CONTROLLER_RECOG_SUCCESS):
		log.Println(log.DebugLog, "Recog success, msglen: ", msglen)
		ClearRecogTimeoutTimer()
		//if VoiceStatus_FINISH.CanExec() {
		schedule.SendSCmd(schedule.SCMD_SuperTask_Voice_RecogFinish, &data)
		//} else {
		//	log.Println(log.DebugLog, "VoiceStatus_FINISH", VoiceStatus_FINISH.Debug())
		//}

	case uint32(C.CMD_MSC_MSG_CONTROLLER_SESSION_BEGIN):
		log.Println(log.DebugLog, "Session begin!")
		var tmp struct {
			Id string `json:"sessionId"`
		}
		sessionId := ""
		if err := json.Unmarshal(data, &tmp); err == nil {
			sessionId = tmp.Id
		}

		eventPoint.EpRecord("A321", map[string]interface{}{"sessionid": string(sessionId), "status":"succes",})
		VoiceSessionId = sessionId
	case uint32(C.CMD_MSC_MSG_CONTROLLER_RECOG_ERROR):
		log.Println(log.ErrorLog, "Recog err: ", string(data))
		//if VoiceStatus_ERROR.CanExec() {
		ClearRecogTimeoutTimer()
		var tmp MscErrcode
		err := json.Unmarshal(data, &tmp)
		if err == nil {
			schedule.SendSCmd(schedule.SCMD_SuperTask_Voice_RecogErr, tmp)
			eventPoint.EpRecord("A321", map[string]interface{}{"status":"fail","errCode":tmp.Errorcode,})
		}
		//} else {
		//	log.Println(log.DebugLog, "VoiceStatus_ERROR can not exec, do not send err to schedule!", GetCurVoiceStatus())
		//}

		//Voice status: wake up. data: {"angle":93,"score":53,"beam":2,"power":332032770048.000000}
	case uint32(C.CMD_MSC_MSG_CONTROLLER_WAKEUP):
		UpdateActiveTime()
		//log.Println(log.DebugLog, "wake up!")
		//		if VoiceStatus_WAKEUP.CanExec() {
		ClearRecogTimeoutTimer()
		var tmp MscWakeUp
		err := json.Unmarshal(data, &tmp)
		log.Println(log.DebugLog, "wake up", tmp, err)
		if err == nil {
			if VoiceStatus_WAKEUP.CanExec() {
				wakeupByMain := false
				if tmp.Wakeupwords != MainWakeupWord && GetCurVoiceStatus() != VoiceStatus_IDLE {
					wakeupByMain = true
					log.Println(log.DebugLog, "session is begin, so close voice session and set to idle for not main wakeup word")
					VoiceEndSession()
					UpdateVoiceStatus(VoiceStatus_IDLE)
				}
				switch tmp.Wakeupwords {
				case MainWakeupWord:
					schedule.SendSCmd(schedule.SCMD_SuperTask_Voice_WakeUp, tmp)
				case NextSongWord: //Voice status: wake up for next song.
					if IsWakeupCmdEnable(NextSong) {
						log.Println(log.DebugLog, "oneshot: wake up for next song")
					} else {
						log.Println(log.WarningLog, "oneshot: wake up for next song is not enable")
						return nil
					}
					var serverDetail ServerDetailBase = ServerDetailBase{
						Cmd: int(MSC_CMD_NEXT),
						Tts: "下一首",
					}
					data, err := json.Marshal(serverDetail)
					if nil != err {
						log.Println(log.ErrorLog, err.Error())
						return nil
					}

					var tmp ServerRet
					tmp.Cmd = int(MSC_CMD_NEXT)
					tmp.Code = 1000
					if wakeupByMain {
						tmp.Desc = MSC_CMD_ONE_SHOT_WAKEUP
					} else {
						tmp.Desc = MSC_CMD_ONE_SHOT
					}

					tmp.Detail = string(data)
					//tmp.TimeStamp = time.Now().UnixNano()/1000000

					dataMsg, err := json.Marshal(tmp)
					if nil != err {
						log.Println(log.ErrorLog, err.Error())
						return nil
					}
					MscSuccessCommand(&dataMsg, uint32(len(dataMsg)))
				case VolumeUpWord: //Voice status: wake up for volume up.
					if IsWakeupCmdEnable(VolumeAdjust) {
						log.Println(log.DebugLog, "oneshot: wake up for volume up")
					} else {
						log.Println(log.WarningLog, "oneshot: wake up for volume up is not enable")
						return nil
					}
					var serverDetail ServerDetailBase = ServerDetailBase{
						Cmd: int(MSC_CMD_VOLUME_UP),
						Tts: "音量已经调到%d",
					}
					data, err := json.Marshal(serverDetail)
					if nil != err {
						log.Println(log.ErrorLog, err.Error())
						return nil
					}

					var tmp ServerRet
					tmp.Cmd = int(MSC_CMD_VOLUME_UP)
					tmp.Code = 1000
					if wakeupByMain {
						tmp.Desc = MSC_CMD_ONE_SHOT_WAKEUP
					} else {
						tmp.Desc = MSC_CMD_ONE_SHOT
					}
					tmp.Detail = string(data)
					//tmp.TimeStamp = time.Now().UnixNano()/1000000

					dataMsg, err := json.Marshal(tmp)
					if nil != err {
						log.Println(log.ErrorLog, err.Error())
						return nil
					}
					MscSuccessCommand(&dataMsg, uint32(len(dataMsg)))
				case VolumeDownWord: //Voice status: wake up for volume down.
					if IsWakeupCmdEnable(VolumeAdjust) {
						log.Println(log.DebugLog, "oneshot: wake up for volume down")
					} else {
						log.Println(log.WarningLog, "oneshot: wake up for volume down is not enable")
						return nil
					}
					var serverDetail ServerDetailBase = ServerDetailBase{
						Cmd: int(MSC_CMD_VOLUME_DOWN),
						Tts: "音量已经调到%d",
					}
					data, err := json.Marshal(serverDetail)
					if nil != err {
						log.Println(log.ErrorLog, err.Error())
						return nil
					}

					var tmp ServerRet
					tmp.Cmd = int(MSC_CMD_VOLUME_DOWN)
					tmp.Code = 1000
					if wakeupByMain {
						tmp.Desc = MSC_CMD_ONE_SHOT_WAKEUP
					} else {
						tmp.Desc = MSC_CMD_ONE_SHOT
					}
					tmp.Detail = string(data)
					//tmp.TimeStamp = time.Now().UnixNano()/1000000

					dataMsg, err := json.Marshal(tmp)
					if nil != err {
						log.Println(log.ErrorLog, err.Error())
						return nil
					}
					MscSuccessCommand(&dataMsg, uint32(len(dataMsg)))
				}

			} else {
				log.Println(log.DebugLog, "Wake up, but can not exec, mic status:", IsMicClose)
				UpdateVoiceStatus(VoiceStatus_IDLE)
			}
		} else {
			//glog.Error("Wake up decode error %v, %s\n", err, string(data))
			log.Printf(log.ErrorLog, "Wake up decode error %v, %s\n", err, string(data))
		}
		//} else {
		//	log.Println(log.DebugLog, "VoiceStatus_WAKEUP", VoiceStatus_WAKEUP.Debug())
		//}

		//Voice status: Recoging
	case uint32(C.CMD_MSC_MSG_CONTROLLER_RECOGING):
		log.Println(log.DebugLog, "Recoging ....")
		schedule.SendSCmd(schedule.SCMD_SuperTask_Voice_Recoging, string(data))

		//ask for init args
	case uint32(C.CMD_CONTROLLER_REQMSG_INITARGS):
		SendUUIDToVE()

		//ask for player status, req:CMD_CONTROLLER_RSPMSG_PLAYERSTATUS.
	case uint32(C.CMD_CONTROLLER_REQMSG_PLAYERSTATUS):
		//UpdateVboxSt(nil)

		//todo show mic status
	case uint32(C.CMD_MSC_RSPMSG_MIC_CONTROL):

	case uint32(C.CMD_YUNXIN_RECVMSG):
		log.Println(log.DebugLog, "Recv yunxin msg:", string(data))
		var tmp YunxinAPPMsg
		tmp.Content.OfflineStatus = OffLineStatus_Offline
		if err := json.Unmarshal(data, &tmp); err == nil {
			log.Printf(log.DebugLog, "Msg time:%+v\n", time.Time(tmp.Content.TimeStampM))
			if tmp.Content.OfflineStatus == OffLineStatus_Online && time.Now().Sub(time.Time(tmp.Content.TimeStampM)) >= 10 * time.Second {
				log.Printf(log.ErrorLog, "Time out, do not deal the msg, msg time:%+v!\n", time.Time(tmp.Content.TimeStampM))
				return nil
			}

			if tmp.Content.OfflineStatus == OffLineStatus_Online && time.Time(tmp.Content.TimeStampM).Before(FirstCalTime) {
				log.Printf(log.ErrorLog, "Msg's time(%+v) is before first cal time(%+v), do nothing!\n", time.Time(tmp.Content.TimeStampM), FirstCalTime)
				return nil
			}

			appDataFormat := []byte(tmp.Content.MsgBody)
			AppSuccessCommand(&appDataFormat, uint32(len(appDataFormat)))
		} else {
			log.Println(log.ErrorLog, "Decode yunxin msg err!", err)
		}

	case uint32(C.CMD_YUNXIN_SYSMSG):
		DbusYunxinSysMsgControl(data)

	case uint32(C.CMD_YUNXIN_STATUS):
		DecodeYunxinStatus(data)

	case uint32(C.CMD_NDUILITE_FESPA_SET_ARG):
		Nduilite_fespa_set()

	default:
		log.Printf(log.WarningLog, "Unknow bus command: %d\n", buscmd)
	}

	return nil
}

func _sigProcess(sig *dbus.Signal) {
	//log.Println(log.DebugLog, "Recv dbus signal!")
	defer func() {
		if err := recover(); err != nil {
			log.Println(log.ErrorLog, "Get sig func err: ", err)
		}
	}()
	if len(sig.Path) == 0 {
		log.Println(log.DebugLog, "Warn : path is null")
		return
	}

	path := string(sig.Path)
	SetModOnlineByPath(path)
	if cmd := sig.Body[2].(uint32); cmd == uint32(C.CMD_MISC_PING) {
		//this is a ping, ignore
		return
	}
	switch path {
	case Modules[MODULE_DLNA].Path:
		//check by buscmd
		if len(sig.Body) >= 4 {
			buscmd := sig.Body[2].(uint32)
			if buf, bufok := sig.Body[3].(string); bufok {
				//DLNAMsgProcess(buscmd, buf)
				DlnaCmdProcess(buscmd, buf)
			}
		}
	case Modules[MODULE_AIRPLAY].Path:
		//check by buscmd
		if len(sig.Body) >= 4 {
			buscmd := sig.Body[2].(uint32)
			if buf, bufok := sig.Body[3].(string); bufok {
				//DLNAMsgProcess(buscmd, buf)
				if AIRPLAY_MODE_ITSELF == AirPlay_Mode {
					AirPlayerMsgProcess2(buscmd, buf)
				} else {
					AirPlayerMsgProcess(buscmd, buf)
				}

			}
		}
	case Modules[MODULE_OTA].Path:
		//check by buscmd
		if len(sig.Body) >= 3 {
			buscmd := sig.Body[2].(uint32)
			switch buscmd {
			case uint32(C.CMD_OTA_STATUS):
				if len(sig.Body) >= 4 {
					if buf, bufok := sig.Body[3].(string); bufok {
						DbusOtaCmdDeal([]byte(buf))
					}
				}
			}
		}

	case Modules[MODULE_PLAYER].Path:
		if len(sig.Body) >= 4 {
			buscmd := sig.Body[2].(uint32)
			switch buscmd {
			case uint32(C.CMD_MISC_PING):
				return
			default:

			}
			bodystring, isBodyOk := sig.Body[3].(string)
			if !isBodyOk || len(bodystring) == 0 {
				log.Println(log.ErrorLog, "Decode player msg error", isBodyOk)
				return
			}
			playerMsgProcess(bodystring)
		}
	case Modules[MODULE_CONTROLLER].Path:
		//do nothing

	case Modules[MODULE_BT].Path:
		//buscmd
		buscmd := sig.Body[2].(uint32)
		switch buscmd {
		//wifi paring data
		case uint32(C.CMD_WIFI_CONF):
			var tmp BtWifiParing
			buf, bufok := sig.Body[3].(string)
			log.Println(log.DebugLog, "Recv bt ", buf)
			if bufok {
				if err := json.Unmarshal([]byte(buf), &tmp); err == nil {
					if CurBootState == BootStage_WIFIPARING || IsInBackupSystem() {
						log.Println(log.DebugLog, "In wifi paring, tell wifi module")
						if bytedata, err := base64.StdEncoding.DecodeString(tmp.Pwd); err == nil && string(bytedata) == "mp@20180911" {
							log.Println(log.DebugLog, "Turn on adb!")
							ADBControl(true)
							SendBleStatus(APPInitStatus_PARING_NOT_RESPONSE)
						} else {
							tmp.OrigString = buf
							ClearWifiChanAddWifi(tmp)
						}
						log.Println(log.DebugLog, tmp)
					} else {
						log.Println(log.DebugLog, "Currently not in wifi paring, tell app error")
						SendBleStatus(APPInitStatus_NOT_IN_WIFIPARING)
					}
				} else {
					SendBleStatus(APPInitStatus_JSON_ERROR)
					log.Println(log.ErrorLog, "Decode bt wifiparing error", err, buf)
				}
			} else {
				log.Println(log.ErrorLog, "body 3 error")
			}

		case uint32(C.CMD_BT_NAME_GET_RESP):
			var tmp struct {
				BtName string `json:"bt_name"`
			}

			if buf, bufok := sig.Body[3].(string); bufok {
				if err := json.Unmarshal([]byte(buf), &tmp); err == nil {
					if BTNAME != tmp.BtName && BTNAME == DEFAULT_DEV_NAME {
						BTNAME = tmp.BtName
						BtNameGetFlag = true
						NetworkServiceSwitch(BtNameGetFlag)
					}
				}
				log.Println(log.DebugLog, "Recv bt name: ", buf)
			}
		case uint32(C.CMD_BT_EVT_NTF):
			var tmp BtStatus

			if buf, bufok := sig.Body[3].(string); bufok {
				log.Println(log.DebugLog, "Recv ble status: ", buf)
				if err := json.Unmarshal([]byte(buf), &tmp); err == nil {
					CurBtstatus = tmp
					if tmp.Status == BtEvt_BLE_CONNECT {
						SoundEffectPlayCmd(CMD_SE_PLAY, vui.SoundNotice_Slianjiechenggong001.GetPath())
					} else {
						//SoundEffectPlayCmd(CMD_SE_PLAY, vui.SoundNotice_Stuichufankui001.GetPath())
					}
				}
			}

		default:
			if buf, bufok := sig.Body[3].(string); bufok {
				if buscmd == uint32(C.CMD_BT_AVK_RC_PLAY) {
					BtAvkDataRecving = true
				}else if buscmd == uint32(C.CMD_BT_AVK_SOUND_STOP_EVT) || buscmd == uint32(C.CMD_BT_AVK_DISC_EVT) {
					BtAvkDataRecving = false
				}
				BtMsgProcess(buscmd, buf)
			} else {
				log.Printf(log.DebugLog, "invalid msg.cmd:0x%x", buscmd)
			}
		}
	case Modules[MODULE_WIFI].Path:
		if !*log.TerminalCmd {
			log.Printf(log.DebugLog, "Recv wifi msg:%+v\n", sig.Body)
		}
		buscmd := sig.Body[2].(uint32)
		switch buscmd {
		case uint32(C.CMD_WIFI_ON_RESP):
			SoundEffectPlayCmd(CMD_SE_PLAY, vui.SoundNotice_Slianjiechenggong001.GetPath())
			led_mcu.DirectLedClear(atservice.GUIDE_EFFECT_ID_NET_MODE)
			WifiSwitch = WifiSwitch_On
			RequestWifiAutoConnect(true)

		case uint32(C.CMD_WIFI_OFF_RESP):
			SoundEffectPlayCmd(CMD_SE_PLAY, vui.SoundNotice_Slianjiechenggong001.GetPath())
			led_mcu.DirectLedClear(atservice.GUIDE_EFFECT_ID_NET_MODE)
			WifiSwitch = WifiSwitch_Off

		case uint32(C.CMD_WIFI_AUTO_CONN_OUT):
			IsWifiAutoConnecting = false
			SRevent.BroadCastSRevent(SRevent.SRevent_type_AutoConnectEnd)

		case uint32(C.CMD_WIFI_CHANGE_VALID_AP_RESP):
			IsWifiChanging = true
			SRevent.BroadCastSRevent(SRevent.SRevent_type_ChangeWifiStart)

		case uint32(C.CMD_WIFI_CHANGE_VALID_AP_OUT):
			IsWifiChanging = false
			SRevent.BroadCastSRevent(SRevent.SRevent_type_ChangeWifiEnd)

		case uint32(C.CMD_WIFI_AUTO_CONN_RESP):
			SRevent.BroadCastSRevent(SRevent.SRevent_type_AutoConnectStart)
			var tmp struct {
				ResCode APPInitStatus `json:"resCode"`
			}
			buf, bufok := sig.Body[3].(string)
			log.Println(log.DebugLog, "Recv wifi:", buf, bufok)
			if bufok {
				err := json.Unmarshal([]byte(buf), &tmp)
				if err == nil {
					if tmp.ResCode == 0 {
						log.Println(log.DebugLog, "Get wifi module is connecting wifi!")
						IsWifiAutoConnecting = true
					} else {
						log.Println(log.DebugLog, "Wifi auto connect error!", tmp.ResCode)
					}
				} else {
					log.Println(log.ErrorLog, "Decode wifi auto connect error", err, buf)
				}
			} else {
				log.Println(log.ErrorLog, "body 3 error")
			}
		case uint32(C.CMD_WIFI_CONF_RESP):
			var tmp struct {
				ResCode APPInitStatus `json:"resCode"`
			}
			buf, bufok := sig.Body[3].(string)
			log.Println(log.DebugLog, "Recv wifi:", buf, bufok)
			if bufok {
				err := json.Unmarshal([]byte(buf), &tmp)
				if err == nil {
					APPWIFIPARINGSTAUTS = APPInitStatus(tmp.ResCode)
					ClearWifiChan()
					if tmp.ResCode == APPInitStatus_SUCCESS {
						log.Println(log.DebugLog, "Success wifi paring")
						UpdateWifiStatus(WifiStatuses_CONNECTED)
					} else {
						log.Println(log.DebugLog, "Wifi connect error!", tmp.ResCode)
					}
				} else {
					log.Println(log.ErrorLog, "Decode bt wifiparing error", err, buf)
				}
			} else {
				log.Println(log.ErrorLog, "body 3 error")
			}
		case uint32(C.CMD_WIFI_STATE_RESP):
			buf, bufok := sig.Body[3].(string)
			log.Println(log.DebugLog, buf, bufok)
			var tmp struct {
				WifiState  int    `json:"wifi_state"`
				WifiRssi   int    `json:"wifi_rssi"`
				RouterMac  string `json:"wifi_mac"`
				RouterSsid string `json:"wifi_ssid"`
			}
			if bufok {
				err := json.Unmarshal([]byte(buf), &tmp)
				if err == nil {
					SetWifiRssi(tmp.WifiRssi)
					RouterSsid = tmp.RouterSsid
					RouterMac = tmp.RouterMac
					log.Println(log.DebugLog, "Wifi cur state(4097-Disconnect,4099-Connected):", tmp.WifiState)
					switch tmp.WifiState {
					case 0x1003:
						CurWifiStatus = WifiStatuses_CONNECTED

					case 0x1001:
						CurWifiStatus = WifiStatuses_DISCONNECT
					}
				}
			}
		case uint32(C.CMD_WIFI_STATE_NTF):
			buf, bufok := sig.Body[3].(string)
			log.Println(log.DebugLog, buf, bufok)
			var tmp struct {
				WifiEvt    int    `json:"wifi_evt"`
				WifiRssi   int    `json:"wifi_rssi"`
				RouterMac  string `json:"wifi_mac"`
				RouterSsid string `json:"wifi_ssid"`
			}

			if bufok {
				err := json.Unmarshal([]byte(buf), &tmp)
				if err == nil {
					SetWifiRssi(tmp.WifiRssi)
					if (RouterSsid != tmp.RouterSsid || RouterMac != tmp.RouterMac) && len(tmp.RouterSsid) > 0 && len(tmp.RouterMac) > 0 {
						RouterSsid = tmp.RouterSsid
						RouterMac = tmp.RouterMac
						eventPoint.EpRecord("F669", map[string]interface{}{"SSID": tmp.RouterSsid, "MAC": tmp.RouterMac})
					}
					switch tmp.WifiEvt {
					case 0:
						CurWifiStatus = WifiStatuses_CONNECTED
						WifiConnectedEvent()
					case 1:
						CurWifiStatus = WifiStatuses_DISCONNECT
						WifiDisconnectedEvent()
					case 2:
						CurWifiStatus = WifiStatuses_CONNECTING
					}
				}
			}
		default:
			if buscmd > uint32(C.CMD_WIFI_BL_CMD_START) && buscmd < uint32(C.CMD_WIFI_BL_CMD_END) {
				if len(sig.Body) >= 4 {
					iotDbusMsg(buscmd, sig.Body[3].(string))
				} else {
					iotDbusMsg(buscmd, "")
				}
			}
		}
	default:
		//log.Println(log.ErrorLog, "Unknow path:", sig.Path)
	}
}

func sigProcess(sigch <-chan *dbus.Signal) {
	for {
		select {
		case sig := <-sigch:
			_sigProcess(sig)
		}
	}
}

func playerMsgProcess(msg string) {
	var tmp schedule.PlayerDetail
	//log.Printf(log.DebugLog, msg)
	err := json.Unmarshal([]byte(msg), &tmp)
	if err != nil {
		log.Println(log.ErrorLog, "Unmarshal player status error: ", err)
	} else {
		schedule.SetPlayerStatus(tmp)
	}
}

func seplayerMsgProcess(msg string) {
	log.Println(log.DebugLog, "SEPlayer state: ", msg)
	se_state, _ := strconv.Atoi(msg)
	schedule.SePlayerStateChange(PlayerStatuses(se_state))
}

func BroadChangeTestServer() {
	interfaces.BroadSignalAll(MODULE_CONTROLLER, uint32(C.CMD_MISC_CHANGE2TEST), "")
}

func BroadChangeOnlineServer() {
	interfaces.BroadSignalAll(MODULE_CONTROLLER, uint32(C.CMD_MISC_CHANGE2ONLINE), "")
}
