package controller

/*
#include <uvdbus/smart_sound.h>
*/
import (
	"encoding/json"
	"fmt"
	. "netease_control_center/globals"
	"netease_control_center/interfaces/eventPoint"
	"netease_control_center/interfaces/http"
	"netease_control_center/interfaces/innerTask"
	"netease_control_center/interfaces/log"
	. "netease_control_center/interfaces/schedule"
	"netease_control_center/interfaces/vui"
	"netease_control_center/modules/hardware/led_mcu"
	"netease_control_center/modules/hardware/mcu_leds/atservice"
	"netease_control_center/modules/player"
	. "netease_control_center/modules/player"
	"netease_control_center/nembd/controller/adau1761"
	"netease_control_center/utils/ntp"
	"strconv"
	"strings"
	"time"
	"netease_control_center/interfaces/cserveraddr"
	"netease_control_center/modules/storage"
)

const (
	VOL_VALUE   int8 = iota + 1
	VOL_PERCENT
)

func MscToastLed_Before() {
	if IsMicClose == false {
		vui.IconLed_iconMusic004.Show()
		tmp := DirectLed{EffectId: atservice.GUIDE_EFFECT_ID_EXEC_CMD, Action: atservice.GUIDE_ACTION_START}
		led_mcu.DirectLedControl(tmp.EffectId, tmp.Action, tmp.StartLampNum, []byte{uint8(adau1761.MustGetVol())})
	}
}
func MscToastFinish(arg TtsPlayerArg) {
	//停止执行灯灯效
	//if IsMicClose == false {
	tmp := DirectLed{EffectId: atservice.GUIDE_EFFECT_ID_EXEC_CMD, Action: atservice.GUIDE_ACTION_STOP}
	led_mcu.DirectLedControl(tmp.EffectId, tmp.Action, tmp.StartLampNum, []byte{})
	vui.IconLed_Clear.Show()
	//}

	//检查是否网络缓存播放失败
	if arg.StopReason == NoticeStopReason_Error {
		go MscToastFile(vui.SoundNotice_Song_Get_Timeout.GetPath(), CONST_AUDIO_ID, true, false, nil)
	}
}

func volChangeCb(params *NoticePlayerParams) {
	params.BeforeSpecialFunc = func() {
		if IsMicClose == false {
			AlwaysShowVolumeIcon()
			tmp := DirectLed{EffectId: atservice.GUIDE_EFFECT_ID_EXEC_CMD, Action: atservice.GUIDE_ACTION_START}
			led_mcu.DirectLedControl(tmp.EffectId, tmp.Action, tmp.StartLampNum, []byte{uint8(adau1761.MustGetVol())})
		}
	}
	params.SpecialFunc = func(arg TtsPlayerArg) {
		//if IsMicClose == false {
		tmp := DirectLed{EffectId: atservice.GUIDE_EFFECT_ID_EXEC_CMD, Action: atservice.GUIDE_ACTION_STOP}
		led_mcu.DirectLedControl(tmp.EffectId, tmp.Action, tmp.StartLampNum, []byte{})
		vui.IconLed_Clear.Show()
		//}

		//检查是否网络缓存播放失败
		if arg.StopReason == NoticeStopReason_Error {
			go MscToastFile(vui.SoundNotice_Song_Get_Timeout.GetPath(), CONST_AUDIO_ID, true, false, nil)
		}
	}
}

func MscToastFile(file string, uuid string, needRepeat bool, keep bool, configChange func(params *NoticePlayerParams)) {
	tmpconfig := player.GetDefaultNoticePlayerParams()
	tmpconfig.NeedRepeat = needRepeat
	tmpconfig.Keep = keep
	tmpconfig.Level = TTS_LEVEL_1
	tmpconfig.SrcType = AdSrcType_FILE
	tmpconfig.Tts = file
	tmpconfig.Uuid = uuid
	tmpconfig.IconIn = vui.IconLed_DoNothing
	tmpconfig.IconOut = vui.IconLed_DoNothing

	tmpconfig.BeforeSpecialFunc = MscToastLed_Before
	tmpconfig.SpecialFunc = MscToastFinish

	if configChange != nil {
		configChange(&tmpconfig)
	}

	NoticePlayerSendSCmd2(SCMD_SuperTask_Tts_Ctrl_Play, tmpconfig)
}

func MscToastTts(tts string, RespId string, needRepeat bool, keep bool, configChange func(params *NoticePlayerParams)) {
	tmpconfig := player.GetDefaultNoticePlayerParams()
	tmpconfig.Keep = keep
	tmpconfig.NeedRepeat = needRepeat
	tmpconfig.Level = TTS_LEVEL_1
	tmpconfig.SrcType = AdSrcType_TTS
	tmpconfig.Tts = tts
	tmpconfig.Uuid = RespId
	tmpconfig.IconIn = vui.IconLed_DoNothing
	tmpconfig.IconOut = vui.IconLed_DoNothing

	tmpconfig.BeforeSpecialFunc = MscToastLed_Before
	tmpconfig.SpecialFunc = MscToastFinish

	if configChange != nil {
		configChange(&tmpconfig)
	}

	NoticePlayerSendSCmd2(SCMD_SuperTask_Tts_Ctrl_Play, tmpconfig)
}

func MscToast(adsrc AdSrcType, tts string, RespId string, needRepeat bool, keep bool, configChange func(params *NoticePlayerParams)) {
	tmpconfig := player.GetDefaultNoticePlayerParams()
	tmpconfig.Keep = keep
	tmpconfig.NeedRepeat = needRepeat
	tmpconfig.Level = TTS_LEVEL_1
	tmpconfig.SrcType = adsrc
	tmpconfig.Tts = tts
	tmpconfig.Uuid = RespId
	tmpconfig.IconIn = vui.IconLed_DoNothing
	tmpconfig.IconOut = vui.IconLed_DoNothing

	tmpconfig.BeforeSpecialFunc = MscToastLed_Before
	tmpconfig.SpecialFunc = MscToastFinish

	if configChange != nil {
		configChange(&tmpconfig)
	}

	NoticePlayerSendSCmd2(SCMD_SuperTask_Tts_Ctrl_Play, tmpconfig)
}

