Ver código fonte

Z991239-3726 #comment 同步修改到新分支

80274480 3 anos atrás
pai
commit
79b1c21f62

+ 14 - 12
Module/mod_SalesRecorder/mod_SalesRecorder.cpp

@@ -214,7 +214,9 @@ static BOOL FindMatchedFile(LPCSTR sFindPath, LPCSTR sFindFileName, ULONGLONG& u
 	if (pDir == NULL) return FALSE;
 
 	//linux不支持*查找,去掉后缀
-	if (tmpFindFileName.IsEndWith("*.wmv")) {
+	char strsuffix[MAX_PATH] = { 0 };
+	snprintf(strsuffix, MAX_PATH, "*.%s", RVC_RECORD_SUFFIX);
+	if (tmpFindFileName.IsEndWith(strsuffix)) {
 		tmpFindFileName = tmpFindFileName.SubString(0, tmpFindFileName.GetLength() - 5);
 	}
 
@@ -881,7 +883,7 @@ ErrorCodeEnum CSalesRecorderEntity::ShowVideo( const char *wmvfilename )
 			if (strPath.GetLength() > 0 && strPath[strPath.GetLength()-1] != SPLIT_SLASH) {
 				strPath += SPLIT_SLASH_STR;
 			}
-			CSimpleStringA strFindFileName = CSimpleStringA::Format("%s*.wmv", wmvfilename);
+			CSimpleStringA strFindFileName = CSimpleStringA::Format("%s*.%s", wmvfilename, RVC_RECORD_SUFFIX);
 			ULONGLONG uVideoCount = 0;
 			BOOL bRet = FindMatchedFile((LPCSTR)strPath, (LPCTSTR)strFindFileName, uVideoCount);
 			Dbg("bRet = %d while find %s", bRet, wmvfilename);
@@ -915,7 +917,7 @@ ErrorCodeEnum CSalesRecorderEntity::PlaySalesRecordVideo( const char *wmvfilenam
 			if (strPath.GetLength() > 0 && strPath[strPath.GetLength()-1] != SPLIT_SLASH) {
 				strPath += SPLIT_SLASH_STR;
 			}
-			CSimpleStringA strFindFileName = CSimpleStringA::Format("%s*.wmv", wmvfilename);
+			CSimpleStringA strFindFileName = CSimpleStringA::Format("%s*.%s", wmvfilename, RVC_RECORD_SUFFIX);
 			ULONGLONG uVideoCount = 0;
 			BOOL bRet = FindMatchedFile((LPCSTR)strPath, (LPCTSTR)strFindFileName, uVideoCount);
 			Dbg("bRet = %d while find %s", bRet, wmvfilename);
@@ -948,7 +950,7 @@ void CSalesRecorderEntity::DeleteVideo( const char *wmvfilename )
 			if (strPath.GetLength() > 0 && strPath[strPath.GetLength()-1] != SPLIT_SLASH) {
 				strPath += SPLIT_SLASH_STR;
 			}
-			CSimpleStringA strFindFileName = CSimpleStringA::Format("%s*.wmv", wmvfilename);
+			CSimpleStringA strFindFileName = CSimpleStringA::Format("%s*.%s", wmvfilename, RVC_RECORD_SUFFIX);
 			ULONGLONG uVideoCount = 0;
 			BOOL bRet = FindMatchedFile((LPCSTR)strPath, (LPCTSTR)strFindFileName, uVideoCount);
 			if(bRet)
@@ -958,7 +960,7 @@ void CSalesRecorderEntity::DeleteVideo( const char *wmvfilename )
 				BOOL bDeleteSucc = TRUE;
 				for(int i = 0; i != uVideoCount; ++i)
 				{
-					fileName = CSimpleStringA::Format("%s%s_%d.wmv", (LPCSTR)strPath, wmvfilename, i);
+					fileName = CSimpleStringA::Format("%s%s_%d.%s", (LPCSTR)strPath, wmvfilename, i, RVC_RECORD_SUFFIX);
 
 					if(remove(fileName.GetData())) {
 						bDeleteSucc = FALSE;
@@ -1000,7 +1002,7 @@ ErrorCodeEnum CSalesRecorderEntity::SaveVideo( const char *wmvfilename )
 			}
 			ULONGLONG uVideoCount = 0;
 			// 移动销售录像 edit by ly 2018/03/05
-			CSimpleStringA strFindFileName = CSimpleStringA::Format("S_%s*.wmv", wmvfilename);
+			CSimpleStringA strFindFileName = CSimpleStringA::Format("S_%s*.%s", wmvfilename, RVC_RECORD_SUFFIX);
 			BOOL bRet = FindMatchedFile((LPCSTR)sourPath, (LPCSTR)strFindFileName, uVideoCount);
 			if(bRet)
 			{
@@ -1018,8 +1020,8 @@ ErrorCodeEnum CSalesRecorderEntity::SaveVideo( const char *wmvfilename )
 					Dbg("strFindFileName=%s", (LPCSTR)strFindFileName);
 					for(int i = 0; i != uVideoCount; ++i)
 					{
-						sourFileName = CSimpleStringA::Format("%s%s_%d.wmv", (LPCSTR)sourPath, (LPCSTR)strFindFileName, i);
-						destFileName = CSimpleStringA::Format("%s%s_%d.wmv", (LPCSTR)destPath, (LPCSTR)strFindFileName, i);
+						sourFileName = CSimpleStringA::Format("%s%s_%d.%s", (LPCSTR)sourPath, (LPCSTR)strFindFileName, i, RVC_RECORD_SUFFIX);
+						destFileName = CSimpleStringA::Format("%s%s_%d.%s", (LPCSTR)destPath, (LPCSTR)strFindFileName, i, RVC_RECORD_SUFFIX);
 						if(rename(sourFileName.GetData(), destFileName.GetData())) {
 							bMoveSucc = FALSE;
 							ErrorCode = Error_NotImpl;
@@ -1042,7 +1044,7 @@ ErrorCodeEnum CSalesRecorderEntity::SaveVideo( const char *wmvfilename )
 			}
 			// 移动见证录像
 			uVideoCount = 0;
-			strFindFileName = CSimpleStringA::Format("W_%s*.wmv", wmvfilename);
+			strFindFileName = CSimpleStringA::Format("W_%s*.%s", wmvfilename, RVC_RECORD_SUFFIX);
 			bRet = FindMatchedFile((LPCSTR)sourPath, (LPCSTR)strFindFileName, uVideoCount);
 			if(bRet)
 			{
@@ -1060,8 +1062,8 @@ ErrorCodeEnum CSalesRecorderEntity::SaveVideo( const char *wmvfilename )
 					Dbg("uVideoCount=%d", uVideoCount);
 					for(int i = 0; i != uVideoCount; ++i)
 					{
-						sourFileName = CSimpleStringA::Format("%s%s_%d.wmv", (LPCSTR)sourPath, (LPCSTR)strFindFileName, i);
-						destFileName = CSimpleStringA::Format("%s%s_%d.wmv", (LPCSTR)destPath, (LPCSTR)strFindFileName, i);
+						sourFileName = CSimpleStringA::Format("%s%s_%d.%s", (LPCSTR)sourPath, (LPCSTR)strFindFileName, i, RVC_RECORD_SUFFIX);
+						destFileName = CSimpleStringA::Format("%s%s_%d.%s", (LPCSTR)destPath, (LPCSTR)strFindFileName, i, RVC_RECORD_SUFFIX);
 						if(rename(sourFileName.GetData(), destFileName.GetData())) {
 							bMoveSucc = FALSE;
 							Dbg("Error Code %lu while move %s ", errno, (LPCSTR)sourFileName);
@@ -1620,7 +1622,7 @@ void CSalesRecorderEntity::UploadTempPathVideos() {
 		char srcFilePath[MAX_PATH] = { 0 };
 		DIR* pDir = NULL;
 		struct dirent* pFile = NULL;
-		sprintf_s(srcFilePath, MAX_PATH, "%s*.wmv", sourPath);
+		snprintf(srcFilePath, MAX_PATH, "%s*.%s", sourPath, RVC_RECORD_SUFFIX);
 
 		pDir = opendir(sourPath);
 		if (pDir == NULL) return ;

+ 273 - 117
Module/mod_counterconnector/ConnectorFSM.cpp

@@ -11,6 +11,7 @@
 #define SIP_CONNECT_FAIL_TIMES       10
 #define LIVEDETECT_CONNECT_INTERVAL	5000   //live detection实体检测间隔5s
 #define LIVEDETECTION_TIMEOUT		60000  //活体检测超时时间60s
+#define CALLROUTE_MAX_TRY_COUNT		3
 
 #ifndef MAX_PATH
 #define MAX_PATH 260
@@ -26,45 +27,6 @@ unsigned long GetTickCount()
 }
 #endif
 
-static int iHttpLogCount = 0; 
-
-struct GrayLaunchReq : CHTTPReq{
-	GrayLaunchReq(){m_timeOut = 5;}
-	CSimpleStringA m_terminal_no;
-	CSimpleStringA m_branch_no;
-    CSimpleStringA m_modular;
-	virtual string ToJson(){
-		char reqcontent[512];
-		//string reqcontent = "{\"terminal_no\":\"" + m_terminal_no.GetData() + "\",\"branch_no\":\"" + m_branch_no.GetData() + 
-		//	"\",\"m_modular\":\"" + m_modular.GetData() + "\"}";
-		sprintf(reqcontent, "{\"terminal_no\":\"%s\",\"branch_no\":\"%s\",\"modular\":\"%s\"}", m_terminal_no.GetData(), 
-			m_branch_no.GetData(), m_modular.GetData());
-		return reqcontent;
-	}
-};
-
-
-struct GrayLaunchResponse : CHTTPRet{
-	GrayLaunchResponse():m_result(false){}
-	bool m_result;
-	virtual bool Parse(string strData){
-		Dbg("GrayLaunchResponse: data = %s", strData.c_str());
-		Json::Value root;
-		Json::Reader reader;
-		reader.parse(strData, root, false);
-		if (root["data"].isBool()) {
-			m_result = root["data"].asBool();
-		}
-		return m_result;
-	}
-};
-
-static void HTTPLogCallback(const char* msg){
-	if (0 == iHttpLogCount){
-		LogWarn(Severity_Low, Error_Unexpect, LOG_WARN_COUNTERCONNECT_GRAY_FAILED, msg);
-		iHttpLogCount++;
-	}	
-}
 
 class  SyncServiceClient:public SyncService_ClientBase
 {
@@ -155,7 +117,7 @@ public:
 
 
 ACMCallFSM::ACMCallFSM(  )
-	: m_pPhoneClient(NULL), m_pChannelClient(NULL), m_bRing(FALSE),m_nCurSipServer(MAIN_SERVER),m_nCurChanServer(MAIN_SERVER)
+	: m_pPhoneClient(NULL), m_pChannelClient(NULL), m_bRing(FALSE),m_nCurSipServer(MAIN_SERVER),m_nCurChanServer(MAIN_SERVER),m_iFailedLastState(0),m_LastSipError(Error_Succeed), m_LastAssistError(Error_Succeed)
 {
 
 }
@@ -180,6 +142,9 @@ ErrorCodeEnum ACMCallFSM::OnInit()
 	m_strCallRouteBranchNo = NULL;
 	m_strCallRouteAccessNo = NULL;
 	m_pCallRouteList = NULL;
+	m_strDefaultServer = NULL;
+	m_LastSipError = Error_Succeed;
+	m_LastAssistError = Error_Succeed;
 	ErrorCodeEnum Error = LoadConfig();
 	if (Error != Error_Succeed)
 		goto on_error;
@@ -192,6 +157,10 @@ ErrorCodeEnum ACMCallFSM::OnInit()
 	Dbg("chan proxy ip1:%s,num1:%s,port1:%d;ip2:%s,num2:%s,port2:%d", (LPCSTR)m_strChanProxyIP[0],(LPCSTR)m_strChanCallNum[0], m_iChanProxyPort[0],(LPCSTR)m_strChanProxyIP[1],(LPCSTR)m_strChanCallNum[1], m_iChanProxyPort[1]);
 	Dbg("CallRouteIP:%s,port:%d", (LPCSTR)m_strCallRouteIP,m_iCallRoutePort);
 	Dbg("TerminalId: %s", (LPCSTR)m_strTerminalId);
+	Dbg("default_voip_server: %s", m_strDefaultServer.GetData());
+	if(m_strDefaultServer.GetLength() > 0){
+		ParseDefaultServer(m_strDefaultServer.GetData());
+	}
 	m_bHangup = FALSE;
 	m_bHandFree = TRUE;
 	m_bAgentHandFree = TRUE;
@@ -356,11 +325,154 @@ void ACMCallFSM::SetDelayTime()
 	}
 }
 
+
+static int CStringSplit(char* str, char** result, size_t ucount, const char* del)
+{
+	char* ptr = NULL;
+	size_t unum = ucount;
+	char* p = strtok_r(str, del, &ptr);
+	while (p != NULL && unum > 0){
+		*result++ = p;
+		p = strtok_r(NULL, del, &ptr);
+		unum--;
+	}
+
+	return ucount - unum;
+}
+
+
+static int GetCallInfoFromConfig(char* strcallurl, size_t ucalllen, char* strassist, size_t assitlen, size_t *uport, const char* psrc)
+{
+	int iRet = -1;
+	if (NULL == psrc || NULL == strcallurl || NULL == strassist){
+		return iRet;
+	}
+
+	char *result[MAX_VOIP_SERVER_NUM] = {0};
+	int icount = CStringSplit((char*)psrc, result, MAX_VOIP_SERVER_NUM, ",");
+	if(2 == icount){
+		_snprintf(strcallurl, ucalllen, "%s", result[0]);
+		char *assitresult[MAX_VOIP_SERVER_NUM] = {0};
+		icount = CStringSplit(result[1], assitresult, MAX_VOIP_SERVER_NUM, " ");
+		if(2 == icount){
+			_snprintf(strassist, assitlen, "%s", assitresult[0]);
+			*uport = atoi(assitresult[1]);
+			iRet = 0;
+		}
+	}
+	return iRet;
+}
+
+/*无符号长整形转字符型*/
+static char* _ultoa(unsigned long value, char* pstring, int radix)
+{
+	char tmp[33] = { 0 };
+	char* tp = tmp;
+	long i;
+	unsigned long v = value;
+	char* sp;
+
+	if (radix > 36 || radix <= 1 || NULL == pstring) {
+		return 0;
+	}
+
+
+	while (v || tp == tmp)
+	{
+		i = v % radix;
+		v = v / radix;
+		if (i < 10)
+			* tp++ = i + '0';
+		else
+			*tp++ = i + 'a' - 10;
+	}
+
+	sp = pstring;
+
+	while (tp > tmp)
+		* sp++ = *--tp;
+	*sp = 0;
+	return pstring;
+}
+
+static int get_interger_netaddr(char *strbuf, size_t ubufszie, const char* szip)
+{
+	int ret = -1;
+
+	unsigned long ulip = 0;
+	if (NULL == strbuf || NULL == szip){
+		return ret;
+	}
+
+	ulip = inet_addr(szip);
+	_ultoa(ulip, strbuf, 10);
+
+	ret = 0;
+	return ret;
+}
+
+int ACMCallFSM::ParseDefaultServer(const char* strServer)
+{
+	int iRet = 0;
+	if(NULL == strServer){
+		return iRet;
+	}
+
+	char *result[MAX_VOIP_SERVER_NUM] = {0};
+	int icount = CStringSplit((char*)strServer, result, MAX_VOIP_SERVER_NUM, "|");
+	int index = 0;
+	while(index < icount && result[index]){
+		m_voipserver.push_back(result[index]);
+		index++;
+	}
+
+	iRet = m_voipserver.size();
+	Dbg("default voip server number is %d.", iRet);
+	for (int i = 0; i < iRet; i++){
+		Dbg("default voip server address is %s", m_voipserver[i].c_str());
+	}
+
+	return iRet;
+}
+
+
 ErrorCodeEnum ACMCallFSM::OnExit()
 {
 	return Error_Succeed;
 }
 
+
+int ACMCallFSM::GetFailedErrorCode(int iSrcState)
+{
+	int iState = 0;
+	if (s20 != iSrcState){
+		switch (m_iFailedLastState) {
+		case s11:
+			if(Error_Succeed != m_LastSipError){
+				iState = 5;
+			}
+			else{
+				iState = 1;
+			}
+			break;
+
+		case s12:
+			if (Error_Succeed != m_LastAssistError){
+				iState = 5;
+			}
+			else{
+				iState = 2;
+			}
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	return iState;
+}
+
 void ACMCallFSM::OnStateTrans(int iSrcState, int iDstState)
 {
 	Dbg("FSM state from state %s to %s", GetStateName(iSrcState), GetStateName(iDstState));
@@ -375,10 +487,16 @@ void ACMCallFSM::OnStateTrans(int iSrcState, int iDstState)
 		int st1 = TranslateState(iSrcState);
 		int st2 = TranslateState(iDstState);
 
+		if (eState_Fail == st2){
+			m_iFailedLastState = iSrcState;
+		}
+
 		if (st1 != st2) {
 			PhoneState evt;
 			evt.state = st2;
 			evt.status = CSimpleStringA::Format("OnStateTrans from state %d to %d", st1, st2);
+			evt.errcode = 0;
+			LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALL_STATE_TRANS, evt.status.GetData());
 			//LOG_TRACE(evt.status);
 			if (!((st2 == eState_Fail)&&(m_nCurChanServer != Error_Server)&&(m_nCurSipServer != Error_Server))||m_bHangup)
 			{
@@ -386,6 +504,9 @@ void ACMCallFSM::OnStateTrans(int iSrcState, int iDstState)
 					char strmsg[MAX_PATH] = {0};
 					snprintf(strmsg, MAX_PATH,"Broadcast state from %d to %d", st1, st2);
 					Dbg(strmsg);
+					if (eState_Fail == st1 && eState_Offline == st2){
+						evt.errcode = GetFailedErrorCode(iSrcState);
+					}
 					SpSendBroadcast(GetEntityBase()->GetFunction(), SP_MSG_OF(PhoneState), SP_MSG_SIG_OF(PhoneState), evt);
 					LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_BROADCAST_CALL_STATE, strmsg);
 				} 
@@ -402,7 +523,9 @@ void ACMCallFSM::OnStateTrans(int iSrcState, int iDstState)
 				}
 
 				if (eState_Fail == st1 && eState_Offline == st2){
-					LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CONNECT_FAILED, "connect failed!");
+					char strmsg[MAX_PATH] = {0};
+					snprintf(strmsg, MAX_PATH, "connect failed and last state is %d, and current src state is %d.", m_iFailedLastState, iSrcState);
+					LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CONNECT_FAILED, strmsg);
 				}
 			}
 			SetCallState(st2);
@@ -446,6 +569,7 @@ void ACMCallFSM::s0_on_entry()
 		free_node_list(m_pCallRouteList);	
 		m_pCallRouteList = NULL;
 	}
+	m_iFailedLastState = 0;
 }
 void ACMCallFSM::s0_on_exit() 
 {
@@ -586,14 +710,28 @@ unsigned int ACMCallFSM::s9_on_event(FSMEvent* event)
 void ACMCallFSM::s8_on_entry() 
 {
 	//get call route,采用直接总行方式
-	call_info_t call_info;
-	call_info.callroute_server_ip = m_strCallRouteIP;
-	call_info.callroute_server_port = m_iCallRoutePort;
-	call_info.szbranchno = m_strCallRouteBranchNo;
-	call_info.szcaller_num = m_strTerminalId;
-	call_info.szdest_num = m_strCallRouteAccessNo;
-	m_pCallRouteList = get_callroute_list(&call_info);
-			
+	if (m_strCallRouteIP.GetLength() != 0) {
+		int icount = 0;
+		call_info_t call_info;
+		call_info.callroute_server_ip = m_strCallRouteIP;
+		call_info.callroute_server_port = m_iCallRoutePort;
+		call_info.szbranchno = m_strCallRouteBranchNo;
+		call_info.szcaller_num = m_strTerminalId;
+		call_info.szdest_num = m_strCallRouteAccessNo;
+
+		do 
+		{
+			m_pCallRouteList = get_callroute_list(&call_info);
+			icount++;
+		} while (!m_pCallRouteList && icount < CALLROUTE_MAX_TRY_COUNT);
+				
+		if (icount > 1){
+			char strmsg[MAX_PATH] = {0};
+			snprintf(strmsg, MAX_PATH, "request call route {%s:%d} %d times.", m_strCallRouteIP.GetData(), m_iCallRoutePort, icount);
+			LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_TIMES, strmsg);
+		}
+	}
+		
 	int time = GetDelayTime();
 	Dbg("get Delay time = %d",time);
 	if (time > 0)
@@ -653,78 +791,97 @@ unsigned int ACMCallFSM::s10_on_event(FSMEvent* event)
 
 void ACMCallFSM::s11_on_entry() 
 {
-	ErrorCodeEnum Error = Error_Succeed;
+	//ErrorCodeEnum Error = Error_Succeed;
+	m_LastSipError = Error_Succeed;
 	LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_MAKECALL,"begin make call");
+
 	if (m_nCurSipServer == Error_Server){
-		Error = Error_NetBroken;
+		m_LastSipError = Error_NetBroken;
 	}
 
-	if (Error == Error_Succeed){
-		bool center_connect = FALSE;
+	if (m_LastSipError == Error_Succeed){
+		//bool center_connect = FALSE;
 		//get call route,采用直接总行方式
 		if (m_strCallRouteIP.GetLength() != 0) {
 			callurl_node_t *node = get_no_used_node(m_pCallRouteList);
+
+			char ipstr[256] = {0};
+			char callid_str[64] = { 0 };
+			GetLocalIP(ipstr, 256);
+			get_format_uuid(callid_str, 64);
+
 			if (node != NULL){
-				LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_HEADOFFICE_CALL, "Begin Head Office Make Call!");
-				char ipstr[256] = {0};
-				char callid_str[64] = { 0 };
-				GetLocalIP(ipstr, 64);
-				get_format_uuid(callid_str, 64);
-				Error = MakeCall(node->strcallurl, CSimpleStringA::Format("sip:%s@%s;transport=UDP", node->strnewcallernum, ipstr), 
+				Dbg("Begin Head Office Make Call!");
+				m_LastSipError = MakeCall(node->strcallurl, CSimpleStringA::Format("sip:%s@%s;transport=UDP", node->strnewcallernum, ipstr), 
 					callid_str, m_CallingParam);
 				m_iChanProxyPort[0] = node->uassistport;
 				m_iChanProxyPort[1] = node->uassistport;
 				m_strChanProxyIP[0] = node->strassistip;
 				m_strChanProxyIP[1] = node->strassistip;
-				if (Error!=Error_Succeed){
-					m_nCurSipServer?(m_nCurSipServer=Error_Server):(m_nCurSipServer=BACK_SERVER);
-				}
-				m_nCurChanServer = BACK_SERVER;
 				node->bused = TRUE;
-				char strmsg[256] = { 0 };
-				snprintf(strmsg, 256, "head office make call result:0x%08x", Error);
-				LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_HEADOFFICE_CALL, strmsg);
-				center_connect = TRUE;
 			}	
 			else{
-				LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_BRANCHMODE_CALL, "head office mode no more call router, try to connect branch server.");
-				//m_nCurSipServer = MAIN_SERVER;
-				//m_nCurChanServer = MAIN_SERVER;
-				center_connect = FALSE;
-			}		
-		}
-
-		//old call branch server方式
-		if(!center_connect){
-			if (m_CallingParam.nCallType != NORMAL_CALLTYPE && m_CallingParam.nCallType != DOUBLERECORD_CALLTYPE)
-			{
-				Dbg("Begin Branch Make Distribute Call!");
-				Error = MakeCall(m_nCurSipServer,m_CallingParam);
-				if (Error!=Error_Succeed)
-				{
-					m_nCurSipServer?(m_nCurSipServer=Error_Server):(m_nCurSipServer=BACK_SERVER);
+				int icount = m_voipserver.size();
+				if (icount > 0){
+					int index = GetTickCount()%icount;
+					char strcallurl[MAX_PATH] = {0};
+					char strassistip[32] = {0};
+					size_t uport = 0;
+					if (0 == GetCallInfoFromConfig(strcallurl, MAX_PATH, strassistip, 32, &uport, m_voipserver[index].c_str())){
+						char strassitinter[32] = {0};
+						get_interger_netaddr(strassitinter, 32, strassistip);
+						m_LastSipError = MakeCall(strcallurl, CSimpleStringA::Format("sip:%s#%s@%s;transport=UDP", m_strTerminalId.GetData(), strassitinter, ipstr), 
+							callid_str, m_CallingParam);
+						m_iChanProxyPort[0] = uport;
+						m_iChanProxyPort[1] = uport;
+						m_strChanProxyIP[0] = strassistip;
+						m_strChanProxyIP[1] = strassistip;
+						char strmsg[MAX_PATH] = {0};
+						snprintf(strmsg, MAX_PATH, "head office mode no more call router, use default config(call url is %s, assistip is %s).", strcallurl, strassistip);
+						LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_CONFIG, strmsg);
+					}
 				}
-				Dbg("branch make call result:0x%08x", Error);
 			}
-			else
-			{	
-				if (NORMAL_CALLTYPE == m_CallingParam.nCallType){
-					Dbg("Begin Branch Make Normal Call!");
-				}
-				else{
-					Dbg("Begin Branch Make Record Call!");
-				}
-				
-				Error = MakeCall(m_strHintCallNum.GetLength() > 0 ? (LPCSTR)m_strHintCallNum : (LPCSTR)m_strSIPCallNum[m_nCurSipServer],m_nCurSipServer);
-				if (Error!=Error_Succeed)
-				{
-					m_nCurSipServer?(m_nCurSipServer=Error_Server):(m_nCurSipServer=BACK_SERVER);
-				}
-				Dbg("branch make call result:0x%08x", Error);
+
+			if (m_LastSipError!=Error_Succeed){
+				m_nCurSipServer?(m_nCurSipServer=Error_Server):(m_nCurSipServer=BACK_SERVER);
 			}
+			m_nCurChanServer = BACK_SERVER;
+			
+			Dbg("head office make call result:0x%08x", m_LastSipError);
 		}
-	}
-	if (Error != Error_Succeed) 
+
+		//old call branch server方式
+		//if(!center_connect){
+		//	if (m_CallingParam.nCallType != NORMAL_CALLTYPE && m_CallingParam.nCallType != DOUBLERECORD_CALLTYPE)
+		//	{
+		//		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Begin Branch Make Distribute Call!");
+		//		Error = MakeCall(m_nCurSipServer,m_CallingParam);
+		//		if (Error!=Error_Succeed)
+		//		{
+		//			m_nCurSipServer?(m_nCurSipServer=Error_Server):(m_nCurSipServer=BACK_SERVER);
+		//		}
+		//		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("branch make call result:0x%08x", Error);
+		//	}
+		//	else
+		//	{	
+		//		if (NORMAL_CALLTYPE == m_CallingParam.nCallType){
+		//			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Begin Branch Make Normal Call!");
+		//		}
+		//		else{
+		//			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Begin Branch Make Record Call!");
+		//		}
+		//		
+		//		Error = MakeCall(m_strHintCallNum.GetLength() > 0 ? (LPCSTR)m_strHintCallNum : (LPCSTR)m_strSIPCallNum[m_nCurSipServer],m_nCurSipServer);
+		//		if (Error!=Error_Succeed)
+		//		{
+		//			m_nCurSipServer?(m_nCurSipServer=Error_Server):(m_nCurSipServer=BACK_SERVER);
+		//		}
+		//		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("branch make call result:0x%08x", Error);
+		//	}
+		//}
+	}
+	if (m_LastSipError != Error_Succeed) 
 	{
 		PostEventFIFO(new FSMEvent(USER_EVT_JMP_FAIL));
 	}
@@ -744,8 +901,8 @@ unsigned int ACMCallFSM::s11_on_event(FSMEvent* event)
 			m_bHangup = TRUE;
 			DWORD now = GetTickCount();
 			int interval = now - m_nStarttime;
-			char msg[128];
-			sprintf(msg, "sip connecting, customer active hangup after: %d", interval);
+			char msg[128] = {0};
+			snprintf(msg, 128, "sip connecting, customer active hangup after %d ms.", interval);
 			LogWarn(Severity_Low, Error_Unexpect, LOG_WARN_COUNTERCONNECT_SIPCONNECT_HANGUP, msg);
 	}
 	else if (event->iEvt == USER_EVT_SIP_STATE_IDLE) 
@@ -818,23 +975,24 @@ unsigned int ACMCallFSM::s11_on_event(FSMEvent* event)
 
 void ACMCallFSM::s12_on_entry() 
 {
-	ErrorCodeEnum Error = Error_Succeed;
+	//ErrorCodeEnum Error = Error_Succeed;
+	m_LastAssistError = Error_Succeed;
 	if (m_nCurChanServer == Error_Server)
 	{
-		Error = Error_NetBroken;
+		m_LastAssistError = Error_NetBroken;
 	}
 	m_nSipErrorNum = 0;
 	Sleep(200);
-	if (Error == Error_Succeed) 
+	if (m_LastAssistError == Error_Succeed) 
 	{
 		Dbg("begin start channel,m_nCurChanServer=%d",m_nCurChanServer);
 		if (m_CallingParam.nCallType == NORMAL_CALLTYPE  && m_CallingParam.nCallType != DOUBLERECORD_CALLTYPE)
 		{
-			Error = StartChannel(m_nCurChanServer);
+			m_LastAssistError = StartChannel(m_nCurChanServer);
 		} 
 		else
 		{
-			Error = StartChannel(m_nCurChanServer,m_CallingParam);
+			m_LastAssistError = StartChannel(m_nCurChanServer,m_CallingParam);
 			//if (DOUBLERECORD_CALLTYPE == m_CallingParam.nCallType){
 			//	if (FALSE == m_bHandFree){
 			//		StopSpeakerAudioCapture();
@@ -842,17 +1000,17 @@ void ACMCallFSM::s12_on_entry()
 			//	}
 			//}
 		}
-		Dbg("start channel result:0x%08x", Error);
-		if (Error != Error_Succeed) 
+		Dbg("start channel result:0x%08x", m_LastAssistError);
+		if (m_LastAssistError != Error_Succeed) 
 		{
-			Dbg("start channel failed:0x%08x,start hangup", Error);
+			Dbg("start channel failed:0x%08x,start hangup", m_LastAssistError);
 			HangupCall();
 			m_nCurChanServer?(m_nCurChanServer=Error_Server):(m_nCurChanServer=BACK_SERVER);
-			Dbg("hangup call result:0x%08x", Error);
+			Dbg("hangup call result:0x%08x", m_LastAssistError);
 		}
 	}
 
-	if (Error != Error_Succeed) 
+	if (m_LastAssistError != Error_Succeed) 
 	{
 		PostEventFIFO(new FSMEvent(USER_EVT_JMP_FAIL));
 	}
@@ -866,8 +1024,8 @@ unsigned int ACMCallFSM::s12_on_event(FSMEvent* event)
 		m_bHangup = TRUE;
 		DWORD now = GetTickCount();
 		int interval = now - m_nStarttime;
-		char msg[128];
-		sprintf(msg, "chan connecting, customer active hangup after: %d", interval);
+		char msg[128] = {0};
+		snprintf(msg, 128, "chan connecting, customer active hangup after %d ms.", interval);
 		LogWarn(Severity_Low, Error_Unexpect, LOG_WARN_COUNTERCONNECT_CHANCONNECT_HANGUP, msg);
 	}
 	else if (event->iEvt == USER_EVT_SIP_STATE_IDLE) 
@@ -1381,8 +1539,6 @@ unsigned int ACMCallFSM::s62_on_event(FSMEvent* event)
 		{
 			Dbg("release call timeout,restart sipphone");
 			PostEventFIFO(new FSMEvent(USER_EVT_JMP_FAIL));
-			//重启mod_sipphone
-			//RealSipErrorCheck();
 			LogEvent(Severity_Middle, EVENT_MOD_RELEASESIP_TIMEOUT,"restart sipphone ");
 			LogWarn(Severity_Low, Error_Unexpect, LOG_WARN_COUNTERCONNECT_RESTART_SIPPHONE,"restart sipphone ");
 		}

+ 14 - 0
Module/mod_counterconnector/ConnectorFSM.h

@@ -40,6 +40,8 @@ using namespace InteractionContext;
 #include "../mod_livenessdetection/LivenessDetection_msg_g.h"
 using namespace LivenessDetection;
 
+#include <vector>
+#include <string>
 
 #define USER_EVT_PICKUP_CALL	EVT_USER+1
 #define USER_EVT_HANDFREE_CALL	EVT_USER+2
@@ -90,6 +92,10 @@ enum CurServerNum
 	BACK_SERVER = 1,
 };
 
+#ifndef MAX_VOIP_SERVER_NUM
+#define MAX_VOIP_SERVER_NUM 10
+#endif
+
 struct ChanStateConnectedEvent : public FSMEvent 
 {
 	ChanStateConnectedEvent(const char *param) : FSMEvent(USER_EVT_CHAN_STATE_CONNECTED), m_param(param) {}
@@ -884,6 +890,7 @@ private:
 		table.AddEntryInt("CounterConnector", "call_route_port", m_iCallRoutePort, 0);
 		table.AddEntryString("CounterConnector", "call_route_access_no", m_strCallRouteAccessNo, NULL);
 		table.AddEntryString("Initializer", "SubBankNo", m_strCallRouteBranchNo, NULL);
+		table.AddEntryString("CounterConnector", "default_voip_server", m_strDefaultServer, NULL);
 		CSmartPointer<IConfigInfo> spConfig;
 		ErrorCodeEnum Error = m_pEntity->GetFunction()->OpenConfig(Config_CenterSetting, spConfig);
 		if (Error == Error_Succeed) {
@@ -974,6 +981,8 @@ private:
 	BOOL ReConnectionSipphone();
 	int GetDelayTime();
 	void SetDelayTime();
+	int ParseDefaultServer(const char* strServer);
+	int GetFailedErrorCode(int iSrcState);
 
 public:
 	BOOL m_bHandFree;
@@ -991,6 +1000,7 @@ public:
 	CallingParam m_CallingParam;
 	SessionParam m_SessionParam;
 	int m_nSysCallType;//0:普通模式,1:p2p模式
+	int m_iFailedLastState;
 
 private:
 	DWORD m_nStarttime;
@@ -1011,6 +1021,10 @@ private:
 	CSimpleStringA m_strCallRouteBranchNo;
 	CSimpleStringA m_strCallRouteAccessNo;
 	node_list_head_t *m_pCallRouteList;
+	CSimpleStringA m_strDefaultServer;
+	std::vector<std::string> m_voipserver;
+	ErrorCodeEnum m_LastSipError;
+	ErrorCodeEnum m_LastAssistError;
 
 	BOOL m_bRing;
 };

+ 1 - 0
Module/mod_counterconnector/ConnectorService.xml

@@ -12,6 +12,7 @@
 	<message name="PhoneState">
 		<param name="state" type="int"/>
 		<param name="status" type="string"/>
+		<param name="errcode" type="int"/>
 	</message>
 		<message name="CallTransferInfo">
 		<param name="CallNum" type="string"/>

+ 2 - 1
Module/mod_counterconnector/CounterConnector_msg_g.h

@@ -21,10 +21,11 @@ struct PhoneState
 {
 	int state;
 	CSimpleStringA status;
+	int errcode;
 
 	void Serialize(SpBuffer &Buf)
 	{
-		auto & buf = Buf & state & status;
+		auto & buf = Buf & state & status & errcode;
 	}
 
 };

+ 0 - 5
Module/mod_counterconnector/Event.h

@@ -43,11 +43,6 @@
 #define EVENT_MOD_CONNECT_STOP_RECORD_BROADCAST		0x10303060	//结束双录语音播报
 #define EVENT_MOD_CONNECT_BEGAIN_RECORD_CALL		0x10303061	//开始双录呼叫
 
-
-#define LOG_EVT_DISTRIBUTE_ASSISTANTCHANNEL_IDLE	0x30C00001		// 协助通道重置
-#define LOG_EVT_DISTRIBUTE_SIPPHONE_IDLE			0x30C00002		// sip话机重置
-
-
 #define SYSVAR_CALLTYPE	"CallType"
 #define CALLTYPE_NORMAL "N" // 呼叫类型,普通模式
 #define CALLTYPE_MOBILE	"M" // 呼叫类型,手机模式

+ 245 - 250
Module/mod_counterconnector/mod_counterconnector.cpp

@@ -9,62 +9,65 @@
 #include "CounterConnector_msg_g.h"
 #include "../include/EventCode.h"
 #include "y2k_time.h"
+
 using namespace CounterConnector;
 
 #define EVT_CONVERTER	"EventConverter"
 
-
-	void CCounterConnectorEntity ::OnPreStart(CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext) 
-	{ 
-		ErrorCodeEnum Error = __OnStart(Error_Succeed);
-		CSmartPointer<IEntityFunction> spFunction = GetFunction();
-		Error = spFunction->SubscribeBroadcast("LivenessDetection", NULL, this, m_uidlivenessListener);
-		if (Error != Error_Succeed)
-		{
-			LOG_TRACE("subscribe LivenessDetection evt failed!");
-			pTransactionContext->SendAnswer(Error);
-			return;
-		}
+void CCounterConnectorEntity ::OnPreStart(CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext) 
+{ 
+	ErrorCodeEnum Error = __OnStart(Error_Succeed);
+	CSmartPointer<IEntityFunction> spFunction = GetFunction();
+	Error = spFunction->SubscribeBroadcast("LivenessDetection", NULL, this, m_uidlivenessListener);
+	if (Error != Error_Succeed)
+	{
+		LOG_TRACE("subscribe LivenessDetection evt failed!");
 		pTransactionContext->SendAnswer(Error);
+		return;
 	}
-	void CCounterConnectorEntity ::OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext) 
-	{ 
-		ErrorCodeEnum Error = __OnClose(Error_Succeed);
-		pTransactionContext->SendAnswer(Error); 
-	}
-	void CCounterConnectorEntity ::OnSelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionContext> pTransactionContext) 
-	{ 
-		if (Test_ShakeHand == eTestType)
-		{
-			pTransactionContext->SendAnswer(Error_Succeed); 
-		}
-	}
+	pTransactionContext->SendAnswer(Error);
+}
 
-	ErrorCodeEnum CCounterConnectorEntity ::__OnStart(ErrorCodeEnum preOperationError)
+
+void CCounterConnectorEntity ::OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext) 
+{ 
+	ErrorCodeEnum Error = __OnClose(Error_Succeed);
+	pTransactionContext->SendAnswer(Error); 
+}
+
+
+void CCounterConnectorEntity ::OnSelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionContext> pTransactionContext) 
+{ 
+	if (Test_ShakeHand == eTestType)
 	{
-		if (preOperationError != Error_Succeed)
-			return preOperationError;
-		//MessageBoxA(0, 0, 0, 0);
-		//is Pad Version
-		m_pCurrentSession = NULL;
-		m_bIsSalesRecord = FALSE;
-		m_bIsRemoteRecord = FALSE;
-		m_bHasLaunched = FALSE;
-		CSmartPointer<IEntityFunction> spFunction = GetFunction();
-		CSystemStaticInfo stStaticinfo;
-		spFunction->GetSystemStaticInfo(stStaticinfo);
-		if (stricmp(stStaticinfo.strMachineType,"RVC.PAD")==0)
-		{
-			m_bIsPadType = TRUE;
-		}
-		else
-		{
-			m_bIsPadType = FALSE;
-		}
-		m_IsStand2SType = TRUE;
-		if (stricmp(stStaticinfo.strMachineType,"RVC.Stand2S")!=0){
-			m_IsStand2SType = FALSE;
-		}
+		pTransactionContext->SendAnswer(Error_Succeed); 
+	}
+}
+
+
+ErrorCodeEnum CCounterConnectorEntity ::__OnStart(ErrorCodeEnum preOperationError)
+{
+	if (preOperationError != Error_Succeed)
+		return preOperationError;
+	//MessageBoxA(0, 0, 0, 0);
+	//is Pad Version
+	m_pCurrentSession = NULL;
+	m_bIsSalesRecord = FALSE;
+	m_bIsRemoteRecord = FALSE;
+	m_bHasLaunched = FALSE;
+	CSmartPointer<IEntityFunction> spFunction = GetFunction();
+	CSystemStaticInfo stStaticinfo;
+	spFunction->GetSystemStaticInfo(stStaticinfo);
+	if (stricmp(stStaticinfo.strMachineType,"RVC.PAD")==0){
+		m_bIsPadType = TRUE;
+	}
+	else{
+		m_bIsPadType = FALSE;
+	}
+	m_IsStand2SType = TRUE;
+	if (stricmp(stStaticinfo.strMachineType,"RVC.Stand2S")!=0){
+		m_IsStand2SType = FALSE;
+	}
 
 	ErrorCodeEnum Error;
 	m_pCounterConnectorChannel = new ChannelCounterConnectorClient(this);
@@ -75,164 +78,161 @@ using namespace CounterConnector;
 		return Error;
 	}
 
