中间件标准版5.1git,去除基础模块

FsProxy.cpp 29KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969
  1. #include "StdAfx.h"
  2. #include "FsProxy.h"
  3. #include "ChanExten.h"
  4. #include "ChanTrunk.h"
  5. #include "Session.h"
  6. #include "OperationReactor.h"
  7. #include "../IVR/IvrSysInc.h"
  8. SINGLETON_IMPLEMENT(CFsProxy)
  9. CFsProxy::CFsProxy(void) : m_Gateway(this), m_pEventHandler(NULL)
  10. {
  11. }
  12. CFsProxy::~CFsProxy(void)
  13. {
  14. }
  15. /*****************************************************************
  16. **【函数名称】 __transLogicState2CtiState
  17. **【函数功能】 将逻辑状态转换为CTI识别的状态
  18. **【参数】
  19. **【返回值】
  20. ****************************************************************/
  21. UINT CFsProxy::__transLogicState2CtiState( DEV_RES_TYPE ChanType, CHAN_LOGIC_STATE State )
  22. {
  23. if(ChanType == DEV_RES_TYPE_EXT)
  24. {
  25. UINT HoldMask = State & HELD_STATE_IND_MASK;
  26. switch(State & HELD_STATE_FILTER_MASK)
  27. {
  28. case CHAN_LOGIC_STATE_DISABLED: return INNER_STATE_DISABLED; // 不可用
  29. case CHAN_LOGIC_STATE_FREE: return INNER_STATE_FREE | HoldMask; // 空闲
  30. case CHAN_LOGIC_STATE_INIT: return INNER_STATE_INIT | HoldMask; // 摘机等待拨号
  31. case CHAN_LOGIC_STATE_DIALING: return INNER_STATE_DIALING | HoldMask; // 拨号
  32. case CHAN_LOGIC_STATE_RING_BACK: return INNER_STATE_RING_BACK | HoldMask; // 呼出振铃
  33. case CHAN_LOGIC_STATE_ALERTING: return INNER_STATE_ALERTING | HoldMask; // 来电振铃
  34. case CHAN_LOGIC_STATE_TALKING: return INNER_STATE_TALKING | HoldMask; // 通话中
  35. default:
  36. ASSERT(FALSE);
  37. return INNER_STATE_DISABLED;
  38. }
  39. }
  40. else
  41. {
  42. switch(State)
  43. {
  44. case CHAN_LOGIC_STATE_DISABLED: return TRUNK_STATE_DISABLED; // 不可用
  45. case CHAN_LOGIC_STATE_FREE: return TRUNK_STATE_FREE; // 空闲
  46. case CHAN_LOGIC_STATE_DIALING: return TRUNK_STATE_DIALING; // 拨号
  47. case CHAN_LOGIC_STATE_RING_BACK: return TRUNK_STATE_RING_BACK; // 呼出振铃
  48. case CHAN_LOGIC_STATE_ALERTING: return TRUNK_STATE_ALERTING; // 来电振铃
  49. case CHAN_LOGIC_STATE_STANDBY:
  50. case CHAN_LOGIC_STATE_TALKING: return TRUNK_STATE_TALKING; // 通话中
  51. default:
  52. ASSERT(FALSE);
  53. return TRUNK_STATE_UNKNOWN;
  54. }
  55. }
  56. }
  57. /*****************************************************************
  58. **【函数名称】 __addExten
  59. **【函数功能】 添加分机
  60. **【参数】
  61. **【返回值】
  62. ****************************************************************/
  63. void CFsProxy::__addExten( UINT ExtenNo )
  64. {
  65. CChanExten* pExten = new CChanExten(this, ExtenNo);
  66. m_MapChanExt.SetAt(ExtenNo, pExten);
  67. pExten->regist();
  68. }
  69. /*****************************************************************
  70. **【函数名称】 delExten
  71. **【函数功能】 删除分机
  72. **【参数】
  73. **【返回值】
  74. ****************************************************************/
  75. void CFsProxy::__delExten( UINT ExtenNo )
  76. {
  77. CChanExten* pExten = NULL;
  78. if(m_MapChanExt.Lookup(ExtenNo, pExten))
  79. {
  80. if(pExten->isFree())
  81. {
  82. m_MapChanExt.RemoveKey(ExtenNo);
  83. FS_LINK_DELETE(pExten);
  84. }
  85. else pExten->discard(true);
  86. }
  87. }
  88. /*****************************************************************
  89. **【函数名称】 __freeExten
  90. **【函数功能】 清空分机
  91. **【参数】
  92. **【返回值】
  93. ****************************************************************/
  94. void CFsProxy::__freeExten( void )
  95. {
  96. UINT ExtenNo = 0;
  97. CChanExten* pExten = NULL;
  98. POSITION Pos = m_MapChanExt.GetStartPosition();
  99. while(Pos != NULL)
  100. {
  101. m_MapChanExt.GetNextAssoc(Pos, ExtenNo, pExten);
  102. FS_LINK_DELETE(pExten);
  103. }
  104. m_MapChanExt.RemoveAll();
  105. }
  106. /*****************************************************************
  107. **【函数名称】 __initTrunkChan
  108. **【函数功能】 初始化中继通道
  109. **【参数】
  110. **【返回值】
  111. ****************************************************************/
  112. void CFsProxy::__initTrunkChan( void )
  113. {
  114. for(int i = 1; i <= CConfig::trunkCount(); ++i)
  115. {
  116. CChanTrunk* pTrunk = new CChanTrunk(this, i);
  117. m_ArrayTrunk.Add(pTrunk);
  118. pTrunk->regist();
  119. }
  120. }
  121. /*****************************************************************
  122. **【函数名称】 __freeTrunkChan
  123. **【函数功能】 清空中继通道
  124. **【参数】
  125. **【返回值】
  126. ****************************************************************/
  127. void CFsProxy::__freeTrunkChan( void )
  128. {
  129. CChanTrunk* pTrunk = NULL;
  130. for(int i = 0; i < m_ArrayTrunk.GetCount(); ++i)
  131. {
  132. pTrunk = m_ArrayTrunk[i];
  133. FS_LINK_DELETE(pTrunk);
  134. }
  135. m_ArrayTrunk.RemoveAll();
  136. }
  137. /*****************************************************************
  138. **【函数名称】 __getSession
  139. **【函数功能】 查找会话
  140. **【参数】
  141. **【返回值】
  142. ****************************************************************/
  143. CSession* CFsProxy::__getSession( PCHAN_EVENT_NOTIFY pNotify, bool NewWhenNull /*= false*/ )
  144. {
  145. CSession* pSession = __getSession(pNotify->CallId);
  146. if(pSession == NULL && NewWhenNull)
  147. {
  148. pSession = new CSession(this, pNotify->CallId);
  149. pSession->prepare(pNotify);
  150. m_MapSession.SetAt(pNotify->CallId, pSession);
  151. LOGGER(LOG_LEVEL_NORMAL,_T("{CFsProxy}:Add Session[%s],ChanId[%s],EventId[%d]"), pSession->id(), pNotify->ChanId, pNotify->EventId);
  152. }
  153. return pSession;
  154. }
  155. /*****************************************************************
  156. **【函数名称】 __getSession
  157. **【函数功能】 查找会话
  158. **【参数】
  159. **【返回值】
  160. ****************************************************************/
  161. CSession* CFsProxy::__getSession( LPCTSTR SessionId )
  162. {
  163. CSession* pSession = NULL;
  164. m_MapSession.Lookup(SessionId, pSession);
  165. return pSession;
  166. }
  167. /*****************************************************************
  168. **【函数名称】 __delSession
  169. **【函数功能】 删除会话
  170. **【参数】
  171. **【返回值】
  172. ****************************************************************/
  173. void CFsProxy::__delSession( LPCTSTR SessionId )
  174. {
  175. if (SessionId == NULL)
  176. return;
  177. CSession* pSession = NULL;
  178. if(m_MapSession.Lookup(SessionId, pSession))
  179. {
  180. m_MapSession.RemoveKey(SessionId);
  181. LOGGER(LOG_LEVEL_NORMAL, _T("{FsProxy}: Delete Session[%s]"), pSession->id());
  182. FS_LINK_DELETE(pSession);
  183. }
  184. }
  185. /*****************************************************************
  186. **【函数名称】 __freeSession
  187. **【函数功能】 清空会话
  188. **【参数】
  189. **【返回值】
  190. ****************************************************************/
  191. void CFsProxy::__freeSession( void )
  192. {
  193. CString SessionId = 0;
  194. CSession* pSession = NULL;
  195. POSITION Pos = m_MapSession.GetStartPosition();
  196. while(Pos != NULL)
  197. {
  198. m_MapSession.GetNextAssoc(Pos, SessionId, pSession);
  199. FS_LINK_DELETE(pSession);
  200. }
  201. m_MapSession.RemoveAll();
  202. }
  203. /*****************************************************************
  204. **【函数名称】 __kill
  205. **【函数功能】 挂断通道
  206. **【参数】
  207. **【返回值】
  208. ****************************************************************/
  209. bool CFsProxy::__kill( LONG JobId, LPCTSTR ChanId )
  210. {
  211. CString EslCmd;
  212. if(JobId == FS_LINK_JOBID_INVALID)
  213. EslCmd.Format(_T("bgapi uuid_kill %s"), ChanId);
  214. else
  215. EslCmd.Format(_T("bgapi uuid_kill %s\r\n%s: %ld"), ChanId, ESL_HEADER_JOB_UUID, JobId);
  216. return m_Gateway.sendCmd(EslCmd);
  217. }
  218. /*****************************************************************
  219. **【函数名称】 init
  220. **【函数功能】 初始化
  221. **【参数】
  222. **【返回值】
  223. ****************************************************************/
  224. bool CFsProxy::init( IEslEventHandler* pEventHandler )
  225. {
  226. ASSERT(pEventHandler != NULL);
  227. m_pEventHandler = pEventHandler;
  228. __initTrunkChan();
  229. if(m_Gateway.start())
  230. {
  231. m_Gateway.hangupAll();
  232. if(m_Gateway.scanExten())
  233. {
  234. LOGGER(LOG_LEVEL_NORMAL, _T("{FsProxy}: FreeSWITCH代理初始化成功"));
  235. return true;
  236. }
  237. else
  238. {
  239. LOGGER(LOG_LEVEL_ERROR, _T("{FsProxy}: FreeSWITCH代理初始化失败, 扫描分机资源失败"));
  240. return false;
  241. }
  242. }
  243. else
  244. {
  245. LOGGER(LOG_LEVEL_ERROR, _T("{FsProxy}: FreeSWITCH代理初始化失败, ESL网关启动失败"));
  246. m_pEventHandler = NULL;
  247. return false;
  248. }
  249. }
  250. /*****************************************************************
  251. **【函数名称】 release
  252. **【函数功能】 释放资源
  253. **【参数】
  254. **【返回值】
  255. ****************************************************************/
  256. void CFsProxy::release( void )
  257. {
  258. m_Gateway.stop();
  259. __freeSession();
  260. __freeExten();
  261. __freeTrunkChan();
  262. }
  263. /*****************************************************************
  264. **【函数名称】 onChanRegist
  265. **【函数功能】 通道注册的处理函数
  266. **【参数】
  267. **【返回值】
  268. ****************************************************************/
  269. void CFsProxy::onChanRegist( DEV_RES_TYPE ChanType, UINT ChanNo, CHAN_LOGIC_STATE ChanState )
  270. {
  271. CDevControl::GetInstance().onEventResDetail(ChanType, ChanNo);
  272. CDevControl::GetInstance().onEventResState(ChanType, ChanNo, __transLogicState2CtiState(ChanType, ChanState));
  273. }
  274. /*****************************************************************
  275. **【函数名称】 onExtenDestroy
  276. **【函数功能】 分机销毁的处理函数
  277. **【参数】
  278. **【返回值】
  279. ****************************************************************/
  280. void CFsProxy::onExtenDestroy( UINT ExtenNo )
  281. {
  282. CDevControl::GetInstance().onEventResState(DEV_RES_TYPE_EXT, ExtenNo, INNER_STATE_REMOVE);
  283. }
  284. /*****************************************************************
  285. **【函数名称】 onExtenDirectOp
  286. **【函数功能】 分机直接操作启动
  287. **【参数】 OpType 启动的操作类型
  288. pHostChan 触发事件的通道
  289. pNotify 触发操作事件内容
  290. **【返回值】
  291. ****************************************************************/
  292. void CFsProxy::onExtenDirectOp( DEV_OP OpType, CVirtualChan* pHostChan, PCHAN_EVENT_NOTIFY pNotify )
  293. {
  294. switch(OpType)
  295. {
  296. case DEV_OP_CALL_OUT:
  297. {
  298. if(!COperationReactor::GetInstance().onExtenCallFromDev(pHostChan, pNotify))
  299. __kill(FS_LINK_JOBID_INVALID, pHostChan->chanId());
  300. }
  301. break;
  302. } // end switch
  303. }
  304. /*****************************************************************
  305. **【函数名称】 onChanStateUpdate
  306. **【函数功能】 通道状态更新处理
  307. **【参数】
  308. **【返回值】
  309. *****************************************************************/
  310. void CFsProxy::onChanStateUpdate( LONG OpInstance, CVirtualChan* pChan )
  311. {
  312. if(OpInstance != FS_LINK_INSTANCE_INVALID)
  313. m_pEventHandler->onEslEvtChanState(OpInstance, pChan);
  314. CDevControl::GetInstance().onEventResState(pChan->type(), pChan->no(), __transLogicState2CtiState(pChan->type(), pChan->state()), pChan->callerNum(), pChan->calleeNum());
  315. }
  316. /*****************************************************************
  317. **【函数名称】 onChanPoor
  318. **【函数功能】 空闲通道枯竭处理
  319. **【参数】
  320. **【返回值】
  321. *****************************************************************/
  322. void CFsProxy::onChanPoor( CSession* pSession, PCHAN_EVENT_NOTIFY pNotify )
  323. {
  324. __kill(FS_LINK_JOBID_INVALID, pNotify->ChanId);
  325. }
  326. /*****************************************************************
  327. **【函数名称】 onTrunkCallIn
  328. **【函数功能】 中继呼入
  329. **【参数】
  330. **【返回值】
  331. *****************************************************************/
  332. void CFsProxy::onTrunkCallIn( CChanTrunk* pTrunk )
  333. {
  334. CDevControl::GetInstance().onEventDevOperation(pTrunk->no(), DEV_OP_CALL_IN, pTrunk->callerNum(), pTrunk->calleeNum());
  335. }
  336. /*****************************************************************
  337. **【函数名称】 onEslDisconnect
  338. **【函数功能】 ESL连接中断处理
  339. **【参数】
  340. **【返回值】
  341. *****************************************************************/
  342. void CFsProxy::onEslDisconnect( void )
  343. {
  344. CDevControl::GetInstance().onEventDevDown();
  345. }
  346. /*****************************************************************
  347. **【函数名称】 onEslSipReg
  348. **【函数功能】 分机注册的处理函数
  349. **【参数】
  350. **【返回值】
  351. ****************************************************************/
  352. void CFsProxy::onEslExtenReg( UINT ExtenNo )
  353. {
  354. CChanExten* pExten = getExten(ExtenNo);
  355. if(pExten == NULL)
  356. {
  357. __addExten(ExtenNo);
  358. }
  359. else
  360. {
  361. if(pExten->isVoid()) // 若被丢弃,则改变丢弃状态
  362. pExten->discard(false);
  363. }
  364. #ifdef _DEBUG
  365. LOGGER(LOG_LEVEL_NORMAL, _T("{FsProxy}: 分机[%u]注册"), ExtenNo);
  366. #endif
  367. }
  368. /*****************************************************************
  369. **【函数名称】 onEslExtenUnreg
  370. **【函数功能】 分机注销的处理函数
  371. **【参数】
  372. **【返回值】
  373. ****************************************************************/
  374. void CFsProxy::onEslExtenUnreg( UINT ExtenNo )
  375. {
  376. __delExten(ExtenNo);
  377. #ifdef _DEBUG
  378. LOGGER(LOG_LEVEL_NORMAL, _T("{FsProxy}: 分机[%u]注销"), ExtenNo);
  379. #endif
  380. }
  381. /*****************************************************************
  382. **【函数名称】 onEslEvtBgJobDone
  383. **【函数功能】 后台任务执行结束事件处理
  384. **【参数】
  385. **【返回值】
  386. *****************************************************************/
  387. void CFsProxy::onEslEvtBgJobDone( PBG_JOB_NOTIFY pNotify )
  388. {
  389. ASSERT(m_pEventHandler != NULL);
  390. m_pEventHandler->onEslEvtBgJobDone(pNotify);
  391. }
  392. /*****************************************************************
  393. **【函数名称】 onEslEvtChannel
  394. **【函数功能】 通道事件处理
  395. **【参数】
  396. **【返回值】
  397. *****************************************************************/
  398. void CFsProxy::onEslEvtChannel( PCHAN_EVENT_NOTIFY pNotify )
  399. {
  400. ASSERT(pNotify != NULL);
  401. if (pNotify == NULL)
  402. return;
  403. CSession* pSession = __getSession(pNotify, true);
  404. ASSERT(pSession != NULL);
  405. if (pSession == NULL)
  406. {
  407. LOGGER(LOG_LEVEL_WARNING, _T("{FsProxy}: 通道事件,没有找到会话,EslEventId=%d,ChanId[%s],CallId[%s],Caller[%s],Callee[%s]"), pNotify->EventId, pNotify->ChanId, pNotify->CallId, pNotify->Caller, pNotify->Callee);
  408. return;
  409. }
  410. __try {
  411. pSession->onChanEvent(pNotify);
  412. if (pSession->isVoid())
  413. __delSession(pSession->id());
  414. }
  415. __except (EXCEPTION_EXECUTE_HANDLER)
  416. {
  417. LOGGER(LOG_LEVEL_WARNING, _T("{FsProxy}: 处理通道事件时异常[%u],EslEventId=%d,ChanId[%s],CallId[%s],Caller[%s],Callee[%s]"), GetExceptionCode(), pNotify->EventId, pNotify->ChanId, pNotify->CallId, pNotify->Caller, pNotify->Callee);
  418. __delSession(pSession->id());
  419. }
  420. }
  421. /*****************************************************************
  422. **【函数名称】 onEslEvtDtmf
  423. **【函数功能】 DTMF事件处理
  424. **【参数】
  425. **【返回值】
  426. *****************************************************************/
  427. void CFsProxy::onEslEvtDtmf( PDTMF_NOTIFY pNotify )
  428. {
  429. ASSERT(pNotify != NULL);
  430. CSession* pSession = __getSession(pNotify->CallId);
  431. ASSERT(pSession != NULL);
  432. if(pSession != NULL)
  433. pSession->onChanDtmf(pNotify);
  434. }
  435. /*****************************************************************
  436. **【函数名称】 onEslEvtHold
  437. **【函数功能】 保持事件处理
  438. **【参数】
  439. **【返回值】
  440. *****************************************************************/
  441. void CFsProxy::onEslEvtHold( PHOLD_NOTIFY pNotify )
  442. {
  443. ASSERT(pNotify != NULL);
  444. CSession* pSession = __getSession(pNotify->CallId);
  445. ASSERT(pSession != NULL);
  446. if(pSession != NULL)
  447. pSession->onChanHold(pNotify);
  448. }
  449. /*****************************************************************
  450. **【函数名称】 getExten
  451. **【函数功能】 查找分机
  452. **【参数】
  453. **【返回值】
  454. ****************************************************************/
  455. CChanExten* CFsProxy::getExten( UINT ExtenNo )
  456. {
  457. CChanExten* pExten = NULL;
  458. m_MapChanExt.Lookup(ExtenNo, pExten);
  459. return pExten;
  460. }
  461. /*****************************************************************
  462. **【函数名称】 getTrunk
  463. **【函数功能】 查找中继
  464. **【参数】
  465. **【返回值】
  466. ****************************************************************/
  467. CChanTrunk* CFsProxy::getTrunk( UINT TrunkNo )
  468. {
  469. if(TrunkNo > (UINT)m_ArrayTrunk.GetCount())
  470. return NULL;
  471. --TrunkNo;
  472. return m_ArrayTrunk[TrunkNo];
  473. }
  474. /*****************************************************************
  475. **【函数名称】 delChan
  476. **【函数功能】 删除通道
  477. **【参数】
  478. **【返回值】
  479. ****************************************************************/
  480. void CFsProxy::delChan( CVirtualChan* pChan )
  481. {
  482. if(pChan->type() == DEV_RES_TYPE_EXT)
  483. __delExten(pChan->no());
  484. }
  485. /*****************************************************************
  486. **【函数名称】 getFreeTrunk
  487. **【函数功能】 查找空闲中继
  488. **【参数】
  489. **【返回值】
  490. ****************************************************************/
  491. CChanTrunk* CFsProxy::getFreeTrunk( void )
  492. {
  493. // 当前轮循到的索引
  494. static int PosStatic = 0;
  495. // 保证遍历一轮
  496. for(int i = 0; i < m_ArrayTrunk.GetCount(); ++i)
  497. {
  498. // 保证POS是有效的
  499. if(PosStatic >= m_ArrayTrunk.GetCount())
  500. PosStatic = 0;
  501. CChanTrunk* pTrunk = m_ArrayTrunk[PosStatic++];
  502. ASSERT(pTrunk != NULL);
  503. // 当前外线是否空闲
  504. if(pTrunk->isFree())
  505. return pTrunk;
  506. }
  507. return NULL;
  508. }
  509. /*****************************************************************
  510. **【函数名称】 getAssoChanInSession
  511. **【函数功能】 获取会话中关联通道
  512. **【参数】
  513. **【返回值】
  514. ****************************************************************/
  515. CVirtualChan* CFsProxy::getAssoChanInSession( CVirtualChan* pChan )
  516. {
  517. CSession* pSession = __getSession(pChan->sessionId());
  518. if(pSession != NULL)
  519. return pSession->getAssoChan(pChan);
  520. else
  521. return NULL;
  522. }
  523. /*****************************************************************
  524. **【函数名称】 getBusyChan
  525. **【函数功能】 获取忙通道
  526. **【参数】
  527. **【返回值】
  528. *****************************************************************/
  529. CVirtualChan* CFsProxy::getBusyChan( LPCTSTR ChanId )
  530. {
  531. CVirtualChan* pBusyChan = NULL;
  532. m_MapBusyChan.Lookup(ChanId, pBusyChan);
  533. return pBusyChan;
  534. }
  535. /*****************************************************************
  536. **【函数名称】 regBusyChan
  537. **【函数功能】 登记忙通道
  538. **【参数】
  539. **【返回值】
  540. *****************************************************************/
  541. void CFsProxy::regBusyChan( CVirtualChan* pChan )
  542. {
  543. m_MapBusyChan.SetAt(pChan->chanId(), pChan);
  544. }
  545. /*****************************************************************
  546. **【函数名称】 unregBusyChan
  547. **【函数功能】 取消登记忙通道
  548. **【参数】
  549. **【返回值】
  550. *****************************************************************/
  551. void CFsProxy::unregBusyChan( CVirtualChan* pChan )
  552. {
  553. m_MapBusyChan.RemoveKey(pChan->chanId());
  554. }
  555. /*****************************************************************
  556. **【函数名称】 ExtenCall
  557. **【函数功能】 分机呼叫
  558. **【参数】
  559. **【返回值】
  560. ****************************************************************/
  561. bool CFsProxy::ExtenCall( LONG JobId, CVirtualChan* pChan, LPCTSTR CallerNum, LPCTSTR CalleeNum )
  562. {
  563. CString EslCmd;
  564. EslCmd.Format(_T("bgapi originate {origination_caller_id_number=%lu}user/%lu %s XML %s\r\n%s: %ld"),
  565. pChan->no(), pChan->no(), CalleeNum, CConfig::extContext(), ESL_HEADER_JOB_UUID, JobId);
  566. return m_Gateway.sendCmd(EslCmd);
  567. }
  568. /*****************************************************************
  569. **【函数名称】 PredictionCall
  570. **【函数功能】 预测外呼
  571. **【参数】
  572. **【返回值】
  573. ****************************************************************/
  574. bool CFsProxy::PredictionCall( LONG JobId, CString CallerNum, CString CalleeNum )
  575. {
  576. CString CallString;
  577. if(!m_CallStringMaker.makeCallStringWithDefault(CallerNum, CalleeNum, CallString))
  578. return false;
  579. CString EslCmd;
  580. EslCmd.Format(_T("bgapi originate {origination_caller_id_number=%s,%s=%ld}%s %s XML %s\r\n%s: %ld"),
  581. CallerNum, ESL_VAR_OP_INSTANCE, JobId, CallString, CalleeNum, CConfig::pCallContext(), ESL_HEADER_JOB_UUID, JobId);
  582. return m_Gateway.sendCmd(EslCmd);
  583. }
  584. /*****************************************************************
  585. **【函数名称】 answer
  586. **【函数功能】 应答通道
  587. **【参数】
  588. **【返回值】
  589. ****************************************************************/
  590. bool CFsProxy::answer( LONG JobId, CVirtualChan* pChan )
  591. {
  592. return false;
  593. }
  594. /*****************************************************************
  595. **【函数名称】 kill
  596. **【函数功能】 挂断通道
  597. **【参数】
  598. **【返回值】
  599. ****************************************************************/
  600. bool CFsProxy::kill( LONG JobId, CVirtualChan* pChan )
  601. {
  602. return __kill(JobId, pChan->chanId());
  603. }
  604. /*****************************************************************
  605. **【函数名称】 consult
  606. **【函数功能】 协商呼叫
  607. **【参数】
  608. **【返回值】
  609. ****************************************************************/
  610. bool CFsProxy::consult( LONG JobId, CVirtualChan* pChan, CString DestNum )
  611. {
  612. CString CallerNum;
  613. CString CallString;
  614. if(!m_CallStringMaker.makeCallString(CallerNum, DestNum, CallString))
  615. return false;
  616. CString EslCmd;
  617. EslCmd.Format(_T("bgapi uuid_broadcast %s att_xfer::%s\r\n%s: %ld"), pChan->chanId(), CallString, ESL_HEADER_JOB_UUID, JobId);
  618. return m_Gateway.sendCmd(EslCmd);
  619. }
  620. /*****************************************************************
  621. **【函数名称】 insert
  622. **【函数功能】 强插
  623. **【参数】
  624. **【返回值】
  625. ****************************************************************/
  626. bool CFsProxy::insert( LONG JobId, CVirtualChan* pChan, LPCTSTR DestSessionId )
  627. {
  628. CString EslCmd;
  629. EslCmd.Format(_T("bgapi originate {origination_caller_id_number=%lu}user/%lu &three_way(%s)\r\n%s: %ld"),
  630. pChan->no(), pChan->no(), DestSessionId, ESL_HEADER_JOB_UUID, JobId);
  631. return m_Gateway.sendCmd(EslCmd);
  632. }
  633. /*****************************************************************
  634. **【函数名称】 intercept
  635. **【函数功能】 强截
  636. **【参数】
  637. **【返回值】
  638. ****************************************************************/
  639. bool CFsProxy::intercept( LONG JobId, CVirtualChan* pChan, LPCTSTR DestChanId )
  640. {
  641. CString EslCmd;
  642. EslCmd.Format(_T("bgapi originate {origination_caller_id_number=%lu}user/%lu &intercept(%s)\r\n%s: %ld"),
  643. pChan->no(), pChan->no(), DestChanId, ESL_HEADER_JOB_UUID, JobId);
  644. return m_Gateway.sendCmd(EslCmd);
  645. }
  646. /*****************************************************************
  647. **【函数名称】 listen
  648. **【函数功能】 监听
  649. **【参数】
  650. **【返回值】
  651. ****************************************************************/
  652. bool CFsProxy::listen( LONG JobId, CVirtualChan* pChan, LPCTSTR DestChanId )
  653. {
  654. CString EslCmd;
  655. EslCmd.Format(_T("bgapi originate {origination_caller_id_number=%lu}user/%lu &eavesdrop(%s)\r\n%s: %ld"),
  656. pChan->no(), pChan->no(), DestChanId, ESL_HEADER_JOB_UUID, JobId);
  657. return m_Gateway.sendCmd(EslCmd);
  658. }
  659. /*****************************************************************
  660. **【函数名称】 meeting
  661. **【函数功能】 会议
  662. **【参数】
  663. **【返回值】
  664. ****************************************************************/
  665. bool CFsProxy::meeting( LONG JobId, CString CallerNum, CString DestNum, LPCTSTR MeetingId )
  666. {
  667. CString CallString;
  668. if(!m_CallStringMaker.makeCallString(CallerNum, DestNum, CallString))
  669. return false;
  670. CString EslCmd;
  671. EslCmd.Format(_T("bgapi originate {origination_caller_id_number=%s,%s=%ld}%s %s XML %s\r\n%s: %ld"),
  672. CallerNum, ESL_VAR_OP_INSTANCE, JobId, CallString, MeetingId, CConfig::meetingContext(), ESL_HEADER_JOB_UUID, JobId);
  673. return m_Gateway.sendCmd(EslCmd);
  674. }
  675. /*****************************************************************
  676. **【函数名称】 muteOn
  677. **【函数功能】 静音
  678. **【参数】
  679. **【返回值】
  680. ****************************************************************/
  681. bool CFsProxy::muteOn( LONG JobId, CVirtualChan* pChan )
  682. {
  683. CString EslCmd;
  684. EslCmd.Format(_T("bgapi uuid_audio %s start write mute -4\r\n%s: %ld"), pChan->chanId(), ESL_HEADER_JOB_UUID, JobId);
  685. return m_Gateway.sendCmd(EslCmd);
  686. }
  687. /*****************************************************************
  688. **【函数名称】 muteOff
  689. **【函数功能】 取消静音
  690. **【参数】
  691. **【返回值】
  692. ****************************************************************/
  693. bool CFsProxy::muteOff( LONG JobId, CVirtualChan* pChan )
  694. {
  695. CString EslCmd;
  696. EslCmd.Format(_T("bgapi uuid_audio %s stop write mute -4\r\n%s: %ld"), pChan->chanId(), ESL_HEADER_JOB_UUID, JobId);
  697. return m_Gateway.sendCmd(EslCmd);
  698. }
  699. /*****************************************************************
  700. **【函数名称】 holdon
  701. **【函数功能】 保持
  702. **【参数】
  703. **【返回值】
  704. ****************************************************************/
  705. bool CFsProxy::holdon( LONG JobId, CVirtualChan* pChan )
  706. {
  707. CString EslCmd;
  708. EslCmd.Format(_T("bgapi uuid_hold %s\r\n%s: %ld"), pChan->chanId(), ESL_HEADER_JOB_UUID, JobId);
  709. return m_Gateway.sendCmd(EslCmd);
  710. }
  711. /*****************************************************************
  712. **【函数名称】 takeBack
  713. **【函数功能】 接回
  714. **【参数】
  715. **【返回值】
  716. ****************************************************************/
  717. bool CFsProxy::takeBack( LONG JobId, CVirtualChan* pChan )
  718. {
  719. CString EslCmd;
  720. EslCmd.Format(_T("bgapi uuid_hold off %s\r\n%s: %ld"), pChan->chanId(), ESL_HEADER_JOB_UUID, JobId);
  721. return m_Gateway.sendCmd(EslCmd);
  722. }
  723. /*****************************************************************
  724. **【函数名称】 record
  725. **【函数功能】 录音
  726. **【参数】
  727. **【返回值】
  728. ****************************************************************/
  729. bool CFsProxy::record( LONG JobId, CVirtualChan* pChan, LPCTSTR RcdFile )
  730. {
  731. CString EslCmd;
  732. EslCmd.Format(_T("bgapi uuid_record %s start %s\r\n%s: %ld"), pChan->chanId(), RcdFile, ESL_HEADER_JOB_UUID, JobId);
  733. return m_Gateway.sendCmd(EslCmd);
  734. }
  735. /*****************************************************************
  736. **【函数名称】 transfer
  737. **【函数功能】 呼叫转移
  738. **【参数】
  739. **【返回值】
  740. ****************************************************************/
  741. bool CFsProxy::transfer( LONG JobId, CVirtualChan* pChan, LPCTSTR DestNum )
  742. {
  743. CString EslCmd;
  744. EslCmd.Format(_T("bgapi uuid_transfer %s %s xml %s\r\n%s: %ld"), pChan->chanId(), DestNum, CConfig::extContext(), ESL_HEADER_JOB_UUID, JobId);
  745. return m_Gateway.sendCmd(EslCmd);
  746. }
  747. /*****************************************************************
  748. **【函数名称】 transfer2Context
  749. **【函数功能】 转移通道至其它Context
  750. **【参数】
  751. **【返回值】
  752. ****************************************************************/
  753. bool CFsProxy::transfer2Context( LONG JobId, LPCTSTR DestChanId, LPCTSTR Exten, LPCTSTR Context, bool BothSide /*= false*/ )
  754. {
  755. CString EslCmd;
  756. if(BothSide)
  757. EslCmd.Format(_T("bgapi uuid_transfer %s -both %s xml %s\r\n%s: %ld"), DestChanId, Exten, Context, ESL_HEADER_JOB_UUID, JobId);
  758. else
  759. EslCmd.Format(_T("bgapi uuid_transfer %s %s xml %s\r\n%s: %ld"), DestChanId, Exten, Context, ESL_HEADER_JOB_UUID, JobId);
  760. return m_Gateway.sendCmd(EslCmd);
  761. }
  762. /*****************************************************************
  763. **【函数名称】 cancel
  764. **【函数功能】 取消当前执行的应用
  765. **【参数】
  766. **【返回值】
  767. ****************************************************************/
  768. bool CFsProxy::cancel( CChanTrunk* pChan )
  769. {
  770. ASSERT(pChan != NULL);
  771. return m_Gateway.Execte2(ESL_APP_BREAK,NULL,pChan->chanId());
  772. }
  773. /*****************************************************************
  774. **【函数名称】 hangup
  775. **【函数功能】 挂机
  776. **【参数】
  777. **【返回值】
  778. ****************************************************************/
  779. bool CFsProxy::hangup( CChanTrunk* pChan )
  780. {
  781. ASSERT(pChan != NULL);
  782. return m_Gateway.execute(pChan->m_pEslHandle,ESL_APP_HANGUP,NULL);
  783. }
  784. /*****************************************************************
  785. **【函数名称】 leaveWord
  786. **【函数功能】 留言
  787. **【参数】
  788. **【返回值】
  789. ****************************************************************/
  790. bool CFsProxy::leaveWord( CChanTrunk* pChan, LPCTSTR FileName, UINT LimitTime, TCHAR FinishKey )
  791. {
  792. ASSERT(pChan != NULL);
  793. CString Param;
  794. Param.Format(_T("playback_terminators=%c"), FinishKey);
  795. m_Gateway.Execte2(ESL_APP_SET,Param,pChan->chanId());
  796. Param.Format(_T("%s %lu"), FileName, LimitTime);
  797. return m_Gateway.Execte2(ESL_APP_LEAVEWORD,Param,pChan->chanId());
  798. }
  799. /*****************************************************************
  800. **【函数名称】 playAndDtmf
  801. **【函数功能】 放音收按键
  802. **【参数】
  803. **【返回值】
  804. ****************************************************************/
  805. bool CFsProxy::playAndDtmf( CChanTrunk* pChan, PlayVoiceContent* pPlayContent )
  806. {
  807. ASSERT(pChan != NULL);
  808. ASSERT(pPlayContent != NULL);
  809. if(pChan==NULL||pPlayContent==NULL) return false;
  810. TCHAR AudioFile[MAX_PATH] = { 0 };
  811. // 如果使用了TTS,进行TTS转换
  812. switch(pPlayContent->nTts)
  813. {
  814. default:
  815. case PLAY_CONTENT_AUDIO: // 不使用TTS
  816. lstrcpy(AudioFile, pPlayContent->szFileName);
  817. break;
  818. case PLAY_CONTENT_TTS_STR: // TTS文本
  819. {
  820. ITtsInterface::getInstance().setTTSParam(pPlayContent->nTtsDigitMode, pPlayContent->nTtsSpeed, pPlayContent->nTtsVolume);
  821. if(!ITtsInterface::getInstance().string2Audio(pPlayContent->szFileName, AudioFile, MAX_PATH))
  822. {
  823. LOGGER(LOG_LEVEL_WARNING, _T("{FsProxy}: 中继通道[%lu]放音时TTS文本转换失败"), pChan->no());
  824. return false;
  825. }
  826. }
  827. break;
  828. case PLAY_CONTENT_TTS_FILE: // TTS文件
  829. {
  830. ITtsInterface::getInstance().setTTSParam(pPlayContent->nTtsDigitMode, pPlayContent->nTtsSpeed, pPlayContent->nTtsVolume);
  831. if(!ITtsInterface::getInstance().file2Audio(pPlayContent->szFileName, AudioFile, MAX_PATH))
  832. {
  833. LOGGER(LOG_LEVEL_WARNING, _T("{FsProxy}: 中继通道[%lu]放音时TTS文件转换失败, File = %s"), pChan->no(), pPlayContent->szFileName);
  834. return false;
  835. }
  836. }
  837. break;
  838. }
  839. CString Param;
  840. if(pPlayContent->nModel == PVM_PLAY_ONLY && pPlayContent->cDtmfEnd == 0)
  841. {
  842. Param.Format(_T("playback_terminators=none"));
  843. m_Gateway.Execte2(ESL_APP_SET,Param,pChan->chanId());
  844. //m_Gateway.execute(pChan->m_pEslHandle,ESL_APP_SET,Param);
  845. Param.Format(_T("%s"), AudioFile);
  846. return m_Gateway.Execte2(ESL_APP_PLAY,Param,pChan->chanId());
  847. //return m_Gateway.execute(pChan->m_pEslHandle,ESL_APP_PLAY,Param);
  848. }
  849. else
  850. {
  851. Param.Format(_T("%lu %lu 1 %lu %c %s silence_stream://250 %s"), pPlayContent->nDtmfCount, pPlayContent->nDtmfCount,
  852. pPlayContent->nDtmfCount * pPlayContent->nDtmfPeriod * 1000, pPlayContent->cDtmfEnd, AudioFile, ESL_VAR_DTMF_KEY);
  853. return m_Gateway.Execte2(ESL_APP_PLAY_DTMF,Param,pChan->chanId());
  854. //return m_Gateway.execute(pChan->m_pEslHandle,ESL_APP_PLAY_DTMF,Param);
  855. }
  856. }
  857. /*****************************************************************
  858. **【函数名称】 bridge
  859. **【函数功能】 桥接通道
  860. **【参数】
  861. **【返回值】
  862. ****************************************************************/
  863. bool CFsProxy::bridge( CChanTrunk* pChan, CString CallerNum, CString CalleeNum )
  864. {
  865. CString CallString;
  866. if(!m_CallStringMaker.makeCallString(CallerNum, CalleeNum, CallString))
  867. return false;
  868. CString Param;
  869. Param.Format(_T("ringback=${us-ring}"));
  870. m_Gateway.Execte2(ESL_APP_SET,Param,pChan->chanId());
  871. return m_Gateway.Execte2(ESL_APP_BRIDGE,CallString,pChan->chanId());
  872. }