func MscSuccessCommand(msg *[]byte, msglen uint32) {
	var retData ServerRet
	if msglen <= 0 || msg == nil {
		return
	}
	err := json.Unmarshal(*msg, &retData)
	if err != nil {
		log.Println(log.ErrorLog, "Server resp error, json decode error ", err)
		return
	}
	log.Printf(log.DebugLog, "CMD:%d, desc: %s, retcode:%d rspId:%s\n", retData.Cmd, retData.Desc, retData.Code, retData.RspId)

	if retData.RspId == "" || len(retData.RspId) == 0 {
		retData.RspId = CONST_AUDIO_ID
	}

	if ErrCode(retData.Code) != ERR_SUCCESS {
		log.Println(log.ErrorLog, "server error and exit")

		return
	}

	BirthdayAction = BIRTHDAY_NULL_ACTION
	// 关闭场景外的生日处理逻辑
	//if !HasCheckBirthdayInfo {
	//	switch Cmd(retData.Cmd) {
	//	case MSC_CMD_TTS_TOAST, MSC_CMD_TTS_UNKNOW1, MSC_CMD_TTS_UNKNOW2, MSC_CMD_TTS_UNKNOW3:
	//		var tmp ServerDetailBase
	//		err := json.Unmarshal([]byte(retData.Detail), &tmp)
	//		if err != nil {
	//			log.Println(log.WarningLog, "Unkonw tts")
	//			return false
	//		}
	//		if !tmp.Keep {
	//			BirthdayAction = BIRTHDAY_BEFORE_TASK
	//		}
	//	case MSC_CMD_ALARM_ADD, MSC_CMD_ALARM_CANCLE, MSC_CMD_ALARM_CLOSE, MSC_CMD_ALARM_QUERY,
	//		MSC_CMD_REMIND_ADD, MSC_CMD_REMIND_CANCLE, MSC_CMD_REMIND_CLOSE, MSC_CMD_REMIND_QUERY,
	//		MSC_CMD_WHETHER, MSC_CMD_COLLECT_MUSIC, MSC_CMD_UNCOLLECT_MUSIC:
	//		BirthdayAction = BIRTHDAY_BEFORE_TASK
	//	case MSC_CMD_PLAY_MUSIC, MSC_CMD_PLAY_LIST, MSC_CMD_PLAY_RCMD, MSC_CMD_PLAY_LISTS:
	//		BirthdayAction = BIRTHDAY_AFTER_TASK
	//	}
	//}

	defer func() {
		if BIRTHDAY_AFTER_TASK == BirthdayAction {
			BirthdayPlayProcess()
		}
	}()

	if retData.Desc == MSC_CMD_ONE_SHOT || retData.Desc == MSC_CMD_ONE_SHOT_WAKEUP {
		eventPoint.EpRecord("A224", map[string]interface{}{"msgid": retData.Cmd, "rspid": retData.RspId, "sourceos": eventPoint.EpOs_Device})
	} else {
		eventPoint.EpRecord("A224", map[string]interface{}{"msgid": retData.Cmd, "rspid": retData.RspId, "sourceos": eventPoint.EpOs_Server})
	}

	ntp.SetUnixTimeToLocal(retData.TimeStamp, 5*time.Minute, true)
	switch Cmd(retData.Cmd) {
	case MSC_CMD_IOTWIFIPARING:
		SendSCmd(SCMD_SuperTask_Enter_IOT_WifiParing)

	case MSC_CMD_BTONWIFIOFF:
		SendSCmd(SCMD_SuperTask_Enter_btOnWifiOff)

	case MSC_CMD_CHAT:
		if isMute() {
			return
		}

		var tmp ServerDetailBase
		err := json.Unmarshal([]byte(retData.Detail), &tmp)
		if err != nil {
			log.Println(log.WarningLog, "Unkonw tts")
			return
		}
		fmt.Printf("Msc command:%+v\n", tmp)

		//闲聊+暂停命令，0：不中断，1：中断暂停
		if tmp.Interrupt == 1 {
			mode := getCurDeviceMode(false)
			switch mode {
			case Exec_MusicPlay_mode:
				// 不显示icon
				log.Println(log.DebugLog, "pause music by chat interrupt")
				eventPoint.SetEpOsSouce("F141", eventPoint.EpOs_Server)
				SendSCmd(SCMD_MusicPlayer_Pause, PlayerArg{GloablePause: false, NotShowIcon: true})
			}
		}

		if len(tmp.Tts2) > 0 {
			MscToastFile(tmp.Tts2, retData.RspId, true, tmp.Keep, nil)
		} else if len(tmp.Tts) > 0 {
			MscToastTts(tmp.Tts, retData.RspId, true, tmp.Keep, nil)
		}
	case MSC_CONFIRM_NO:
		if isMute() {
			return
		}
		log.Println(log.DebugLog, "Confirm no!")
		log.Println(log.DebugLog, "Confirm yes!")
		var confirmparam struct {
			Param string `json:"confirmParam"`
		}
		if err := json.Unmarshal([]byte(retData.Detail), &confirmparam); err == nil {
			var clientparam struct {
				Param string `json:"clientParam"`
			}
			if err2 := json.Unmarshal([]byte(confirmparam.Param), &clientparam); err2 == nil {
				execInnterCmd(innerTask.ICmd_ConfirmSession_Deal, 0, clientparam.Param, "no")
			} else {
				log.Println(log.ErrorLog, "Decode json err:", err2)
			}
		} else {
			log.Println(log.ErrorLog, "Decode json err:", err)
		}

	case MSC_CONFIRM_DELAY:
		log.Println(log.DebugLog, "Confirm delay!")
		var confirmparam struct {
			Param     string `json:"confirmParam"`
			DelayTime int    `json:"data"`
		}

		if err := json.Unmarshal([]byte(retData.Detail), &confirmparam); err == nil {
			var clientparam struct {
				Param string `json:"clientParam"`
			}
			if err2 := json.Unmarshal([]byte(confirmparam.Param), &clientparam); err2 == nil {
				execInnterCmd(innerTask.ICmd_ConfirmSession_Deal, confirmparam.DelayTime, clientparam.Param, "delay")
			} else {
				log.Println(log.ErrorLog, "Decode json err:", err2)
			}
		} else {
			log.Println(log.ErrorLog, "Decode json err:", err)
		}
	case MSC_CONFIRM_YES:
		log.Println(log.DebugLog, "Confirm yes!")
		var confirmparam struct {
			Param string `json:"confirmParam"`
		}
		if err := json.Unmarshal([]byte(retData.Detail), &confirmparam); err == nil {
			var clientparam struct {
				Param string `json:"clientParam"`
			}
			if err2 := json.Unmarshal([]byte(confirmparam.Param), &clientparam); err2 == nil {
				execInnterCmd(innerTask.ICmd_ConfirmSession_Deal, 0, clientparam.Param, "yes")
			} else {
				log.Println(log.ErrorLog, "Decode json err:", err2)
			}
		} else {
			log.Println(log.ErrorLog, "Decode json err:", err)
		}

	case MSC_CMD_EXITSCENE:
		var tts string
		if tmpsscene := GetCurSScene(); tmpsscene != nil {
			tts = "场景已退出"
		} else {
			tts = "当前没有开启场景"
		}

		tmpconfig := player.GetDefaultNoticePlayerParams()
		tmpconfig.Keep = false
		tmpconfig.NeedRepeat = true
		tmpconfig.Level = TTS_LEVEL_1
		tmpconfig.SrcType = AdSrcType_TTS
		tmpconfig.Tts = tts
		tmpconfig.Uuid = retData.RspId
		tmpconfig.LedOn = DirectLed{EffectId: atservice.GUIDE_EFFECT_ID_EXEC_CMD, Action: atservice.GUIDE_ACTION_START, Data: []byte{}}
		tmpconfig.LedOff = DirectLed{EffectId: atservice.GUIDE_EFFECT_ID_EXEC_CMD, Action: atservice.GUIDE_ACTION_STOP, Data: []byte{}}
		tmpconfig.IconIn = vui.IconLed_DoNothing
		tmpconfig.IconOut = vui.IconLed_DoNothing
		tmpconfig.SpecialFunc = func(arg TtsPlayerArg) {
			Scene_Exit()

			//检查是否网络缓存播放失败
			if arg.StopReason == NoticeStopReason_Error {
				go MscToastFile(vui.SoundNotice_Song_Get_Timeout.GetPath(), CONST_AUDIO_ID, false, false, nil)
			}
		}

		NoticePlayerSendSCmd2(SCMD_SuperTask_Tts_Ctrl_Play, tmpconfig)

	case MSC_CMD_ENTERSCENE:
		var tmp struct {
			Scene http.Scene `json:"data"`
		}
		if err := json.Unmarshal([]byte(retData.Detail), &tmp); err == nil {
			if len(tmp.Scene.Id) > 0 {
				SceneRequestPlay(tmp.Scene)
			} else {
				log.Println(log.ErrorLog, "Get nil id scene!!!!!")
			}
		} else {
			log.Println(log.ErrorLog, "json err:", err)
		}

	case MSC_CMD_MUSIC_NO_COPYRIGHT_TOAST, MSC_CMD_TTS_IDLE, MSC_CMD_REMIND_CLOSE, MSC_CMD_ALARM_CLOSE, MSC_CMD_TTS_TOAST, MSC_CMD_TTS_UNKNOW0, MSC_CMD_TTS_UNKNOW1, MSC_CMD_TTS_UNKNOW2, MSC_CMD_TTS_UNKNOW3:
		var tmp ServerDetailBase
		err := json.Unmarshal([]byte(retData.Detail), &tmp)
		if err != nil {
			log.Println(log.WarningLog, "Unkonw tts")
			return
		}
		fmt.Printf("Msc command:%+v\n", tmp)

		if len(tmp.Tts) > 0 || len(tmp.Tts2) > 0 {
			var src AdSrcType
			var pt string
			if len(tmp.Tts2) > 0 {
				src = AdSrcType_FILE
				pt = tmp.Tts2
			} else {
				src = AdSrcType_TTS
				pt = tmp.Tts
			}

			MscToast(src, pt, retData.RspId, true, tmp.Keep, func(params *NoticePlayerParams) {
				bf := params.BeforeExecFunc
				params.BeforeExecFunc = func() {
					bf()
					vu := vui.SoundNotice(tmp.VoiceEffect)
					pt := vu.GetPath()
					if len(tmp.VoiceEffect) > 0 && len(pt) > 0 {
						PlayNoticeSync(AdSrcType_FILE, pt, CONST_AUDIO_ID, false, nil)
					}
				}
			})
		} else if len(tmp.VoiceEffect) > 0 {
			//only voiceeffect
			vu := vui.SoundNotice(tmp.VoiceEffect)
			pt := vu.GetPath()
			if len(pt) > 0 {
				MscToast(AdSrcType_FILE, pt, retData.RspId, false, tmp.Keep, nil)
			} else {
				log.Println(log.ErrorLog, "Not get vui path, do not play", tmp.VoiceEffect)
				SendSCmd(SCMD_SChedule)
			}
		}

	case MSC_CMD_PAUSE:
		//SendSCmd(SCMD_MusicPlayer_Pause, nil)
		//player.SoundEffectPlayCmd(CMD_SE_PLAY, vui.SoundNotice_Scaozuofankui001.GetPath())

		// prd reverse : 20180316
		// todo :　灯光需要完善
		mode := getCurDeviceMode(true)

		player.SoundEffectPlayCmd(CMD_SE_PLAY, vui.SoundNotice_Scaozuofankui001.GetPath())

		switch mode {
		case Idle_mode, Exec_Non_Music_Idle_mode:

		case Pause_mode:
			vui.IconLed_IconChaozuo001.Show()
		case Exec_MusicPlay_mode:
			eventPoint.SetEpOsSouce("F141", eventPoint.EpOs_Server)
			SendSCmd(SCMD_MusicPlayer_Pause, nil)
		case Exec_Non_Music_Played_mode:
			// 不显示icon
			eventPoint.SetEpOsSouce("F141", eventPoint.EpOs_Server)
			SendSCmd(SCMD_MusicPlayer_Pause, PlayerArg{GloablePause: false, NotShowIcon: true})
		}
	case MSC_CMD_NEXT, MSC_CMD_PRE:
		// prd reverse : 20180316
		mode := getCurDeviceMode(true)
		switch mode {
		case Idle_mode, Exec_Non_Music_Idle_mode:
			if retData.Desc == MSC_CMD_ONE_SHOT {
				log.Println(log.WarningLog, "can not use one shot cmd ：in idle mode")
				return
			}
			MscToastTts(TTS_MUSIC_ERR_5, retData.RspId, true, false, nil)

			if retData.Desc == MSC_CMD_ONE_SHOT_WAKEUP {
				log.Println(log.WarningLog, "can not use one shot cmd ：", TTS_MUSIC_ERR_5)
				http.InformLocalMsgToServer(http.Type_Inform_TtsPush, int(MSC_CMD_NEXT), "下一首", TTS_MUSIC_ERR_5) //上传信息流
			} else {
				http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd, Data: TTS_MUSIC_ERR_5, Tts: TTS_MUSIC_ERR_5,
					PlayMode: CurPlayingMode, DataType: http.DATA_TYPE_STRING})
			}

			return
		case Pause_mode:
			if retData.Desc == MSC_CMD_ONE_SHOT {
				log.Println(log.WarningLog, "can not use one shot cmd ：in pause mode")
				return
			}
			switch GetCurPlayerId() {
			case GetScenePlayerId(), PlayerType_Wifi, PlayerType_Bt, PlayerType_Airplay:
				if retData.Desc == MSC_CMD_ONE_SHOT_WAKEUP {
					log.Println(log.DebugLog, "one shot cmd for next song by wakeup")
				}

			case PlayerType_Dlna:
				if retData.Desc != MSC_CMD_ONE_SHOT_WAKEUP && retData.Desc != MSC_CMD_ONE_SHOT {
					log.Println(log.DebugLog, "not one shot cmd for dlna in pause mode, just return")
					/*MscToastTts(TTS_NOT_UNSUPPORT, retData.RspId, true, false, nil)    //lupeng 20190908 #PV1-4216

					if retData.Desc == MSC_CMD_ONE_SHOT_WAKEUP {
						log.Println(log.WarningLog, "can not use one shot cmd ：", TTS_NOT_UNSUPPORT)
						http.InformLocalMsgToServer(http.Type_Inform_TtsPush, int(MSC_CMD_NEXT), "下一首", TTS_NOT_UNSUPPORT) //上传信息流
					} else {
						http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd, Data: TTS_NOT_UNSUPPORT, Tts: TTS_NOT_UNSUPPORT,
							PlayMode: CurPlayingMode, DataType: http.DATA_TYPE_STRING})
					}*/
				} else {
					log.Println(log.DebugLog, "one shot cmd for dlna, so trig next from server")
					serverListParams := http.MusicListServerType{
						Src:     MUSIC_LIST_NULL,
						Id:      nil,
						Params:  nil,
						Start:   0,
						Size:    PAGE_SIZE,
						WantTts: false,

						ExtraData: PlayListSrcRec.ExtraData,
						BizType:   PlayListSrcRec.BizType,
						TrigServer: true,
						Cmd:       retData.Cmd,
						Source:    int(PlayerType_Dlna),

						Mode: CurPlayingMode,
					}
					_, err := GetMusicListNew(PlayerType_Wifi, true, serverListParams)
					if nil != err {
						NoticePlayerSendSCmd(SCMD_SuperTask_Tts_Play, MusicErrTtsMap[string(MUSIC_LIST_NULL)], CONST_AUDIO_ID, AdSrcType_TTS,
							TTS_LEVEL_1, true, false)
						log.Println(log.ErrorLog, err.Error())
					} else {
						go http.InformLocalMsgToServer(http.Type_Inform_TtsPush, int(MSC_CMD_NEXT), TTS_MUSIC_NEXT, TTS_MUSIC_NEXT) //上传信息流
					}
				}

				return
			default:
				log.Println(log.ErrorLog, "err playerId:", GetCurPlayerId())
				return
			}
		case Exec_MusicPlay_mode, Exec_Non_Music_Played_mode:
			switch GetCurPlayerId() {
			case GetScenePlayerId(), PlayerType_Wifi, PlayerType_Bt, PlayerType_Airplay:
				if retData.Desc == MSC_CMD_ONE_SHOT || retData.Desc == MSC_CMD_ONE_SHOT_WAKEUP {
					log.Println(log.DebugLog, "one shot cmd for next song")
					/*播放反馈声音，prd暂时不需要
					PlayNoticeAsync(AdSrcType_FILE, vui.SoundNotice_Shuanxing001.GetPath(), WAKEUP_AUDIO_ID, false, nil, func(id uint32, reason NoticeStopReason) {
						log.Println(log.WarningLog, "one shot cmd audio sound end")
					})*/
				}
			case PlayerType_Dlna:
				if retData.Desc != MSC_CMD_ONE_SHOT_WAKEUP && retData.Desc != MSC_CMD_ONE_SHOT {
					log.Println(log.DebugLog, "not one shot cmd for dlna in pause mode, just return")
					/*MscToastTts(TTS_NOT_UNSUPPORT, retData.RspId, true, false, nil)    //lupeng 20190908 #PV1-4216

					if retData.Desc == MSC_CMD_ONE_SHOT_WAKEUP {
						log.Println(log.WarningLog, "can not use one shot cmd ：", TTS_NOT_UNSUPPORT)
						http.InformLocalMsgToServer(http.Type_Inform_TtsPush, int(MSC_CMD_NEXT), "下一首", TTS_NOT_UNSUPPORT) //上传信息流
					} else {
						http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd, Data: TTS_NOT_UNSUPPORT, Tts: TTS_NOT_UNSUPPORT,
							PlayMode: CurPlayingMode, DataType: http.DATA_TYPE_STRING})
					}*/
				} else {
					log.Println(log.DebugLog, "one shot cmd for dlna, so trig next from server")
					serverListParams := http.MusicListServerType{
						Src:     MUSIC_LIST_NULL,
						Id:      nil,
						Params:  nil,
						Start:   0,
						Size:    PAGE_SIZE,
						WantTts: false,

						ExtraData: PlayListSrcRec.ExtraData,
						BizType:   PlayListSrcRec.BizType,
						TrigServer: true,
						Cmd:       retData.Cmd,
						Source:    int(PlayerType_Dlna),

						Mode: CurPlayingMode,
					}
					_, err := GetMusicListNew(PlayerType_Wifi, true, serverListParams)
					if nil != err {
						NoticePlayerSendSCmd(SCMD_SuperTask_Tts_Play, MusicErrTtsMap[string(MUSIC_LIST_NULL)], CONST_AUDIO_ID, AdSrcType_TTS,
							TTS_LEVEL_1, true, false)
						log.Println(log.ErrorLog, err.Error())
					} else {
						go http.InformLocalMsgToServer(http.Type_Inform_TtsPush, int(MSC_CMD_NEXT), TTS_MUSIC_NEXT, TTS_MUSIC_NEXT) //上传信息流
					}
				}
				return
			default:
				log.Println(log.ErrorLog, "err playerId:", GetCurPlayerId())
				return
			}
		}
		var tmp ServerDetailBase
		err := json.Unmarshal([]byte(retData.Detail), &tmp)
		if err != nil {
			log.Println(log.WarningLog, "Unkonw tts")
			return
		}

		// exec
		switch Cmd(retData.Cmd) {
		case MSC_CMD_NEXT:
			//自然声快捷命令下一首需要音箱端主动去服务器拉取
			if PlayerType_Wifi == GetCurPlayerId() && PlayListSrcRec.BizType == BIZ_TYPE_NATURAL_SOUND {
				log.Println(log.DebugLog, "one shot cmd for next natural sound, so get next from server")
				// 拉取新的自然声
				serverListParams := http.MusicListServerType{
					Src:     NATURAL_SOUND_LIST,
					Id:      &LocalMusicList[GetMusicListIndex()].GetCurPos().Value.(*SongInfo).Id, //服务器需要排除当前自然声
					Params:  nil,
					Start:   0,
					Size:    PAGE_SIZE,
					WantTts: false,

					ExtraData: PlayListSrcRec.ExtraData,
					BizType:   PlayListSrcRec.BizType,
					TrigServer: true,
					Cmd:       retData.Cmd,
					Source:    int(PlayerType_Wifi),

					Mode: CurPlayingMode,
				}
				list, err := GetMusicListNew(PlayerType_Wifi, true, serverListParams)
				if nil != err {
					NoticePlayerSendSCmd(SCMD_SuperTask_Tts_Play, MusicErrTtsMap[string(MUSIC_LIST_NULL)], CONST_AUDIO_ID, AdSrcType_TTS,
						TTS_LEVEL_1, true, false)
					log.Println(log.ErrorLog, err.Error())
				} else {
					RspId = &retData.RspId
					list.InnerTts = list.PullTts
					list.InnerTtsUrl = list.PullTtsUrl
					list.RspId = list.RspId
					SetPlayerArgs(PlayerType_Wifi, list)
					player.PlayerHander[PlayerType_Wifi].RequestPlay_Async(nil)
					go http.InformLocalMsgToServer(http.Type_Inform_TtsPush, int(MSC_CMD_NEXT), TTS_MUSIC_NEXT, TTS_MUSIC_NEXT) //上传信息流
				}
			} else {
				RspId = &retData.RspId

				base := ServerPlayerBase{RspId: retData.RspId, Action: MUSIC_ACTION_NEXT, ActionSrc: MUSIC_ACTION_SRC_VOICE}
				SendSCmd(SCMD_MusicPlayer_PlayNext, PlayerArg{GloablePause: false, NotShowIcon: false, TtsNextPre: &tmp.Tts,
					ServerPlayerBase: base})
			}
		case MSC_CMD_PRE:
			RspId = &retData.RspId

			base := ServerPlayerBase{RspId: retData.RspId, Action: MUSIC_ACTION_PREV, ActionSrc: MUSIC_ACTION_SRC_VOICE}
			SendSCmd(SCMD_MusicPlayer_PlayPre, PlayerArg{GloablePause: false, NotShowIcon: false, TtsNextPre: &tmp.Tts,
				ServerPlayerBase: base})
		}
	case MSC_CMD_CONTINUE:
		//RspId = &retData.RspId
		//eventPoint.SetEpOsSouce("F141", eventPoint.EpOs_Server)
		//SendSCmd(SCMD_MusicPlayer_Play, nil)

		// prd reverse : 20180316
		RspId = &retData.RspId
		eventPoint.SetEpOsSouce("F141", eventPoint.EpOs_Server)

		mode := getCurDeviceMode(true)
		switch mode {
		case Idle_mode, Exec_Non_Music_Idle_mode:
			// 没有有效歌曲,拉取推荐接口
			serverListParams := http.MusicListServerType{
				Src:     SERVER_RCMD,
				Id:      nil,
				Params:  nil,
				Start:   0,
				Size:    PAGE_SIZE,
				WantTts: true,

				Mode: CurPlayingMode,
			}
			list, err := GetMusicListNew(PlayerType_Wifi, true, serverListParams)
			if nil != err {
				NoticePlayerSendSCmd(SCMD_SuperTask_Tts_Play, MusicErrTtsMap[string(SERVER_RCMD)], CONST_AUDIO_ID, AdSrcType_TTS,
					TTS_LEVEL_1, true, false)
				log.Println(log.ErrorLog, err.Error())
			} else {
				RspId = &retData.RspId
				list.InnerTts = list.PullTts
				list.InnerTtsUrl = list.PullTtsUrl
				list.RspId = list.RspId
				SetPlayerArgs(PlayerType_Wifi, list)
				player.PlayerHander[PlayerType_Wifi].RequestPlay_Async(nil)
			}
		case Pause_mode, Exec_MusicPlay_mode, Exec_Non_Music_Played_mode:
			if CurPlayingMode == LIST_ORDER_PLAY && PlayListSrcRec.ListHasEnd == true {
				var continuePlayTts string
				if PlayListSrcRec.BizType == BIZ_TYPE_MUSIC {
					continuePlayTts = TTS_TEXT_MUSIC_END
				} else {
					continuePlayTts = TTS_TEXT_RADIO_END
				}
				MscToastTts(continuePlayTts, retData.RspId, true, false, func(params *NoticePlayerParams) {
					specialFuncBackup := params.SpecialFunc
					params.SpecialFunc = func(arg TtsPlayerArg) {
						specialFuncBackup(arg)
						//电台模式下，继续播放最后一个节目
						if PlayListSrcRec.BizType != BIZ_TYPE_MUSIC {
							SendSCmd(SCMD_MusicPlayer_Play, nil)
						} else {
							SendSCmd(SCMD_MusicPlayer_Pause, PlayerArg{GloablePause: false, NotShowIcon: true})
						}

						//检查是否网络缓存播放失败
						if arg.StopReason == NoticeStopReason_Error {
							go MscToastFile(vui.SoundNotice_Song_Get_Timeout.GetPath(), CONST_AUDIO_ID, false, false, nil)
						}
					}
				})
			} else {
				SendSCmd(SCMD_MusicPlayer_Play, nil)
			}
		}
	case MSC_CMD_PLAY_MUSIC:
		var tmp struct {
			ServerDetailBase
			ServerSongDetail
			PlayMode  MusicPlayMode `json:"playMode"`
			IsMatch   bool          `json:"isMatch"`
			ExtraData string        `json:"extraData"`
		}

		err := json.Unmarshal([]byte(retData.Detail), &tmp)
		if err != nil {
			log.Printf(log.WarningLog, "Unknow list %v\n", err)
			return
		}
		serverData := createServerMusicList(&tmp.ServerSongDetail.Song, tmp.PlayMode, retData.RspId, tmp.Tts, tmp.Tts2)
		if nil == serverData {
			log.Println(log.WarningLog, "serverData nil")
			return
		}
		serverData.IsMatch = tmp.IsMatch
		serverData.ExtraData = tmp.ExtraData

		RspId = &retData.RspId
		serverData.Action = MUSIC_ACTION_NEXT
		serverData.ActionSrc = MUSIC_ACTION_SRC_VOICE
		SetPlayerArgs(PlayerType_Wifi, serverData)
		player.PlayerHander[PlayerType_Wifi].RequestPlay_Async(nil)

	case MSC_CMD_PLAY_LIST, MSC_CMD_PLAY_RCMD:
		var tmp struct {
			ServerDetailBase
			ServerMusicList
		}
		err := json.Unmarshal([]byte(retData.Detail), &tmp)
		if err != nil {
			log.Println(log.ErrorLog, err.Error())
			return
		}
		if MUSIC_SHARE_RCMD == tmp.MusicList.Type {
			MscToastTts(tmp.Tts, retData.RspId, true, tmp.Keep, func(params *NoticePlayerParams) {
				specialFuncBackup := params.SpecialFunc
				params.SpecialFunc = func(arg TtsPlayerArg) {
					specialFuncBackup(arg)

					RspId = &retData.RspId
					tmp.InnerTts = ""
					tmp.InnerTtsUrl = tmp.Tts2
					tmp.RspId = retData.RspId
					SetPlayerArgs(PlayerType_Wifi, &tmp.ServerMusicList)
					player.PlayerHander[PlayerType_Wifi].RequestPlay_Async(nil)

					//检查是否网络缓存播放失败
					if arg.StopReason == NoticeStopReason_Error {
						go MscToastFile(vui.SoundNotice_Song_Get_Timeout.GetPath(), CONST_AUDIO_ID, false, false, nil)
					}
				}
			})
		} else {
			//if MSC_CMD_PLAY_RCMD == Cmd(retData.Cmd) {
			//	tmp.ServerCmd = uint16(MSC_CMD_PLAY_RCMD)
			//}
			RspId = &retData.RspId
			tmp.InnerTts = tmp.Tts
			tmp.InnerTtsUrl = tmp.Tts2
			tmp.RspId = retData.RspId
			tmp.Action = MUSIC_ACTION_NEXT
			tmp.ActionSrc = MUSIC_ACTION_SRC_VOICE
			SetPlayerArgs(PlayerType_Wifi, &tmp.ServerMusicList)
			player.PlayerHander[PlayerType_Wifi].RequestPlay_Async(nil)
		}
	case MSC_CMD_PLAY_LISTS:
		var tmp struct {
			ServerDetailBase
			ServerMusicLists
		}
		err := json.Unmarshal([]byte(retData.Detail), &tmp)
		if err != nil {
			log.Println(log.ErrorLog, err.Error())
			return
		}
		RspId = &retData.RspId
		tmp.InnerTts = tmp.Tts
		tmp.InnerTtsUrl = tmp.Tts2
		tmp.RspId = retData.RspId
		tmp.Action = MUSIC_ACTION_NEXT
		tmp.ActionSrc = MUSIC_ACTION_SRC_VOICE
		SetPlayerArgs(PlayerType_Wifi, &tmp.ServerMusicLists)
		player.PlayerHander[PlayerType_Wifi].RequestPlay_Async(nil)

	case MSC_CMD_COLLECT_MUSIC, MSC_CMD_UNCOLLECT_MUSIC:
		mode := getCurDeviceMode(true)
		switch mode {
		case Idle_mode, Pause_mode, Exec_Non_Music_Played_mode, Exec_Non_Music_Idle_mode:
			MscToastTts(TTS_MUSIC_ERR_4, retData.RspId, true, false, nil)
			return
		case Exec_MusicPlay_mode:
			if ignoreCmdInDAB() {
				MscToastTts(TTS_MUSIC_ERR_3, retData.RspId, true, false, nil)
				return
			}
		}
		// exec
		var tmp struct {
			ServerDetailBase
			HasSuccess bool `json:"data"`
		}
		err := json.Unmarshal([]byte(retData.Detail), &tmp)
		if nil != err {
			log.Println(log.ErrorLog, err.Error())
			return
		}
		if len(tmp.Tts2) > 0 {
			MscToastFile(tmp.Tts2, retData.RspId, true, tmp.Keep, nil)
		} else if len(tmp.Tts) > 0 {
			MscToastTts(tmp.Tts, retData.RspId, true, tmp.Keep, func(params *NoticePlayerParams) {
				if Cmd(retData.Cmd) == MSC_CMD_COLLECT_MUSIC {
					params.BeforeExecFunc = func() {
						if IsMicClose == false {
							vui.IconLed_IconChaozuo005.Show()
							tmp := DirectLed{EffectId: atservice.GUIDE_EFFECT_ID_EXEC_CMD, Action: atservice.GUIDE_ACTION_START}
							led_mcu.DirectLedControl(tmp.EffectId, tmp.Action, tmp.StartLampNum, []byte{uint8(adau1761.MustGetVol())})
						}

						switch Cmd(retData.Cmd) {
						case MSC_CMD_COLLECT_MUSIC:
							player.SoundEffectPlayCmd(CMD_SE_PLAY, vui.SoundNotice_Slianjiechenggong001.GetPath())
						case MSC_CMD_UNCOLLECT_MUSIC:
							player.SoundEffectPlayCmd(CMD_SE_PLAY, vui.SoundNotice_Scaozuofankui001.GetPath())
						}
					}
					params.BeforeSpecialFunc = nil
				}
			})
		}

	case MSC_CMD_CYCLE_LIST, MSC_CMD_CYCLE_RANDOM, MSC_CMD_CYCLE_ONE_SONG, MSC_CMD_ORDER_PLAY:
		// prd reverse : 20180316
		mode := getCurDeviceMode(true)
		switch mode {
		case Idle_mode, Exec_Non_Music_Idle_mode:
			MscToastTts(TTS_MUSIC_ERR_1, retData.RspId, true, false, nil)
			return
		case Pause_mode:
			if ignoreCmdInDAB() {
				MscToastTts(TTS_MUSIC_ERR_2, retData.RspId, true, false, nil)
				return
			}
		case Exec_MusicPlay_mode, Exec_Non_Music_Played_mode:
			if ignoreCmdInDAB() {
				MscToastTts(TTS_MUSIC_ERR_2, retData.RspId, true, false, nil)
				return
			}
		}
		// exec
		switch Cmd(retData.Cmd) {
		case MSC_CMD_CYCLE_LIST:
			// 切换到顺序播放时，如果当前是单曲循环，不需要处理
			if LIST_RANDOM_CYCLE == CurPlayingMode {
				ResetUnPlayListCurNode()
			}
			CurPlayingMode = LIST_ORDER_CYCLE
		case MSC_CMD_ORDER_PLAY:
			// 切换到顺序播放时，如果当前是单曲循环，不需要处理
			if LIST_RANDOM_CYCLE == CurPlayingMode {
				ResetUnPlayListCurNode()
			}
			CurPlayingMode = LIST_ORDER_PLAY
		case MSC_CMD_CYCLE_RANDOM:
			if LIST_ORDER_CYCLE == CurPlayingMode || SINGLE_CYCLE == CurPlayingMode {
				ResetUnPlayListCurNode()
			}
			CurPlayingMode = LIST_RANDOM_CYCLE
		case MSC_CMD_CYCLE_ONE_SONG:
			// 切换到单曲播放时，如果当前是顺序循环，不需要处理
			if LIST_RANDOM_CYCLE == CurPlayingMode {
				ResetUnPlayListCurNode()
			}
			CurPlayingMode = SINGLE_CYCLE
		}
		log.Println(log.DebugLog, "Change playmode:", CurPlayingMode)
		playModeBroadCast(CurPlayingMode)
		var tmp ServerDetailBase
		err := json.Unmarshal([]byte(retData.Detail), &tmp)
		if nil != err {
			log.Println(log.ErrorLog, err.Error())
			return
		}

		if Pause_mode == mode {
			if len(tmp.Tts2) > 0 {
				MscToastFile(tmp.Tts2, retData.RspId, true, tmp.Keep, func(params *NoticePlayerParams) {
					specialFuncBackup := params.SpecialFunc

					params.SpecialFunc = func(arg TtsPlayerArg) {
						specialFuncBackup(arg)
						SendSCmd(SCMD_MusicPlayer_Play, nil)

						//检查是否网络缓存播放失败
						if arg.StopReason == NoticeStopReason_Error {
							go MscToastFile(vui.SoundNotice_Song_Get_Timeout.GetPath(), CONST_AUDIO_ID, false, false, nil)
						}
					}
				})
			} else if len(tmp.Tts) > 0 {
				MscToastTts(tmp.Tts, retData.RspId, true, tmp.Keep, func(params *NoticePlayerParams) {
					specialFuncBackup := params.SpecialFunc

					params.SpecialFunc = func(arg TtsPlayerArg) {
						specialFuncBackup(arg)
						SendSCmd(SCMD_MusicPlayer_Play, nil)

						//检查是否网络缓存播放失败
						if arg.StopReason == NoticeStopReason_Error {
							go MscToastFile(vui.SoundNotice_Song_Get_Timeout.GetPath(), CONST_AUDIO_ID, false, false, nil)
						}
					}
				})
			}
		} else {
			if len(tmp.Tts2) > 0 {
				MscToastFile(tmp.Tts2, retData.RspId, true, tmp.Keep, nil)
			} else if len(tmp.Tts) > 0 {
				MscToastTts(tmp.Tts, retData.RspId, true, tmp.Keep, nil)
			}
		}
	case MSC_CMD_VOLUME_DOWN:
		if retData.Desc == MSC_CMD_ONE_SHOT {

			mode := getCurDeviceMode(true)
			if !mode.IsActive() {
				log.Println(log.WarningLog, "can not use one shot cmd volume down: not in playing mode")
				return
			} else {
				log.Println(log.DebugLog, "one shot cmd for volume down")
			}
		}

		var tmp struct {
			ServerDetailBase
			Type  int8 `json:"type"`
			Value int  `json:"value"`
		}
		err := json.Unmarshal([]byte(retData.Detail), &tmp)
		if nil != err {
			log.Println(log.ErrorLog, err.Error())
			return
		}

		if isMute() {
			tts0 := fmt.Sprintf(tmp.Tts, 0)
			http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd, Data: tts0, Tts: tts0,
				PlayMode: CurPlayingMode, DataType: http.DATA_TYPE_STRING})
			return
		}

		eventPoint.SetEpOsSouce("H511", eventPoint.EpOs_Server)

		tosetvol := adau1761.MustGetVol()
		if tmp.Value == 0 {
			tosetvol -= IncVolLevel.GetCfgListVui()
		} else {
			switch tmp.Type {
			case VOL_VALUE:
				tosetvol -= tmp.Value
			case VOL_PERCENT:
				tosetvol -= GetVolByPer(tmp.Value)
			}
		}

		switch {
		case tosetvol < 1:
			tosetvol = 1
		case tosetvol > MaxVolume:
			tosetvol = MaxVolume
		}
		VolSet(tosetvol)
		volBroadCast(VOL_VOICE_ACTION)

		var ttsPush string
		if len(tmp.Tts2) > 0 {
			ttsPush = tmp.Tts2
		} else if len(tmp.Tts) > 0 {
			if vol, err := VolGet(); nil == err {
				var volTts int
				switch tmp.Type {
				case VOL_VALUE:
					volTts = vol
				case VOL_PERCENT:
					volTts = GetPerByVol(vol)
				default:
					volTts = GetPerByVol(vol)
				}
				ttsPush = fmt.Sprintf(tmp.Tts, volTts)
			}
		}

		mode := getCurDeviceMode(true)
		if Exec_MusicPlay_mode == mode {
			ShowVolumeLed()
		} else {
			if len(tmp.Tts2) > 0 {
				MscToastFile(tmp.Tts2, retData.RspId, true, tmp.Keep, volChangeCb)
			} else if len(tmp.Tts) > 0 {
				MscToastTts(ttsPush, retData.RspId, true, tmp.Keep, volChangeCb)
			}
		}

		if retData.Desc == MSC_CMD_ONE_SHOT || retData.Desc == MSC_CMD_ONE_SHOT_WAKEUP {
			http.InformLocalMsgToServer(http.Type_Inform_TtsPush, int(MSC_CMD_VOLUME_DOWN), "小声一点", ttsPush)
		} else {
			http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd, Data: ttsPush, Tts: ttsPush,
				PlayMode: CurPlayingMode, DataType: http.DATA_TYPE_STRING})
		}
	case MSC_CMD_VOLUME_UP:
		eventPoint.SetEpOsSouce("H511", eventPoint.EpOs_Server)

		if retData.Desc == MSC_CMD_ONE_SHOT {
			mode := getCurDeviceMode(true)
			if !mode.IsActive() {
				log.Println(log.WarningLog, "can not use one shot cmd volume up: not in playing mode")
				return
			} else {
				log.Println(log.DebugLog, "one shot cmd for volume up")
			}
		}

		var tmp struct {
			ServerDetailBase
			Type  int8 `json:"type"`
			Value int  `json:"value"`
		}
		err := json.Unmarshal([]byte(retData.Detail), &tmp)
		if nil != err {
			log.Println(log.ErrorLog, err.Error())
			return
		}

		tosetvol := adau1761.MustGetVol()
		if tmp.Value == 0 {
			tosetvol += IncVolLevel.GetCfgListVui()
		} else {
			switch tmp.Type {
			case VOL_VALUE:
				tosetvol += tmp.Value
			case VOL_PERCENT:
				tosetvol += GetVolByPer(tmp.Value)
			}
		}

		switch {
		case tosetvol < 1:
			tosetvol = 1
		case tosetvol > MaxVolume:
			tosetvol = MaxVolume
		}
		VolSet(tosetvol)
		volBroadCast(VOL_VOICE_ACTION)

		var ttsPush string
		if len(tmp.Tts2) > 0 {
			ttsPush = tmp.Tts2
		} else if len(tmp.Tts) > 0 {
			if vol, err := VolGet(); nil == err {
				var volTts int
				switch tmp.Type {
				case VOL_VALUE:
					volTts = vol
				case VOL_PERCENT:
					volTts = GetPerByVol(vol)
				default:
					volTts = GetPerByVol(vol)
				}
				ttsPush = fmt.Sprintf(tmp.Tts, volTts)
			}
		}

		mode := getCurDeviceMode(true)
		if Exec_MusicPlay_mode == mode {
			ShowVolumeLed()
		} else {
			if len(tmp.Tts2) > 0 {
				MscToastFile(tmp.Tts2, retData.RspId, true, tmp.Keep, volChangeCb)
			} else if len(tmp.Tts) > 0 {
				MscToastTts(ttsPush, retData.RspId, true, tmp.Keep, volChangeCb)
			}
		}

		if retData.Desc == MSC_CMD_ONE_SHOT || retData.Desc == MSC_CMD_ONE_SHOT_WAKEUP {
			http.InformLocalMsgToServer(http.Type_Inform_TtsPush, int(MSC_CMD_VOLUME_UP), "大声一点", ttsPush)
		} else {
			http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd, Data: ttsPush, Tts: ttsPush,
				PlayMode: CurPlayingMode, DataType: http.DATA_TYPE_STRING})
		}
	case MSC_CMD_VOL_MAX:
		eventPoint.SetEpOsSouce("H511", eventPoint.EpOs_Server)
		VolSet(MaxVolume)
		volBroadCast(VOL_VOICE_ACTION)

		mode := getCurDeviceMode(true)
		if Exec_MusicPlay_mode == mode {
			ShowVolumeLed()
		} else {
			var tmp ServerDetailBase
			err := json.Unmarshal([]byte(retData.Detail), &tmp)
			if nil != err {
				log.Println(log.ErrorLog, err.Error())
				return
			}
			if len(tmp.Tts2) > 0 {
				MscToastFile(tmp.Tts2, retData.RspId, true, tmp.Keep, volChangeCb)
			} else if len(tmp.Tts) > 0 {
				MscToastTts(tmp.Tts, retData.RspId, true, tmp.Keep, volChangeCb)
			}
		}
	case MSC_CMD_VOL_MIN:
		VolSet(MinVolume)
		volBroadCast(VOL_VOICE_ACTION)
		eventPoint.SetEpOsSouce("H511", eventPoint.EpOs_Server)

		mode := getCurDeviceMode(true)
		if Exec_MusicPlay_mode == mode {
			ShowVolumeLed()
		} else {
			var tmp ServerDetailBase
			err := json.Unmarshal([]byte(retData.Detail), &tmp)
			if nil != err {
				log.Println(log.ErrorLog, err.Error())
				return
			}
			if len(tmp.Tts2) > 0 {
				MscToastFile(tmp.Tts2, retData.RspId, true, tmp.Keep, volChangeCb)
			} else if len(tmp.Tts) > 0 {
				MscToastTts(tmp.Tts, retData.RspId, true, tmp.Keep, volChangeCb)
			}
		}
	case MSC_CMD_VOL_SET:
		var tmp struct {
			Value int8   `json:"value"`
			Type  int8   `json:"type"`
			Tts   string `json:"tts"`
			Tts2  string `json:"tts2"`
		}
		err := json.Unmarshal([]byte(retData.Detail), &tmp)
		if nil != err {
			log.Println(log.ErrorLog, err.Error())
			return
		}

		if 0 == tmp.Value && isMute() {
			tts0 := fmt.Sprintf(tmp.Tts, 0)
			http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd, Data: tts0, Tts: tts0,
				PlayMode: CurPlayingMode, DataType: http.DATA_TYPE_STRING})
			return
		}

		switch tmp.Type {
		case VOL_VALUE:
			if tmp.Value > MaxVolume {
				tmp.Value = MaxVolume
			}
		case VOL_PERCENT:
			tmp.Value = int8(GetVolByPer(int(tmp.Value)))
		default:
			log.Println(log.ErrorLog, "err type:", tmp.Type)
			return
		}
		VolSet(int(tmp.Value))
		volBroadCast(VOL_VOICE_ACTION)
		eventPoint.SetEpOsSouce("H511", eventPoint.EpOs_Server)

		var ttsPush string
		if len(tmp.Tts2) > 0 {
			ttsPush = tmp.Tts2
		} else if len(tmp.Tts) > 0 {
			if vol, err := VolGet(); nil == err {
				var volTts int
				switch tmp.Type {
				case VOL_VALUE:
					volTts = vol
				case VOL_PERCENT:
					volTts = GetPerByVol(vol)
				default:
					volTts = GetPerByVol(vol)
				}
				ttsPush = fmt.Sprintf(tmp.Tts, volTts)
			}
		}
		http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd, Data: ttsPush, Tts: ttsPush,
			PlayMode: CurPlayingMode, DataType: http.DATA_TYPE_STRING})

		mode := getCurDeviceMode(true)
		if Exec_MusicPlay_mode == mode {
			ShowVolumeLed()
		} else {
			if len(tmp.Tts2) > 0 {
				MscToastFile(ttsPush, retData.RspId, true, false, volChangeCb)
			} else if len(tmp.Tts) > 0 {
				MscToastTts(ttsPush, retData.RspId, true, false, volChangeCb)
			}
		}
	case MSC_CMD_QUERY_VOL:
		var tmp struct {
			Type int8   `json:"type"`
			Tts  string `json:"tts"`
			Tts2 string `json:"tts2"`
		}
		err := json.Unmarshal([]byte(retData.Detail), &tmp)
		if nil != err {
			log.Println(log.ErrorLog, err.Error())
			return
		}

		if isMute() {
			tts0 := fmt.Sprintf(tmp.Tts, 0)
			http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd, Data: tts0, Tts: tts0,
				PlayMode: CurPlayingMode, DataType: http.DATA_TYPE_STRING})
			return
		}

		vol, err := VolGet()
		if err != nil {
			log.Println(log.ErrorLog, err.Error())
			return
		}
		var ttsInfo string
		switch tmp.Type {
		case VOL_VALUE:
			ttsInfo = fmt.Sprintf(tmp.Tts, vol)
		case VOL_PERCENT:
			volPer := GetPerByVol(vol)
			ttsInfo = fmt.Sprintf(tmp.Tts, volPer)
		default:
			ttsInfo = fmt.Sprintf(tmp.Tts, vol)
		}

		http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd, Data: ttsInfo, Tts: ttsInfo,
			PlayMode: CurPlayingMode, DataType: http.DATA_TYPE_STRING})

		MscToastTts(ttsInfo, retData.RspId, true, false, volChangeCb)

	case MSC_CMD_REMIND_ADD:
		var tmp struct {
			Remind RemindInfo `json:"data"`
			Tts    string     `json:"tts"`
		}
		log.Println(log.DebugLog, "Remind:", retData.Detail)
		if err := json.Unmarshal([]byte(retData.Detail), &tmp); err == nil {
			DbusSendRemind(tmp.Remind)
		}
		if "" != tmp.Tts {
			remindCtrlMsg = &tmp.Tts
			remindCtrlUuid = &retData.RspId
			log.Println(log.DebugLog, "play remind info, later:", tmp.Tts)
		}
	case MSC_CMD_REMIND_CANCLE:
		var tmp struct {
			Ids []uint64 `json:"ids"`
			Tts string   `json:"tts"`
		}
		//todo after done, toast tts
		if err := json.Unmarshal([]byte(retData.Detail), &tmp); err == nil {
			log.Println(log.DebugLog, "Del ids:", tmp.Ids)
			if len(tmp.Ids) > 0 {
				if tmp.Ids[0] == 0 {
					//delete all
					log.Println(log.DebugLog, "Will delete all")
					if len(tmp.Tts) > 0 {
						deleteRemindsCtrlMsg = &tmp.Tts
						deleteRemindCtrlUuid = &retData.RspId
					}
					DbusDelAllReminds()
				} else {
					log.Println(log.DebugLog, "Will delete ", tmp.Ids)
					DbusDelRemindsArray(tmp.Ids)
				}
			} else {
				log.Println(log.DebugLog, "remind array len == 0 do nothings")
			}
		}

		if "" != tmp.Tts {
			remindCtrlMsg = &tmp.Tts
			remindCtrlUuid = &retData.RspId
		}
	case MSC_CMD_ALARM_ADD:
		var tmp struct {
			Alarm AlarmClockInfo `json:"data"`
			Tts   string         `json:"tts"`
		}
		log.Println(log.DebugLog, "alarm:", retData.Detail)
		if err := json.Unmarshal([]byte(retData.Detail), &tmp); err == nil {
			DbusSendAlarmClock(tmp.Alarm)
		}

		if "" != tmp.Tts {
			alarmCtrlMsg = &tmp.Tts
			alarmCtrlUuid = &retData.RspId
			log.Println(log.WarningLog, "wait alram ret to play tts")
		}
	case MSC_CMD_ALARM_CANCLE:
		var tmp struct {
			Ids []uint64 `json:"ids"`
			Tts string   `json:"tts"`
		}
		//todo after done toast the tts
		if err := json.Unmarshal([]byte(retData.Detail), &tmp); err == nil {
			log.Println(log.DebugLog, "Del ids:", tmp.Ids)
			if len(tmp.Ids) > 0 {
				if tmp.Ids[0] == 0 {
					//delete all
					log.Println(log.DebugLog, "Will delete all")
					if len(tmp.Tts) > 0 {
						deleteAlarmsCtrlMsg = &tmp.Tts
						deleteAlarmCtrlUuid = &retData.RspId
					}
					DbusDelAllAlarmClocks()
				} else {
					log.Println(log.DebugLog, "Will delete ", tmp.Ids)
					DbusDelAlarmClocksArray(tmp.Ids)
				}
			} else {
				log.Println(log.DebugLog, "alarm num == 0 do nothings")
			}
		}
		if "" != tmp.Tts {
			alarmCtrlMsg = &tmp.Tts
			alarmCtrlUuid = &retData.RspId
			log.Println(log.WarningLog, "wait alram ret to play tts")
		}
	case MSC_CMD_WHETHER:
		var tmp ServerDetailBase
		err := json.Unmarshal([]byte(retData.Detail), &tmp)
		if err != nil {
			log.Println(log.WarningLog, "Unkonw tts")
			return
		}
		fmt.Println(tmp.Tts)

		if len(tmp.Tts2) > 0 {
			MscToastFile(tmp.Tts2, retData.RspId, true, tmp.Keep, nil)
		} else if len(tmp.Tts) > 0 {
			MscToastTts(tmp.Tts, retData.RspId, true, tmp.Keep, nil)
		}
	case MSC_CMD_BT_ON:
		var tmp ServerDetailBase
		err := json.Unmarshal([]byte(retData.Detail), &tmp)
		if err != nil {
			log.Println(log.WarningLog, "Unkonw tts")
			return
		}
		fmt.Println(tmp.Tts)
		if len(tmp.Tts2) > 0 {
			MscToastFile(tmp.Tts2, retData.RspId, true, tmp.Keep, nil)
		} else if len(tmp.Tts) > 0 {
			MscToastTts(tmp.Tts, retData.RspId, true, tmp.Keep, nil)
		}

		player.OpenBtOfBt()
	case MSC_CMD_BT_OFF:
		var tmp ServerDetailBase
		err := json.Unmarshal([]byte(retData.Detail), &tmp)
		if err != nil {
			log.Println(log.WarningLog, "Unkonw tts")
			return
		}
		fmt.Println(tmp.Tts)
		if len(tmp.Tts2) > 0 {
			MscToastFile(tmp.Tts2, retData.RspId, true, tmp.Keep, nil)
		} else if len(tmp.Tts) > 0 {
			MscToastTts(tmp.Tts, retData.RspId, true, tmp.Keep, nil)
		}

		player.CloseBtOfBt()
	case MSC_CMD_MUSIC_DENY:
		if ignoreCmdInDAB() {
			MscToastTts(TTS_NOT_UNSUPPORT, retData.RspId, true, false, nil)
			return
		}
		var tmp struct {
			ServerDetailBase
			DenyInfos []DenyInfo `json:"data"`
		}
		if err := json.Unmarshal([]byte(retData.Detail), &tmp); nil != err {
			log.Println(log.WarningLog, err.Error())
			return
		}
		hasCur := WifiMusicFilterSet(&tmp.Tts, tmp.DenyInfos)

		log.Printf(log.DebugLog, "hasCur:%+v denyinfos:%+v\n", hasCur, tmp.DenyInfos)
		if !hasCur {
			if len(tmp.Tts2) > 0 {
				MscToastFile(tmp.Tts2, retData.RspId, true, tmp.Keep, nil)
			} else if len(tmp.Tts) > 0 {
				if !strings.Contains(tmp.Tts, "%s") {
					MscToastTts(tmp.Tts, retData.RspId, true, tmp.Keep, nil)
				} else {
					if song, err := GetCurWifiSongInfo(); nil == err {
						if songDetail, _, _, err := http.GetSongDetailInfoDo(&song.Id); nil == err {
							tts := fmt.Sprintf(tmp.Tts, songDetail.Song.Name)
							MscToastTts(tts, retData.RspId, true, tmp.Keep, nil)
						}
					}
				}
			}
		} else {
			base := ServerPlayerBase{RspId: retData.RspId, InnerTts: tmp.Tts, InnerTtsUrl: tmp.Tts2}
			SendSCmd(SCMD_MusicPlayer_PlayNext, PlayerArg{GloablePause: false, NotShowIcon: false, ServerPlayerBase: base})
		}
	case MSC_CMD_REPEAT:
		ttsRepeatInfo := GetTtsRepeatInfo()
		if ttsRepeatInfo.HasSetTtsInfo {
			if time.Now().Sub(ttsRepeatInfo.TimePlay) >= RepeatCmdDurtion.GetCfgListTime() {
				log.Printf(log.WarningLog, "tts repeat time is out, content:%+v, time:%+v\n", ttsRepeatInfo.Tts, ttsRepeatInfo.TimePlay)
				ClearTtsRepeatInfo()

				MscToastTts(TTS_REPEAT_NIL, retData.RspId, false, false, nil)

				http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd, PlayMode: CurPlayingMode,
					Data: TTS_REPEAT_NIL, Tts: TTS_REPEAT_NIL,
					DataType: http.DATA_TYPE_STRING})

			} else {
				if strings.HasPrefix(ttsRepeatInfo.Tts, "/mnt") == false && strings.HasPrefix(ttsRepeatInfo.Tts, "/usr") == false {
					http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd, PlayMode: CurPlayingMode,
						Data: ttsRepeatInfo.Tts, Tts: ttsRepeatInfo.Tts,
						DataType: http.DATA_TYPE_STRING})
				}

				ttsRepeatInfo.NoticePlayerParams.SpecialFunc = func(arg TtsPlayerArg) {
					//检查是否网络缓存播放失败
					if arg.StopReason == NoticeStopReason_Error {
						go MscToastFile(vui.SoundNotice_Song_Get_Timeout.GetPath(), CONST_AUDIO_ID, false, false, nil)
					}
				}

				player.NoticePlayerSendSCmd2(SCMD_SuperTask_Tts_Ctrl_Play, ttsRepeatInfo.NoticePlayerParams)
			}
		} else {
			log.Println(log.WarningLog, "repeatCmd is nil")
			MscToastTts(TTS_REPEAT_NIL, retData.RspId, false, false, nil)

			http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd, PlayMode: CurPlayingMode,
				Data: TTS_REPEAT_NIL, Tts: TTS_REPEAT_NIL,
				DataType: http.DATA_TYPE_STRING})
		}
	case MSC_CMD_REPEAT_MUSIC:
		curPlayer := GetCurPlayer()
		if nil == curPlayer {
			// todo : 当前播放器为空

		} else {
			if curPlayer.GetPlayerId() == uint32(GetScenePlayerId()) ||
				curPlayer.GetPlayerId() == uint32(PlayerType_Wifi) {

				deviceMode := getCurDeviceMode(true)
				if Exec_MusicPlay_mode != deviceMode {
					MscToastTts(TTS_REPEAT_NIL, retData.RspId, true, false, nil)

					http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd, PlayMode: CurPlayingMode,
						Data: TTS_REPEAT_NIL, Tts: TTS_REPEAT_NIL,
						DataType: http.DATA_TYPE_STRING})
					return
				}

				if curPlayer.IsPlaying() {
					status := curPlayer.GetPlayerStatus()
					status.CurPos = 0
					log.Println(log.DebugLog, "MSC_CMD_REPEAT_MUSIC set CurPos to 0")
					curPlayer.SetPlayerStatus(status)
					SendSCmd(SCMD_MusicPlayer_Seek, uint32(status.CurPos))
				} else {
					eventPoint.SetEpOsSouce("F141", eventPoint.EpOs_Server)
					if time.Now().Sub(curPlayer.GetLastPasusedTime()) >= RepeatCmdDurtion.GetCfgListTime() {
						SendSCmd(SCMD_MusicPlayer_Play, nil)
					} else {
						status := curPlayer.GetPlayerStatus()
						status.CurPos = 0
						log.Println(log.DebugLog, "MSC_CMD_REPEAT_MUSIC1 set CurPos to 0")
						curPlayer.SetPlayerStatus(status)
						SendSCmd(SCMD_MusicPlayer_Play, nil)
					}
				}

				var songInfo SongInfo
				songId := curPlayer.GetPlayerStatus().Uuid
				song, _, hasSong := LocalMusicList[CUR_MUSIC_LIST].Search(&songId, false)
				if hasSong {
					songInfo = *song
				} else {
					songInfo = SongInfo{Id: songId}
				}
				var oftag, showtag string = "", ""
				if uint32(PlayerType_Wifi) == curPlayer.GetPlayerId() {
					if nil != PlayListSrcRec.TagName {
						oftag = *PlayListSrcRec.TagName
					}
					if nil != PlayListSrcRec.TagNameShow {
						showtag = *PlayListSrcRec.TagNameShow
					}
				} else {
					if nil != ScenesPlayerListSrc.TagName {
						oftag = *ScenesPlayerListSrc.TagName
					}
					if nil != ScenesPlayerListSrc.TagNameShow {
						showtag = *ScenesPlayerListSrc.TagNameShow
					}
				}
				http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd,
					Data: songInfo, Tts: "", Oftag: oftag,
					ShowTag: showtag, PlayMode: CurPlayingMode,
					DataType: http.DATA_TYPE_SONG,
				})
			} else {
				MscToastTts(TTS_REPEAT_NIL, retData.RspId, true, false, nil)
				http.PushInfoToServerForApp(http.InfoForApp{ResponseId: retData.RspId, Cmd: retData.Cmd, PlayMode: CurPlayingMode,
					Data: TTS_REPEAT_NIL, Tts: TTS_REPEAT_NIL,
					DataType: http.DATA_TYPE_STRING})
			}
		}
	case MSC_CMD_MODE_CHANGE:
		var tmp struct {
			ServerDetailBase
			ModeInfoDto ModeInfo `json:"modeInfoDto"`
		}
		if err := json.Unmarshal([]byte(retData.Detail), &tmp); nil != err {
			log.Println(log.WarningLog, err.Error())
			return
		}

		log.Printf(log.DebugLog, "Detail:%+v   tmp:%+v\n", retData.Detail, tmp)
		SendSCmdStruct(SCmdStruct{SCmd: SCMD_MusicPlayer_Pause, Arg: []interface{}{PlayerArg{NotShowIcon: true}}, ExecCb: func(cb SCmdStructExecCb) {
			tmp := GetCurVboxBroadcastSt(false)
			tmp.PlayerStPtr.ContinuousTaskSt = MUSIC_ST_IDLE
			TrigBroadcastStatus(tmp)
			ResetWifiPlayer()
		}})

		if len(tmp.Tts2) > 0 {
			MscToastFile(tmp.Tts2, retData.RspId, true, tmp.Keep, nil)
		} else if len(tmp.Tts) > 0 {
			MscToastTts(tmp.Tts, retData.RspId, true, tmp.Keep, nil)
		}
	default:
		log.Printf(log.ErrorLog, "Unknow the cmd %d\n", retData.Cmd)
		MscToastTts(TTS_NOT_UNSUPPORT, retData.RspId, true, false, nil)
	}

	return
}

