/// <summary>
        /// 获取呼入的主叫号码
        /// </summary>
        /// <param name="chnlno">通道编号</param>
        /// <returns>返回主叫号码,要取得主叫号码对应的电话线路必须申请来电显示功能,如果获取主叫号码超时则直接返回空字符串。</returns>
        private string GetCallerNumber(int chnlno)
        {
            byte[] callNumber = new byte[32 * sizeof(char)];
            long   T          = Environment.TickCount;
            int    result     = -1;

            // 只有当函数返回3或4时才表示接收完毕
            do
            {
                if (Environment.TickCount - T > driver.Timeout * Defaultdelay)
                {
                    return("");
                }
                System.Threading.Thread.Sleep(Defaultdelay);

                // 获取主叫号码
                lock (D160X.SyncObj)
                {
                    result = D160X.GetCallerIDStr(chnlno, callNumber);
                }
            } while (result != 3 && result != 4);

            string Astr = Encoding.UTF8.GetString(callNumber);

            Astr = Astr.Substring(0, Astr.Length - 8); // 去除FSK码
            return(Astr);
        }
        /// <summary>
        /// 侦听板卡上所有外线的呼入事件,在一个循环中进行侦听并且不断的检查是否发出了停止信号(abort)
        /// </summary>
        protected override void Listen()
        {
            while (!abort)
            {
                int    n;
                bool   chnlRing = false;
                string callNumber;
                for (int i = 0; i < driver.ChannelCount; i++)
                {
                    lock (D160X.SyncObj)
                    {
                        n          = -1;
                        callNumber = string.Empty;
                        switch (driver.Channels[i].ChannelType)
                        {
                        case ChannelType.TRUNK:     // 监听外线通道的呼入事件
                            if (D160X.RingDetect(i))
                            {
                                n = i;
                                //callNumber = GetCallerNumber(i);
                                if (driver.Channels[i] != null)
                                {
                                    driver.Channels[i].Logger.Info(String.Format("Call 事件分配器探测到通道 {0} 有呼入事件发生,呼入电话号码为: ", i, callNumber));
                                }
                            }
                            break;

                        case ChannelType.USER:      // 监听内线通道的呼出事件
                            if (D160X.OffHookDetect(i))
                            {
                                n          = i;
                                callNumber = driver.Channels[i].ChannelAlias;
                                if (driver.Channels[i] != null)
                                {
                                    driver.Channels[i].Logger.Info(String.Format("Call 事件分配器探测到通道 {0} 有提机事件发生,呼出通道别名为: {1}", i, driver.Channels[i].ChannelAlias));
                                }
                            }
                            break;
                        }

                        // 分发事件到订阅者组件,此处不检查callNumber是否为空是因为没有来电显示D160X模拟卡
                        // 便无法取得主叫号码。
                        if (n != -1 && Subject.Invocations > 0)
                        {
                            ICallHandler handler = Subject as ICallHandler;
                            handler.Call(n, callNumber);
                        }
                    }
                }
                System.Threading.Thread.Sleep(Interval); // 使事件侦听暂停一段时间
            }
        }
        protected override void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    // 关闭所有事件分配器
                    Active = false;
                    System.Threading.Thread.Sleep(5000);
                    logger.Info(String.Format("{0}板卡适配器从系统中卸载成功。\n", VersionInfo.Name));
                }

                // Release unmanaged resources
                D160X.DConf_DisableConfCard();
                D160X.DisableCard();
                D160X.FreeDRV();
                D160X.DJFax_DisableCard();

                disposed = true;
            }
            base.Dispose(disposing);
        }
        /// <summary>
        /// 加载板卡驱动程序并初始化当前板卡下的所有通道
        /// </summary>
        /// <returns>如果初始成功则返回0,否则返回相应的错误编码</returns>
        protected override long Initialize()
        {
            base.Initialize(); // 执行基类的初始化工作

            // 添加呼入事件分配器
            Logger.Info("初始化板卡内置的事件分配器 Call……");
            IEventService eventService = workItem.Services.Get <IEventService>();

            if (eventService != null)
            {
                eventService.RegisterEventDispatcher("Call", new CallDispatcher(typeof(ICallHandler), typeof(CallDispatcher), this));
            }

            Logger.Info(string.Format("准备初始化{0}板卡适配器……", VersionInfo.Name));
            long loadDriverSucces = -1;

            try
            {
                loadDriverSucces = D160X.LoadDRV();
                if (loadDriverSucces != -1)
                {
                    CanWork = true;
                }
                else
                {
                    return(loadDriverSucces);
                }
            }
            catch (Exception ex)
            {
                Logger.Fatal(string.Format("加载{0}驱动程序失败,错误代码为:{1}", VersionInfo.Name, loadDriverSucces), ex);
            }

            // 初始化板卡的会议资源
            int Initconf = D160X.DConf_EnableConfCard();

            string[] InitconfResult = new string[] { "成功", "不是D161A卡", "在INI中,Connect参数必须设置为1", "已经使用了模拟的会议卡,并且初始化成功" };
            Logger.Info(String.Format("初始化{0}的会议资源,{1}", VersionInfo.Name, InitconfResult[Initconf]));
            if (Initconf == 0)
            {
                confGroups = new Dictionary <int, List <int> >();
            }

            D160X.Sig_Init(0); // 初始化信号音检测
            int chnlCount = D160X.CheckValidCh();

            for (int i = 0; i < chnlCount; i++)
            {
                // 初始化每条通道
                AbstractChannel chnl = new DB160XChannel(this, i);
                if (chnl != null)
                {
                    ISubscripterRegister subscripter = new CallSubscripter(chnl); // 预定义的呼叫事件订阅器
                    if (eventService != null)
                    {
                        eventService.RegisterSubscripter(subscripter);
                    }

                    Channels.Add(chnl);
                    chnl.CurrentStatus = ChannelStatus.IDLE;
                    OnCreatedChannel(this, new EventArgs <IChannel>(chnl)); // 触发通道创建事件
                }
            }

            D160X.EnableCard(chnlCount, FileBufferLength);
            int initFax = D160X.DJFax_DriverReady(2048);

            if (initFax == 0)
            {
                Logger.Info("初始化传真资源,成功");
            }
            else
            {
                Logger.Info("因为不是传真卡或配置不正确初始化板卡的传真资源失败,返回的错误代码: " + initFax.ToString());
            }
            Logger.Info(string.Format("完成{0}板卡适配器的初始化工作", VersionInfo.Name));

            return(loadDriverSucces);
        }