+	{
+		ChannelService_BeginState_Sub Sub;
+		Error = m_pCounterConnectorChannel->BeginState(Sub);
+		if (Error != Error_Succeed) 
 		{
-			ChannelService_BeginState_Sub Sub;
-			Error = m_pCounterConnectorChannel->BeginState(Sub);
-			if (Error != Error_Succeed) 
-			{
-				LOG_TRACE("BeginState biz channel failed!");
-				m_pCounterConnectorChannel->GetFunction()->CloseSession();
-				m_pCounterConnectorChannel = NULL;
-				return Error;
-			}
+			LOG_TRACE("BeginState biz channel failed!");
+			m_pCounterConnectorChannel->GetFunction()->CloseSession();
+			m_pCounterConnectorChannel = NULL;
+			return Error;
 		}
+	}
 
+	{
+		ChannelService_BeginRecv_Sub Sub;
+		Sub.type = ACM_TYPE_DEVICE;
+		Error = m_pCounterConnectorChannel->BeginRecv(Sub);
+		if (Error != Error_Succeed) 
 		{
-			ChannelService_BeginRecv_Sub Sub;
-			Sub.type = ACM_TYPE_DEVICE;
-			Error = m_pCounterConnectorChannel->BeginRecv(Sub);
-			if (Error != Error_Succeed) 
-			{
-				Dbg("Begin BeginRecv ACM_TYPE_DEVICE failed!");
-				m_pCounterConnectorChannel->GetFunction()->CloseSession();
-				m_pCounterConnectorChannel = NULL;
-				return Error;
-			}
+			Dbg("Begin BeginRecv ACM_TYPE_DEVICE failed!");
+			m_pCounterConnectorChannel->GetFunction()->CloseSession();
+			m_pCounterConnectorChannel = NULL;
+			return Error;
 		}
+	}
 