func AppSuccessCommand(msg *[]byte, msglen uint32) {
	if msglen <= 0 || nil == msg {
		log.Println(log.WarningLog, "app cmd nil")
		return
	}
	var app AppParamBase
	err := json.Unmarshal(*msg, &app)
	if nil != err {
		log.Println(log.WarningLog, err.Error())
		return
	}

	eventPoint.EpRecord("A224", map[string]interface{}{"msgid": app.CmdId, "rspid": app.MsgId, "sourceos": eventPoint.EpOs_App})

	//control cmd
	switch app.CmdId {
	case APP_CMD_UPGRADE:
		//OTA
		OTACheckNewVersion(false, true)
		return
	case APP_CMD_CLOSEALARM:
		Alarm_Close()
		return
	case APP_CMD_OTASTATUS:
		SendOtaStatusByYunxin(GetOTAStatus(), false, app.MsgId)
		return
	}

	//music cmd
	//if ignoreCmdInDAB() {
	//	MscToastTts(TTS_NOT_UNSUPPORT, false)
	//	return
	//}
	switch app.CmdId {
	case APP_CMD_DEVICE_EVENT:
		var tmp DeviceEventStruct
		if err = json.Unmarshal([]byte(app.Detail), &tmp); err == nil {
			switch tmp.EventType {
			case DeviceEventType_IotWifiParing:
				var ev DeviceEventAction
				if iot_running {
					ev = DeviceEventAction_Start
				} else {
					ev = DeviceEventAction_End
				}
				SendEventnByYunxinWithRid(DeviceEventType_IotWifiParing, ev, app.ReplyId, false, nil)
			default:
				log.Println(log.DebugLog, "Un support event status query!", tmp.EventType)
			}
		}
	case APP_CMD_MUSIC_PLAY:
		RestoreDefaultVolWhen0()
		if len(app.Detail) < 1 {
			log.Println(log.WarningLog, "param nil when play")
			return
		}
		var playParam AppPlayReq

		playParam.Action = MUSIC_ACTION_NEXT
		playParam.ActionSrc = MUSIC_ACTION_SRC_APP

		err := json.Unmarshal([]byte(app.Detail), &playParam)
		if nil != err {
			log.Println(log.WarningLog, err.Error())
			return
		}

		mode := getCurDeviceMode(true)
		if Exec_MusicPlay_mode == mode {
			SendSCmd(SCMD_MusicPlayer_Pause, PlayerArg{NotShowIcon: true})
		}

		switch playParam.Field {
		case SCENE_FIELD_ST:
			ScenesAppCtrlPlay(&playParam)
		case WIFIMUSIC_FIELD_ST:
			SetPlayerArgs(PlayerType_Wifi, &playParam)
			player.PlayerHander[PlayerType_Wifi].RequestPlay_Async(nil)
		default:
			SetPlayerArgs(PlayerType_Wifi, &playParam)
			player.PlayerHander[PlayerType_Wifi].RequestPlay_Async(nil)
		}

		EndVoiceGrandateDisappear(RESTORE_VOL)
	case APP_CMD_MUSIC_CONTINUE:
		RestoreDefaultVolWhen0()
		eventPoint.SetEpOsSouce("F141", eventPoint.EpOs_App)
		PlayListSrcRec.ListHasEnd = false //歌单播放结束标志位false
		SendSCmd(SCMD_MusicPlayer_Play)
	case APP_CMD_MUSIC_PAUSE:
		eventPoint.SetEpOsSouce("F141", eventPoint.EpOs_App)
		SendSCmd(SCMD_MusicPlayer_Pause)
	case APP_CMD_MUSIC_NEXT:
		RestoreDefaultVolWhen0()
		mode := getCurDeviceMode(true)
		if Exec_MusicPlay_mode == mode {
			SendSCmd(SCMD_MusicPlayer_Pause, PlayerArg{NotShowIcon: true})
		}

		base := ServerPlayerBase{Action: MUSIC_ACTION_NEXT, ActionSrc: MUSIC_ACTION_SRC_APP}
		SendSCmd(SCMD_MusicPlayer_PlayNext, PlayerArg{GloablePause: false, NotShowIcon: false,
			ServerPlayerBase: base})

		EndVoiceGrandateDisappear(RESTORE_VOL)
	case APP_CMD_MUSIC_PRE:
		RestoreDefaultVolWhen0()
		mode := getCurDeviceMode(true)
		if Exec_MusicPlay_mode == mode {
			SendSCmd(SCMD_MusicPlayer_Pause, PlayerArg{NotShowIcon: true})
		}

		PlayListSrcRec.ListHasEnd = false //歌单播放结束标志位false
		base := ServerPlayerBase{Action: MUSIC_ACTION_PREV, ActionSrc: MUSIC_ACTION_SRC_APP}
		SendSCmd(SCMD_MusicPlayer_PlayPre, PlayerArg{GloablePause: false, NotShowIcon: false,
			ServerPlayerBase: base})

		EndVoiceGrandateDisappear(RESTORE_VOL)
	case APP_CMD_VOLUME:
		if len(app.Detail) < 1 {
			log.Println(log.WarningLog, "param nil when seek")
			return
		}
		var tmp struct {
			VolPer uint8 `json:"volPer"`
		}

		err := json.Unmarshal([]byte(app.Detail), &tmp)
		if nil != err {
			log.Println(log.WarningLog, err.Error())
			return
		}
		vol := GetVolByPer(int(tmp.VolPer))
		log.Println(log.DebugLog, "vol:", vol, "  VolPer:", tmp.VolPer)

		if 0 == vol && isMute() {
			return
		}
		VolSet(int(vol))

		volBroadCast(VOL_APP_ACTION)

		ShowVolumeLed()
		eventPoint.SetEpOsSouce("H511", eventPoint.EpOs_App)

	case APP_CMD_SEEK:
		RestoreDefaultVolWhen0()
		if len(app.Detail) < 1 {
			log.Println(log.WarningLog, "param nil when seek")
			return
		}
		var tmp struct {
			SeekTIme uint32 `json:"seekTime"`
		}
		err := json.Unmarshal([]byte(app.Detail), &tmp)
		if nil != err {
			log.Println(log.WarningLog, err.Error())
			return
		}
		SendSCmd(SCMD_MusicPlayer_Seek, tmp.SeekTIme)

		EndVoiceGrandateDisappear(RESTORE_VOL)
	case APP_CMD_CYCLE_ONE_SONG:
		RestoreDefaultVolWhen0()
		// 切换到单曲播放时，如果当前是顺序循环，不需要处理
		if LIST_RANDOM_CYCLE == CurPlayingMode {
			ResetUnPlayListCurNode()
		}
		CurPlayingMode = SINGLE_CYCLE
		playModeBroadCast(CurPlayingMode)
		log.Println(log.DebugLog, "Change playmode:", CurPlayingMode)
	case APP_CMD_CYCLE_LIST:
		RestoreDefaultVolWhen0()

		// 切换到顺序播放时，如果当前是单曲循环，不需要处理
		if LIST_RANDOM_CYCLE == CurPlayingMode {
			ResetUnPlayListCurNode()
		}
		CurPlayingMode = LIST_ORDER_CYCLE
		playModeBroadCast(CurPlayingMode)
		log.Println(log.DebugLog, "Change playmode:", CurPlayingMode)
	case APP_CMD_LIST_NO_CYCLE:
		RestoreDefaultVolWhen0()

		// 切换到顺序播放时，如果当前是单曲循环，不需要处理
		if LIST_RANDOM_CYCLE == CurPlayingMode {
			ResetUnPlayListCurNode()
		}
		CurPlayingMode = LIST_ORDER_PLAY
		playModeBroadCast(CurPlayingMode)
		log.Println(log.DebugLog, "Change playmode:", CurPlayingMode)
	case APP_CMD_CYCLE_RANDOM:
		RestoreDefaultVolWhen0()

		if LIST_ORDER_CYCLE == CurPlayingMode || SINGLE_CYCLE == CurPlayingMode {
			ResetUnPlayListCurNode()
		}
		CurPlayingMode = LIST_RANDOM_CYCLE
		playModeBroadCast(CurPlayingMode)
		log.Println(log.DebugLog, "Change playmode:", CurPlayingMode)
	case APP_CMD_CFGLIST_SET:
		var tmp struct {
			Desc string `json:"desc"`
		}
		err := json.Unmarshal([]byte(app.Detail), &tmp)
		if nil != err {
			log.Println(log.ErrorLog, err.Error())
			return
		}
		var cfglist CfgListType
		err = json.Unmarshal([]byte(tmp.Desc), &cfglist)
		if nil != err {
			log.Println(log.ErrorLog, err.Error())
			return
		}
		log.Printf(log.WarningLog, "app cfglist:%+v\n", cfglist)
		SetAndSaveCfgList(cfglist)

		cfgListStrNew := GetCfgList(tmp.Desc)
		// direct send to app
		//http.PushCfgList(cfgListStrNew)
		tmp.Desc = cfgListStrNew
		log.Printf(log.DebugLog, "cfglist 2 server:%+v\n", tmp)
		SendCmdByYunxin(APP_CMD_CFGLIST_SET_RSP, tmp, false, app.MsgId)
	case APP_CMD_CFGLIST_GET:
		var tmp struct {
			Desc string `json:"desc"`
		}
		err := json.Unmarshal([]byte(app.Detail), &tmp)
		if nil != err {
			log.Println(log.ErrorLog, err.Error())
			return
		}

		cfgListStrNew := GetCfgList(tmp.Desc)
		// direct send to app
		//http.PushCfgList(cfgListStrNew)
		tmp.Desc = cfgListStrNew
		log.Printf(log.DebugLog, "cfglist 2 server:%+v\n", tmp)
		SendCmdByYunxin(APP_CMD_CFGLIST_GET_RSP, tmp, false, app.MsgId)
	case APP_CMD_VBOX_SYNC:
		RestoreDefaultVolWhen0()
		mode := getCurDeviceMode(true)
		if Exec_MusicPlay_mode == mode {
			SendSCmd(SCMD_MusicPlayer_Pause, PlayerArg{NotShowIcon: true})
		}

		var ret struct {
			Desc string `json:"desc"`
		}
		var retBool struct {
			Success bool `json:"success"`
		}

		var tmp VboxChangeInfo
		err := json.Unmarshal([]byte(app.Detail), &tmp)
		if nil != err {
			log.Println(log.ErrorLog, err.Error())
			retBool.Success = false
		} else {
			list := createVboxChangeMusicInfo(tmp)
			if nil == list {
				retBool.Success = false
			} else {
				retBool.Success = true

				SetPlayerArgs(PlayerType_Wifi, list)
				player.PlayerHander[PlayerType_Wifi].RequestPlay_Async(SCmd_Args{SCmd_Base_Args: SCmd_Base_Args{OemArg: nil},
					SCmdPlayer_Args: SCmdPlayer_Args{StartPos: tmp.Pos}})
			}
		}
		data, err := json.Marshal(retBool)
		if nil == err {
			ret.Desc = string(data)
			SendCmdByYunxin(APP_CMD_VBOX_SYNC_RESP, ret, false, app.MsgId)
		} else {
			log.Println(log.ErrorLog, err.Error())
		}
	case APP_CMD_LIST_PLAY:
		RestoreDefaultVolWhen0()

		mode := getCurDeviceMode(true)
		if Exec_MusicPlay_mode == mode {
			SendSCmd(SCMD_MusicPlayer_Pause, PlayerArg{NotShowIcon: true})
		}
		var tmp VboxChangeInfo
		err := json.Unmarshal([]byte(app.Detail), &tmp)
		if nil != err {
			log.Println(log.ErrorLog, err.Error())
		} else {
			list := createVboxChangeMusicInfo(tmp)
			if nil != list {
				SetPlayerArgs(PlayerType_Wifi, list)
				player.PlayerHander[PlayerType_Wifi].RequestPlay_Async(nil)
			}
		}

	case APP_CMD_ENV_CHANGE:
		type APP_Env struct {
			Env  cserveraddr.DEVENV `json:"env"`
			Desc string             `json:"string"`
		}
		var env APP_Env
		if err = json.Unmarshal([]byte(app.Detail), &env); err == nil {
			switch env.Env {
			case cserveraddr.DEVENV_DEVELOP:
				cserveraddr.SetDevEnv(cserveraddr.DEVENV_DEVELOP)
				goto _clearuuid

			case cserveraddr.DEVENV_TEST:
				cserveraddr.SetDevEnv(cserveraddr.DEVENV_TEST)
				goto _clearuuid

			case cserveraddr.DEVENV_PUBLISH:
				cserveraddr.SetDevEnv(cserveraddr.DEVENV_PUBLISH)
				goto _clearuuid

			case cserveraddr.DEVENV_PRERELEASE:
				cserveraddr.SetDevEnv(cserveraddr.DEVENV_PRERELEASE)
				goto _clearuuid

			case 999:
				env.Env = cserveraddr.GetDevEnv()
				SendCmdByYunxin(APP_CMD_ENV_CHANGE, env, false, app.ReplyId)
			default:
				env.Env = 998
				env.Desc = fmt.Sprintln("Unsuport cmd:", env.Env)
				SendCmdByYunxin(APP_CMD_ENV_CHANGE, env, false, app.ReplyId)
			}

			return

		_clearuuid:
			env.Desc = fmt.Sprintln("Success change to:", env.Env)
			SendCmdByYunxin(APP_CMD_ENV_CHANGE, env, false, app.ReplyId)
			storage.Config_set(MODULE_CONTROLLER, SQL_KEY_BINDUSER, "")
			storage.Config_set(MODULE_CONTROLLER, SQL_KEY_UUID, "")

			fmt.Println("New addr:", cserveraddr.GetServerAddr(), "New env:", cserveraddr.GetDevEnv())
			fmt.Println("Clear uuid and reboot 2s after!")

			go func() {
				time.Sleep(2 * time.Second)
				log.Printf(log.DebugLog, "begin to reboot....\n")
				CSystemSafeReboot()
			}()
		} else {
			env.Env = 998
			env.Desc = fmt.Sprintln("Json err:", err, " orig msg:", app.Detail)
			SendCmdByYunxin(APP_CMD_ENV_CHANGE, env, false, app.ReplyId)
		}

	default:
		log.Println(log.ErrorLog, "Unknow app msg:", string(*msg))
		MscToastTts(TTS_NOT_UNSUPPORT, CONST_AUDIO_ID, true, false, nil)
	}
}

