/// <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); }
/// <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); }