+	{
+		ChannelService_BeginRecv_Sub Sub;
+		Sub.type = ACM_TYPE_AGENTVIDEOTYPE;
+		Error = m_pCounterConnectorChannel->BeginRecv(Sub);
+		if (Error != Error_Succeed) 
 		{
-			ChannelService_BeginRecv_Sub Sub;
-			Sub.type = ACM_TYPE_AGENTVIDEOTYPE;
-			Error = m_pCounterConnectorChannel->BeginRecv(Sub);
-			if (Error != Error_Succeed) 
-			{
-				Dbg("Begin BeginRecv ACM_TYPE_AGENTVIDEOTYPE failed!");
-				m_pCounterConnectorChannel->GetFunction()->CloseSession();
-				m_pCounterConnectorChannel = NULL;
-				return Error;
-			}
+			Dbg("Begin BeginRecv ACM_TYPE_AGENTVIDEOTYPE failed!");
+			m_pCounterConnectorChannel->GetFunction()->CloseSession();
+			m_pCounterConnectorChannel = NULL;
+			return Error;
 		}
+	}
 
+	{
+		ChannelService_BeginRecv_Sub Sub;
+		Sub.type = ACM_TYPE_CALLTRANS;
+		Error = m_pCounterConnectorChannel->BeginRecv(Sub);
+		if (Error != Error_Succeed) 
 		{
-			ChannelService_BeginRecv_Sub Sub;
-			Sub.type = ACM_TYPE_CALLTRANS;
-			Error = m_pCounterConnectorChannel->BeginRecv(Sub);
-			if (Error != Error_Succeed) 
-			{
-				Dbg("Begin BeginRecv ACM_TYPE_CALLTRANS failed!");
-				m_pCounterConnectorChannel->GetFunction()->CloseSession();
-				m_pCounterConnectorChannel = NULL;
-				return Error;
-			}
+			Dbg("Begin BeginRecv ACM_TYPE_CALLTRANS failed!");
+			m_pCounterConnectorChannel->GetFunction()->CloseSession();
+			m_pCounterConnectorChannel = NULL;
+			return Error;
 		}
+	}
 