func playModeBroadCast(playMode MusicPlayMode) {
	CurPlayerSt.PlayMode = playMode
	var playModeSt VboxBroadcastSt = VboxBroadcastSt{
		PlayerStPtr:   &CurPlayerSt,
		VboxVolStPtr:  &CurVboxVolSt,
		ScenesStPtr:   &CurScenesSt,
		CurrentStatus: CurCurrentStatus,
	}

	TrigBroadcastStatus(playModeSt)
}

func createVboxChangeMusicInfo(params VboxChangeInfo) interface{} {
	log.Printf(log.DebugLog, "app cmd params:%+v\n", params)
	switch params.Type {
	case USER_LISTS_COLLECT, USER_LISTS_CREATE, USER_LISTS, MUSIC_LIST_WORD, MUSIC_LIST_SERACH_WORD, ALBUM_ARTIST_ID:
		ret := createVboxChangeMusicLists(params)
		if nil == ret {
			return nil
		} else {
			return ret
		}
	default:
		ret := createVboxChangeMusicList(params)
		if nil == ret {
			return nil
		} else {
			return ret
		}
	}
}

func createVboxChangeMusicLists(params VboxChangeInfo) *ServerMusicLists {
	var tmp ServerMusicLists
	var songIdIndex MusicLenType = 0
	var hasPushSong bool = false
	// app推送的控制都不走重复播放歌单逻辑
	tmp.IgnoreListRepeat = true

	if len(params.SongId) > 0 {
		hasPushSong = true
	}

	serverListParams := http.MusicListServerType{
		Src:          params.Type,
		Params:       nil,
		Start:        0,
		Size:         LIST_SIZE,
		WantTts:      true,
		Mode:         CurPlayingMode,
		Oftag:        &params.Oftag,
		OftagForShow: nil,
		CloudId:      params.CloudId,
		ModeId:       params.ModeId,
		ExtraData:    params.ExtraData,
	}
	switch params.Type {
	case USER_LISTS_COLLECT,
		USER_LISTS_CREATE,
		USER_LISTS,
		ALBUM_ARTIST_ID:
		serverListParams.Id = &params.ListId
	case MUSIC_LIST_WORD,
		MUSIC_LIST_SERACH_WORD:
		serverListParams.Id = &params.Oftag
		params := MUSIC_ORDER_HOT
		serverListParams.Params = &params
	}
	// 歌单列表
	list, err := GetMusicListsNew(PlayerType_Wifi, true, serverListParams)
	if nil != err {
		log.Println(log.ErrorLog, err.Error())
		MscToastFile(vui.SoundNotice_PullFromServer_Timeout.GetPath(), CONST_AUDIO_ID, true, false, nil)
		return nil
	}

	if nil == list || nil == list.MusicLists || 0 == len(list.MusicLists) ||
		nil == list.MusicLists[0].SongList {
		log.Println(log.ErrorLog, "err list from server")
		MscToastFile(vui.SoundNotice_PullFromServer_Timeout.GetPath(), CONST_AUDIO_ID, true, false, nil)
		return nil
	}

	tmp.MusicLists = make([]MusicListInfo, len(list.MusicLists))
	for k, v := range list.MusicLists {
		tmp.MusicLists[k] = v
	}

	var hasTheSong bool = false
	if hasPushSong {
		for _, v := range list.MusicLists[0].SongList {
			if v.Id == params.SongId {
				hasTheSong = true
			}
		}
		if !hasTheSong {
			log.Println(log.WarningLog, "the list do not has the song.")
		}
	} else {
		tmp.MusicLists[0].Url = list.MusicLists[0].Url
		tmp.MusicLists[0].Index = list.MusicLists[0].Index
	}

	if hasTheSong || !hasPushSong {
		tmp.MusicLists[0].SongList = make([]SongInfo, len(tmp.MusicLists[0].SongList))
		for k, song := range list.MusicLists[0].SongList {
			tmp.MusicLists[0].SongList[k] = song
			tmp.MusicLists[0].SongList[k].SourceOs = int8(eventPoint.EpOs_App)
			if hasPushSong {
				if params.SongId == song.Id {
					songIdIndex = MusicLenType(k)
				}
			}
		}
	} else {
		tmp.MusicLists[0].SongList = make([]SongInfo, 1+len(tmp.MusicLists[0].SongList))
		tmp.MusicLists[0].SongList[0].Id = params.SongId
		tmp.MusicLists[0].SongList[0].ArtistId = params.ArtistId
		tmp.MusicLists[0].SongList[0].CanPlay = true
		tmp.MusicLists[0].SongList[0].SourceOs = int8(eventPoint.EpOs_App)

		for k, song := range list.MusicLists[0].SongList {
			tmp.MusicLists[0].SongList[k+1] = song
			tmp.MusicLists[0].SongList[k+1].SourceOs = int8(eventPoint.EpOs_App)
		}
	}

	tmp.MusicLists[0].Type = params.Type
	tmp.MusicLists[0].Id = params.ListId
	tmp.PlayMode = params.PlayMode
	tmp.Oftag = params.Oftag
	tmp.OftagForShow = list.OftagForShow
	tmp.MusicLists[0].HasMore = list.MusicLists[0].HasMore
	tmp.ModeId = params.ModeId
	tmp.CloudId = params.CloudId
	tmp.InnerTts = list.PullTts
	tmp.InnerTtsUrl = list.PullTtsUrl

	if hasPushSong {
		tmp.MusicLists[0].Index = songIdIndex
		songDetail, err := player.GetSongDetail(PlayerType_Wifi, &params.SongId, true)
		if nil != err {
			log.Println(log.ErrorLog, err.Error())
			MscToastFile(vui.SoundNotice_PullFromServer_Timeout.GetPath(), CONST_AUDIO_ID, true, false, nil)
			return nil
		}
		tmp.MusicLists[0].Url = songDetail.Song.Url
	}

	NormalListMap[NORMAL_LIST_PAGE].Init()
	if hasPushSong {
		var startSize MusicLenType
		if params.Page > 1 {
			startSize = MusicLenType(params.Page-1) * params.PageSize
		} else {
			startSize = 0
		}
		NormalListMap[NORMAL_LIST_PAGE].BackIndex = startSize + songIdIndex
	}

	// 清除歌曲过滤列表
	LocalMusicFilter.Init()

	tmp.Action = MUSIC_ACTION_NEXT
	tmp.ActionSrc = MUSIC_ACTION_SRC_APP
	tmp.ExtraData = params.ExtraData

	return &tmp
}

