Newer
Older
safe_production_front / public / DispatchLib / DispatchCtrlLib.js
wangxitong on 16 Aug 52 KB first commit
//————————————————————————————————————— 配置 ——————————————————————————————————————————

var DispatchLibPath = ""; //可指定绝对路径

//——————————————————————————————— DispatchRtcLib ——————————————————————————————————————
function DispatchCtrlLib() { }

function DispatchLib_add_scripts(script_file) {
    var tag_hdr = document.getElementsByTagName("head")[0];
    var tag_script = document.createElement('script');
    tag_script.setAttribute('type', 'text/javascript');
    tag_script.setAttribute('src', DispatchLibPath + script_file);
    tag_hdr.appendChild(tag_script);
};


function DispatchLib_get_path() {
    if (DispatchLibPath == "") {
        var scripts = document.getElementsByTagName("script");
        var file = scripts[scripts.length - 1].getAttribute("src");
        DispatchLibPath = file.substr(0, file.lastIndexOf("/"));
    
        if (DispatchLibPath.length) {
            DispatchLibPath += "/";
        }

        DispatchLibPath = location.origin + location.pathname.substr(0, location.pathname.lastIndexOf("/")) + "/" + DispatchLibPath;
    } 
};


DispatchLib_get_path();
DispatchLib_add_scripts("DispatchRtcLib.js");
DispatchLib_add_scripts("DispatchVideoLib.js");


DispatchCtrlLib.callback = null;

DispatchCtrlLib.websocket = null;
DispatchCtrlLib.extnumber = "";
DispatchCtrlLib.LoginInfo = null;
DispatchCtrlLib.msip = "";
DispatchCtrlLib.fsip = "";

//需由应用层定义回调 function(Number, Type, CallID)
DispatchCtrlLib.cb_forward = null;
DispatchCtrlLib.cb_ptz = null;

DispatchCtrlLib.WsWorker = null;

//SharedWorker相关
DispatchCtrlLib.SharedWorker = null;
DispatchCtrlLib.SharedWorkerName = null;
//暴露接口
DispatchCtrlLib.SendSharedWorkerMsg = function (to, msg) {
    if (DispatchCtrlLib.SharedWorker) {
        var sharedmsg = {
            cmd: 'WorkerMsg',
            from: DispatchCtrlLib.SharedWorkerName,
            to: to,
            data: msg,
        };
        DispatchCtrlLib.SharedWorker.port.postMessage(sharedmsg)
        console.log("SharedWorkerMessage: " + JSON.stringify(sharedmsg));
    }
}

DispatchCtrlLib.onSharedWorkerMsg = function (from, data) {
    /*
    let menuList = window.mainFrame.menuList;
    if (from == "audio") {
        ScsMapConstant.voiceseparate = 0;
        from = "voice";
    }
    if (from == "video") {
        ScsMapConstant.videoseparate = 0;
    }
    if (from == "map") {
        ScsMapConstant.mapseparate = 0;
    }
    if (from == "conference") {
        ScsMapConstant.conferenceseparate = 0;
    }
    for (let i = 0; i < menuList.length; i++) {
        let list = window.mainFrame.currentSecondMenuList[menuList[i].id];
        if (list) {
            for (let j = 0; j < list.length; j++) {
                if (list[j].menuPath.split("/").length == 2 && list[j].menuPath.split("/")[1] == from) {
                    if (list.length <= 1) {
                        window.mainFrame.isCollapse = 0;
                    } else {
                        window.mainFrame.isCollapse = 1;
                    }
                    menuList[i].isNewWin = false;
                    let [sub1] = window.mainFrame.menuListFirst.filter((item) => {
                        return item.id == list[j].parentId;
                    });
                    let [sub2] = window.mainFrame.menuListSecond.filter((item) => {
                        return item.id == list[j].parentId;
                    });
                    if (sub1 && sub1.submenuList.length > 0) {
                        sub1.submenuList.map((item) => {
                            if (item.id == list[j].id) {
                                item.isNewWinChild = false;
                            }
                        });
                    }
                    if (sub2 && sub2.submenuList.length > 0) {
                        sub2.submenuList.map((item) => {
                            if (item.id == list[j].id) {
                                item.isNewWinChild = false;
                            }
                        });
                    }
                    list[j].isNewWinChild = false;
                    window.mainFrame.currentSecondMenu = list;
                    gotoFirstChildMenuNew(list[j].parentId);
                    gotoSecondChildMenuNew(list[j].menuPath, list[j].id, list[j]);
                    return false;
                }
            }
        }
    }
    // 主屏关闭 关闭分屏
    if (from == "main") {
        window.opener = null;
        window.open(" ", "_self");
        window.close();
    }
    */
}

//内部默认回调
DispatchCtrlLib.FuncCallback = function (msg) {

    var parm = msg;
    if (typeof msg == "string") {
        parm = JSON.parse(msg);
        console.log("DispatchCtrlLib.FuncCallback: " + msg);
    } else {
        console.log("DispatchCtrlLib.FuncCallback: " + JSON.stringify(msg));
    }

    if ((parm.Msg == "LoginRsp" || parm.Msg == "InitializeRsp")  && parm.LoginInfo) {
        if (typeof parm.LoginInfo.ExtNumber == "string") {
            DispatchCtrlLib.extnumber = parm.LoginInfo.ExtNumber.toString();
            console.log("DispatchCtrlLib.extnumber: " + DispatchCtrlLib.extnumber);
        }

        if (typeof parm.LoginInfo.MsIP == "string") {
            DispatchCtrlLib.msip = parm.LoginInfo.MsIP;
            console.log("DispatchCtrlLib.msip: " + DispatchCtrlLib.msip);
        }

        if (typeof parm.LoginInfo.FsIP == "string") {
            DispatchCtrlLib.fsip = parm.LoginInfo.FsIP;
            console.log("DispatchCtrlLib.fsip: " + DispatchCtrlLib.fsip);
        }

        DispatchCtrlLib.LoginInfo = parm.LoginInfo;
    }


    if (DispatchCtrlLib.callback) {
        DispatchCtrlLib.callback(parm.Msg, parm);
    }
}

DispatchCtrlLib.SendWorkerMsg = function (msg) {
    
    if (DispatchCtrlLib.WsWorker) {
        //主页会优先这个分支
        console.log("WorkerMessage: " + JSON.stringify(msg));
        DispatchCtrlLib.WsWorker.postMessage(msg);
    } else if (DispatchCtrlLib.SharedWorker) {
        var sharedmsg = {
            cmd: 'WorkerWsMsg',
            from: DispatchCtrlLib.SharedWorkerName,
            to: 'main',
            data: msg,
        };
        DispatchCtrlLib.SharedWorker.port.postMessage(sharedmsg)
        console.log("SharedWorkerMessage: " + JSON.stringify(sharedmsg));
    } else {
        console.log("WorkerMessage Fail: " + JSON.stringify(msg));
    }  
}