Exemple #5
0
        /// <summary>
        /// Plays the message.
        /// </summary>
        /// <param name="channel">The channel.</param>
        /// <param name="text">The text.</param>
        /// <param name="allowBreak">if set to <c>true</c> [allow break].</param>
        /// <param name="playType">Type of the play.</param>
        /// <returns></returns>
        public override SwitchStatus PlayMessage(IChannel channel, string text, bool allowBreak, TTSPlayType playType)
        {
            if (!canWork)
            {
                Logger.Warn("因TTS引擎初始化失败或其它原因造成不可用,不能进行TTS放音");
                return(SwitchStatus.FAILURE);
            }

            if (channel == null)
            {
                Logger.Warn("传入通道参数未初始化不能进行TTS放音");
                return(SwitchStatus.FAILURE);
            }

            lock (D160X.SyncObj)
            {
                Logger.Info(string.Format("通道 {0} 准备TTS放音,放音内容为:{1}", channel.ChannelID, text));
                Int32 Playflag = TTS3.DJTTS3_StartPlayText(channel.ChannelID, Encoding.UTF8.GetBytes(text), TTS3.INFO_TEXT_BUFFER,
                                                           0, 45, 50, XmlTag ? TTS3.INFO_USE_LABLE : TTS3.INFO_NOTUSE_LABLE);
                Logger.Debug("TTS放音结果为:" + Playflag.ToString());
                D160X.InitDtmfBuf(channel.ChannelID);
            }

            // 在放音后就要不断的检查其是否已经播放完毕
            Int32 Playend = TTS3.INFO_PLAY_NOT_COMPLATE;

            while (Playend == TTS3.INFO_PLAY_NOT_COMPLATE)
            {
                lock (D160X.SyncObj)
                {
                    D160X.PUSH_PLAY();
                }
                System.Threading.Thread.Sleep(Defaultdelay);

                bool dtmfHited = false;
                lock (D160X.SyncObj)
                {
                    dtmfHited = D160X.DtmfHit(channel.ChannelID);
                }
                if (allowBreak && dtmfHited)
                {
                    lock (D160X.SyncObj)
                    {
                        TTS3.DJTTS3_StopPlayText(channel.ChannelID);
                    }
                    Logger.Info(string.Format("通道 {0} TTS放音过程被对方按键中断", channel.ChannelID));
                    return(SwitchStatus.BREAK);
                }

                if (channel.HangUpDetect())
                {
                    lock (D160X.SyncObj)
                    {
                        TTS3.DJTTS3_StopPlayText(channel.ChannelID);
                    }
                    Logger.Info(string.Format("通道 {0} TTS放音过程被对方挂机中断", channel.ChannelID));
                    channel.ResetChannel();
                    return(SwitchStatus.BREAK);
                }

                lock (D160X.SyncObj)
                {
                    Playend = TTS3.DJTTS3_CheckPlayTextEnd(channel.ChannelID);
                }
            }

            lock (D160X.SyncObj)
            {
                TTS3.DJTTS3_StopPlayText(channel.ChannelID);
            }
            Logger.Info(string.Format("通道 {0} TTS放音结束", channel.ChannelID));
            return(SwitchStatus.SUCCESS);
        }