func createVboxChangeMusicList(params VboxChangeInfo) *ServerMusicList {
	if USER_LISTS == params.Type {
		SetPlayUserListsFlag(true)
		params.Type = USER_LISTS_CREATE
		log.Println(log.DebugLog, "type change from USER_LISTS to USER_LISTS_CREATE.")
	} else {
		SetPlayUserListsFlag(false)
	}

	var tmp ServerMusicList
	var songIdIndex MusicLenType = 0
	var hasMoreMusic bool = false
	// app推送的控制都不走重复播放歌单逻辑
	tmp.IgnoreListRepeat = true

	var hasPushSong bool = false
	if len(params.SongId) > 0 {
		hasPushSong = true
	}

	var startSize MusicLenType
	if params.Page > 1 {
		startSize = MusicLenType(params.Page-1) * params.PageSize
	} else {
		startSize = 0
	}

	OldBizType := PlayListSrcRec.BizType
	PlayListSrcRec.BizType = params.BizType

	pullListId := params.ListId
	switch params.Type {
	case NEW_TOPLIST,
		HOT_TOPLIST,
		DENON_TOPLIST,
		CLASSIC_TOPLIST,
		BEATPORT_TOPLIST,
		ORIGINAL_TOPLIST,
		SORIGN_TOPLIST,
		ACG_TOPLIST,
		US_BILLBOARD_TOPLIST,
		JP_ORICON_TOPLIST,
		CH_NEW_TOPLIST,
		CH_HOT_TOPLIST,
		JP_NEW_LIST,
		KOREA_NEW_LIST,
		EU_US_NEW_LIST:
		pullListId = strconv.Itoa(int(params.Type))
	case SIMILAR_SONG, RADIO_STATION_LIST:
		pullListId = params.SongId
	default:

	}

	if SINGLE_SONG != params.Type {
		// get page songs
		serverListParams := http.MusicListServerType{
			Src:     params.Type,
			Id:      &pullListId,
			Params:  nil,
			Start:   startSize,
			Size:    params.PageSize,
			WantTts: true,

			Mode:         CurPlayingMode,
			Oftag:        &params.Oftag,
			OftagForShow: nil,
			CloudId:      params.CloudId,
			ModeId:       params.ModeId,

			ExtraData: params.ExtraData,
			BizType:   params.BizType,
			Order:     params.Order,
			AlbumID:   params.ListId,
		}
		list, err := GetMusicListNew(PlayerType_Wifi, true, serverListParams)

		if nil != err {
			log.Println(log.ErrorLog, err.Error())
			MscToastFile(vui.SoundNotice_PullFromServer_Timeout.GetPath(), CONST_AUDIO_ID, true, false, nil)
			return nil
		}
		if nil == list || nil == list.MusicList.SongList {
			log.Println(log.ErrorLog, "err list from server")
			MscToastFile(vui.SoundNotice_PullFromServer_Timeout.GetPath(), CONST_AUDIO_ID, true, false, nil)
			return nil
		}
		tmp.ExtraData = list.ExtraData
		tmp.MusicList.CopyrightTts = list.MusicList.CopyrightTts
		tmp.MusicList.UpdateTime = list.MusicList.UpdateTime

		tmp.MusicList.BizType = list.MusicList.BizType
		tmp.MusicList.Offset = list.MusicList.Offset
		tmp.MusicList.PageSize = list.MusicList.PageSize
		tmp.MusicList.Order = list.MusicList.Order
		tmp.MusicList.ArtistName = list.MusicList.ArtistName
		tmp.MusicList.Url = list.MusicList.Url
		tmp.MusicList.Index = list.MusicList.Index

		hasMoreMusic = list.MusicList.HasMore
		if serverListParams.Src == SIMILAR_SONG {
			hasPushSong = false
		}

		var hasTheSong bool = false
		if hasPushSong {
			for _, v := range list.MusicList.SongList {
				if v.Id == params.SongId {
					// 有推送歌曲,且当前列表有这首歌
					hasTheSong = true
				}
			}
			if !hasTheSong {
				log.Println(log.WarningLog, "the list do not has the song.")
			}
		} else {
			tmp.MusicList.Url = list.MusicList.Url
			tmp.MusicList.Index = list.MusicList.Index
		}

		if hasTheSong || !hasPushSong {
			tmp.MusicList.SongList = make([]SongInfo, len(list.MusicList.SongList))
			for k, song := range list.MusicList.SongList {
				tmp.MusicList.SongList[k] = song
				tmp.MusicList.SongList[k].SourceOs = int8(eventPoint.EpOs_App)
				if hasPushSong {
					if params.SongId == song.Id {
						songIdIndex = MusicLenType(k)
					}
				}
			}
		} else {
			tmp.MusicList.SongList = make([]SongInfo, 1+len(list.MusicList.SongList))
			tmp.MusicList.SongList[0].Id = params.SongId
			tmp.MusicList.SongList[0].ArtistId = params.ArtistId
			tmp.MusicList.SongList[0].CanPlay = true
			tmp.MusicList.SongList[0].SourceOs = int8(eventPoint.EpOs_App)

			for k, song := range list.MusicList.SongList {
				tmp.MusicList.SongList[k+1] = song
				tmp.MusicList.SongList[k+1].SourceOs = int8(eventPoint.EpOs_App)
			}
		}

		tmp.InnerTts = list.PullTts
		tmp.InnerTtsUrl = list.PullTtsUrl
		tmp.OftagForShow = list.OftagForShow
	} else {
		tmp.MusicList.SongList = make([]SongInfo, 1)
		tmp.MusicList.SongList[0].Id = params.SongId
		tmp.MusicList.SongList[0].ArtistId = params.ArtistId
		tmp.MusicList.SongList[0].CanPlay = true
		tmp.MusicList.SongList[0].SourceOs = int8(eventPoint.EpOs_App)
	}

	tmp.MusicList.Type = params.Type
	tmp.MusicList.Id = params.ListId
	tmp.PlayMode = params.PlayMode
	tmp.Oftag = params.Oftag
	tmp.MusicList.HasMore = hasMoreMusic
	tmp.ModeId = params.ModeId
	tmp.CloudId = params.CloudId

	if (hasPushSong && params.BizType == BIZ_TYPE_MUSIC) || SINGLE_SONG == params.Type {
		tmp.MusicList.Index = songIdIndex
		songDetail, err := player.GetSongDetail(PlayerType_Wifi, &params.SongId, true)
		if nil != err {
			log.Println(log.ErrorLog, err.Error())
			MscToastFile(vui.SoundNotice_PullFromServer_Timeout.GetPath(), CONST_AUDIO_ID, true, false, nil)
			return nil
		}
		tmp.MusicList.Url = songDetail.Song.Url
	}

	if SINGLE_SONG != params.Type {
		LocalMusicFilter.Init()

		NormalListMap[NORMAL_LIST_PAGE].Init()
		if hasPushSong {
			NormalListMap[NORMAL_LIST_PAGE].BackIndex = startSize + songIdIndex
		} else {
			NormalListMap[NORMAL_LIST_PAGE].BackIndex = 0
		}
	} else {
		NormalListMap[NORMAL_LIST_PAGE].BackIndex = 0
	}

	PlayListSrcRec.BizType = OldBizType
	tmp.Action = MUSIC_ACTION_NEXT
	tmp.ActionSrc = MUSIC_ACTION_SRC_APP

	return &tmp
}