-		m_fsm.Init(this);
-		int i = 0;
-		m_arrListener.Init(24);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_PICKUP_CALL,NULL,false);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANDFREE_CALL,NULL,false);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANDFREE_TO_PICKUP);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_PICKUP_TO_HANDFREE);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANNUP);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANNUP_BY_CONNECTING);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANNUP_BY_AGENT);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_GPIO_PICKUP);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_GPIO_HANDFREE);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_AGENT_HANDFREE_PICKUP);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_AGENT_PICKUP_HANDFREE);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_SELFCHECK_SIPPHONE_IDLE);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STARTRECORD,NULL,false);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STOPRECORD,NULL,false);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_RETURNMENU,NULL,false);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STARTPHOTOGRAPH,NULL,false);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_DISTRIBUTE_ASSISTANTCHANNEL_IDLE);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_DISTRIBUTE_SIPPHONE_IDLE);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_STOP_RECORD_BROADCAST,NULL,false);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_BEGAIN_RECORD_CALL,NULL,false);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STARTREMOTERECORD,NULL,false);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STOPREMOTERECORD,NULL,false);
-		spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STARTRECORDPREVIEW,NULL,false);
+	m_fsm.Init(this);
+	int i = 0;
+	m_arrListener.Init(24);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_PICKUP_CALL,NULL,false);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANDFREE_CALL,NULL,false);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANDFREE_TO_PICKUP);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_PICKUP_TO_HANDFREE);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANNUP);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANNUP_BY_CONNECTING);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANNUP_BY_AGENT);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_GPIO_PICKUP);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_GPIO_HANDFREE);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_AGENT_HANDFREE_PICKUP);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_AGENT_PICKUP_HANDFREE);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_SELFCHECK_SIPPHONE_IDLE);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STARTRECORD,NULL,false);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STOPRECORD,NULL,false);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_RETURNMENU,NULL,false);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STARTPHOTOGRAPH,NULL,false);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_STOP_RECORD_BROADCAST,NULL,false);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_BEGAIN_RECORD_CALL,NULL,false);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STARTREMOTERECORD,NULL,false);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STOPREMOTERECORD,NULL,false);
+	spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STARTRECORDPREVIEW,NULL,false);
 	
