亲爱的各位朋友,好久都没关注我的blog了,主要是工作太忙、项目太杂!目前最新的一个项目是一个机遇物联网的的项目。
说到物联网,已经热的不能再热了,我在此就不赘述,直奔主题吧.
由于我更多的精力花在项目管理和协调上,因此开发做的极少,但是在该项目中,我还是小试牛刀(主要是熟悉技术怕丢生了),写了其中的一个子应用:CallCenter(呼叫中心)
项目环境介绍:
1.需求:自来水厂对用户开放的一个热线,主要用以播放一些信息、要闻,转坐席受理、咨询之类的事。
其中,IVR和坐席的通讯通过Socket来实现的,而且Socket是自己写的一个连接池用以控制多连接以及连接的断开。
2.规模:4路呼入,2路坐席(容量有点小,但是功能基本不少)
3.环境:东进模拟语音卡D081A,
4.语言:C# (VS2008)
(如果有需要该类应用项目的朋友可以在此留下联系方式!)
虽说这种应用已经很泛滥了,但是我在此还是想献丑一下,借以帮助后来人,或者有需要的人,以及项目!开始贴代码了
DLL的引入:
using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace CC.DJ081A.Lib { public class Tc08a32 { #region 语音卡初始化函数 /// <summary> /// 一般,当没有特别说明,在调用 Tc08a32.h 中其他的 API 函数前,必须先调用本函数来加载驱动程序。 0表示成功 /// </summary> /// <returns></returns> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern int LoadDRV(); /// <summary> /// 关闭设备驱动程序。在程序退出时调用本函数。 /// </summary> /// <returns></returns> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern int FreeDRV(); /// <summary> /// 初始化电话卡的硬件,并为每个通道分配语音缓冲区 /// </summary> /// <param name="wUsedCh"></param> /// <param name="wFileBufLen"></param> /// <returns></returns> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern int EnableCard(int wUsedCh, int wFileBufLen); /// <summary> /// 取消卡功能 /// </summary> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void DisableCard(); /// <summary> /// 检测在当前机器内可用的通道总数 /// </summary> /// <returns></returns> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern short CheckValidCh(); /// <summary> /// 检测通道类型CHTYPE_USER(0) CHTYPE_TRUNK(1)CHTYPE_EMPTY(2) /// </summary> /// <param name="chn"></param> /// <returns></returns> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern CHN_TYPE CheckChType(int chn); /// <summary> /// 设置压缩比率。调用本函数后,录放音均以该压缩比率进行 /// </summary> /// <param name="wPackRate"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void SetPackRate(int wPackRate); /// <summary> /// 设定要检测的挂机忙音的参数 /// </summary> /// <param name="wPackRate"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void SetBusyPara(int wPackRate); /// <summary> /// 设定拨号以后要检测的信号音的参数 /// </summary> /// <param name="RingBack1"></param> /// <param name="RingBack0"></param> /// <param name="BusyLen"></param> /// <param name="RingTimes"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void SetDialPara(int RingBack1, int RingBack0,int BusyLen,int RingTimes); /// <summary> /// 用户自定义信号音 /// </summary> /// <param name="filename"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void ReadGenerateSigBuf(string filename); /// <summary> /// 维持文件录放音的持续进行; 需要在处理函数的大循环中调用本函数 /// </summary> /// <param name="filename"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void PUSH_PLAY(); [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern int GetSysInfo(); #endregion #region 振铃及摘机函数 /// <summary> /// 检查(外线)是否有振铃信号或(内线)是否有摘机 /// 1:有振铃信号(外线、录音)或话机摘机(内线)。 /// </summary> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern bool RingDetect(int wChnlNo); /// <summary> /// 对某一个内线或录音通道开始挂机检测。 /// </summary> /// <param name="wChnlNo"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void StartHangUpDetect(int wChnlNo); /// <summary> /// 检测某一个内线或录音通道的挂机状态。本函数需要在调用函数StartHangUpDetect()后使用。当需要检测拍叉簧时,请使用本函数 /// </summary> /// <param name="wChnlNo"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern int HangUpDetect(int wChnlNo); /// <summary> /// 外线挂机。对于内线,本函数不起作用。请不要对内线通道调用本函数。 /// </summary> /// <param name="wChnlNo"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void HangUp(int wChnlNo); /// <summary> /// 检测某一个内线通道的摘机状态。 在调用函数 FeedRealRing()开始一个断续的铃流后,请调用本函数来检测摘机状态 /// </summary> /// <param name="wChnlNo"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern bool OffHookDetect(int wChnlNo); /// <summary> /// 外线摘机,对于内线,本函数不起作用。请不要对内线通道调用本函数。 /// </summary> /// <param name="wChnlNo"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void OffHook(int wChnlNo); /// <summary> /// 对某一个内线通道馈连续的铃流。调用本函数后,本通道所连接的电话机将会不停的振铃,直到调用函数 FeedPower()才会停止。 /// </summary> /// <param name="wChnlNo"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void FeedRing(int wChnlNo); /// <summary> /// 对某一个内线通道馈断续的铃流。断续的时间长度为响铃 1 秒,停止4秒 /// </summary> /// <param name="wChnlNo"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void FeedRealRing(int wChnlNo); /// <summary> /// 对某一个内线通道馈电,同时停止馈铃流。 /// </summary> /// <param name="wChnlNo"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void FeedPower(int wChnlNo); /// <summary> /// 某通道启动一个计时器,不能使用 ClockType 为 0~2 的计时器(ClockType 为 0~2 的计时器仅供内部使用) 。 (用户可用的为3~9) /// </summary> /// <param name="wChnlNo"></param> /// <param name="ClockType"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void StartTimer(int wChnlNo, int ClockType); /// <summary> /// 本函数返回从计时器启动到现在的时间,单位为 0.01 秒 /// </summary> /// <param name="wChnlNo"></param> /// <param name="ClockType"></param> /// <returns></returns> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern long ElapseTime(int wChnlNo, int ClockType); /// <summary> /// 控制信号音的播放。本函数实质上使用内存循环放音来实现的 /// </summary> /// <param name="wChnlNo"></param> /// <param name="SigType"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void StartPlaySignal(int wChnlNo, int SigType); /// <summary> /// 维持断续振铃及信号音的函数,一定要在程序大循环中调用本函数 /// </summary> /// <param name="?"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void FeedSigFunc(); /// <summary> /// 检测某一个内线或录音通道的挂机状态。本函数需要在调用函数,StartHangUpDetect()后使用 /// </summary> /// <returns></returns> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern int HangUpDetect(); [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern int ReadCheckResult(int wChnlNo, int mode); #endregion #region 收按键 /// <summary> /// 清空系统的 DTMF缓冲区,当在缓冲区中有 DTMF按键的值时,此值将会丢失。 /// </summary> /// <param name="?"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void InitDtmfBuf(int wChnlNo); /// <summary> /// 查看指定通道是否有 DTMF按键。当收到一个有效的 DTMF按键后,本函数返回 true /// </summary> /// <param name="wChnlNo"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern bool DtmfHit(int wChnlNo); /// <summary> /// 获取该通道收到的 DTMF编码。当在缓冲区中有 DTMF按键时,调用本函数将返回最早的一个 DTMF按键, /// 同时将该按键从缓冲区中移去;当在缓冲区中没有收到任何的 DTMF按键时,本函数返回-1。 /// </summary> /// <param name="wChnlNo"></param> /// <returns></returns> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern int GetDtmfCode(int wChnlNo); /// <summary> /// 某个通道开始新的信号音检测。在摘机、挂机、拨号结束等状态改变后,调用本函数来开始新的信号音检测。 /// </summary> /// <param name="wChnlNo"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void StartSigCheck(int wChnlNo); #endregion #region 放音 /// <summary> /// 指定通道开始普通内存放音。 /// </summary> /// <param name="wChnlNo"></param> /// <param name="PlayBuf"></param> /// <param name="dwStartPos"></param> /// <param name="dwPlayLen"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void StartPlay(int wChnlNo, StringBuilder PlayBuf, int dwStartPos, int dwPlayLen); /// <summary> /// 指定通道停止内存放音 /// </summary> /// <param name="wChnlNo"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void StopPlay(int wChnlNo); /// <summary> /// 开始文件放音。停止该方式的放音,一定要用函数 StopPlayFile()。检查放音是否结束,用函数 CheckPlayEnd()。 /// </summary> /// <param name="wChnlNo"></param> /// <param name="FileName"></param> /// <param name="StartPos"></param> /// <returns></returns> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern bool StartPlayFile(int wChnlNo, StringBuilder FileName, int StartPos); /// <summary> /// 开始文件录音。当调用本函数进行文件录音时,用 dwRecordLen 来指定录音的最大长度 /// </summary> /// <param name="wChnlNo"></param> /// <param name="FileName"></param> /// <param name="dwRecordLen"></param> /// <returns></returns> [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern bool StartRecordFile(int wChnlNo, byte[] FileName, long dwRecordLen); [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern void StopRecordFile(int wChnlNo); /// <summary> /// 检查指定通道录音是否结束(缓冲区已满) /// </summary> /// <param name="ChannelNo"></param> /// <returns></returns> [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern int CheckRecordEnd(int ChannelNo); /// <summary> /// 停止文件放音 /// </summary> /// <param name="wChnlNo"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void StopPlayFile(int wChnlNo); [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void RsetIndexPlayFile(int wChnlNo); /// <summary> /// 添加索引文件到剪贴板中。 /// </summary> /// <param name="wChnlNo"></param> /// <param name="fileName"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern bool AddIndexPlayFile(int wChnlNo,StringBuilder fileName); /// <summary> /// 多文件放音 /// </summary> /// <param name="wChnlNo"></param> /// <returns></returns> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern bool StartIndexPlayFile(int wChnlNo); [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern int DRec_OffHookDetect(int wChnlNo); #endregion #region 联通 [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern int SetLink(int wOne, int wAnother); #endregion #region 收主叫 /// <summary> /// 初始化某个通道的 Caller-ID缓冲区。 /// </summary> /// <param name="wChnlNo"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void ResetCallerIDBuffer(int wChnlNo); /// <summary> /// 3(ID_STEP_OK):接收完毕,校验正确 /// </summary> /// <param name="wChnlNo"></param> /// <param name="caller"></param> /// <returns></returns> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern short GetCallerIDStr(int wChnlNo, byte[] caller); [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern int CheckPlayEnd(int wChnlNo); [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern int CheckIndexPlayFile(int wChnlNo); [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern int StopIndexPlayFile(int wChnlNo); /// <summary> /// 接收主叫(增加日期时间、主叫号码、主叫用户信息) 。 /// </summary> /// <param name="wChnlNo"></param> /// <param name="strTime"></param> /// <param name="strCallerID"></param> /// <param name="strUser"></param> [DllImport("lib//Tc08a32.dll", CharSet = CharSet.Ansi)] public static extern void GetCallerIDStrEx(int wChnlNo, StringBuilder strTime, StringBuilder strCallerID, StringBuilder strUser); [DllImport("lib//NewSig.dll", CharSet = CharSet.Ansi)] public static extern void Sig_Init(int imode); [DllImport("lib//NewSig.dll", CharSet = CharSet.Ansi)] public static extern int Sig_CheckBusy(int imode); #endregion } }