func createServerMusicList(songDetail *SongInfoDetail, playMode MusicPlayMode, rspId string, tts string, ttsUrl string) *ServerMusicList {
	if nil == songDetail {
		return nil
	}
	var tmp ServerMusicList

	tmp.MusicList.Type = SINGLE_SONG
	tmp.MusicList.Id = ""
	tmp.MusicList.Index = 0
	tmp.MusicList.Url = songDetail.Url
	tmp.MusicList.SongList = make([]SongInfo, 1)

	tmp.MusicList.SongList[0] = songDetail.SongInfo

	tmp.PlayMode = playMode
	tmp.MusicList.Gain = songDetail.Gain

	tmp.RspId = rspId
	tmp.InnerTts = tts
	tmp.InnerTtsUrl = ttsUrl

	return &tmp
}

func ignoreCmdInDAB() bool {
	return PlayerType_Wifi != GetCurPlayerId()
}

func getCurDeviceMode(print bool) (ret DeviceMode) {
	curPlayer := GetCurPlayer()
	if print {
		fmt.Printf("curplayer:%+v\n", *curPlayer)
	}
	if curPlayer.IsPlaying() {
		ret = Exec_MusicPlay_mode
	} else {
		if !curPlayer.IsInterrupt() {
			if GetCurScheduleDomain().IsMusicDomain() == false {
				ret = Exec_Non_Music_Idle_mode
			} else if MUSIC_ST_PAUSED == curPlayer.GetPlayerStatus().Status {
				ret = Pause_mode
			} else {
				ret = Idle_mode
			}
		} else {
			// 播放器被打断过
			if curPlayer.PlayAfterResume {
				if GetCurScheduleDomain().IsMusicDomain() == true {
					ret = Exec_MusicPlay_mode
				} else {
					ret = Exec_Non_Music_Played_mode
				}
			} else {
				if GetCurScheduleDomain().IsMusicDomain() == false {
					ret = Exec_Non_Music_Idle_mode
				} else if MUSIC_ST_PAUSED == curPlayer.GetPlayerStatus().Status {
					ret = Pause_mode
				} else {
					ret = Idle_mode
				}
			}
		}
	}
	if print {
		fmt.Printf("deviceMode:%+v, curplayer:%+v, domain:%+v\n", ret, curPlayer, GetCurScheduleDomain())
	}

	return ret
}

