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 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;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值