-		spFunction->RegistSysVarEvent("UIState", this);
+	spFunction->RegistSysVarEvent("UIState", this);
 
-		return Error_Succeed;
-	}
+	return Error_Succeed;
+}
 
-	void CCounterConnectorEntity::OnSysVarEvent(const char *pszKey,  const char *pszValue,const char *pszOldValue,const char *pszEntityName)
+void CCounterConnectorEntity::OnSysVarEvent(const char *pszKey,  const char *pszValue,const char *pszOldValue,const char *pszEntityName)
+{
+	if (_stricmp(pszKey, "UIState") == 0)
 	{
-		if (_stricmp(pszKey, "UIState") == 0)
+		Dbg("Current UIState is %s.", pszValue);
+		if (pszValue[0] == 'M')
 		{
-			Dbg("Current UIState is %s.", pszValue);
-			if (pszValue[0] == 'M')
-			{
-				if (FALSE == m_bHasLaunched){
-					m_bHasLaunched = TRUE;
-					Dbg("UI has launched success.");
-				}
-			}		
-		}
+			if (FALSE == m_bHasLaunched){
+				m_bHasLaunched = TRUE;
+				Dbg("UI has launched success.");
+			}
+		}		
 	}
+}
 
-	ErrorCodeEnum CCounterConnectorEntity ::__OnClose(ErrorCodeEnum preOperationError)
-	{
-		if (preOperationError != Error_Succeed)
-			return preOperationError;
-		int i;
-		CSmartPointer<IEntityFunction> spFunction = GetFunction();
-		for (i = 0; i < m_arrListener.GetCount(); ++i) {
-			spFunction->UnsubscribeLog(m_arrListener[i]);
-		}
-
-		spFunction->UnregistSysVarEvent("UIState");
-
-		m_arrListener.Clear();
-		m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_EXIT));
-		return Error_Succeed;
+ErrorCodeEnum CCounterConnectorEntity ::__OnClose(ErrorCodeEnum preOperationError)
+{
+	if (preOperationError != Error_Succeed)
+		return preOperationError;
+	int i;
+	CSmartPointer<IEntityFunction> spFunction = GetFunction();
+	for (i = 0; i < m_arrListener.GetCount(); ++i) {
+		spFunction->UnsubscribeLog(m_arrListener[i]);
 	}
 
-	void CCounterConnectorEntity ::OnLog(const CAutoArray<CUUID> &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
-		const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID, 
-		const CAutoArray<DWORD> &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage, const linkContext& pLinkInfo)
+	spFunction->UnregistSysVarEvent("UIState");
+	m_arrListener.Clear();
+	m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_EXIT));
+	return Error_Succeed;
+}
+
+void CCounterConnectorEntity ::OnLog(const CAutoArray<CUUID> &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
+	const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID, 
+	const CAutoArray<DWORD> &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage, const linkContext& pLinkInfo)
+{
+	LOG_TRACE("user_code = 0x%08x", dwUserCode);
+	switch (dwUserCode) 
 	{
-		LOG_TRACE("user_code = 0x%08x", dwUserCode);
-		switch (dwUserCode) 
-		{
 		case EVENT_MOD_CONNECT_GPIO_PICKUP:
+		{
+			m_fsm.m_bHandFree = FALSE;
+			if (!m_fsm.m_bIsAgentControl)
 			{
-				m_fsm.m_bHandFree = FALSE;
-				if (!m_fsm.m_bIsAgentControl)
-				{
-					m_fsm.m_bAgentHandFree = FALSE;
-				}
-				CSimpleStringA strValue;
-				GetFunction()->GetSysVar("CallState", strValue);
-				Dbg("摘机,and CallState is %s.", strValue.GetData());
+				m_fsm.m_bAgentHandFree = FALSE;
 			}
-			break;
+			CSimpleStringA strValue;
+			GetFunction()->GetSysVar("CallState", strValue);
+			Dbg("摘机,and CallState is %s.", strValue.GetData());
+		}
+		break;
 		case EVENT_MOD_CONNECT_GPIO_HANDFREE:
+		{
+			m_fsm.m_bHandFree = TRUE;
+			if (!m_fsm.m_bIsAgentControl)
 			{
-				m_fsm.m_bHandFree = TRUE;
-				if (!m_fsm.m_bIsAgentControl)
-				{
-					m_fsm.m_bAgentHandFree = TRUE;
-				}
-				CSimpleStringA strValue;
-				GetFunction()->GetSysVar("CallState", strValue);
-				Dbg("挂机,and CallState is %s.", strValue.GetData());
+				m_fsm.m_bAgentHandFree = TRUE;
 			}
-			break;
+			CSimpleStringA strValue;
+			GetFunction()->GetSysVar("CallState", strValue);
+			Dbg("挂机,and CallState is %s.", strValue.GetData());
+		}
+		break;
 		case EVENT_MOD_CONNECT_PICKUP_CALL: // 提机呼叫
-			{
-				if (m_bHasLaunched){
-					Dbg("提机呼叫");
-					m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_PICKUP_CALL));
-				}
-				else{
-					Dbg("UI has not launched, ignore it.");
-				}
+		{
+			if (m_bHasLaunched){
+				Dbg("提机呼叫");
+				m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_PICKUP_CALL));
 			}
-			break;
+			else{
+				Dbg("UI has not launched, ignore it.");
+			}
+		}
+		break;
 		case EVENT_MOD_CONNECT_HANDFREE_CALL: // 免提呼叫
 			if (m_fsm.m_bHandFree)
 			{
@@ -346,7 +346,6 @@ using namespace CounterConnector;
 		case EVENT_MOD_CONNECT_HANNUP_BY_AGENT: // 授权操作
 			m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_AGENT_WRITABLE));
 