var VoipCallID = 100;

/************************** 初始化&登录 ******************************/
//初始化资源 返回非0时表示初始化媒体失败
DispatchCtrlLib.Initialize = function (callback, no_media, page_name) {

    if (typeof callback == "function") {
        DispatchCtrlLib.callback = callback;
    }


    if (typeof (no_media) == "number" && no_media == 1) {
        try {
            DispatchCtrlLib.NewWorker();
        } catch (e) {
            console.log(e)
        }
    } else {
        //等待DispatchRtcLib加载
        var interval = window.setInterval(function () {
            if (typeof DispatchRtcLib != "undefined") {
                DispatchRtcLib.Init();

                try {
          if (typeof (page_name) != "string") {
            page_name = 'main';
          }
          DispatchCtrlLib.SharedWorkerName = page_name;
          
          DispatchCtrlLib.NewSharedWorker();

          if (DispatchCtrlLib.SharedWorkerName == 'main') {
            //main主页面才会创建Worker
            DispatchCtrlLib.NewWorker();
          } else {
            VoipCallID = 2000 + Math.floor((Math.random() * 10000) + 1);
          }
          
        } catch (e) {
                    console.log(e)
                }

                clearInterval(interval);
            }
        }, 500);

        return 0;
    }

    return 0;
}

DispatchCtrlLib.onWorkerMessage = function (evt) {
    if (evt.data) {
        
        if (evt.data.WsMsg) {
            switch (evt.data.WsMsg) {
                case "opened":
                    console.log("WsWorker opened");
                    DispatchCtrlLib.FuncCallback({
                        Msg: "InitializeRsp",
                        Result: 0
                    });
                    break;
                case "closed":
                    console.log("WsWorker closed");
                    DispatchCtrlLib.WsWorker = null;
                    break;
                case "AudioCaptureStart":
                    msg = {
                        Msg: "AudioCaptureStart",
                    };
        
                    DispatchPocLib.AudioWorkletNode.port.postMessage(msg)
                    break;
                case "AudioCaptureStop":
                    msg = {
                        Msg: "AudioCaptureStop",
                    };
        
                    DispatchPocLib.AudioWorkletNode.port.postMessage(msg)
                    break;
                case "AudioPlayBuffer":
                    msg = {
                        Msg: "AudioPlayBuffer",
                        BufferLeft: evt.data.BufferLeft,
                        BufferRight: evt.data.BufferRight,
                    };
        
                    DispatchPocLib.AudioWorkletNode.port.postMessage(msg)
                    break;
                    
            default:
                    break;
            }
            return;
        }
        
        if (evt.data.Msg) {
            console.log("DispatchCtrlLib.WebsocketOnMessage:", evt.data);

            if (DispatchCtrlLib.SharedWorker && DispatchCtrlLib.SharedWorkerName == 'main') {
                //主页面将回调分发至其他页面
                var sharedmsg = {
                    cmd: 'WorkerWsMsg',
                    from: DispatchCtrlLib.SharedWorkerName,
                    to: 'all',
                    data: evt.data,
                };
                DispatchCtrlLib.SharedWorker.port.postMessage(sharedmsg)

                console.log("SharedWorkerMessage: " + JSON.stringify(evt.data));
               
                if (evt.data.Msg == "LoginRsp" && evt.data.LoginInfo) {
                    //登录信息保存至SharedWorker
                    var sharedmsg = {
                        cmd: 'WorkerLogin',
                        from: DispatchCtrlLib.SharedWorkerName,
                        to: 'worker',
                        data: evt.data,
                    };
                    DispatchCtrlLib.SharedWorker.port.postMessage(sharedmsg)

                    console.log("SharedWorkerMessage: " + JSON.stringify(evt.data));
                }
            }

            if (typeof (DispatchRtcLib) != "undefined") {
                if (DispatchRtcLib.OnMsgCallback(evt.data)) {
                    DispatchCtrlLib.FuncCallback(evt.data);
                }
            } else {
                DispatchCtrlLib.FuncCallback(evt.data);
            }
        }
    }




}

DispatchCtrlLib.onWorkerError = function (evt) {
    console.log("DispatchCtrlLib.onWorkerError:" + evt);
    //DispatchCtrlLib.WsWorker = null;
}

DispatchCtrlLib.NewWorker = function () {
    if (DispatchCtrlLib.WsWorker == null) {
        try {
            DispatchCtrlLib.WsWorker = new Worker(DispatchLibPath + "DispatchWsWorker.js");
            DispatchCtrlLib.WsWorker.onmessage = DispatchCtrlLib.onWorkerMessage;
            DispatchCtrlLib.WsWorker.onerror = DispatchCtrlLib.onWorkerError
        } catch (error) {
            DispatchCtrlLib.WsWorker = null;
        }
    }
}

DispatchCtrlLib.onSharedWorkerMessage = function (evt) {   
    var msg = evt.data
    /*
    console.log("DispatchCtrlLib.onSharedWorkerMessage:", msg, '分屏出去的菜单', ScsTreeView.splitScreenMenu);
    ScsTreeView.splitScreenMenu ? ScsTreeView.splitScreenMenu.map((item, index) => {
        msg.data.name ? (msg.data.name.includes(item) ? ScsTreeView.splitScreenMenu.splice(index, 1) : '') : (msg.from.includes(item) ? ScsTreeView.splitScreenMenu.splice(index, 1) : '');
    }) : ''
    */
    if (msg.cmd == 'WorkerConnected') {                   
        //创建后,传入页面名称
        DispatchCtrlLib.SharedWorker.port.postMessage({
            cmd: 'WorkerInit',
            from: DispatchCtrlLib.SharedWorkerName,
            to: 'worker',
            data: {},
        })
        if (DispatchCtrlLib.SharedWorkerName != 'main') {
            DispatchCtrlLib.FuncCallback({
                Msg: "InitializeRsp",
                Result: 0
            });
        }
    } else if (msg.cmd == 'WorkerMsg') {
        if (DispatchCtrlLib.onSharedWorkerMsg) {
            DispatchCtrlLib.onSharedWorkerMsg(msg.from, msg.data);
        }
    } else if (msg.cmd == 'WorkerWsMsg') {
        if (DispatchCtrlLib.SharedWorkerName == 'main') {
            //主页面为分页的请求
            console.log("WorkerMessage: " + JSON.stringify(msg.data));
            DispatchCtrlLib.WsWorker.postMessage(msg.data);
      if (msg.data.Msg == "PttLoadChannelReq") {
        //由主页面进行采集,其他页面不启动
        DispatchPocLib.Start();
      }
        } else {
            //分页为回调
            if (DispatchRtcLib.OnMsgCallback(msg.data)) {
                DispatchCtrlLib.FuncCallback(msg.data);
            }
        }
    } else if (msg.cmd == "WorkerVoipLastIncomingCall") {
        if (DispatchRtcLib.VoipLastIncomingCallInfo) {
            //获取最新来电

            DispatchCtrlLib.SharedWorker.port.postMessage({
                cmd: 'WorkerWsMsg',
                from: DispatchCtrlLib.SharedWorkerName,
                to: msg.from,
                data: DispatchRtcLib.VoipLastIncomingCallSdp,
            })

            DispatchCtrlLib.SharedWorker.port.postMessage({
                cmd: 'WorkerWsMsg',
                from: DispatchCtrlLib.SharedWorkerName,
                to: msg.from,
                data: DispatchRtcLib.VoipLastIncomingCallInfo,
            })
        } 
    }
}