func isMute() (ret bool) {
	defer func() {
		if ret {
			log.Println(log.WarningLog, "mute......")
		}
	}()

	vol, err := adau1761.GetVol()

	if nil != err {
		return false
	}

	if MinVolume == vol {
		//led_mcu.DirectLedControl(atservice.GUIDE_EFFECT_ID_VOLUME_ADJUST, atservice.GUIDE_ACTION_START, 1, []byte{uint8(MaxVolume), 0})
		//
		//tmp := vui.IconLed_ShowVolume
		//tmp.Arg = 0
		//tmp.OnHold = 0
		//tmp.Show()
		ShowVolumeLed()
		return true
	} else {
		return false
	}
}

func VboxChangeTestTopList() {
	log.Println(log.ErrorLog, "VboxChangeTest VboxChangeTestTopList")

	var tmp struct {
		Cmd    int    `json:"cmd"`
		Detail string `json:"detail"`
	}
	typeSrc := NEW_TOPLIST
	//topListId := strconv.Itoa(int(typeSrc))

	var vboxChangeInfo VboxChangeInfo = VboxChangeInfo{
		SongId: "A3626959E89CDF66E60E126A6CA1F78A",
		Page:   2,
		//ListId:   topListId,
		PageSize: PAGE_SIZE,
		Type:     typeSrc,
		Pos:      50000,
		HasMore:  true,
	}
	data, err := json.Marshal(vboxChangeInfo)
	if nil != err {
		log.Println(log.ErrorLog, err.Error())
		return
	}
	tmp.Detail = string(data)
	tmp.Cmd = 5010

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

func VboxChangeTestFM() {
	log.Println(log.ErrorLog, "VboxChangeTest VboxChangeTestFM")

	var tmp struct {
		Cmd    int    `json:"cmd"`
		Detail string `json:"detail"`
	}
	typeSrc := PRIVATE_FM
	topListId := strconv.Itoa(int(typeSrc))

	var vboxChangeInfo VboxChangeInfo = VboxChangeInfo{
		SongId:   "834F47F9DEC7C748855A8B4866DE1A34",
		Page:     10,
		ListId:   topListId,
		PageSize: FM_SIZE,
		Type:     typeSrc,
		HasMore:  true,
	}
	data, err := json.Marshal(vboxChangeInfo)
	if nil != err {
		log.Println(log.ErrorLog, err.Error())
		return
	}
	tmp.Detail = string(data)
	tmp.Cmd = 5010

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

func VboxChangeTestNaturalSound() {
	log.Println(log.ErrorLog, "VboxChangeTest VboxChangeTestNaturalSound")

	var tmp struct {
		Cmd    int    `json:"cmd"`
		Detail string `json:"detail"`
	}
	typeSrc := NATURAL_SOUND_LIST

	var bizSrc struct {
		BizSource int `json:"bizSource"`
	}
	bizSrc.BizSource = 2
	data1, err1 := json.Marshal(bizSrc)
	if nil != err1 {
		log.Println(log.ErrorLog, err1.Error())
		return
	}

	var vboxChangeInfo VboxChangeInfo = VboxChangeInfo{
		SongId:    "",
		Page:      1,
		ListId:    "17",
		PageSize:  PAGE_SIZE,
		Type:      typeSrc,
		HasMore:   true,
		BizType:   BIZ_TYPE_NATURAL_SOUND,
		ExtraData: string(data1),
	}
	data, err := json.Marshal(vboxChangeInfo)
	if nil != err {
		log.Println(log.ErrorLog, err.Error())
		return
	}
	tmp.Detail = string(data)
	tmp.Cmd = 5012

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

func VboxTestdeny() {
	log.Println(log.ErrorLog, "VboxChangeTest VboxTestdeny")

	var tmp struct {
		Cmd    int    `json:"cmd"`
		Detail string `json:"detail"`
		Code int `json:"code"`
	}

	var denyInfo DenyInfo = DenyInfo {
		Data : []string{"8FFEC9AC75F29C61D3A2BBF51C36BD1C", "5ECC9314FBE04C64BC2C5C62173CFCF8"},//测试排除多个歌曲Id
		Type : 1,
	}

	var denyData struct {
		Data []DenyInfo `json:"data"`
		Cmd int `json:"cmd"`
		Tts string `json:"tts"`
	}

	denyData.Cmd = int(MSC_CMD_MUSIC_DENY)
	denyData.Data = append(denyData.Data, denyInfo)
	denyData.Tts = string("好的，为你播放下一首%s")
	data, err := json.Marshal(denyData)
	if nil != err {
		log.Println(log.ErrorLog, err.Error())
		return
	}
	tmp.Detail = string(data)
	tmp.Cmd = int(MSC_CMD_MUSIC_DENY)
	tmp.Code = 1000

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

func VboxChangeTestRadioStation() {
	log.Println(log.ErrorLog, "VboxChangeTest VboxChangeTestRadioStation")

	var tmp struct {
		Cmd    int    `json:"cmd"`
		Detail string `json:"detail"`
	}
	typeSrc := RADIO_STATION_LIST

	var bizSrc struct {
		BizSource int `json:"bizSource"`
	}
	bizSrc.BizSource = 1
	data1, err1 := json.Marshal(bizSrc)
	if nil != err1 {
		log.Println(log.ErrorLog, err1.Error())
		return
	}

	var vboxChangeInfo VboxChangeInfo = VboxChangeInfo{
		SongId:    "905514002",
		Page:      1,
		ListId:    "31",
		PageSize:  PAGE_SIZE,
		Type:      typeSrc,
		HasMore:   false,
		BizType:   BIZ_TYPE_RADIO_STATION,
		ExtraData: string(data1),
		Order:     1,
	}
	data, err := json.Marshal(vboxChangeInfo)
	if nil != err {
		log.Println(log.ErrorLog, err.Error())
		return
	}
	tmp.Detail = string(data)
	tmp.Cmd = 5012

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

func VboxChangeTestNormal() {
	log.Println(log.ErrorLog, "VboxChangeTest VboxChangeTestNormal")

	var tmp struct {
		Cmd    int    `json:"cmd"`
		Detail string `json:"detail"`
	}
	typeSrc := ARTIST_ID

	var vboxChangeInfo VboxChangeInfo = VboxChangeInfo{
		SongId:   "562DAA42994D72CBA7D769C8A60EA34E",
		Page:     1,
		ListId:   "3691",
		PageSize: PAGE_SIZE,
		Type:     typeSrc,
		HasMore:  true,
	}
	data, err := json.Marshal(vboxChangeInfo)
	if nil != err {
		log.Println(log.ErrorLog, err.Error())
		return
	}
	tmp.Detail = string(data)
	tmp.Cmd = 5010

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

func VboxChangeTestSingle() {
	log.Println(log.ErrorLog, "VboxChangeTest VboxChangeTestSingle")

	var tmp struct {
		Cmd    int    `json:"cmd"`
		Detail string `json:"detail"`
	}
	typeSrc := SINGLE_SONG

	var vboxChangeInfo VboxChangeInfo = VboxChangeInfo{
		SongId:   "562DAA42994D72CBA7D769C8A60EA34E",
		Page:     1,
		ListId:   "3691",
		PageSize: PAGE_SIZE,
		Type:     typeSrc,
		HasMore:  true,
	}
	data, err := json.Marshal(vboxChangeInfo)
	if nil != err {
		log.Println(log.ErrorLog, err.Error())
		return
	}
	tmp.Detail = string(data)
	tmp.Cmd = 5010

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

func VboxChangeTestTag() {
	log.Println(log.ErrorLog, "VboxChangeTest VboxChangeTestTag")

	var tmp struct {
		Cmd    int    `json:"cmd"`
		Detail string `json:"detail"`
	}
	typeSrc := MUSIC_LIST_WORD

	var vboxChangeInfo VboxChangeInfo = VboxChangeInfo{
		SongId:   "562DAA42994D72CBA7D769C8A60EA34E",
		Page:     1,
		ListId:   "3691",
		Oftag:    "快乐",
		PageSize: PAGE_SIZE,
		Type:     typeSrc,
		HasMore:  true,
	}
	data, err := json.Marshal(vboxChangeInfo)
	if nil != err {
		log.Println(log.ErrorLog, err.Error())
		return
	}
	tmp.Detail = string(data)
	tmp.Cmd = 5010

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

func VboxCardTestTag() {
	log.Println(log.ErrorLog, "VboxChangeTest VboxCardTestTag")

	var tmp struct {
		Cmd    int    `json:"cmd"`
		Detail string `json:"detail"`
	}
	typeSrc := MUSIC_LIST_WORD

	var vboxChangeInfo VboxChangeInfo = VboxChangeInfo{
		SongId:   "",
		Page:     1,
		ListId:   "3691",
		Oftag:    "快乐",
		PageSize: PAGE_SIZE,
		Type:     typeSrc,
		HasMore:  true,
	}
	data, err := json.Marshal(vboxChangeInfo)
	if nil != err {
		log.Println(log.ErrorLog, err.Error())
		return
	}
	tmp.Detail = string(data)
	tmp.Cmd = 5012

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

func VboxTagTestTopList() {
	log.Println(log.ErrorLog, "VboxChangeTest VboxTagTestTopList")

	var tmp struct {
		Cmd    int    `json:"cmd"`
		Detail string `json:"detail"`
	}
	typeSrc := NEW_TOPLIST

	var vboxChangeInfo VboxChangeInfo = VboxChangeInfo{
		SongId:   "",
		ListId:   "topListTestId",
		Page:     2,
		PageSize: PAGE_SIZE,
		Type:     typeSrc,
		HasMore:  true,
	}
	data, err := json.Marshal(vboxChangeInfo)
	if nil != err {
		log.Println(log.ErrorLog, err.Error())
		return
	}
	tmp.Detail = string(data)
	tmp.Cmd = 5012

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

func VboxTagTestMusicShare() {
	log.Println(log.ErrorLog, "VboxChangeTest VboxTagTestMusicShare")

	var tmp struct {
		Cmd    int    `json:"cmd"`
		Detail string `json:"detail"`
	}
	typeSrc := MUSIC_SHARE_RCMD

	var vboxChangeInfo VboxChangeInfo = VboxChangeInfo{
		SongId:   "",
		ListId:   "topListTestId",
		Page:     2,
		PageSize: PAGE_SIZE,
		Type:     typeSrc,
		HasMore:  true,
	}
	data, err := json.Marshal(vboxChangeInfo)
	if nil != err {
		log.Println(log.ErrorLog, err.Error())
		return
	}
	tmp.Detail = string(data)
	tmp.Cmd = 5012

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

func VboxTagTestSongSimilar() {
	log.Println(log.ErrorLog, "VboxChangeTest VboxTagTestSongSimilar")

	var tmp struct {
		Cmd    int    `json:"cmd"`
		Detail string `json:"detail"`
	}
	typeSrc := SIMILAR_SONG

	var vboxChangeInfo VboxChangeInfo = VboxChangeInfo{
		SongId:   "834F47F9DEC7C748855A8B4866DE1A34",
		ListId:   "834F47F9DEC7C748855A8B4866DE1A34",
		Page:     0,
		PageSize: SONG_SIMILAR_SIZE,
		Type:     typeSrc,
		HasMore:  true,
	}
	data, err := json.Marshal(vboxChangeInfo)
	if nil != err {
		log.Println(log.ErrorLog, err.Error())
		return
	}
	tmp.Detail = string(data)
	tmp.Cmd = 5012

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