-		case LOG_EVT_DISTRIBUTE_ASSISTANTCHANNEL_IDLE:
 		case LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE:		//若assistchannel重启
 			Dbg("user_code = %08x", dwUserCode);
 			m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_ASSISTCHAN_IDEL));
@@ -468,27 +467,23 @@ using namespace CounterConnector;
 				Dbg("offline state,ignore UI_STARTPHOTOGRAPH hangup event");
 			}
 			break;
-		case LOG_EVT_DISTRIBUTE_SIPPHONE_IDLE:  //sip话机状态重置
-			Dbg("recv LOG_EVT_DISTRIBUTE_SIPPHONE_IDLE");
-			m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_SIPPHONE_IDEL));
-			break;
 
 		default:
 			break;
 		}
 	}
 
-	CServerSessionBase*CCounterConnectorEntity::OnNewSession(const char* /*pszRemoteEntityName*/, const char* /*pszClass*/)
-	{
-		LOG_FUNCTION();
-		m_pCurrentSession = new CCounterConnectorSession(this);
-		return m_pCurrentSession;
-	}
+CServerSessionBase*CCounterConnectorEntity::OnNewSession(const char* /*pszRemoteEntityName*/, const char* /*pszClass*/)
+{
+	LOG_FUNCTION();
+	m_pCurrentSession = new CCounterConnectorSession(this);
+	return m_pCurrentSession;
+}
 
-	bool CCounterConnectorEntity ::IsService() const
-	{
-		return true;
-	}
+bool CCounterConnectorEntity ::IsService() const
+{
+	return true;
+}
 
 	//change audio device message
 	void CCounterConnectorEntity ::OnReceivePkt(int type, int sub_type, const char *buffer, int size)
@@ -589,82 +584,82 @@ using namespace CounterConnector;
 		m_bIsRemoteRecordStopSpeakerCapture = FALSE;
 	}
 
-	void CCounterConnectorEntity::StopRemoteRecordSpeakerAudioCapture()
-	{
-		if(DOUBLERECORD_CALLTYPE == m_fsm.m_CallingParam.nCallType){
-			if (TRUE == m_IsStand2SType){
-				if (FALSE == m_bIsRemoteRecordStopSpeakerCapture){
-					if (Error_Succeed == m_fsm.StopSpeakerAudioCapture()){
-						m_bIsRemoteRecordStopSpeakerCapture = TRUE;
-					}
-				}
-				else{
-					Dbg("remote record has stop speaker capture.");
+void CCounterConnectorEntity::StopRemoteRecordSpeakerAudioCapture()
+{
+	if(DOUBLERECORD_CALLTYPE == m_fsm.m_CallingParam.nCallType){
+		if (TRUE == m_IsStand2SType){
+			if (FALSE == m_bIsRemoteRecordStopSpeakerCapture){
+				if (Error_Succeed == m_fsm.StopSpeakerAudioCapture()){
+					m_bIsRemoteRecordStopSpeakerCapture = TRUE;
 				}
 			}
+			else{
+				Dbg("remote record has stop speaker capture.");
+			}
 		}
 	}
+}
 
-	void CCounterConnectorEntity::Handle_StartRecordPreview(const char* pszMessage)
-	{
-		CSimpleStringA strMsg = pszMessage;
-		if (strMsg.IsStartWith("ews|",true)){
-			strMsg = strMsg.SubString(4,strMsg.GetLength()-4);
-		}
-
-		CSimpleStringA strVideo;
-		strVideo = ConstructVideoRenderParam(strMsg, false);						
-		m_fsm.PostEventFIFO(new ShowLocalVideoEvent(strVideo));									// 非连坐席双录
-		m_bIsSalesRecord = TRUE;
+void CCounterConnectorEntity::Handle_StartRecordPreview(const char* pszMessage)
+{
+	CSimpleStringA strMsg = pszMessage;
+	if (strMsg.IsStartWith("ews|",true)){
+		strMsg = strMsg.SubString(4,strMsg.GetLength()-4);
 	}
 
-	//send cur audio device to agent 
-	void CCounterConnectorEntity ::SendCurAudioDevice()
+	CSimpleStringA strVideo;
+	strVideo = ConstructVideoRenderParam(strMsg, false);						
+	m_fsm.PostEventFIFO(new ShowLocalVideoEvent(strVideo));									// 非连坐席双录
+	m_bIsSalesRecord = TRUE;
+}
+
+//send cur audio device to agent 
+void CCounterConnectorEntity ::SendCurAudioDevice()
+{
+	if (m_fsm.m_nSysCallType == 0)
 	{
-		if (m_fsm.m_nSysCallType == 0)
+		ChannelService_Send_Info Info;
+		Info.compress = false;
+		Info.encrypt = false;
+		Info.type = ACM_TYPE_DEVICE;
+		Info.id = 0;
+		Info.sub_type = ACM_AUDIO_DEVICE;
+		Info.data.Alloc(sizeof(int));
+		SpBuffer buf;
+		buf.OpenWrite();
+		int nDevice = 0;
+		if (m_fsm.m_bIsAgentControl)
 		{
-			ChannelService_Send_Info Info;
-			Info.compress = false;
-			Info.encrypt = false;
-			Info.type = ACM_TYPE_DEVICE;
-			Info.id = 0;
-			Info.sub_type = ACM_AUDIO_DEVICE;
-			Info.data.Alloc(sizeof(int));
-			SpBuffer buf;
-			buf.OpenWrite();
-			int nDevice = 0;
-			if (m_fsm.m_bIsAgentControl)
+			if (m_fsm.m_bAgentHandFree)
 			{
-				if (m_fsm.m_bAgentHandFree)
-				{
-					nDevice = 0;
-				}
-				else
-				{
-					nDevice = 1;
-				}
-			} 
+				nDevice = 0;
+			}
 			else
 			{
-				if (m_fsm.m_bHandFree)
-				{
-					nDevice = 0;
-				} 
-				else
-				{
-					nDevice = 1;
-				}
+				nDevice = 1;
 			}
-			buf & nDevice;
-			Info.data = buf.ToBlob();
-			m_pCounterConnectorChannel->Send(Info);
-			Dbg("send cur Audio device = %d",nDevice);
-		}
+		} 
 		else
 		{
-			Dbg("cur call type cannot send pkt");
+			if (m_fsm.m_bHandFree)
+			{
+				nDevice = 0;
+			} 
+			else
+			{
+				nDevice = 1;
+			}
 		}
+		buf & nDevice;
+		Info.data = buf.ToBlob();
+		m_pCounterConnectorChannel->Send(Info);
+		Dbg("send cur Audio device = %d",nDevice);
 	}
+	else
+	{
+		Dbg("cur call type cannot send pkt");
+	}
+}
 
 void CCounterConnectorEntity::SetCallType(CallingTypeEnum eType)
 {

+ 15 - 3
Other/libaudioframework/audiomicspkpulse.c

@@ -469,7 +469,7 @@ static void  stream_write_request_cb(pa_stream* s, size_t length, void* data)
 								audio_micspk->on_audio_playing((void*)delaybuffer, RVC_DELAY_AUDIO_LEN, audio_micspk->user_data);
 							}
 							else {
-								audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d on_audio_playing IS NULL.", __FUNCTION__, __LINE__);
+								audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d on_audio_playing is NULL.", __FUNCTION__, __LINE__);
 							}
 							//if (0 == audio_micspk->on_audio_play_ns(audionsbuffer, RVC_DELAY_AUDIO_LEN, delaybuffer, RVC_DELAY_AUDIO_LEN, audio_micspk->user_data)) {
 								if (audio_ctx->uaudio_len + RVC_DELAY_AUDIO_LEN < RVC_MAX_AUDIO_BUFFER_LEN) {
@@ -902,7 +902,13 @@ int audio_stop_playaudio(audio_context_t* audio_ctx)
 	if (AUDIO_STRM_ON == audio_ctx->play_stream_flag){
 		audio_ctx->play_stream_flag = AUDIO_STRM_OFF;
 		if (0 != audio_ctx->writethreadid) {
-			if (0 == pthread_join(audio_ctx->writethreadid, NULL)) {
+			//if (0 == pthread_join(audio_ctx->writethreadid, NULL)) {
+			struct timespec ts;
+			clock_gettime(CLOCK_REALTIME, &ts);
+			long unsec = ts.tv_nsec + (1000 * 1000 * 1000);
+			ts.tv_sec += (unsec / 1000000000);
+			ts.tv_nsec = (unsec % 1000000000);
+			if (0 == pthread_timedjoin_np(audio_ctx->writethreadid, NULL, &ts)) {
 				audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d pulse audio write thread %u joined success.", __FUNCTION__, __LINE__, audio_ctx->writethreadid);
 				audio_ctx->writethreadid = 0;
 			}
@@ -922,7 +928,13 @@ int audio_stop_pulseaudio(audio_context_t* audio_ctx)
 	if (AUDIO_STRM_ON == audio_ctx->stream_flag){
 		audio_ctx->stream_flag = AUDIO_STRM_OFF;
 		if (0 != audio_ctx->readthreadid){
-			if (0 == pthread_join(audio_ctx->readthreadid, NULL)) {
+			//if (0 == pthread_join(audio_ctx->readthreadid, NULL)) {
+			struct timespec ts;
+			clock_gettime(CLOCK_REALTIME, &ts);
+			long unsec = ts.tv_nsec + (1000 * 1000 * 1000);
+			ts.tv_sec += (unsec / 1000000000);
+			ts.tv_nsec = (unsec % 1000000000);
+			if (0 == pthread_timedjoin_np(audio_ctx->readthreadid, NULL, &ts)) {
 				audio_log_v(AUDIO_LOG_LEVEL_INFO, "%s:%d pulse audio read thread %u joined success.", __FUNCTION__, __LINE__, audio_ctx->readthreadid);
 				audio_ctx->readthreadid = 0;
 			}

+ 7 - 26
Other/libwmvrecord/FFmpegWriter.cpp

@@ -111,10 +111,11 @@ static bool add_stream(LogApi* pLogApi, OutputStream *ost, AVFormatContext *oc,
             (*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
         c->sample_rate = nSanplePsec;
         if ((*codec)->supported_samplerates) {
-            c->sample_rate = (*codec)->supported_samplerates[0];
+           // c->sample_rate = (*codec)->supported_samplerates[0];
             for (i = 0; (*codec)->supported_samplerates[i]; i++) {
-                if ((*codec)->supported_samplerates[i] == 44100)
-                    c->sample_rate = 44100;
+				pLogApi->Debug("(*codec)->supported_samplerates[%d] = %d.", i, (*codec)->supported_samplerates[i]);
+                //if ((*codec)->supported_samplerates[i] == 44100)
+                //    c->sample_rate = 44100;
             }
         }
 		if (nchannels == 2){
@@ -450,29 +451,7 @@ static bool open_video(LogApi* pLogApi, AVFormatContext *oc, AVCodec *codec, Out
 	return true;
 }
 
-/* Prepare a dummy image. */
-static void fill_yuv_image(AVFrame *pict, int frame_index,
-                           int width, int height)
-{
-    int x, y, i;
-
-    i = frame_index;
-
-    /* Y */
-    for (y = 0; y < height; y++)
-        for (x = 0; x < width; x++)
-            pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3;
-
-    /* Cb and Cr */
-    for (y = 0; y < height / 2; y++) {
-        for (x = 0; x < width / 2; x++) {
-            pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2;
-            pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5;
-        }
-    }
-}
-
-static AVFrame *get_video_frame(OutputStream *ost, char *data, int len, AVPixelFormat input_pix_fmt)
+static AVFrame *get_video_frame(LogApi* pLogApi, OutputStream *ost, char *data, int len, AVPixelFormat input_pix_fmt)
 {
     AVCodecContext *c = ost->enc;
 
@@ -619,6 +598,8 @@ bool FFmpegWmvWriter::InitWmvWriter(char* filename, int width, int height, int c
     //av_log_set_level(AV_LOG_DEBUG);
     //av_log_set_callback(log_callback);
     fmt = oc->oformat;
+	m_pLogApi->Debug("real output format name of '%s' is %s, long_name is %s, mime_type is %s, extensions is %s.", filename, fmt->name, fmt->long_name, fmt->mime_type, fmt->extensions);
+
     video_st = new OutputStream();
     audio_st = new OutputStream();
 

+ 12 - 12
Other/libwmvrecord/libwmvrecord.cpp

@@ -1321,10 +1321,10 @@ int libwmvrecord_impl::VideoRecord()
 	int nVideoSizeFailedTimes = 0, nAudioSizeFailedTimes = 0;
 
 	if (m_bWholeSection || !m_bSessionManage) {
-		snprintf(m_WmvFileName, MAX_PATH, "%s%s_%d.wmv", m_PathName, m_FileName, WmvFileSerialNum);
+		snprintf(m_WmvFileName, MAX_PATH, "%s%s_%d.%s", m_PathName, m_FileName, WmvFileSerialNum, RVC_RECORD_SUFFIX);
 	}
 	else {
-		snprintf(m_WmvFileName, MAX_PATH, "%s%s_%d_end.wmv", m_PathName, m_FileName, WmvFileSerialNum);
+		snprintf(m_WmvFileName, MAX_PATH, "%s%s_%d_end.%s", m_PathName, m_FileName, WmvFileSerialNum, RVC_RECORD_SUFFIX);
 	}
 	m_pHostApi->Debug(RECORD_LOG_INFO, "m_WmvFileName = %s", m_WmvFileName);
 
@@ -1902,21 +1902,21 @@ int libwmvrecord_impl::VideoRecord()
 							if (WmvFileSerialNum > 0)//如果当前文件序号大于0,说明前一个文件与当前文件是同一个SESSION,需要修改前一个文件名+END,否则直接改当前文件的文件名
 							{
 								//sessionid切换,前一个文件需要加上END
-								char m_NewFileName[MAX_PATH];
-								char m_OldFileName[MAX_PATH];
+								char m_NewFileName[MAX_PATH] = {0};
+								char m_OldFileName[MAX_PATH] = {0};
 								string FileName(m_WmvFileName);
 								string name = FileName.substr(0, FileName.find_first_of('_') + 1);
 								//m_pHostApi->Debug("renamefile1 name =  %s",name.c_str());
 								//前一个文件名
-								snprintf(m_OldFileName, MAX_PATH, "%s%d.wmv", name.c_str(), WmvFileSerialNum - 1);
-								snprintf(m_NewFileName, MAX_PATH, "%s%d_end.wmv", name.c_str(), WmvFileSerialNum - 1);
+								snprintf(m_OldFileName, MAX_PATH, "%s%d.%s", name.c_str(), WmvFileSerialNum - 1, RVC_RECORD_SUFFIX);
+								snprintf(m_NewFileName, MAX_PATH, "%s%d_end.%s", name.c_str(), WmvFileSerialNum - 1, RVC_RECORD_SUFFIX);
 								m_pHostApi->Debug(RECORD_LOG_INFO, "renamefile1 from %s to %s", m_OldFileName, m_NewFileName);
 								ReNameFile(m_OldFileName, m_NewFileName);
 							}
 							//sessionid切换,当前文件需要重命名
-							char m_NewFileName[MAX_PATH];
+							char m_NewFileName[MAX_PATH] = {0};
 							WmvFileSerialNum = 0;
-							snprintf(m_NewFileName, MAX_PATH, "%s%s_%d.wmv", m_PathName, m_FileName, WmvFileSerialNum);
+							snprintf(m_NewFileName, MAX_PATH, "%s%s_%d.%s", m_PathName, m_FileName, WmvFileSerialNum, RVC_RECORD_SUFFIX);
 							m_pHostApi->Debug(RECORD_LOG_INFO, "renamefile2 from %s to %s", m_WmvFileName, m_NewFileName);
 							if (ReNameFile(m_WmvFileName, m_NewFileName)) {
 								WmvFileSerialNum++;
@@ -1926,15 +1926,15 @@ int libwmvrecord_impl::VideoRecord()
 						else
 						{
 							//继续录像,删除当前文件的"END"
-							char m_NewFileName[MAX_PATH];
-							snprintf(m_NewFileName, MAX_PATH, "%s%s_%d.wmv", m_PathName, m_FileName, WmvFileSerialNum);
+							char m_NewFileName[MAX_PATH] = {0};
+							snprintf(m_NewFileName, MAX_PATH, "%s%s_%d.%s", m_PathName, m_FileName, WmvFileSerialNum, RVC_RECORD_SUFFIX);
 							m_pHostApi->Debug(RECORD_LOG_INFO, "renamefile3 from %s to %s", m_WmvFileName, m_NewFileName);
 							ReNameFile(m_WmvFileName, m_NewFileName);
 							//WMV文件的序列号
 							WmvFileSerialNum++;
 						}
 						//新文件增加END
-						snprintf(m_WmvFileName, MAX_PATH, "%s%s_%d_end.wmv", m_PathName, m_FileName, WmvFileSerialNum);
+						snprintf(m_WmvFileName, MAX_PATH, "%s%s_%d_end.%s", m_PathName, m_FileName, WmvFileSerialNum, RVC_RECORD_SUFFIX);
 						m_pHostApi->Debug(RECORD_LOG_INFO, "generate new file name %s", m_WmvFileName);
 						m_bCloseVideo = FALSE;
 					}
@@ -1942,7 +1942,7 @@ int libwmvrecord_impl::VideoRecord()
 					{
 						//WMV文件的序列号
 						WmvFileSerialNum++;
-						snprintf(m_WmvFileName, MAX_PATH, "%s%s_%d.wmv", m_PathName, m_FileName, WmvFileSerialNum);
+						snprintf(m_WmvFileName, MAX_PATH, "%s%s_%d.%s", m_PathName, m_FileName, WmvFileSerialNum, RVC_RECORD_SUFFIX);
 					}
 				}
 			}

+ 4 - 0
Other/libwmvrecord/libwmvrecord.h

@@ -26,6 +26,10 @@
 
 #define WMVREC_MAX_FILE   600000  //wmv文件最大容量10分钟,超出大小后另辟文件保存
 
+#ifndef RVC_RECORD_SUFFIX 
+#define RVC_RECORD_SUFFIX "mp4"
+#endif
+
 enum eStereoArrayType{
 	eLocalLeft,					
 	eRemoteLeft