SendFax过程分析
传真的发送过程:
1 点击事件的响应函数 CDlgFaxAreaSend::OnButtonClicked
void CDlgFaxAreaSend::OnButtonClicked(UINT nID)
{
switch (nID)
{
case IDC_STATIC_FAX_SEND_BUTTON+3:
{
CString data;
CString temp;
char buff[256];
char path[256];
flog("IDC_STATIC_FAX_SEND_BUTTON+3:sendfax %d",strlen(m_sendpath));
if (strlen(m_sendpath)<=0)
{
m_edit_send_data.GetWindowText(data);
if (strlen(data.GetBuffer(data.GetLength()))<=0)
{
// MessageBox("发送数据不能为空");
return;
}
CFile f;
CFileException e;
m_manage->GetCommonPath(path);
sprintf(buff,"%ssend\\temp.txt",path);
//char* pFileName = buff;
if(!f.Open(buff, CFile::modeCreate | CFile::modeWrite,&e))
{
return;
#ifdef _DEBUG
afxDump<<"File could not be opened"<<e.m_cause<<"\n";
#endif
}
else
{
f.Write((const char*)data,strlen(data));
f.Close();
sprintf(m_sendpath,"%s","temp.txt");
m_static_path.SetWindowText("temp.txt");
MSGINFO t_info;
FaxPath t_faxpath;
memset(&t_info,0,sizeof(MSGINFO));
memset(&t_faxpath,0,sizeof(FaxPath));
sprintf(t_faxpath.path,"%s",buff);
t_info.msgType = SET_FAX_FILE_PATH;
memcpy(t_info.buff,&t_faxpath,sizeof(FaxPath));
flog("sendSET_FAX_FILE_PATH");
m_manage->InsertSendQue(t_info);
}
}
m_edit_send_user.GetWindowText(temp);
if (strlen(temp.GetBuffer(temp.GetLength()))<=0)
{
// MessageBox("收件人不能为空");
return;
}
flog("CDlgFaxAreaSend::OnButtonClicked faxword:%s",temp);
int i = 1;
FaxBook t_book;
MSGINFO t_info1;
PhoneInfo t_phone;
while(0<GetMsg(i,t_book))
{
memset(&t_info1,0,sizeof(MSGINFO));
t_info1.msgType = FAX_SEND_NUM;
memset(&t_phone,0,sizeof(PhoneInfo));
strcpy(t_phone.phone,t_book.faxnum);
memcpy(t_info1.buff,&t_phone,sizeof(PhoneInfo));
flog("t_phone:%s",t_book.faxnum);
m_manage->InsertSendQue(t_info1);
i++;
}
flog("faxbye");
// m_edit_send_user.SetWindowText(_T(""));
// m_static_path.SetWindowText(_T(""));
// ClearMsg();
// m_count = 0;
}
break;
default:break;
}
}
2 ManageQue.InsertSendQue 消息发送
int ManageQue::InsertSendQue(MSGINFO &t_msg)
{
m_send_mutex.Lock();
t_send_que.push_back(t_msg);
m_send_mutex.Unlock();
return 0;
}
3 ManageQue.GetSendQue消息读取
int ManageQue::GetSendQue(MSGINFO &t_msg)
{
m_send_mutex.Lock();
if (t_send_que.size()<=0)
{
m_send_mutex.Unlock();
return -1;
}
memset(&t_msg,0,sizeof(MSGINFO));
memcpy(&t_msg,&t_send_que.front(),sizeof(MSGINFO));
t_send_que.pop_front();
m_send_mutex.Unlock();
return 0;
}
4 处理send队列消息MainManage.ProcessSendMsg
void MainManage::ProcessSendMsg()
{
ChangeBitmap *t_wich = NULL;
int ret;
MSGINFO t_msg;
memset(&t_msg,0,sizeof(t_msg));
Msg_Head t_head;
memset(&t_head,0,sizeof(Msg_Head));
struct PhoneInfo t_phoneinfo;
ret = GetSendQue(t_msg);
if (ret<0)
{
return;
}
int type = t_msg.msgType;
flog("type = %d",type);
switch(type)
{
case FAX_PATH:
{
}
break;
case SET_FAX_FILE_PATH:
{
FaxPath t_path;
memset(&t_path,0,sizeof(FaxPath));
memcpy(&t_path,t_msg.buff,sizeof(FaxPath));
m_msginterface->SetFilePathName(t_path.path);
char buff[100];
sprintf(buff,"发送文件路径path:%s",t_path.path);
userlog.WriteData(t_path.path);
}
break;
case FAX_SEND_NUM:
{
char buff[256];
PhoneInfo t_info;
memset(&t_info,0,sizeof(PhoneInfo));
memcpy(&t_info,t_msg.buff,sizeof(PhoneInfo));
ret = m_msginterface->SendFax(t_info.phone);
if (ret<0)
{
sprintf(buff,"ret = %d,phone = %s发送传真失败",ret,t_info.phone);
userlog.WriteData(buff);
flog(buff);
//MessageBox(NULL,"bbbbbbbbbbbbbbbbbbbbbbbbb","tishi",0);
return;
}
// userlog.WriteData("发送传真信令成功");
flog("MainManage::ProcessSendMsg ret = %d,phone = %s发送传真",ret,t_info.phone);
}
break;
case FAX_RECV_NUM:
{
}
break;
case DITCHER:
{
m_msginterface->SetFax(false);
m_title_menu = DITCHER_TITLE;
}
break;
case RADIO:
m_msginterface->SetFax(false);
m_title_menu = RADIO_TITLE;
break;
case FAX://#define FAX 9013
m_msginterface->SetFax(true);
break;
case NOTE:
m_msginterface->SetFax(false);
break;
}
return ;
}
5 设置fax文件位置 MsgInterface.SetFilePathName
void MsgInterface::SetFilePathName(char* filename)
{
flog("MsgInterface::SetFilePathName %s",filename);
if (strlen(filename)<=0)
{
userLog.WriteData("filename is null");
return;
}
memset(m_filepathname,0,sizeof(m_filepathname));
strcpy(m_filepathname,filename);
}
6 发送fax MsgInterface.SendFax
int MsgInterface::SendFax(char* phone)
{
int ret = -1;
if (m_isReg==false)
{
printf("注册失败!\n");
return -1;
}
if (strlen(phone)<=0)
{
return -2;
}
flog("MsgInterface::SendFax");
char buff[256];
Req_Fax t_req;
memset(&t_req,0,sizeof(Req_Fax));
strcpy(t_req.callerfaxphone,m_faxphone);
strcpy(t_req.calledfaxphone,phone);
FaxPacket t_packet;
memset(&t_packet,0,sizeof(FaxPacket));
FaxControlProcess *faxpro = new FaxControlProcess;
userLog.WriteData(m_fax_sendpath);
flog("m_fax_sendpath %s",m_fax_sendpath);
// GetFaxSendPath();
faxpro->SetControlRootPath(m_fax_sendpath);
struct FaxConArg arg;
faxpro->GetLocalFaxConfig(arg);
t_req.faxMedia.data_redundancy = arg.data_redundancy;
t_req.faxMedia.numFEC = arg.numFEC;
t_req.faxMedia.numIFPs = arg.numIFPs;
t_req.faxMedia.t30_redundancy = arg.t30_redundancy;
t_req.faxMedia.t38FaxMaxDatagram = arg.t38FaxMaxDatagram;
int t38FaxRateManagement = atoi(arg.t38FaxRateManagement);
t_req.faxMedia.t38FaxRateManagement = t38FaxRateManagement;
int t38FaxUdpEC = atoi(arg.T38FaxUdpEC);
t_req.faxMedia.T38FaxUdpEC = t38FaxUdpEC;
t_req.faxMedia.t38FillBitRemoval = arg.t38FillBitRemoval;
GetLocalHost(t_req.faxMedia.ip);
t_packet.port = GetFaxPort();
t_packet.faxprol = NULL;
t_req.faxMedia.port = t_packet.port;
Getfaxid(t_req.faxid);
sprintf(buff,"phone = %s,faxid = %s,faxphone=%s, port = %d",phone,t_req.faxid,m_faxphone,t_req.faxMedia.port);
userLog.WriteData(buff);
flog("buff=%s",buff);
arg.isCaller = true;
strcpy(t_packet.phone,m_faxphone);
strcpy(t_packet.calledphone,phone);
strcpy(t_packet.faxID,t_req.faxid);
int comID = REQ_CALL_FAX;
int seqID = m_tcpMsgProcess->getSeqID();
MsgInfo t_info;
memset(&t_info,0,sizeof(MsgInfo));
t_info.comID = comID;
t_info.len = sizeof(Req_Fax);
memcpy(t_info.data,&t_req,sizeof(Req_Fax));
GetClientNameID(LEFT_HANDLE,t_info.clientID);
flog("SendMsg");
SendMsg(seqID,t_info);
t_packet.seqID = seqID;
t_packet.type = SEND_FAX;
flog("InsertSendFaxPacket");
InsertSendFaxPacket(t_packet);
return 0;
}
7发送消息MsgInterface.SendMsg
输入:seqID msginfo.comID msginfo.len msginfo.clientID msginfo.data
输出:发送到队列 g_send_msg_que
int MsgInterface::SendMsg(int seqID,MsgInfo msginfo)
{
MsgPack msg_pack_t;
memset(&msg_pack_t,0,sizeof(msg_pack_t));
msg_pack_t.std_head.seqID = seqID;
msg_pack_t.std_head.comID = msginfo.comID;
msg_pack_t.std_head.bodyLen = msginfo.len;
strcpy(msg_pack_t.std_head.clientID,msginfo.clientID);
printf("len = %d\n",msginfo.len);
memcpy(msg_pack_t.data,msginfo.data,msginfo.len);
m_tcpMsgProcess->PutData(msg_pack_t);
char buff[100];
char buff2[128];
memset(buff,0,sizeof(buff));
memset(buff2,0,sizeof(buff2));
SYSTEMTIME lpsystime;
GetLocalTime(&lpsystime);
sprintf(buff,"%u-%u-%u %u:%u:%u:%u\n",lpsystime.wYear,lpsystime.wMonth,lpsystime.wDay,lpsystime.wHour,lpsystime.wMinute,lpsystime.wSecond,lpsystime.wMilliseconds);
sprintf(buff2,"发送消息seqID=%d,comID=%d,len = %d,clientID=%s,time=%s",seqID,msginfo.comID,msginfo.len,msginfo.clientID,buff);
userLog.WriteData(buff2);
return 0;
}
8 数据进入消息发送队列TcpMsgProcess.PutData
TcpMsgProcess::SendMessage()会从这个队列里去不断读取数据进行处理
void TcpMsgProcess::PutData(MsgPack &t_p_pack)
{
g_send_mutex.Lock();
g_send_msg_que.push_back(t_p_pack);
g_send_mutex.Unlock();
return;
}
9处理要发送的消息TcpMsgProcess.SendMessage
调用函数m_tcpApi.SendMsg来发包
void TcpMsgProcess::SendMessage()
{
int ret;
MsgPack t_pack_t;
close_mutex.Lock();
if (!m_tcpApi.MsgIsOpen())
{
printf("msg is open failed!\n");
// ::MessageBox(NULL,"tcp库关闭","提示",0);
close_mutex.Unlock();
goto SendMessage_error;
}
close_mutex.Unlock();
m_curtime = GetTickCount();
if ((m_curtime-m_oldtime)>=10*1000)
{
printf("time22 = %d\n", m_curtime-m_oldtime);
memset(&t_pack_t, 0, sizeof(MsgPack));
t_pack_t.std_head.comID = KEEP_ALIVE;
ret = m_tcpApi.SendMsg(t_pack_t.data, sizeof(Req_ClientKeepalive) , t_pack_t.std_head.comID, t_pack_t.std_head.seqID,t_pack_t.std_head.clientID);
if (ret < 0)
{
//::MessageBox(NULL,"发送消息失败","提示",0);
printf("sendmsg error11!\n");
if (m_msgcallback!=NULL)
{
m_msgcallback->sendMsgError();
}
else
Sleep(10);
m_msgcallback = NULL;
goto SendMessage_error;
}
m_oldtime = GetTickCount();
}
g_send_mutex.Lock();
while(g_send_msg_que.size()>0)
{
memset(&t_pack_t,0, sizeof(MsgPack));
memcpy(&t_pack_t, &(g_send_msg_que.front()), sizeof(MsgPack));
g_send_msg_que.pop_front();
g_send_mutex.Unlock();
flog("TcpMsgProcess::SendMessage");
ret = m_tcpApi.SendMsg(t_pack_t.data, t_pack_t.std_head.bodyLen , t_pack_t.std_head.comID, t_pack_t.std_head.seqID,t_pack_t.std_head.clientID);
if (ret < 0)
{
//::MessageBox(NULL,"发送消息失败22","提示",0);
printf("sendmsg error22!\n");
if (m_msgcallback != NULL)
{
m_msgcallback->sendMsgError();
}
else
Sleep(10);
m_msgcallback = NULL;
g_send_mutex.Lock();
g_send_msg_que.push_front(t_pack_t);
g_send_mutex.Unlock();
goto SendMessage_error;
}
g_send_mutex.Lock();
}
g_send_mutex.Unlock();
Sleep(10);
return;
SendMessage_error:
ErrorConnect();
Sleep(10);
return;
}
10 发包函数m_tcpApi.SendMsg
int TcpApi::SendMsg(const char *data, const size_t len , int comID, int seqID,char* clientID)
{
int ret;
int n=0;
MsgPack send_head;
int number = sizeof(MsgHead)+len;
memset(&send_head, 0, sizeof send_head);
send_head.std_head.bodyLen = len;
send_head.std_head.comID = comID;
send_head.std_head.seqID = seqID;
strcpy(send_head.std_head.clientID,clientID);
memcpy(send_head.data , data , len);
while (n<number)
{
ret = send(m_msocket,(char *)&send_head+n,number-n,0);
if (ret <= 0)
{
printf("send data not finish!\n");
return -1;
}
n += ret;
}
flog("TcpApi::SendMsg len=%d comid=%d seqid=%d clientid=%s",n,comID,seqID,clientID);
//fdata((unsigned char *)&send_head,n);
printf("len123 = %d\n",len);
return 0;
}
11 tcp数据接收线程TcpMsgPReciveThread
void * TcpMsgPReciveThread::Thread()
{
JThread::ThreadStarted();
while (stop == false)
{
m_msgprocess.ReciveMessage();
}
return NULL;
}
12 tcp数据接收的实现TcpMsgProcess.ReciveMessage
数据接收完整后放入到g_recv_msg_que队列
void TcpMsgProcess::ReciveMessage()
{
//**********************************
MsgHead t_p_msg;
MsgPack t_pack_t;
int ret;
memset(&t_p_msg, 0 , sizeof(MsgHead));
memset(&t_pack_t, 0, sizeof(MsgPack));
close_mutex.Lock();
if (!m_tcpApi.MsgIsOpen())
{
printf("open failed!\n");
close_mutex.Unlock();
goto ReciveMessage_error;
}
close_mutex.Unlock();
ret = m_tcpApi.ReciveMsgHead(&(t_p_msg.bodyLen),&(t_p_msg.comID),&(t_p_msg.seqID),t_p_msg.clientID);
if (ret < 0 )
{
printf("recv head`````````````\n");
if (m_msgcallback != NULL)
{
m_msgcallback->sendMsgError();
}
else
Sleep(10);
m_msgcallback = NULL;
goto ReciveMessage_error;
}
t_pack_t.std_head.bodyLen = t_p_msg.bodyLen;
t_pack_t.std_head.comID = t_p_msg.comID;
t_pack_t.std_head.seqID = t_p_msg.seqID;
strcpy(t_pack_t.std_head.clientID,t_p_msg.clientID);
if ( t_pack_t.std_head.bodyLen > MAX_MSG_DATA_LEN)
{
printf("bodylen error`````````````\n");
if (m_msgcallback!=NULL)
{
printf("cccccc\n");
m_msgcallback->sendMsgError();
}
else
Sleep(10);
m_msgcallback = NULL;
goto ReciveMessage_error;
}
ret = m_tcpApi.ReciveData(t_pack_t.data, t_pack_t.std_head.bodyLen);
if (ret != 0)
{
printf("recv data`````````````\n");
if (m_msgcallback != NULL)
{
m_msgcallback->sendMsgError();
}
else
Sleep(10);
m_msgcallback = NULL;
goto ReciveMessage_error;
}
if (t_p_msg.comID == RSQ_ALIVE)
{
printf("RSQ_ALIVE is successful!\n");
return;
}
g_recv_mutex.Lock();
g_recv_msg_que.push_back(t_pack_t);
g_recv_mutex.Unlock();
return;
ReciveMessage_error :
ErrorConnect();
Sleep(10);
return;
//*********************************************************************
}
13 数据接收队列的接收端TcpMsgProcess.GetData MsgRecvInterface.ProcessRecv
int TcpMsgProcess::GetData(MsgPack &t_p_pack)
{
memset(&t_p_pack,0,sizeof(t_p_pack));
g_recv_mutex.Lock();
if (g_recv_msg_que.size()>0)
{
memcpy(&t_p_pack,&(g_recv_msg_que.front()),sizeof(MsgPack));
g_recv_msg_que.pop_front();
g_recv_mutex.Unlock();
return 0;
}
g_recv_mutex.Unlock();
return -1;
}
void MsgRecvInterface::ProcessRecv()
{
MsgPack msg_pack_t;
g_recv_mutex.Lock();
if(g_recv_msg_que.size()>0)
{
memset(&msg_pack_t,0,sizeof(msg_pack_t));
memcpy(&msg_pack_t,&g_recv_msg_que.front(),sizeof(msg_pack_t));
g_recv_msg_que.pop_front();
g_recv_mutex.Unlock();
// char buff[100];
// sprintf(buff,"seqID = %d,comID = %d,len = %d,clientID=%s",msg_pack_t.std_head.seqID,msg_pack_t.std_head.comID,msg_pack_t.std_head.bodyLen,msg_pack_t.std_head.clientID);
// userLog.WriteData(buff);
JudgeComID(msg_pack_t);
return;
}
else
{
Sleep(10);
}
g_recv_mutex.Unlock();
}
14 处理收到的消息MsgRecvInterface.JudgeComID
void MsgRecvInterface::JudgeComID(MsgPack msg_pack_t)
{
int comID = msg_pack_t.std_head.comID;
int len = msg_pack_t.std_head.bodyLen;
int seqID = msg_pack_t.std_head.seqID;
int ret = -1;
MsgInfo t_msginfo;
memset(&t_msginfo,0,sizeof(t_msginfo));
char buff[100];
char buff2[128];
memset(buff,0,sizeof(buff));
memset(buff2,0,sizeof(buff2));
SYSTEMTIME lpsystime;
GetLocalTime(&lpsystime);
sprintf(buff,"%u-%u-%u %u:%u:%u:%u\n",lpsystime.wYear,lpsystime.wMonth,lpsystime.wDay,lpsystime.wHour,lpsystime.wMinute,lpsystime.wSecond,lpsystime.wMilliseconds);
sprintf(buff2,"seqID = %d,comID = %d,len = %d,clientID=%s,time=%s",seqID,comID,len,msg_pack_t.std_head.clientID,buff);
userLog.WriteData(buff2);
...
if (comID==REQ_CALL_FAX)
{
flog("MsgRecvInterface::JudgeComID comID==REQ_CALL_FAX");
ret = ReqCallFax(msg_pack_t.data,len,seqID,comID);
}
if (comID==RSQ_CALL_FAX)
{
ret = RsqCallFax(msg_pack_t.data,len,seqID,comID);
}
if (comID==REQ_FAX_END)
{
ret = ReqFaxEnd(msg_pack_t.data,len,seqID,comID);
}
...
}
15 发送传真流程 MsgRecvInterface.RsqCallFax
int MsgRecvInterface::RsqCallFax(char* data, int len, int seqID,int comID)
{
char buff[256];
Req_Fax* t_req = (Req_Fax*)data;
sprintf(buff,"传真应答called = %s, caller=%s,faxid = %s, tagid = %s,ip=%s,port = %d",t_req->calledfaxphone,t_req->callerfaxphone,t_req->faxid,t_req->tagid,t_req->faxMedia.ip,t_req->faxMedia.port);
userLog.WriteData(buff);
FaxPacket t_packet;
memset(&t_packet,0,sizeof(FaxPacket));
int ret = m_msgInterface->FindFaxSendPacket(t_req->callerfaxphone,t_req->faxid,t_packet);
if (ret<0)
{
userLog.WriteData("查找号码失败");
return -1;
}
strcpy(t_packet.tagID,t_req->tagid);
strcpy(t_packet.faxID,t_req->faxid);
strcpy(t_packet.rhost,t_req->faxMedia.ip);
t_packet.rport = t_req->faxMedia.port;
memcpy(&t_packet.faxmedia,&t_req->faxMedia,sizeof(FaxMedia));
m_msgInterface->UpdateFaxSendPacket(t_packet);
//FaxControlProcess faxpro;
if (t_packet.faxprol==NULL)
{
t_packet.faxprol = new FaxControlProcess;
if (t_packet.faxprol==NULL)
{
userLog.WriteData("new faxcontrolprocess error !");
return -1;
}
}
char path[256];
m_msgInterface->GetFaxSendPath(path);
t_packet.faxprol->SetControlRootPath(path);
struct FaxConArg arg;
t_packet.faxprol->GetLocalFaxConfig(arg);
arg.isCaller = true;
char fileName[100];
memset(fileName,0,sizeof(fileName));
m_msgInterface->GetFilePathName(fileName);
if (strlen(fileName)<=0)
{
strcpy(fileName,"D:/My Documents/桌面/fax/318控制传真.doc");
}
sprintf(buff,"filename = %s, local port = %d",fileName,t_packet.port);
userLog.WriteData(fileName);
ret = t_packet.faxprol->SetNetIpPort(t_packet.port,t_req->faxMedia.ip,t_req->faxMedia.port);
if (ret<0)
{
sprintf(buff,"des host = %s, des port = %d, ret = %d, local port = %d",t_req->faxMedia.ip,t_req->faxMedia.port,ret,t_packet.port);
userLog.WriteData(buff);
return -2;
}
sprintf(buff,"des host = %s, des port = %d, ret = %d, local port = %d",t_req->faxMedia.ip,t_req->faxMedia.port,ret,t_packet.port);
userLog.WriteData(buff);
ret = t_packet.faxprol->StartFax(arg,fileName,NULL);
if (ret<0)
{
sprintf(buff,"ret = %d,filename = %s,开始传真线程失败",ret,fileName);
userLog.WriteData(buff);
return -2;
}
userLog.WriteData("开始发送传真线程成功");
return 0;
}
16 发送传真FaxControlProcess.StartFax FaxControlProcess.Thread
int FaxControlProcess::StartFax(struct FaxConArg &setFaxPar,const char *sendFile,const char *recvFile)
{
flog("FaxControlProcess::StartFax");
...
if(Start() != 0)
{
printf("fax thread start is fail!\n");
return -6;
}
return 0;
}
void * FaxControlProcess::Thread()
{
JThread::ThreadStarted();
InitFaxErrInform();
while (stop == false)
{
if(isSend)
{
if(!FileConvert(noTiffFile, tiffFile))
{
printf("SEND FileConver is fail:%s!\n",noTiffFile);
SetFaxLastErr(FAX_ERR_FILE_CONVERSION);
break;
}
FaxConSend();
}else
{
FaxConRecv();
if(!faxTransSuc)
break;
if(!FileConvert(tiffFile,noTiffFile))
{
printf("RECV FileConver is fail:%s!\n",noTiffFile);
SetFaxLastErr(FAX_ERR_FILE_CONVERSION);
break;
}
}
break;
}
stop = true;
return NULL;
}
17 文件格式转换FaxControlProcess.FileConvert
bool FaxControlProcess::FileConvert(std::string &inputPath, std::string &outPutPath)
{
if(strcmp(inputPath.c_str(), outPutPath.c_str()) == 0)
{
return true;
}
if(_access(outPutPath.c_str(), 0) == 0)
{
printf("out file is exsit:%s!\n",outPutPath.c_str());
return true;
}
CPrinterSettings Seting("SmartPrinter Pro"); // 设置打印机名称
int iRet;
bool retBool = false;
bool m_fApplyPageFlag = false;
if(m_fApplyPageFlag) /* 设置页眉 */
{
Seting.SetPageHeader("crong crc616 PageHeader",15,"Tahoma",25,25);
Seting.SetPageFooter("crong crc616 SetPageFooter",15,"Tahoma",25,25);
}else
{
Seting.SetPageHeader("");
Seting.SetPageFooter("");
}
Seting.SetPrintMaxPage(-1); // 打印前几页 ? -1: All Page
Seting.SetPageSize(9) ; // 标准页面 A4 A4 = 9
bool bSilent = true;
CConvertAgent *pConvertEngine = NULL;
pConvertEngine = new CConvertAgent();
printf("fax con srcfile: %s,dstfile %s",inputPath.c_str(),outPutPath.c_str());
if(pConvertEngine != NULL)
{
iRet = pConvertEngine->InitAgent("SmartPrinter Pro", 60, "Demo","Demo"/*,bSilent*/ );
if(iRet == SM_SUCCESS)
{
iRet = pConvertEngine->ConvertDoc(inputPath.c_str(),outPutPath.c_str());
retBool = true;
}
}
if(pConvertEngine != NULL)
{
delete pConvertEngine;
pConvertEngine = NULL;
}
return retBool;
}
18 传真发送FaxControlProcess.FaxConSend
int FaxControlProcess::FaxConSend()
{terminal_state_t t = NULL;struct timeval now, state, start, last;struct udptl_io io;uint8_t buf[2048];int len, last_state = 0;fd_set rdList;struct timeval selTv;int ret = 0;if((t = FaxConInit()) == NULL){printf("FaxConInit is fail!\n");SetFaxLastErr(FAX_ERR_FAXINIT);ReleaseSock();return -1;}io.send = terminal_send;udptl_register(t->t38_fe.t38->hudptl, &io, (void*)fd);gettimeofday(&now, NULL);state = now;start = now;while(1){if(stop){printf("is initiative stop!\n");SetFaxLastErr(FAX_ERR_INITI_DISCON);break;}FD_ZERO(&rdList);FD_SET(fd, &rdList);selTv.tv_sec = 0;selTv.tv_usec = 10000;ret = select(fd+1, &rdList, NULL, NULL, &selTv);if(ret < 0){printf("select is fail!\n");SetFaxLastErr(FAX_ERR_SELECT_TIMEOUT);break;}if(ret > 0 && FD_ISSET(fd, &rdList)){len = recv(fd, (char *)buf, sizeof(buf), 0);if(len > 0){printf("is recv file:%d\n",len);udptl_recv_proc(t->t38_fe.t38->hudptl,buf, len);}}//else//printf("select is timeout!\n");last = now;gettimeofday(&now, NULL);if(tvdiff_sec(now, start) > WATCHDOG_TOTAL_TIMEOUT || tvdiff_sec(now, state) > WATCHDOG_STATE_TIMEOUT){printf("time out \n");SetFaxLastErr(FAX_ERR_SEND_TIMEOUT);break;}terminal_send_timeout(t, tvdiff_us(now, last) * 8 / 1000);if(last_state != t30_get_status(t->t30)){last_state = t30_get_status(t->t30);state = now;}if(last_state == 12)//T30_PHASE_CALL_FINISHED{SetFaxLastErr(GetFaxt30LastErr(t));break;}}printf("Send faxTransSuc:%d,lastErr:%d\n", faxTransSuc, GetFaxLastErr());if(GetFaxLastErr() == T30_ERR_OK)faxTransSuc = true;udptl_unregister(t->t38_fe.t38->hudptl);terminal_free(t);ReleaseSock();return 0;
}
发送的主要函数是terminal_send_timeout
void udptl_register(void* handle, struct udptl_io *ops, void* data)
{struct udptl_struct *s =(struct udptl_struct *) handle;s->ops = ops;s->ops_data = data;
}
t->t38_fe.t38->hudptl是一个句柄struct udptl_struct *
struct udptl_struct
{/*! This option indicates the error correction scheme used in transmitted UDPTL* packets and expected in received UDPTL packets.*/int32_t error_correction_scheme;/*! This option indicates the number of error correction entries transmitted in* UDPTL packets and expected in received UDPTL packets.*/uint32_t error_correction_entries;/*! This option indicates the span of the error correction entries in transmitted* UDPTL packets (FEC only).*/uint32_t error_correction_span;/*! The maximum size UDPTL packet that can be accepted by* the remote device.*/int32_t far_max_datagram;/*! The maximum size UDPTL packet that we are prepared to* accept, or -1 if it hasn't been calculated since the last* changes were applied to the UDPTL structure.*/int32_t local_max_datagram;/*! The maximum IFP that can be submitted for sending* to the remote device. Calculated from far_max_datagram,* error_correction_scheme and error_correction_entries,* or -1 if it hasn't been calculated since the last* changes were applied to the UDPTL structure.*/int32_t far_max_ifp;/*! The maximum IFP that the local endpoint is prepared* to accept. Along with error_correction_scheme and* error_correction_entries, used to calculate local_max_datagram.*/int32_t local_max_ifp;uint32_t tx_seq_no;uint32_t rx_seq_no;uint32_t rx_expected_seq_no;uint8_t raw[8192];struct frame f[UDPTL_BUF_MASK + 1];struct tx_buf tx[UDPTL_BUF_MASK + 1];struct rx_buf rx[UDPTL_BUF_MASK + 1];udptl_callback_t cb;void* data;struct udptl_io* ops;void* ops_data;
};
发送数据的函数
int32_t terminal_send_timeout(terminal_state_t s, int32_t samples)
{front_end_state_t *fe;int32_t delay;fe = &s->t38_fe;if(fe->current_rx_type == T30_MODEM_DONE || fe->current_tx_type == T30_MODEM_DONE){return 1;}fe->samples += samples;t30_timer_update(s->t30, samples);if(fe->timeout_rx_samples && fe->samples > fe->timeout_rx_samples){fe->timeout_rx_samples = 0;front_end_status(s, T30_FRONT_END_RECEIVE_COMPLETE);}if(fe->timed_step == T38_TIMED_STEP_NONE){return 0;}if(fe->ms_per_tx_chunk && fe->samples < fe->next_tx_samples){return 0;}delay = 0;switch(fe->timed_step & 0xFFF0){case T38_TIMED_STEP_NON_ECM_MODEM:delay = stream_non_ecm(s);break;case T38_TIMED_STEP_HDLC_MODEM:delay = stream_hdlc(s);break;case T38_TIMED_STEP_CED:delay = stream_ced(s);break;case T38_TIMED_STEP_CNG:delay = stream_cng(s);break;case T38_TIMED_STEP_PAUSE:/* End of timed pause */fe->timed_step = T38_TIMED_STEP_NONE;front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE);break;case T38_TIMED_STEP_NO_SIGNAL:delay = stream_no_signal(s);break;}fe->next_tx_samples += us_to_samples(delay);return 0;
}
发送数据的核心函数
int32_t t38_core_send_data(t38_state_t s, int32_t data_type, int32_t field_type, const uint8_t* field, int32_t field_len, int32_t category)
{t38_data_field_t field0;uint8_t buf[1000];int32_t len;field0.field_type = field_type;field0.field = field;field0.field_len = field_len;if((len = t38_encode_data(s, buf, data_type, &field0, 1)) < 0){return len;}udptl_send_proc(s->hudptl, buf, len);s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF;return 0;
}
最底层发送函数
int32_t udptl_send_proc(void* handle, uint8_t* buf, int32_t len)
{struct udptl_struct *s =(struct udptl_struct *) handle;len = udptl_build_packet(s, s->raw, sizeof(s->raw), buf, len);if(s->ops && s->ops->send){s->ops->send(s->ops_data, s->raw, len);}return 0;
}
间隔符发送函数
int32_t t38_core_send_indicator(t38_state_t s, int32_t indicator)
{uint8_t buf[100];int32_t len;int32_t delay;int32_t transmissions;delay = 0;/* Only send an indicator if it represents a change of state. *//* If the 0x100 bit is set in indicator it will bypass this test, and force transmission */if(s->current_tx_indicator != indicator){/* Zero is a valid count, to suppress the transmission of indicators when thetransport means they are not needed - e.g. TPKT/TCP. */transmissions = (indicator & 0x100) ? 1 : s->category_control[T38_PACKET_CATEGORY_INDICATOR];indicator &= 0xFF;if(s->category_control[T38_PACKET_CATEGORY_INDICATOR]){if((len = t38_encode_indicator(s, buf, indicator)) < 0){return len;}udptl_send_proc(s->hudptl, buf, len);s->tx_seq_no = (s->tx_seq_no + 1) & 0xFFFF;delay = modem_startup_time[indicator].training;if(s->allow_for_tep){delay += modem_startup_time[indicator].tep;}}s->current_tx_indicator = indicator;}return delay;
}
其他的发送函数
case T30_STATE_F_CFR:if (s->step == 0){/* Shut down HDLC transmission. */if (s->send_hdlc_handler)s->send_hdlc_handler(s->send_hdlc_user_data, NULL, 0);s->step++;}
设置发送文件路径
void t30_set_tx_file(t30_state_t s, const uint8_t *file, int32_t start_page, int32_t stop_page)
{strncpy((char*)s->tx_file,(char*)file, sizeof(s->tx_file));s->tx_file[sizeof(s->tx_file) - 1] = '\0';s->tx_start_page = start_page;s->tx_stop_page = stop_page;
}
SendFax过程分析相关推荐
- Android窗口管理服务WindowManagerService计算窗口Z轴位置的过程分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8570428 通过前面几篇文章的学习,我们知道了 ...
- Android窗口管理服务WindowManagerService计算Activity窗口大小的过程分析
在Android系统中,Activity窗口的大小是由WindowManagerService服务来计算的.WindowManagerService服务会根据屏幕及其装饰区的大小来决定Activity ...
- JDBC中驱动加载的过程分析
JDBC中驱动加载的过程分析 作者:kenty 来源:博客园 发布时间:2007-08-20 15:01 阅读:1100 次 原文链接 [收藏] 本篇从java.sql.Driver ...
- Android应用程序窗口(Activity)的测量(Measure)、布局(Layout)和绘制(Draw)过程分析(上)...
在前面一篇文章中,我们分析了Android应用程序窗口的绘图表面的创建过程.Android应用程序窗口的绘图表面在创建完成之后,我们就可以从上到下地绘制它里面的各个视图了,即各个UI元素了.不过在绘制 ...
- 深入Vue - 源码目录及构建过程分析
摘要: Vue源码阅读第一步. 原文:深入vue - 源码目录及构建过程分析 公众号:前端小苑 Fundebug经授权转载,版权归原作者所有. 本文主要梳理一下vue代码的目录,以及vue代码构建流程 ...
- 20145223《信息安全系统设计基础》 GDB调试汇编堆栈过程分析
20145223<信息安全系统设计基础> GDB调试汇编堆栈过程分析 分析的c语言源码 生成汇编代码--命令:gcc -g example.c -o example -m32 进入gdb调 ...
- 基于linux的netfilter处理数据包的过程分析,基于Linux的Netfilter处理数据包的过程分析...
基于Linux的Netfilter处理数据包的过程分析 防火墙技术在保护网络安全方面的作用越来越明显.相比较window,Linux有更好的网络性能,因此基于Linux的Netfilter技术 (本文 ...
- Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析...
在前面一篇文章中,我们分析了Android应用程序与SurfaceFlinger服务的连接过程.Android应用程序成功连接上SurfaceFlinger服务之后,还需要一块匿名共享内存来和Surf ...
- Netty3 源代码分析 - NIO server绑定过程分析
Netty3 源代码分析 - NIO server绑定过程分析 一个框架封装的越好,越利于我们高速的coding.可是却掩盖了非常多的细节和原理.可是源代码可以揭示一切. 服务器端代码在指定 ...
最新文章
- linux ln(link) 命令详解
- shell的相关知识(变量、脚本定义)
- linux下如何安装rzsz
- 使用Leap Motion Orion开发酷炫的手势识别VR/AR应用
- 用Java刷OJ超时怎么办?原因分析及解决方式
- 基于mindspore的口罩检测训练与在线推理
- 使用/proc/meminfo文件查看内存状态信息
- 三角形垂点坐标js算法(三点定圆求圆心)
- Git总结笔记1-搭建和使用30条简明笔记
- 机器学习降维之主成分分析
- VC++_2010_学习版_未能下载以下组件解决方案和microsoft应用程序错误报告
- 解决Nvidia 显卡驱动安装失败的方法
- 喜马拉雅FM下载的音频文件保存在哪_怎么导出来
- 【加法器】——模拟电路设计简单的二进制数加法器
- 谷歌面试题:两个玻璃球摔碎的楼层高度
- Android自带Switch系列汇总学习
- logit回归怎么看显著性_请教用SPSS做两分类逻辑回归时自变量的显著性问题
- 回顾外滩踩踏事件,吸取的教训
- 几款好用的UML建模工具
- Centos 7 无法启动,Entering emergency mode问题解决