UniMedia 6S級電話語音中間件典型應用-電話QQ 
                    [附源碼]
                  
                   2009/05/11
                  1.應用場景
                    電信增值應用?蛻舸螂娫掃M入系統(tǒng),按鍵選擇聊天室,或者自動查找匹配的用戶,進行一對一的聊天。
                  
                  2.源碼片段
                  
                    假定呼入電話,聽到提示音,按鍵為1的為等待聊天用戶,電話呼入按鍵為2的為主動尋找等待聊天的用戶
                  
                  //全局變量定義
                  
                  SCPMANAGER g_SCPManager
                  CALL g_TheCall
                  int g_iTaskID
                  
                  sub main(LIST& cpl)
                  {
                  int iCallID, iRet
                  
                  //注冊系統(tǒng)錯誤處理函數(shù)
                  EventMap(INF_SYS_ERROR, OnSysError, 0)
                  //注冊掛機通知處理函數(shù)
                  EventMap(INF_CTI_ONHOOK, OnCallEndInform, 0)
                  //注冊被路由通知處理函數(shù)
                  EventMap(INF_CTI_ROUTED, OnRoutedInform, 0)
                  //注冊取消路由通知處理函數(shù)
                  EventMap(INF_CTI_UNROUTED, OnUnroutedInform, 0)
                  //注冊異步結束通知處理函數(shù)
                  EventMap(INF_SYS_ASYNCFINISHED, OnAsyncFinishedInform, 0)
                  
                  //在BOOT進程啟動該進程時,參數(shù)是按照CALLID、ANO、BNO,UUD順序先后存放在參數(shù)列表cpl中
                  //根據(jù)業(yè)務需要取出參數(shù)值
                  
                  //獲得命令行參數(shù)的callid
                  cpl.GetItem(0, iCallID, iRet)
                  Log(DBG, "Call Income: CallID=", iCallID)
                  
                  //根據(jù)對象ID獲得當前Call對象
                  g_SCPManager.FindCallByID(iCallID, g_TheCall, iRet)
                  //設置Call對象的業(yè)務處理進程ID為當前進程
                  g_TheCall.AttachCurrentProcess(iRet)
                  //應答CALL
                  g_TheCall.Answer(iRet)
                  
                  
                  //來話聊天業(yè)務處理過程:
                  //來話應答成功后,首先進行放音收碼,在分析用戶的按鍵
                  // 如果用戶按鍵為"1",則假定用戶為等候交談的客戶,設置業(yè)務參數(shù)名值對為("Number"、"Waiting"),用戶聽音樂等待其它用戶的交談申請
                  // 如果用戶按鍵為"2",則假定用戶為主動尋找交談的客戶,則從業(yè)務參數(shù)名值對為("Number"、"Waiting")的等待用戶中查找一個進行交談,并把等待呼叫的名值對該為("Number"、"Connecting")
                  // 如果用戶按鍵為其它,則在循環(huán)播放收碼
                  while(true)
                  {
                  //同步循環(huán)放音收碼
                  string sDigits,sTermChar
                  g_TheCall.PlayReceiveDTMF(true, "welcome.vox", 1, "*", sTermChar, 
                  sDigits, -1, iRet)
                  
                  switch(sDigits)
                  {
                  case("1")
                  //等待被連接
                  Log(DBG, "Playing wait music to Income Call(", iCallID, ").")
                  g_TheCall.Play(true, true, "musichold.vox", g_iTaskID, iRet)
                  //設置呼叫對象的業(yè)務名值對
                  g_TheCall.SetParam("Number", sDigits, iRet)
                  //注冊被連接事件函數(shù)
                  EventMap(INF_CTI_ROUTED, OnRoutedInform, 1)
                  
                  //無限等待(直到用戶主動掛機)
                  Wait(-1)
                  break
                  
                  case("2")
                  //設置呼叫對象為查找用戶的標志
                  g_TheCall.SetParam("Number", sDigits, iRet)
                  //查找空閑等候用戶,主動進行連接
                  Log(DBG, "Matching user(", iCallID, ")...")
                  
                  //查找交談對象并進行連接操作,實現(xiàn)通話交流
                  MatchWaitingUser(g_TheCall)
                  
                  //無限等待(直到用戶主動掛機)
                  Wait(-1)
                  break
                  
                  default
                  Log(DBG, "用戶按鍵其它碼,需重新收碼,Digits=", sDigits)
                  break
                  }//end of Switch
                  }// end of While
                  
                  Log(DBG, "Finished. Bye.")
                  }
                  
                  //查找函數(shù)的業(yè)務處理過程:
                  //首先給主動查找用戶播放等待提示語音
                  //然后根據(jù)呼叫對象的名值對從全局呼叫對象實例管理器中查找等待呼叫
                  //如果成功找到,則停止當前呼叫的提示語音,主動進行連接通話操作
                  //如果沒有找到,則等待1秒鐘在循環(huán)查找
                  sub MatchWaitingUser(CALL& call)
                  {
                  int iRet,iTaskID
                  
                  //異步循環(huán)放音
                  call.Play(true, true, "waiting.vox", iTaskID, iRet)
                  
                  
                  while(true)
                  {
                  CALL callWait
                  //根據(jù)名值對查找等待呼叫對象
                  g_SCPManager.FindCallByParam("Number", "1", callWait, iRet)
                  if (iRet == RET_SUCC)
                  {
                  //重新設置等待連接呼叫的名值對
                  callWait.SetParam("Number","Connecting",iRet)
                  
                  //找到等待用戶,停止當前呼叫的語音提示
                  call.StopOP(iTaskID, iRet)
                  
                  //主動連接兩個CALL
                  call.ConnectCall(callWait, iRet)
                  break
                  }
                  else
                  {
                  //沒有找到,1000毫秒后繼續(xù)尋找
                  Wait(1000)
                  }
                  }//end of while
                  }
                  
                  //Chat工程中所有事件處理函數(shù)實現(xiàn)
                  
                  //錯誤處理函數(shù)
                  sub OnSysError(int tag)
                  {
                  Log(ERR, "System error: ", __LASTERRSTR__)
                  }
                  
                  //掛機通知處理函數(shù)
                  sub OnCallEndInform(int tag, CALL& call)
                  {
                  Log(INF, "OnHooked. CallID=", call.CallID)
                  Log(INF, "Exit...")
                  Exit("掛機退出")
                  }
                  
                  //被路由通知處理函數(shù)
                  sub OnRoutedInform(int tag, CALL& call1, CALL& call2)
                  {
                  Log(INF, "Routed. CallID1=", call1.CallID, " CallID2=", call2.CallID)
                  
                  int iRet
                  string paraValue
                  //在連接前已經(jīng)把等待呼叫的名值對的值由1改為Connecting
                  call1.GetParam("Number", paraValue, iRet)
                  if (paraValue == "Connecting")
                  {
                  //call1如果是被連接的等待用戶,需要停止它已經(jīng)在播放的等候音樂
                  call1.StopOP(g_iTaskID, iRet)
                  }
                  }
                  
                  //取消路由通知處理函數(shù)
                  sub OnUnroutedInform(int tag, CALL& call1, CALL& call2)
                  {
                  Log(INF, "Unrouted. CallID1=", call1.CallID, " CallID2=", call2.CallID)
                  }
                  
                  //異步結束通知處理函數(shù)
                  sub OnAsyncFinishedInform(int tag, CALL& call, int optype, int 
                  taskid, int ret)
                  {
                  if (ret == RET_SUCC)
                  {
                  Log(INF, "異步結束OK. CallID=", call.CallID, " optype=", optype, 
                  " taskid=", taskid)
                  }
                  else
                  {
                  Log(INF, "異步結束FAIL. CallID=", call.CallID, " optype=", optype, 
                  " taskid=", taskid)
                  }
                  } 
                  CTI論壇報道
                  
 相關鏈接: