传真的发送过程:
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 the
transport 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;
}