传真的发送过程:

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过程分析相关推荐

  1. Android窗口管理服务WindowManagerService计算窗口Z轴位置的过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8570428 通过前面几篇文章的学习,我们知道了 ...

  2. Android窗口管理服务WindowManagerService计算Activity窗口大小的过程分析

    在Android系统中,Activity窗口的大小是由WindowManagerService服务来计算的.WindowManagerService服务会根据屏幕及其装饰区的大小来决定Activity ...

  3. JDBC中驱动加载的过程分析

    JDBC中驱动加载的过程分析 作者:kenty  来源:博客园  发布时间:2007-08-20 15:01  阅读:1100 次  原文链接   [收藏]    本篇从java.sql.Driver ...

  4. Android应用程序窗口(Activity)的测量(Measure)、布局(Layout)和绘制(Draw)过程分析(上)...

    在前面一篇文章中,我们分析了Android应用程序窗口的绘图表面的创建过程.Android应用程序窗口的绘图表面在创建完成之后,我们就可以从上到下地绘制它里面的各个视图了,即各个UI元素了.不过在绘制 ...

  5. 深入Vue - 源码目录及构建过程分析

    摘要: Vue源码阅读第一步. 原文:深入vue - 源码目录及构建过程分析 公众号:前端小苑 Fundebug经授权转载,版权归原作者所有. 本文主要梳理一下vue代码的目录,以及vue代码构建流程 ...

  6. 20145223《信息安全系统设计基础》 GDB调试汇编堆栈过程分析

    20145223<信息安全系统设计基础> GDB调试汇编堆栈过程分析 分析的c语言源码 生成汇编代码--命令:gcc -g example.c -o example -m32 进入gdb调 ...

  7. 基于linux的netfilter处理数据包的过程分析,基于Linux的Netfilter处理数据包的过程分析...

    基于Linux的Netfilter处理数据包的过程分析 防火墙技术在保护网络安全方面的作用越来越明显.相比较window,Linux有更好的网络性能,因此基于Linux的Netfilter技术 (本文 ...

  8. Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析...

    在前面一篇文章中,我们分析了Android应用程序与SurfaceFlinger服务的连接过程.Android应用程序成功连接上SurfaceFlinger服务之后,还需要一块匿名共享内存来和Surf ...

  9. Netty3 源代码分析 - NIO server绑定过程分析

    Netty3 源代码分析 - NIO server绑定过程分析      一个框架封装的越好,越利于我们高速的coding.可是却掩盖了非常多的细节和原理.可是源代码可以揭示一切. 服务器端代码在指定 ...

最新文章

  1. linux ln(link) 命令详解
  2. shell的相关知识(变量、脚本定义)
  3. linux下如何安装rzsz
  4. 使用Leap Motion Orion开发酷炫的手势识别VR/AR应用
  5. 用Java刷OJ超时怎么办?原因分析及解决方式
  6. 基于mindspore的口罩检测训练与在线推理
  7. 使用/proc/meminfo文件查看内存状态信息
  8. 三角形垂点坐标js算法(三点定圆求圆心)
  9. Git总结笔记1-搭建和使用30条简明笔记
  10. 机器学习降维之主成分分析
  11. VC++_2010_学习版_未能下载以下组件解决方案和microsoft应用程序错误报告
  12. 解决Nvidia 显卡驱动安装失败的方法
  13. 喜马拉雅FM下载的音频文件保存在哪_怎么导出来
  14. 【加法器】——模拟电路设计简单的二进制数加法器
  15. 谷歌面试题:两个玻璃球摔碎的楼层高度
  16. Android自带Switch系列汇总学习
  17. logit回归怎么看显著性_请教用SPSS做两分类逻辑回归时自变量的显著性问题
  18. 回顾外滩踩踏事件,吸取的教训
  19. 几款好用的UML建模工具
  20. Centos 7 无法启动,Entering emergency mode问题解决

热门文章

  1. 耗时半年,用 Python 写了一个电子考勤系统
  2. 读书《Python数据挖掘课程》
  3. 信息安全(二)——密码学
  4. matlab 半高斯拟合,高斯曲线拟合求半宽高
  5. FLV视频格式详解(转)
  6. 大数据就业的三大方向和十种岗位
  7. 如何在做YouTube推广时快速查找网红?
  8. Python字典遍历
  9. 闹钟DeskClock缅甸语显示不全问题分析
  10. 牛客网最热门的 Java 面试题库(附答案),终于整理好了