DispatchCtrlLib.NewSharedWorker = function () {
    if (DispatchCtrlLib.SharedWorker == null) {
        try {
            DispatchCtrlLib.SharedWorker = new SharedWorker(DispatchLibPath + "DispatchSharedWorker.js", 'DispatchSharedWorker')
            DispatchCtrlLib.SharedWorker.port.onmessage = DispatchCtrlLib.onSharedWorkerMessage;
            DispatchCtrlLib.SharedWorker.port.onerror = null;
        } catch (error) {
            DispatchCtrlLib.SharedWorker = null;
        }
    }
}

//释放资源
DispatchCtrlLib.Uninitialize = function () {
    if (DispatchCtrlLib.WsWorker) {
        DispatchCtrlLib.WsWorker.postMessage({
            Msg: "Uninitialize"
        });

    }
    return 0;
}

//登录
DispatchCtrlLib.Login = function (Name, Password, Server, Port) {
    if (typeof Name == "string" && typeof Password == "string" && typeof Server == "string") {
        var msg = new Object;
        msg.Msg = "LoginReq";
        msg.Name = Name;
        msg.Password = Password;
        msg.Server = Server;
        if (typeof Type == "number") {
            msg.Port = Port;
        } else {
            msg.Port = 3002;
        }
        DispatchCtrlLib.SendWorkerMsg(msg);

        return 0;
    } else {
        return -1;
    }
}

//登录
DispatchCtrlLib.LoginToken = function (Name, Token, Server, Port) {
    if (typeof Name == "string" && typeof Token == "string" && typeof Server == "string") {
        var msg = new Object;
        msg.Msg = "LoginReq";
        msg.Name = Name;
        msg.Token = Token;
        msg.Server = Server;
        if (typeof Type == "number") {
            msg.Port = Port;
        } else {
            msg.Port = 3002;
        }
        DispatchCtrlLib.SendWorkerMsg(msg);

        return 0;
    } else {
        return -1;
    }
}

//注销
DispatchCtrlLib.Logout = function () {

    var msg = new Object;
    msg.Msg = "LogoutReq";
    DispatchCtrlLib.SendWorkerMsg(msg);

    return 0;
}

DispatchCtrlLib.LoginHold = function () {}

/************************** 监控视频 ******************************/
//拉取监控视频
DispatchCtrlLib.MonitorVideoPull = function (Number, Type, Name) {
    if (typeof Number == "string" && typeof Type == "number") {
        var msg = new Object;
        msg.Msg = "MonitorVideoPullReq";
        msg.Number = Number;
        msg.Name = Name;
        msg.Type = Type;
        msg.CallID = VoipCallID++;

        var target = {};
        target.Number = Number;
        target.Type = Type;

        if (Name) {
            target.Name = Name;
        } else {
            target.Name = "";
        }

        var OnMakeCallSucess = function (sdp) {
            msg.OfferSdp = sdp;

            console.log("DispatchCtrlLib.MonitorVideoPull " + msg.CallID + " local_sdp:");
            console.log(sdp);

            DispatchCtrlLib.SendWorkerMsg(msg);
        }

        var OnMakeCallFail = function (error) {
            console.log("DispatchCtrlLib.MonitorVideoPull Fail:" + error);

            var failmsg = new Object;
            failmsg.Msg = "MonitorVideoStatusNotify";
            failmsg.CallID = msg.CallID;
            failmsg.Status = 7;
            failmsg.Reason = error;

            DispatchCtrlLib.FuncCallback(failmsg);
        }

        DispatchRtcLib.CreateOffer(msg.CallID, DispatchRtcLib_MoniterVideo, OnMakeCallSucess, OnMakeCallFail, target);

        return msg.CallID;
    } else {
        return -1;
    }
}

//挂断监控视频
DispatchCtrlLib.MonitorVideoHangup = function (CallID) {
    if (typeof CallID == "number") {
        var msg = new Object;
        msg.Msg = "MonitorVideoHangupReq";
        msg.CallID = CallID;
        DispatchRtcLib.Stop(CallID);
        DispatchCtrlLib.SendWorkerMsg(msg);

        var failmsg = new Object;
        failmsg.Msg = "MonitorVideoStatusNotify";
        failmsg.CallID = msg.CallID;
        failmsg.Status = 0;
        failmsg.Reason = "End Call";

        DispatchCtrlLib.FuncCallback(failmsg);

        return 0;
    } else {
        return -1;
    }
}

//监控视频推送来电处理
DispatchCtrlLib.MonitorVideoHandleIncomingCall = function (CallID, Handle,Number,Name,Type) {
    if (typeof CallID == "number" && typeof Handle == "number") {
        var msg = new Object;
        msg.Msg = "MonitorVideoHandleIncomingCallReq";
        msg.CallID = CallID;
        msg.Handle = Handle;
        var target = {};
        target.Number = Number;
        target.Type = Type;

        if (Name) {
            target.Name = Name;
        } else {
            target.Name = "";
        }
        if (Handle == 1) {
            var OnMakeCallSucess = function (sdp) {
                msg.OfferSdp = sdp;

                console.log("DispatchCtrlLib.MonitorVideoHandleIncomingCall " + msg.CallID + " local_sdp:");
                console.log(sdp);

                DispatchCtrlLib.SendWorkerMsg(msg);
            }

            var OnMakeCallFail = function (error) {
                console.log("DispatchCtrlLib.MonitorVideoHandleIncomingCall Fail:" + error);

                var failmsg = new Object;
                failmsg.Msg = "MonitorVideoStatusNotify";
                failmsg.CallID = msg.CallID;
                failmsg.Status = 7;
                failmsg.Reason = error;

                DispatchCtrlLib.FuncCallback(failmsg);
            }

            return DispatchRtcLib.CreateOffer(msg.CallID, DispatchRtcLib_MoniterVideo, OnMakeCallSucess, OnMakeCallFail,target);
        } else {
            DispatchCtrlLib.SendWorkerMsg(msg);
        }
        return 0;
    } else {
        return -1;
    }
}

