修改三方通话功能,在发起三方通话时,先保持住主叫,然后再拉回主叫到会议

SpanChannel.cpp 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. #include "StdAfx.h"
  2. #include "SpanChannel.h"
  3. #include "DspChannel.h"
  4. #include "Config.h"
  5. #include "VoipChannel.h"
  6. #include "MC.h"
  7. #include "SessionShell.h"
  8. CSpanChannel::CSpanChannel(DEV_RES_CH_TYPE ChannelNo, DEV_RES_NO_TYPE SpanNo, DEV_RES_NO_TYPE NodeNo, DEV_RES_NO_TYPE BoardNo)
  9. : CChannelResource(DEV_RES_TYPE_TRUNK, NodeNo, BoardNo, SpanNo, ChannelNo), m_GcHandle(DEV_HANDLE_INVALID), m_CallId(0), m_IsBlocked(false), m_Mixer(*this)
  10. {
  11. }
  12. CSpanChannel::~CSpanChannel(void)
  13. {
  14. close();
  15. }
  16. /*****************************************************************
  17. **【函数名称】 __freeBindingChan
  18. **【函数功能】 释放绑定的通道
  19. **【参数】
  20. **【返回值】
  21. ****************************************************************/
  22. void CSpanChannel::__freeBindingChan( void )
  23. {
  24. m_Mixer.release();
  25. }
  26. /*****************************************************************
  27. **【函数名称】 __clearCall
  28. **【函数功能】 清除呼叫
  29. **【参数】
  30. **【返回值】
  31. ****************************************************************/
  32. bool CSpanChannel::__clearCall( int Cause /*= GC_NORMAL_CLEARING*/ )
  33. {
  34. if(m_CallId == 0)
  35. return false;
  36. m_State = GCST_DROPCALLING;
  37. if(m_MeetingInfo.MeetingId != MEETING_ID_INVALID)
  38. CMC::GetInstance().meetingRemove(this, m_MeetingInfo);
  39. __freeBindingChan();
  40. if(ISX_gc_DropCall(m_CallId, Cause, EV_ASYNC) == 0)
  41. {
  42. m_CallId = 0;
  43. return true;
  44. }
  45. else return false;
  46. }
  47. /*****************************************************************
  48. **【函数名称】 __onOffered
  49. **【函数功能】 处理来电呼叫
  50. **【参数】
  51. **【返回值】
  52. ****************************************************************/
  53. void CSpanChannel::__onOffered( METAEVENT* pMetaEvent )
  54. {
  55. if(m_State != GCST_NULL)
  56. {
  57. ISX_gc_DropCall(pMetaEvent->crn, GC_CALL_REJECTED);
  58. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]检测到呼叫, 但通道状态异常, 呼叫将忽略"),
  59. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  60. return;
  61. }
  62. m_State = GCST_OFFERED;
  63. m_CallId = pMetaEvent->crn;
  64. GCPARAMEX_MAKECALL* pMakeCallEx = (GCPARAMEX_MAKECALL*)pMetaEvent->evtdatap;
  65. ASSERT(pMakeCallEx != NULL);
  66. // 获取主、被叫号码
  67. CHAR DNIZ[GC_ADDRSIZE] = { 0 };
  68. CHAR ANI[GC_ADDRSIZE] = { 0 };
  69. ISX_gc_GetCallInfo(m_CallId, DESTINATION_ADDRESS, DNIZ);
  70. ISX_gc_GetCallInfo(m_CallId, ORIGINATION_ADDRESS, ANI);
  71. m_CallerNum = ANI;
  72. m_CalleeNum = DNIZ;
  73. CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_ALERTING, m_CallerNum, m_CalleeNum);
  74. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]检测到来电, Caller = %s, Callee = %s"),
  75. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, ANI, DNIZ);
  76. if(ISX_gc_AcceptCall(m_CallId, 0, EV_ASYNC, NULL) != 0)
  77. {
  78. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]释放, 应答中继来电失败, Caller = %s, Callee = %s"),
  79. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, ANI, DNIZ);
  80. __clearCall(GC_CALL_REJECTED);
  81. }
  82. CMC::GetInstance().onDevResState(m_Id);
  83. }
  84. /*****************************************************************
  85. **【函数名称】 __onAccept
  86. **【函数功能】 接收远端呼叫
  87. **【参数】
  88. **【返回值】
  89. ****************************************************************/
  90. void CSpanChannel::__onAccept( void )
  91. {
  92. m_State = GCST_ACCEPTED;
  93. if(ISX_gc_AnswerCall(m_CallId, 0, EV_ASYNC, NULL) != 0)
  94. {
  95. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]释放, 应答中继来电失败, Caller = %s, Callee = %s"),
  96. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
  97. __clearCall(GC_CALL_REJECTED);
  98. }
  99. }
  100. /*****************************************************************
  101. **【函数名称】 __onAlerting
  102. **【函数功能】 处理外呼远端振铃
  103. **【参数】
  104. **【返回值】
  105. ****************************************************************/
  106. void CSpanChannel::__onAlerting( METAEVENT* pMetaEvent )
  107. {
  108. if(m_State == GCST_ALERTING || m_State == GCST_DROPCALLING)
  109. return;
  110. m_State = GCST_ALERTING;
  111. CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_RING_BACK, m_CallerNum, m_CalleeNum);
  112. CMC::GetInstance().onDevResState(m_Id);
  113. }
  114. /*****************************************************************
  115. **【函数名称】 __onAnswered
  116. **【函数功能】 处理应答成功
  117. **【参数】
  118. **【返回值】
  119. ****************************************************************/
  120. void CSpanChannel::__onAnswered( void )
  121. {
  122. if(m_State == GCST_DROPCALLING)
  123. return;
  124. m_State = GCST_CONNECTED;
  125. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]应答成功, 开始通话, Caller = %s, Callee = %s,SessionCode=%lu"),
  126. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum, m_SessionCode);
  127. CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_TALKING, m_CallerNum, m_CalleeNum);
  128. CMC::GetInstance().onDevResState(m_Id);
  129. }
  130. /*****************************************************************
  131. **【函数名称】 __onConnected
  132. **【函数功能】 呼叫成功处理函数
  133. **【参数】
  134. **【返回值】
  135. ****************************************************************/
  136. void CSpanChannel::__onConnected( void )
  137. {
  138. if(m_State == GCST_DROPCALLING)
  139. return;
  140. m_State = GCST_CONNECTED;
  141. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]开始通话, Caller = %s, Callee = %s"),
  142. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
  143. CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_TALKING, m_CallerNum, m_CalleeNum);
  144. CMC::GetInstance().onDevResState(m_Id);
  145. }
  146. /*****************************************************************
  147. **【函数名称】 __onProgressing
  148. **【函数功能】 呼叫进展处理函数
  149. **【参数】
  150. **【返回值】
  151. ****************************************************************/
  152. void CSpanChannel::__onProgressing( void )
  153. {
  154. if(m_State == GCST_PROGRESS || m_State == GCST_DROPCALLING)
  155. return;
  156. m_State = GCST_PROGRESS;
  157. CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_PROGRESSING, m_CallerNum, m_CalleeNum);
  158. }
  159. /*****************************************************************
  160. **【函数名称】 __onTaskFail
  161. **【函数功能】 呼叫失败处理函数
  162. **【参数】
  163. **【返回值】
  164. ****************************************************************/
  165. void CSpanChannel::__onTaskFail( void )
  166. {
  167. switch(ISX_sr_getevtopertype())
  168. {
  169. case OPER_ANSWERCALL:
  170. {
  171. ASSERT(FALSE);
  172. __clearCall();
  173. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]应答来电失败, Caller = %s, Callee = %s"),
  174. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
  175. }
  176. break;
  177. case OPER_MAKECALL:
  178. {
  179. ASSERT(FALSE);
  180. __clearCall();
  181. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]外呼失败, Caller = %s, Callee = %s"),
  182. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
  183. }
  184. break;
  185. case OPER_DROPCALL:
  186. {
  187. ASSERT(FALSE);
  188. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]挂机失败, 已强制释放资源, Caller = %s, Callee = %s"),
  189. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
  190. __onCallFinished();
  191. }
  192. break;
  193. }
  194. }
  195. /*****************************************************************
  196. **【函数名称】 __onCallFinished
  197. **【函数功能】 呼叫结束处理函数
  198. **【参数】
  199. **【返回值】
  200. ****************************************************************/
  201. void CSpanChannel::__onCallFinished( void )
  202. {
  203. m_State = GCST_NULL;
  204. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]空闲"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  205. CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_FREE, NULL, NULL);
  206. reset();
  207. m_CallId = 0;
  208. CMC::GetInstance().onDevResState(m_Id);
  209. }
  210. /*****************************************************************
  211. **【函数名称】 __onCallDisconnected
  212. **【函数功能】 呼叫中断处理函数
  213. **【参数】
  214. **【返回值】
  215. ****************************************************************/
  216. void CSpanChannel::__onCallDisconnected( METAEVENT* pMetaEvent )
  217. {
  218. GCPARAMEX_DROPCALL* pDropCall = (GCPARAMEX_DROPCALL*)pMetaEvent->evtdatap;
  219. ASSERT(pDropCall != NULL);
  220. GC_INFO gcInfo;
  221. ISX_gc_ResultInfo(pMetaEvent, &gcInfo);
  222. long Reason = gcInfo.ccValue & 0xff;
  223. if(m_State != GCST_CONNECTED) // 非通话中挂机
  224. {
  225. int ErrCode;
  226. switch(Reason)
  227. {
  228. case UNASSIGNED_NUMBER:
  229. ErrCode = CALL_FAILED_CAUSE_NUM_INVALID;
  230. break;
  231. case USER_BUSY:
  232. ErrCode = CALL_FAILED_CAUSE_USER_BUSY;
  233. break;
  234. case NO_USER_RESPONDING:
  235. case NO_ANSWER_FROM_USER:
  236. ErrCode = CALL_FAILED_CAUSE_NO_ANSWER;
  237. break;
  238. case CALL_REJECTED:
  239. case NORMAL_CLEARING:
  240. ErrCode = CALL_FAILED_CAUSE_USER_HANGUP;
  241. break;
  242. case DEST_OUT_OF_ORDER:
  243. ErrCode = CALL_FAILED_CAUSE_DST_OFF;
  244. break;
  245. default:
  246. ErrCode = CALL_FAILED_CAUSE_NETWORK_ERR;
  247. break;
  248. }
  249. CSessionShell::GetInstance().onLineChannelEvent(m_Id, m_SessionCode, DEV_CH_EVT_CALL_FAILD_CAUSE, (LPCTSTR)ErrCode);
  250. }
  251. m_State = GCST_DISCONNECTED;
  252. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]检测到远端挂机, Caller = %s, Callee = %s, Cause = %d"),
  253. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum, Reason);
  254. // 远端挂机,结束通道通话
  255. __clearCall();
  256. }
  257. /*****************************************************************
  258. **【函数名称】 open
  259. **【函数功能】 打开系统资源
  260. **【参数】
  261. **【返回值】 成功true,失败false
  262. ****************************************************************/
  263. bool CSpanChannel::open( void )
  264. {
  265. ASSERT(m_GcHandle == DEV_HANDLE_INVALID);
  266. ASSERT(m_Handle == DEV_HANDLE_INVALID);
  267. // 打开DTI channel
  268. m_Handle = ISX_dt_open(m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  269. if(m_Handle == -1)
  270. {
  271. m_Handle = DEV_HANDLE_INVALID;
  272. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{SpanCh}: 数字中继通道[%d-%d-%d-%d]打开失败"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  273. return false;
  274. }
  275. if(ISX_gc_OpenEx(&m_GcHandle, m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, EV_SYNC, this) < 0)
  276. {
  277. m_GcHandle = DEV_HANDLE_INVALID;
  278. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{SpanCh}: GC通道[%d-%d-%d-%d]打开失败"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  279. return false;
  280. }
  281. if(ISX_gc_WaitCall(m_GcHandle, NULL, NULL, -1, EV_ASYNC) < 0)
  282. {
  283. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{SpanCh}: GC通道[%d-%d-%d-%d]等待呼叫失败"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  284. return false;
  285. }
  286. //LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 数字中继通道[%d-%d-%d-%d]打开成功"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  287. return true;
  288. }
  289. /*****************************************************************
  290. **【函数名称】 close
  291. **【函数功能】 关闭系统资源
  292. **【参数】
  293. **【返回值】
  294. ****************************************************************/
  295. void CSpanChannel::close( void )
  296. {
  297. if(m_GcHandle != DEV_HANDLE_INVALID)
  298. {
  299. ISX_gc_Close(m_GcHandle);
  300. m_GcHandle = DEV_HANDLE_INVALID;
  301. }
  302. if(m_Handle != DEV_HANDLE_INVALID)
  303. {
  304. ISX_dt_close(m_Handle);
  305. m_Handle = DEV_HANDLE_INVALID;
  306. }
  307. //LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 数字中继通道[%d-%d-%d-%d]关闭"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  308. }
  309. /*****************************************************************
  310. **【函数名称】 onDevEvent
  311. **【函数功能】 设备事件处理函数
  312. **【参数】
  313. **【返回值】
  314. ****************************************************************/
  315. void CSpanChannel::onDevEvent( METAEVENT* pMetaEvent )
  316. {
  317. ASSERT(pMetaEvent != NULL);
  318. switch(pMetaEvent->evttype)
  319. {
  320. case GCEV_OFFERED:
  321. __onOffered(pMetaEvent);
  322. break;
  323. case GCEV_DIALING:
  324. {
  325. m_State = GCST_DIALING;
  326. CMC::GetInstance().onDevResState(m_Id);
  327. }
  328. break;
  329. case GCEV_ACCEPT:
  330. __onAccept();
  331. break;
  332. case GCEV_ALERTING:
  333. __onAlerting(pMetaEvent);
  334. break;
  335. case GCEV_CONNECTED:
  336. __onConnected();
  337. break;
  338. case GCEV_ANSWERED:
  339. __onAnswered();
  340. break;
  341. case GCEV_PROGRESSING:
  342. __onProgressing();
  343. break;
  344. case GCEV_DROPCALL:
  345. __onCallFinished();
  346. break;
  347. case GCEV_DISCONNECTED:
  348. __onCallDisconnected(pMetaEvent);
  349. break;
  350. case GCEV_TASKFAIL:
  351. __onTaskFail();
  352. break;
  353. case GCEV_BLOCKED:
  354. {
  355. m_IsBlocked = true;
  356. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]阻塞"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  357. }
  358. break;
  359. case GCEV_UNBLOCKED:
  360. {
  361. m_IsBlocked = false;
  362. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]解除阻塞"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  363. }
  364. break;
  365. default:
  366. break;
  367. }
  368. }
  369. /*****************************************************************
  370. **【函数名称】 makeCall
  371. **【函数功能】 呼叫
  372. **【参数】
  373. **【返回值】
  374. ****************************************************************/
  375. bool CSpanChannel::makeCall( LPCTSTR Callee, LPCTSTR Caller, int AccountId )
  376. {
  377. ASSERT(Callee != NULL);
  378. ASSERT(Caller != NULL);
  379. m_CallerNum = Caller;
  380. m_CalleeNum = Callee;
  381. if(m_State != GCST_NULL)
  382. {
  383. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行呼叫请求失败, 通道状态非空闲, caller = %s, callee = %s"),
  384. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
  385. return false;
  386. }
  387. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行呼叫请求, caller = %s, callee = %s"),
  388. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
  389. GCPARAMEX_MAKECALL MakeCallEx;
  390. MakeCallEx.Protocol = eGCPro_PRI;
  391. ISX_sr_default(PARMID_PRI_SETUP, &(MakeCallEx.u.PRISetup));
  392. MakeCallEx.u.PRISetup.CallingNum.ucPlan = 0x01; // ISDN方案
  393. MakeCallEx.u.PRISetup.CallingNum.ucType = 0x04; // 用户号码
  394. MakeCallEx.u.PRISetup.CallingNum.ucSI = 0x01; // 主叫号码掩蔽显示: 0x01:用户提供,检验并传送
  395. lstrcpy((LPTSTR)MakeCallEx.u.PRISetup.CallingNum.Num, Caller);
  396. MakeCallEx.u.PRISetup.CalledNum.ucPlan = 0x01; // ISDN方案
  397. MakeCallEx.u.PRISetup.CalledNum.ucType = 0x04; // 用户号码
  398. lstrcpy((LPTSTR)MakeCallEx.u.PRISetup.CalledNum.Num, Callee);
  399. if (ISX_gc_MakeCall(m_GcHandle, &m_CallId, NULL, NULL, -1, EV_ASYNC, &MakeCallEx) < 0)
  400. {
  401. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]呼出失败, Reason = %s"),
  402. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, ISX_ATDV_ERRMSGP(m_GcHandle));
  403. return false;
  404. }
  405. CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_DIALING, m_CallerNum, m_CalleeNum);
  406. #ifdef _DEBUG
  407. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]拨号中, caller = %s, callee = %s"),
  408. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, Caller, Callee);
  409. #endif
  410. return true;
  411. }
  412. /*****************************************************************
  413. **【函数名称】 answer
  414. **【函数功能】 应答来电
  415. **【参数】
  416. **【返回值】
  417. ****************************************************************/
  418. bool CSpanChannel::answer( void )
  419. {
  420. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行应答请求, caller = %s, callee = %s"),
  421. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
  422. if(m_State == GCST_OFFERED)
  423. return ISX_gc_AcceptCall(m_CallId, 0, EV_ASYNC) == 0;
  424. else
  425. return false;
  426. }
  427. /*****************************************************************
  428. **【函数名称】 dropCall
  429. **【函数功能】 挂机
  430. **【参数】
  431. **【返回值】
  432. ****************************************************************/
  433. bool CSpanChannel::dropCall( bool IsPassive/* = false*/ )
  434. {
  435. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行挂机请求, caller = %s, callee = %s"),
  436. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
  437. return __clearCall(GC_NORMAL_CLEARING);
  438. }
  439. /*****************************************************************
  440. **【函数名称】 playVoice
  441. **【函数功能】 放音
  442. **【参数】
  443. **【返回值】
  444. ****************************************************************/
  445. bool CSpanChannel::playSound( PlayVoiceContent* pContent )
  446. {
  447. ASSERT(pContent != NULL);
  448. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行放音请求, AudioFile = %s,caller = %s, callee = %s"),
  449. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, pContent->szFileName,m_CallerNum, m_CalleeNum);
  450. if(m_State != GCST_CONNECTED)
  451. {
  452. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]放音失败, 通道未处于连接状态, AudioFile = %s"),
  453. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, pContent->szFileName);
  454. return false;
  455. }
  456. return m_Mixer.playSound(pContent);
  457. }
  458. /*****************************************************************
  459. **【函数名称】 playTone
  460. **【函数功能】 放Tone音
  461. **【参数】
  462. **【返回值】
  463. ****************************************************************/
  464. bool CSpanChannel::playTone( int Type )
  465. {
  466. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行Tone音请求, Tone = %d"),
  467. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, Type);
  468. return m_Mixer.playTone(Type);
  469. }
  470. /*****************************************************************
  471. **【函数名称】 playStop
  472. **【函数功能】 停止放音
  473. **【参数】
  474. **【返回值】
  475. ****************************************************************/
  476. bool CSpanChannel::playStop( void )
  477. {
  478. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行停止放音请求"),
  479. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  480. return m_Mixer.playStop();
  481. }
  482. /*****************************************************************
  483. **【函数名称】 startRecord
  484. **【函数功能】 开始录音
  485. **【参数】
  486. **【返回值】
  487. ****************************************************************/
  488. bool CSpanChannel::startRecord( RecordContent* pContent )
  489. {
  490. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行录音请求"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  491. if(m_State == GCST_NULL)
  492. {
  493. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]录音失败, 通道状态空闲"),
  494. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  495. return false;
  496. }
  497. return m_Mixer.startRecord(pContent);
  498. }
  499. /*****************************************************************
  500. **【函数名称】 stopRecord
  501. **【函数功能】 停止录音
  502. **【参数】
  503. **【返回值】
  504. ****************************************************************/
  505. bool CSpanChannel::stopRecord( void )
  506. {
  507. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行停止录音请求"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  508. return m_Mixer.stopRecord();
  509. }
  510. /*****************************************************************
  511. **【函数名称】 monitor
  512. **【函数功能】 监听
  513. **【参数】
  514. **【返回值】
  515. ****************************************************************/
  516. bool CSpanChannel::monitor( COneLeg* pTalker, bool IsStop )
  517. {
  518. ASSERT(pTalker != NULL);
  519. if(IsStop)
  520. {
  521. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行取消监听请求"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  522. return pTalker->cancelMonitor(this);
  523. }
  524. else
  525. {
  526. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行监听请求"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  527. if(m_State != GCST_CONNECTED)
  528. {
  529. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]监听失败, 通道未处于连接状态"),
  530. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  531. return false;
  532. }
  533. return pTalker->allowMonitor(this);
  534. }
  535. }
  536. /*****************************************************************
  537. **【函数名称】 allowMonitor
  538. **【函数功能】 允许监听
  539. **【参数】
  540. **【返回值】
  541. ****************************************************************/
  542. bool CSpanChannel::allowMonitor( COneLeg* pMonitorParty )
  543. {
  544. if(m_State != GCST_CONNECTED)
  545. {
  546. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]接受监听失败, 通道未处于连接状态"),
  547. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  548. return false;
  549. }
  550. if(!m_Mixer.allowedMonitor())
  551. {
  552. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]接受监听失败, 无空闲混音发端可连接"),
  553. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo);
  554. return false;
  555. }
  556. return m_Mixer.setupMonitor(pMonitorParty->routeChannel());
  557. }
  558. /*****************************************************************
  559. **【函数名称】 cancelMonitor
  560. **【函数功能】 取消监听
  561. **【参数】
  562. **【返回值】
  563. ****************************************************************/
  564. bool CSpanChannel::cancelMonitor( COneLeg* pMonitorParty )
  565. {
  566. ASSERT(pMonitorParty != NULL);
  567. return m_Mixer.undoMonitor(pMonitorParty->routeChannel());
  568. }
  569. /*****************************************************************
  570. **【函数名称】 onPlayEnd
  571. **【函数功能】 放音结束处理函数
  572. **【参数】
  573. **【返回值】
  574. ****************************************************************/
  575. void CSpanChannel::onPlayEnd( LPCTSTR lpDtmf )
  576. {
  577. // 通知呼叫控制层放音结束事件
  578. CSessionShell::GetInstance().onLineChannelEvent(m_Id, m_SessionCode, DEV_CH_EVT_PLAY_END, lpDtmf);
  579. }
  580. /*****************************************************************
  581. **【函数名称】 onRecEnd
  582. **【函数功能】 录音结束处理函数
  583. **【参数】
  584. **【返回值】
  585. ****************************************************************/
  586. void CSpanChannel::onRecEnd( UINT TaskId )
  587. {
  588. // 通知呼叫控制层录音结束事件
  589. CString strTmp;
  590. strTmp.Format(_T("%lu"), TaskId);
  591. CSessionShell::GetInstance().onLineChannelEvent(m_Id, m_SessionCode, DEV_CH_EVT_REC_END, strTmp);
  592. }
  593. /*****************************************************************
  594. **【函数名称】 onToneEnd
  595. **【函数功能】 Tone结束处理函数
  596. **【参数】
  597. **【返回值】
  598. ****************************************************************/
  599. void CSpanChannel::onToneEnd( int ToneTp )
  600. {
  601. ASSERT(FALSE);
  602. }
  603. /*****************************************************************
  604. **【函数名称】 onFaxEnd
  605. **【函数功能】 传真结束处理函数
  606. **【参数】
  607. **【返回值】
  608. ****************************************************************/
  609. void CSpanChannel::onFaxEnd( bool IsSuccess, LPCTSTR Reason )
  610. {
  611. CSessionShell::GetInstance().onLineChannelEvent(m_Id, m_SessionCode, IsSuccess ? DEV_CH_EVT_FAX_OK : DEV_CH_EVT_FAX_FAILED, Reason);
  612. __clearCall(GC_NORMAL_CLEARING);
  613. }
  614. /*****************************************************************
  615. **【函数名称】 state
  616. **【函数功能】 返回状态字符串
  617. **【参数】
  618. **【返回值】
  619. ****************************************************************/
  620. LPCTSTR CSpanChannel::getStateStr( void ) const
  621. {
  622. if(m_IsBlocked)
  623. return _T("block");
  624. switch(m_State)
  625. {
  626. case GCST_NULL: return _T("free");
  627. case GCST_DIALING: return _T("calling");
  628. case GCST_OFFERED: return _T("alerting");
  629. case GCST_ALERTING: return _T("ringback");
  630. case GCST_CONNECTED: return _T("talking");
  631. default: return _T("unknown");
  632. }
  633. }
  634. /*****************************************************************
  635. **【函数名称】 reply
  636. **【函数功能】 响应呼叫
  637. **【参数】
  638. **【返回值】
  639. ****************************************************************/
  640. bool CSpanChannel::reply( void )
  641. {
  642. if(m_State == GCST_CONNECTED)
  643. {
  644. if(!playTone(CHANNEL_TONE_RINGBACK)) // 对a-leg放振铃音
  645. {
  646. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]播放回铃音失败, Caller = %s, Callee = %s"),
  647. m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum);
  648. }
  649. }
  650. return true;
  651. }
  652. /*****************************************************************
  653. **【函数名称】 accept
  654. **【函数功能】 应答呼叫
  655. **【参数】
  656. **【返回值】
  657. ****************************************************************/
  658. bool CSpanChannel::accept( void )
  659. {
  660. if(m_State == GCST_CONNECTED)
  661. {
  662. // 停止A-Leg的振铃音
  663. playTone(CHANNEL_TONE_NULL);
  664. }
  665. return true;
  666. }