//监控视频环境音静音
DispatchCtrlLib.MonitorVideoSetVolume = function (CallID, Volume) {
    if (typeof CallID == "number" && typeof Volume == "number") {
        return DispatchRtcLib.VoipSetCallVolume(CallID, Volume);
    } else {
        return -1;
    }
}

//监控视频转分发
DispatchCtrlLib.MonitorVideoPush = function (CallID, Number) {
    if (typeof CallID == "number" && typeof Number == "string") {
        var msg = new Object;
        msg.Msg = "MonitorVideoPushReq";
        msg.CallID = CallID;
        msg.Number = Number;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//摄像头云台控制
DispatchCtrlLib.MonitorVideoPtz = function (Number, Command, Direction, Speed) {
    if (typeof Number == "string" && typeof Command == "number" && typeof Direction == "number" && typeof Speed ==
        "number") {
        var msg = new Object;
        msg.Msg = "MonitorVideoPtzReq";
        msg.Number = Number;
        msg.Command = Command;
        msg.Direction = Direction;
        msg.Speed = Speed;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//终端视频远程控制
DispatchCtrlLib.MonitorVideoRemoteControl = function (Number, Resolution, Camera) {
    if (typeof Number == "string" && typeof Resolution == "number" && typeof Camera == "number") {
        var msg = new Object;
        msg.Msg = "MonitorVideoControlReq";
        msg.Number = Number;
        msg.Resolution = Resolution;
        msg.Camera = Camera;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

/************************** IP通话 ******************************/
//IP语音通话
DispatchCtrlLib.VoipMakeAudioCall = function (ExtNum, DcPhone) {
    if (typeof ExtNum == "string") {
        var msg = new Object;
        msg.Msg = "VoipMakeAudioCallReq";
        msg.ExtNum = ExtNum;

        if (typeof DcPhone == "number") {
            msg.CallID = DcPhone;

            DispatchCtrlLib.SendWorkerMsg(msg);
        } else {
            msg.CallID = VoipCallID++;

            var OnMakeCallSucess = function (sdp) {
                msg.OfferSdp = sdp;

                console.log("DispatchCtrlLib.VoipMakeAudioCall " + msg.CallID + " local_sdp:");
                console.log(sdp);

                DispatchCtrlLib.SendWorkerMsg(msg);
            }

            var OnMakeCallFail = function (error) {
                console.log("DispatchCtrlLib.VoipMakeAudioCall Fail:" + error);

                var failmsg = new Object;
                failmsg.Msg = "VoipCallStatusNotify";
                failmsg.CallID = msg.CallID;
                failmsg.Status = 7;
                failmsg.Reason = error;

                DispatchCtrlLib.FuncCallback(failmsg);
            }

            return DispatchRtcLib.CreateOffer(msg.CallID, DispatchRtcLib_VoipAudio, OnMakeCallSucess, OnMakeCallFail);
        }

        return msg.CallID;
    } else {
        return -1;
    }
}

//IP视频通话
DispatchCtrlLib.VoipMakeVideoCall = function (ExtNum) {
    if (typeof ExtNum == "string") {
        var msg = new Object;
        msg.Msg = "VoipMakeVideoCallReq";
        msg.ExtNum = ExtNum;
        msg.CallID = VoipCallID++;

        var OnMakeCallSucess = function (sdp) {
            msg.OfferSdp = sdp;

            console.log("DispatchCtrlLib.VoipMakeVideoCall " + msg.CallID + " local_sdp:");
            console.log(sdp);

            DispatchCtrlLib.SendWorkerMsg(msg);
        }

        var OnMakeCallFail = function (error) {
            console.log("DispatchCtrlLib.VoipMakeVideoCall Fail:" + error);

            var failmsg = new Object;
            failmsg.Msg = "VoipCallStatusNotify";
            failmsg.CallID = msg.CallID;
            failmsg.Status = 7;
            failmsg.Reason = error;

            DispatchCtrlLib.FuncCallback(failmsg);
        }

        return DispatchRtcLib.CreateOffer(msg.CallID, DispatchRtcLib_VoipVideo, OnMakeCallSucess, OnMakeCallFail);
    } else {
        return -1;
    }
}

//IP通话挂断
DispatchCtrlLib.VoipHangupCall = function (CallID) {
    if (typeof CallID == "number") {
        var msg = new Object;
        msg.Msg = "VoipHangupCallReq";
        msg.CallID = CallID;

        DispatchCtrlLib.SendWorkerMsg(msg);

        DispatchRtcLib.Stop(CallID);

        return 0;
    } else {
        return -1;
    }
}

//IP通话来电处理
DispatchCtrlLib.VoipHandleIncomingCall = function (CallID, Handle) {
    if (typeof CallID == "number" && typeof Handle == "number") {
        var msg = new Object;
        msg.Msg = "VoipHandleIncomingCallReq";
        msg.Handle = Handle;
        msg.CallID = CallID;

        if (Handle == 1) {
            var OnCreateAnswerSucess = function (sdp) {
                msg.AnswerSdp = sdp;

                console.log("DispatchCtrlLib.VoipHandleIncomingCall " + msg.CallID + " local_sdp:");
                console.log(sdp);

                DispatchCtrlLib.SendWorkerMsg(msg);
            }

            var OnCreateAnswerFail = function (error) {
                var failmsg = new Object;
                failmsg.Msg = "VoipCallStatusNotify";
                failmsg.CallID = msg.CallID;
                failmsg.Status = 7;
                failmsg.Reason = error;

                DispatchCtrlLib.FuncCallback(failmsg);
            }

            DispatchRtcLib.CreateAnswer(CallID, OnCreateAnswerSucess, OnCreateAnswerFail);

        } else {
            DispatchCtrlLib.SendWorkerMsg(msg);
        }

        return 0;
    } else {
        return -1;
    }
}

//IP通话设置音量
DispatchCtrlLib.VoipSetCallVolume = function (CallID, Volume) {
    if (typeof CallID == "number" && typeof Volume == "number") {
        return DispatchRtcLib.VoipSetCallVolume(CallID, Volume);
    } else {
        return -1;
    }
}

//Integrated Camera - 摄像头设备名称
//none - 关闭摄像头,默认头像
//screen  - 屏幕共享
DispatchCtrlLib.VoipVideoSetSource = function (CallID, VideoSrc) {
    if (typeof CallID == "number" && typeof VideoSrc == "string") {
        return DispatchRtcLib.VoipVideoSetSource(CallID, VideoSrc);
    } else {
        return -1;
    }
}

//通道设置声道
DispatchCtrlLib.VoipSetCallTrack = function (CallID, Track) {
    return -1; // 废弃
}

//IP通话禁麦
DispatchCtrlLib.VoipSetCallMicMute = function (CallID, Mute) {
    if (typeof CallID == "number" && typeof Mute == "number") {
        return DispatchRtcLib.VoipSetCallMicMute(CallID, Mute);
    } else {
        return -1;
    }
}

//IP通话呼叫转移
DispatchCtrlLib.VoipTransferCall = function (CallID, ExtNum) {
    if (typeof CallID == "number" && typeof ExtNum == "string") {
        var msg = new Object;
        msg.Msg = "VoipTransferCallReq";
        msg.ExtNum = ExtNum;
        msg.CallID = CallID;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//IP通话呼叫保持
DispatchCtrlLib.VoipHoldCall = function (CallID, Type) {
    if (typeof CallID == "number" && typeof Type == "number") {
        var msg = new Object;
        msg.Msg = "VoipHoldCallReq";
        msg.Type = Type;
        msg.CallID = CallID;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//IP调度:开始/结束监听终端状态
DispatchCtrlLib.VoipDispatchMoniterStatus = function (ExtNum, Type) {
    if (typeof ExtNum == "string" && typeof Type == "number") {
        var msg = new Object;
        msg.Msg = "SubVoipStatusReq";
        msg.Type = Type;
        msg.ExtNum = ExtNum;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//IP调度:强插呼叫
DispatchCtrlLib.VoipDispatchInsertCall = function (ExtNum, DcPhone) {
    if (typeof ExtNum == "string") {
        var msg = new Object;
        msg.Msg = "VoipDispatchInsertCallReq";
        msg.ExtNum = ExtNum;
        if (typeof DcPhone == "number") {
            msg.CallID = DcPhone;
        } else {
            msg.CallID = VoipCallID++;
        }
        DispatchCtrlLib.SendWorkerMsg(msg);
        return msg.CallID;
    } else {
        return -1;
    }
}

//IP调度:强断呼叫
DispatchCtrlLib.VoipDispatchInterruptCall = function (ExtNum) {
    if (typeof ExtNum == "string") {
        var msg = new Object;
        msg.Msg = "VoipDispatchInterruptCallReq";
        msg.ExtNum = ExtNum;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//IP调度:强拆呼叫
DispatchCtrlLib.VoipDispatchBreakCall = function (ExtNum, DcPhone) {
    if (typeof ExtNum == "string") {
        var msg = new Object;
        msg.Msg = "VoipDispatchBreakCallReq";
        msg.ExtNum = ExtNum;
        if (typeof DcPhone == "number") {
            msg.CallID = DcPhone;
        } else {
            msg.CallID = VoipCallID++;
        }
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//IP调度:监听呼叫
DispatchCtrlLib.VoipDispatchMoniterCall = function (ExtNum, DcPhone) {
    if (typeof ExtNum == "string") {
        var msg = new Object;
        msg.Msg = "VoipDispatchMoniterCallReq";
        msg.ExtNum = ExtNum;
        if (typeof DcPhone == "number") {
            msg.CallID = DcPhone;
        } else {
            msg.CallID = VoipCallID++;
        }
        DispatchCtrlLib.SendWorkerMsg(msg);
        return msg.CallID;
    } else {
        return -1;
    }
}

//IP调度:呼叫转会议
DispatchCtrlLib.VoipDispatchCallToConference = function (ExtNum, ConfID) {
    if (typeof ExtNum == "string" && typeof ConfID == "string") {
        var msg = new Object;
        msg.Msg = "VoipDispatchCallToConferenceReq";
        msg.ExtNum = ExtNum;
        msg.ConfID = ConfID;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//IP调度:代接来电
DispatchCtrlLib.VoipDispatchSubstituteCall = function (ExtNum, DcPhone) {
    if (typeof ExtNum == "string") {
        var msg = new Object;
        msg.Msg = "VoipDispatchSubstituteCallReq";
        msg.ExtNum = ExtNum;
        if (typeof DcPhone == "number") {
            msg.CallID = DcPhone;
        } else {
            msg.CallID = VoipCallID++;
        }
        DispatchCtrlLib.SendWorkerMsg(msg);
        return msg.CallID;
    } else {
        return -1;
    }
}

//IP调度:设置台席话机
DispatchCtrlLib.VoipDispatchSetDcPhone = function (LeftExt, RightExt) {
    if (typeof LeftExt == "string" && typeof RightExt == "string") {
        var msg = new Object;
        msg.Msg = "VoipDispatchSetDcPhoneReq";
        msg.LeftExt = LeftExt;
        msg.RightExt = RightExt;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return msg.CallID;
    } else {
        return -1;
    }
}

//IP调度:接听台席队列来电
DispatchCtrlLib.VoipDispatchAnswerFifo = function (ExtNum, DcPhone) {
    if (typeof ExtNum == "string") {
        var msg = new Object;
        msg.Msg = "VoipDispatchAnswerFifoReq";
        msg.ExtNum = ExtNum;
        if (typeof DcPhone == "number") {
            msg.CallID = DcPhone;
        } else {
            msg.CallID = VoipCallID++;
        }
        DispatchCtrlLib.SendWorkerMsg(msg);
        return msg.CallID;
    } else {
        return -1;
    }
}

//IP调度:通话桥接
DispatchCtrlLib.VoipDispatchCallBridge = function (ExtNum, OtherExtNum) {
    if (typeof ExtNum == "string" && typeof OtherExtNum == "string") {
        var msg = new Object;
        msg.Msg = "VoipDispatchCallBridgeReq";
        msg.ExtNum = ExtNum;
        msg.OtherExtNum = OtherExtNum;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return msg.CallID;
    } else {
        return -1;
    }
}

//IP调度:来电闭铃
DispatchCtrlLib.VoipDispatchStopRing = function (DcPhone) {
    if (typeof DcPhone == "number") {
        var msg = new Object;
        msg.Msg = "VoipDispatchStopRingReq";
        msg.CallID = DcPhone;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

DispatchCtrlLib.VoipLastIncomingCall = function () {
    if (DispatchCtrlLib.SharedWorker && 
        DispatchCtrlLib.SharedWorkerName != 'main') {
        //分页发送至主页面

        var sharedmsg = {
            cmd: 'WorkerVoipLastIncomingCall',
            from: DispatchCtrlLib.SharedWorkerName,
            to: 'main',
            data: {},
        };
        DispatchCtrlLib.SharedWorker.port.postMessage(sharedmsg)
        console.log("SharedWorkerMessage: " + JSON.stringify(sharedmsg));
    }

    return 0;
}

/************************** 会议 ******************************/
//当前会议信息
DispatchCtrlLib.CurrentConferenceInfo = function () {
    return DispatchConference.CurrentConferenceInfo();
}

//加入会议
DispatchCtrlLib.ConferenceEnter = function (ConfID, Type, ConfPwd) {
    if (typeof ConfID == "string" &&
        typeof Type == "number") {
        return DispatchConference.ConferenceEnter(ConfID, Type, ConfPwd);
    }

    return -1;
}

//接受/拒绝会议邀请
DispatchCtrlLib.ConferenceHandleInvite = function (Handle) {
    if (typeof Handle == "number") {
        return DispatchConference.ConferenceHandleInvite(Handle);
    }

    return -1;
}

//离开会议
DispatchCtrlLib.ConferenceExit = function () {
    return DispatchConference.ConferenceExit();
}

//会议邀请
DispatchCtrlLib.ConferenceInvite = function (ExtNumList, ConfID) {
    for (var i = 0; i < ExtNumList.length; i++) {
        if (typeof ExtNumList[i].ExtNum !== "string") {
            return -1;
        }
    }

    if (ExtNumList.length == 0) {
        return -1;
    }

    if (ConfID) {
        var msg = new Object;
        msg.Msg = "VoipConferenceInviteReq";
        msg.ConfID = ConfID;
        msg.ExtNumList = ExtNumList;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    }

    return DispatchConference.ConferenceInvite(ExtNumList);
}

//会议结束
DispatchCtrlLib.ConferenceEnd = function () {
    return DispatchConference.ConferenceEnd();
}

//会议成员移除
DispatchCtrlLib.ConferenceKick = function (ExtNum) {
    if (typeof ExtNum == "string") {
        return DispatchConference.ConferenceKick(ExtNum);
    } else {
        return -1;
    }
}

//本地麦克风静音
DispatchCtrlLib.ConferenceLocalMicMute = function (Mute) {
    return DispatchConference.ConferenceLocalMicMute(Mute);
}

//会议成员禁言
DispatchCtrlLib.ConferenceMute = function (ExtNum, Mute) {
    if (typeof ExtNum == "string" && typeof Mute == "number") {
        return DispatchConference.ConferenceMute(ExtNum, Mute);
    } else {
        return -1;
    }
}

//会议设置音量
DispatchCtrlLib.ConferenceSetVolume = function (Volume) {
    if (typeof Volume == "number") {
        return DispatchConference.ConferenceSetVolume(Volume);
    } else {
        return -1;
    }
}

//会议切换本地扬声器
DispatchCtrlLib.ConferenceSetSpeaker = function (DevLabel) {
    if (typeof DevLabel == "string") {
        return DispatchConference.ConferenceSetSpeaker(DevLabel);
    } else {
        return -1;
    }
}

//会议切换本地麦克风
DispatchCtrlLib.ConferenceSetMicphone = function (DevLabel) {
    if (typeof DevLabel == "string") {
        return DispatchConference.ConferenceSetMicphone(DevLabel);
    } else {
        return -1;
    }
}

//会议切换本地扬声器
DispatchCtrlLib.ConferenceSetCamera = function (DevLabel) {
    if (typeof DevLabel == "string") {
        return DispatchConference.ConferenceSetCamera(DevLabel);
    } else {
        return -1;
    }
}

//会议视频观看
DispatchCtrlLib.ConferenceWatch = function (ExtNum, VideoLib) {
    if (typeof ExtNum == "string" &&
        typeof VideoLib == "object") {
        return DispatchConference.ConferenceWatch(ExtNum, VideoLib);
    } else {
        return -1;
    }
}

//会议视频聚焦
DispatchCtrlLib.ConferenceFocus = function (ExtNum) {
    if (typeof ExtNum == "string") {
        return DispatchConference.ConferenceFocus(ExtNum);
    } else {
        return -1;
    }
}

//会议移交主持人
DispatchCtrlLib.ConferenceChangeHost = function (ExtNum) {
    if (typeof ExtNum == "string") {
        return DispatchConference.ChangeHost(ExtNum);
    } else {
        return -1;
    }
}

/************************** 对讲 ******************************/



//加载通道
DispatchCtrlLib.PttLoadChannel = function (CallMode, TargetInfo) {

  var ret = DispatchCtrlLib._PttLoadChannel(CallMode, TargetInfo);
  if (ret > 0 && DispatchCtrlLib.SharedWorkerName == 'main') {
    //启动语音采集 由主页面进行采集,其他页面不启动
    DispatchPocLib.Start();
  }

    return ret;
}

DispatchCtrlLib._PttLoadChannel = function (CallMode, TargetInfo) {
    if (typeof CallMode != "number") {
        return -1;
    }

    if (CallMode == 0) {
        if (typeof TargetInfo.GroupNumber == "string") {
            var msg = new Object;
            msg.Msg = "PttLoadChannelReq";
            msg.CallMode = CallMode;
            msg.GroupNumber = TargetInfo.GroupNumber;
            if (typeof TargetInfo.GroupPriority != "number") {
                msg.GroupPriority = 7;
            } else {
                msg.GroupPriority = TargetInfo.GroupPriority;
            }
            
            msg.ChannelID = VoipCallID++;
            DispatchCtrlLib.SendWorkerMsg(msg);
            return msg.ChannelID;
        } else {
            return -1;
        }
    } else if (CallMode == 1) {
        if (typeof TargetInfo.UserNumber == "string") {
            var msg = new Object;
            msg.Msg = "PttLoadChannelReq";
            msg.CallMode = CallMode;
            msg.UserNumber = TargetInfo.UserNumber;
            msg.ChannelID = VoipCallID++;
            DispatchCtrlLib.SendWorkerMsg(msg);
            return msg.ChannelID;
        } else {
            return -1;
        }
    } else if (CallMode == 2) {
        var msg = new Object;
        msg.Msg = "PttLoadChannelReq";
        msg.CallMode = CallMode;
        msg.GroupList = [];
        msg.UserList = [];

        for (var i = 0; i < TargetInfo.GroupList.length; i++) {
            if (typeof TargetInfo.GroupList[i].Number == "string") {
                msg.GroupList.push(TargetInfo.GroupList[i].Number);
            }
        }

        for (var i = 0; i < TargetInfo.UserList.length; i++) {
            if (typeof TargetInfo.UserList[i].Number == "string") {
                msg.UserList.push(TargetInfo.UserList[i].Number);
            }
        }

        if (msg.GroupList.length == 0 && msg.UserList.length == 0) {
            return -1;
        }

        msg.ChannelID = VoipCallID++;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return msg.ChannelID;
    } else {
        return -1;
    }

}

//释放通道
DispatchCtrlLib.PttReleaseChannel = function (ChannelID) {
    if (typeof ChannelID == "number") {
        var msg = new Object;
        msg.Msg = "PttReleaseChannelReq";
        msg.ChannelID = ChannelID;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//开始/取消监听
DispatchCtrlLib.PttMonitor = function (Type, ChannelID) {
    if (typeof ChannelID == "number" && typeof Type == "number") {
        var msg = new Object;
        msg.Msg = "PttMonitorReq";
        msg.ChannelID = ChannelID;
        msg.Type = Type;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//发起/结束呼叫
DispatchCtrlLib.PttCall = function (ChannelID, Type) {
    if (typeof ChannelID == "number" && typeof Type == "number") {
        var msg = new Object;
        msg.Msg = "PttCallReq";
        msg.ChannelID = ChannelID;
        msg.Type = Type;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//申请话权
DispatchCtrlLib.PttTalkRequest = function (ChannelID) {
    if (DispatchDevices.MicphoneList.length == 0) {
        console.log("本地无可用麦克风");
        return -2;
    }

    if (typeof ChannelID == "number") {
        var msg = new Object;
        msg.Msg = "PttTalkRequestReq";
        msg.ChannelID = ChannelID;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//发起呼叫并申请话权
DispatchCtrlLib.PttCallTalkRequest = function (ChannelID) {
    if (DispatchDevices.MicphoneList.length == 0) {
        console.log("本地无可用麦克风");
        return -2;
    }
    
    if (typeof ChannelID == "number") {
        var msg = new Object;
        msg.Msg = "PttCallTalkRequest";
        msg.ChannelID = ChannelID;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//释放话权
DispatchCtrlLib.PttTalkRelease = function (ChannelID) {
    if (typeof ChannelID == "number") {
        var msg = new Object;
        msg.Msg = "PttTalkReleaseReq";
        msg.ChannelID = ChannelID;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//设置对讲音量
DispatchCtrlLib.PttSetVolume = function (ChannelID, Volume) {
    if (typeof ChannelID == "number" && typeof Volume == "number") {
        var msg = new Object;
        msg.Msg = "PttSetVolumeReq";
        msg.ChannelID = ChannelID;
        msg.Volume = Volume;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//通道设置声道
DispatchCtrlLib.PttSetTrack = function (ChannelID, Track) {
    if (typeof ChannelID == "number" && typeof Track == "number") {
        var msg = new Object;
        msg.Msg = "PttSetTrackReq";
        msg.ChannelID = ChannelID;
        msg.Track = Track;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//呼叫强插
DispatchCtrlLib.PttCallInsert = function (ChannelID, UserNumber) {
    if (typeof ChannelID == "number" && typeof UserNumber == "string") {
        var msg = new Object;
        msg.Msg = "PttCallInsert";
        msg.ChannelID = ChannelID;
        msg.UserNumber = UserNumber;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//呼叫强拆
DispatchCtrlLib.PttCallBreak = function (ChannelID, UserNumber) {
    if (typeof ChannelID == "number" && typeof UserNumber == "string") {
        var msg = new Object;
        msg.Msg = "PttCallBreak";
        msg.ChannelID = ChannelID;
        msg.UserNumber = UserNumber;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

/************************** 定位 ******************************/
//开始订阅位置
DispatchCtrlLib.LocStartSubscribe = function (Number, Type, Length, Interval) {
    if (typeof Number == "string") {
        var msg = new Object;
        msg.Msg = "SubLocReq";
        msg.Number = Number;
        msg.Start = 1;
        msg.Type = Type;
        msg.Length = Length;
        msg.Interval = Interval;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//结束订阅位置
DispatchCtrlLib.LocStopSubscribe = function (Number) {
    if (typeof Number == "string") {
        var msg = new Object;
        msg.Msg = "SubLocReq";
        msg.Number = Number;
        msg.Start = 0;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//终端定位参数设置
DispatchCtrlLib.LocSetParm = function (Number, ID, Type, Interval) {
    if (typeof Number == "string" && typeof ID == "number" && typeof Type == "number" && typeof Interval ==
        "number") {
        var msg = new Object;
        msg.Msg = "LocSetParmReq";
        msg.Number = Number;
        msg.ID = ID;
        msg.Type = Type;
        msg.Interval = Interval;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//电子围栏告警处理
DispatchCtrlLib.FenceHandle = function (AlarmID) {
    //废弃接口,移动到http接口
}

/************************** 状态&消息 ******************************/
//订阅终端状态
DispatchCtrlLib.StatusSubscribe = function (Type, UserList) {
    if (typeof Type == "number") {
        var msg = new Object;
        msg.Msg = "SubOnlineReq";
        msg.Type = Type;
        msg.UserList = UserList;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

//发送多媒体消息
DispatchCtrlLib.MsgSend = function (TargetType, TargetInfo, MsgType, MsgInfo) {
    if (typeof TargetType == "number" && typeof MsgType == "number") {
        var msg = new Object;
        msg.Msg = "PttMsgSendReq";
        msg.TargetType = TargetType;
        // msg.TargetInfo = new Object;
        msg.TargetInfo = TargetInfo;
        if (TargetType == 0 || TargetType == 2) {
            if (typeof TargetInfo.UserNumber == "string") {
                msg.TargetInfo.UserNumber = TargetInfo.UserNumber;
            } else {
                return null;
            }
        } else if (TargetType == 1) {
            if (typeof TargetInfo.GroupNumber == "string") {
                msg.TargetInfo.GroupNumber = TargetInfo.GroupNumber;
                msg.TargetInfo.NickName = TargetInfo.NickName;
            } else {
                return null;
            }
        } else if (TargetType == 3) {
            if (typeof TargetInfo.TempGroupID == "string") {
                msg.TargetInfo.TempGroupID = TargetInfo.TempGroupID;

                msg.TargetInfo.GroupList = [];
                msg.TargetInfo.UserList = [];
        
                for (var i = 0; i < TargetInfo.GroupNumberList.length; i++) {
                    if (typeof TargetInfo.GroupNumberList[i].GroupNumber == "string") {
                        msg.TargetInfo.GroupList.push(TargetInfo.GroupNumberList[i].GroupNumber);
                    }
                }
        
                for (var i = 0; i < TargetInfo.UserNumberList.length; i++) {
                    if (typeof TargetInfo.UserNumberList[i].UserNumber == "string") {
                        msg.TargetInfo.UserList.push(TargetInfo.UserNumberList[i].UserNumber);
                    }
                }
        
                if (msg.TargetInfo.GroupList.length == 0 && msg.TargetInfo.UserList.length == 0) {
                    return -1;
                }

                
            } else {
                return null;
            }
        } else {
            return null;
        }

        //校验参数
        if (MsgType == 0 || MsgType == 8) {
            if (typeof MsgInfo.MsgString != "string") {
                return null;
            }
        } else if (MsgType == 1 || MsgType == 2 || MsgType == 3 || MsgType == 5 || MsgType == 7) {
            if (typeof MsgInfo.MsgAttachAddr != "string") {
                return null;
            }
        } else if (MsgType == 4) {
            if (typeof MsgInfo.LatitudeType != "number" ||
                typeof MsgInfo.Latitude != "number" ||
                typeof MsgInfo.LongitudeType != "number" ||
                typeof MsgInfo.Longitude != "number" ||
                typeof MsgInfo.LocDescription != "string") {
                return null;
            }
        } else {
            return null;
        }

        msg.MsgType = MsgType;
        msg.MsgInfo = MsgInfo;

        function guid() {
            function S4() {
                return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
            }
            return (S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4());
        }

        msg.MsgIndex = guid().toString();
        DispatchCtrlLib.SendWorkerMsg(msg);
        return msg.MsgIndex;
    } else {
        return null;
    }
}

//撤回多媒体消息
DispatchCtrlLib.MsgWithdraw = function (MsgIndex, TargetType, TargetInfo) {
    if (typeof MsgIndex == "string" && typeof TargetType == "number") {
        var msg = new Object;
        msg.Msg = "PttMsgSendReq";
        msg.MsgIndex = MsgIndex;
        msg.TargetType = TargetType;
        msg.TargetInfo = TargetInfo;
        if (TargetType == 0 || TargetType == 2) {
            if (typeof TargetInfo.UserID == "number" &&
                typeof TargetInfo.UserNumber == "string" &&
                typeof TargetInfo.UserName == "string") {
                msg.TargetInfo.UserID = TargetInfo.UserID;
                msg.TargetInfo.UserNumber = TargetInfo.UserNumber;
                msg.TargetInfo.UserName = TargetInfo.UserName;
            } else {
                return -1;
            }
        } else if (TargetType == 1) {
            if (typeof TargetInfo.GroupID == "number" &&
                typeof TargetInfo.GroupNumber == "string" &&
                typeof TargetInfo.GroupName == "string") {
                msg.TargetInfo.GroupID = TargetInfo.GroupID;
                msg.TargetInfo.GroupNumber = TargetInfo.GroupNumber;
                msg.TargetInfo.GroupName = TargetInfo.GroupName;
            } else {
                return -1;
            }
        } else if (TargetType == 3) {
            if (typeof TargetInfo.TempGroupID == "string" &&
                typeof TargetInfo.GroupNumberList.GroupNumber == "string" &&
                typeof TargetInfo.UserNumberList.UserNumber == "string") {
                msg.TargetInfo.TempGroupID = TargetInfo.TempGroupID;
                msg.TargetInfo.GroupNumberList = TargetInfo.GroupNumberList;
                msg.TargetInfo.UserNumberList = TargetInfo.UserNumberList;
            } else {
                return -1;
            }
        } else {
            return -1;
        }

        msg.MsgType = 99;
        msg.MsgInfo = new Object;

        DispatchCtrlLib.SendWorkerMsg(msg);

        return 0;
    } else {
        return -1;
    }
}

//发送广播通知
DispatchCtrlLib.MsgBroadcast = function (NoticeID) {
    if (typeof NoticeID == "number") {
        var msg = new Object;
        msg.Msg = "MsgBroadcastReq";
        msg.NoticeID = NoticeID;
        DispatchCtrlLib.SendWorkerMsg(msg);
        return 0;
    } else {
        return -1;
    }
}

/************************** 语音播报 ******************************/
//语音播报试听
DispatchCtrlLib.BroadcastTest = function (Type, Content, Voice) {
    if (typeof Type == "number" && typeof Content == "string" && typeof Voice == "number") {
        var msg = new Object;
        msg.Msg = "BroadcastTestReq";
        msg.Type = Type;
        msg.Content = Content;
        msg.Voice = Voice;
        if (typeof window.Win_DispatchLibFunc == 'function') {
            window.Win_DispatchLibFunc(JSON.stringify(msg));
        } else {
            return -1;
        }        
    } else {
        return -1;
    }
}

//语音播报上传
DispatchCtrlLib.BroadcastUpload = function (Content, Voice) {
    if (typeof Content == "string" && typeof Voice == "number") {
        var msg = new Object;
        msg.Msg = "BroadcastUploadReq";
        msg.Content = Content;
        msg.Voice = Voice;
        if (typeof window.Win_DispatchLibFunc == 'function') {
            window.Win_DispatchLibFunc(JSON.stringify(msg));
        } else {
            return -1;
        } 
    } else {
        return -1;
    }
}

//即时播报
DispatchCtrlLib.BroadcastInstant = function (Content, Voice, Times, ExtNumList) {
    for (var i = 0; i < ExtNumList.length; i++) {
        if (typeof ExtNumList[i].ExtNum !== "string") {
            return -1;
        }
    }
    if (typeof Times == "number" && typeof Content == "string" && typeof Voice == "number") {
        var msg = new Object;
        msg.Msg = "BroadcastInstantReq";
        msg.Times = Times;
        msg.Content = Content;
        msg.Voice = Voice;
        msg.ExtNumList = ExtNumList;
        if (typeof window.Win_DispatchLibFunc == 'function') {
            window.Win_DispatchLibFunc(JSON.stringify(msg));
        } else {
            return -1;
        } 
        return 0;
    } else {
        return -1;
    }
}

//收听播报
DispatchCtrlLib.BroadcastListen = function (Type) {
    return 0;
}

/************************** 其他 ******************************/
//枚举本机通讯设备
DispatchCtrlLib.LocalDevShow = function (Type) {
    if (typeof DispatchDevices == "undefined") {
        return null;
    }
    return DispatchDevices;
}

//选择本机通讯设备
DispatchCtrlLib.LocalDevSet = function (Type, DevID) {
    if (typeof Type == "number" && typeof DevID == "string") {
        return DispatchDevices.setLocalDevice(Type, DevID);
    } else {
        return -1;
    }
}

//已废弃
DispatchCtrlLib.WinSetName = function (Name) {
    return 0;
}

//窗口消息设置
DispatchCtrlLib.WinSendMsg = function (Target, Content) {
    if (DispatchCtrlLib.SharedWorker) {
        var sharedmsg = {
            cmd: 'WorkerWsMsg',
            from: DispatchCtrlLib.SharedWorkerName,
            to: Target,
            data: Content,
        };
        DispatchCtrlLib.SharedWorker.port.postMessage(sharedmsg)
        console.log("SharedWorkerMessage: " + JSON.stringify(sharedmsg));
        return 0;
    } else {
        return -1;
    }
}

//已废弃
DispatchCtrlLib.PlaySoundReq = function (type) {
    return 0;
}

//设置第三方业务ID
DispatchCtrlLib.SetThirdID = function (ThirdID) {
    if (typeof ThirdID == "string" || typeof ThirdID == "undefined") {
        var msg = new Object;
        msg.Msg = "SysSetThirdID";
        msg.ThirdID = ThirdID;
        DispatchCtrlLib.SendWorkerMsg(msg);

        return 0;
    } else {
        return -1;
    }
}