Преглед изворни кода

add driver_cloud_grpc_thread.

yuchuli пре 3 година
родитељ
комит
c12cebecec

+ 58 - 0
src/driver/driver_cloud_grpc_thread/driver_cloud_grpc_thread.pro

@@ -0,0 +1,58 @@
+QT -= gui
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+QMAKE_LFLAGS += -no-pie
+
+# The following define makes your compiler emit warnings if you use
+# any Qt feature that has been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+        ../../include/msgtype/cloud.pb.cc \
+    ../../include/msgtype/uploadthreadmsg.pb.cc \
+        main.cpp \
+    grpcclient.cpp \
+    uploadthreadmsg.grpc.pb.cc
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+!include(../../../include/common.pri ) {
+    error( "Couldn't find the common.pri file!" )
+}
+
+!include(../../../include/ivprotobuf.pri ) {
+    error( "Couldn't find the ivprotobuf.pri file!" )
+}
+
+!include(../../../include/ivboost.pri ) {
+    error( "Couldn't find the ivboost.pri file!" )
+}
+
+!include(../../../include/ivgrpc.pri ) {
+    error( "Couldn't find the ivgrpc.pri file!" )
+}
+
+!include(../../../include/ivyaml-cpp.pri ) {
+    error( "Couldn't find the ivyaml-cpp.pri file!" )
+}
+
+
+
+HEADERS += \
+    ../../include/msgtype/cloud.pb.h \
+    ../../include/msgtype/uploadthreadmsg.pb.h \
+    grpcclient.h \
+    uploadthreadmsg.grpc.pb.h
+

+ 47 - 0
src/driver/driver_cloud_grpc_thread/driver_cloud_grpc_thread.yaml

@@ -0,0 +1,47 @@
+server : 47.96.250.93
+port : 50051
+uploadinterval : 100
+
+VIN : AAAAAAAAAAAAAAAAA
+queryMD5 : 5d41402abc4b2a76b9719d911017c592
+ctrlMD5  : 5d41402abc4b2a76b9719d911017c592
+
+
+uploadmessage:
+  usbpic:
+    msgname: compresspic
+    buffersize: 10000000
+    buffercount: 1
+  hcp2_gpsimu:
+    msgname: hcp2_gpsimu
+    buffersize: 100000
+    buffercount: 1
+
+#  tracemap:
+#    msgname: tracemap
+#    buffersize: 10000000
+#    buffercount: 1
+
+  simpletrace:
+    msgname: simpletrace
+    buffersize: 10000000
+    buffercount: 1
+    bimportant: true
+    keeptime: 3000
+
+ctrlmessage:
+  xodrsrc:
+    msgname: xodrsrc
+    buffersize: 1000
+    buffercount: 1
+  xodrreq:
+    msgname: xodrreq
+    buffersize: 1000
+    buffercount: 1
+  remotectrl:
+    msgname: remotectrl
+    buffersize: 10000
+    buffercount: 1
+
+
+

+ 501 - 0
src/driver/driver_cloud_grpc_thread/grpcclient.cpp

@@ -0,0 +1,501 @@
+#include "grpcclient.h"
+
+grpcclient * ggrpcclient;
+
+void ListenData(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+{
+    ggrpcclient->UpdateData(strdata,nSize,strmemname);
+
+}
+
+void ListenPicData(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+{
+    ggrpcclient->UpdatePicData(strdata,nSize,strmemname);
+
+}
+
+
+grpcclient::grpcclient(std::string stryamlpath)
+{
+    ggrpcclient = this;
+    dec_yaml(stryamlpath.data());
+
+    mstrpicmsgname[0] = "PicFront";
+    mstrpicmsgname[1] = "PicRear";
+    mstrpicmsgname[2] = "PicLeft";
+    mstrpicmsgname[3] = "PicRight";
+
+    unsigned int i;
+    for(i=0;i<mvectormsgunit.size();i++)
+    {
+        mvectormsgunit[i].mpa = iv::modulecomm::RegisterRecv(mvectormsgunit[i].mstrmsgname,ListenData);
+    }
+
+    for(i=0;i<mvectorctrlmsgunit.size();i++)
+    {
+        mvectorctrlmsgunit[i].mpa = iv::modulecomm::RegisterSend(mvectorctrlmsgunit[i].mstrmsgname,mvectorctrlmsgunit[i].mnBufferSize,
+                                                                 mvectorctrlmsgunit[i].mnBufferCount);
+    }
+
+    for(i=0;i<NUM_CAM;i++)
+    {
+        mpaPic[i] = iv::modulecomm::RegisterRecv(mstrpicmsgname[i].data(),ListenPicData);
+    }
+
+
+    for(i=0;i<NUM_CAM;i++)
+    {
+        unsigned int j;
+        for(j=0;j<NUM_THREAD_PERCAM;j++)
+        {
+            mpThread[i*NUM_THREAD_PERCAM + j] = new std::thread(&grpcclient::threadpicupload,this,i);
+        }
+    }
+
+}
+
+void grpcclient::run()
+{
+    int nsize = mvectormsgunit.size();
+    int i;
+
+    int ninterval = atoi(gstruploadinterval.data());
+    if(ninterval<=0)ninterval = 100;
+
+    QTime xTime;
+    xTime.start();
+    int nlastsend = xTime.elapsed();
+
+    std::string target_str = gstrserverip+":";
+    target_str = target_str + gstrserverport ;//std::to_string()
+    auto cargs = grpc::ChannelArguments();
+    cargs.SetMaxReceiveMessageSize(1024 * 1024 * 1024); // 1 GB
+    cargs.SetMaxSendMessageSize(1024 * 1024 * 1024);
+
+    std::shared_ptr<Channel> channel = grpc::CreateCustomChannel(
+             target_str, grpc::InsecureChannelCredentials(),cargs);
+
+    std::unique_ptr<iv::UploadThread::Stub> stub_ = iv::UploadThread::NewStub(channel);
+
+
+    iv::UploadRequestThread request;
+
+    int nid = 0;
+
+    // Container for the data we expect from the server.
+    iv::UploadReplyThread reply;
+
+    gpr_timespec timespec;
+      timespec.tv_sec = 30;//设置阻塞时间为2秒
+      timespec.tv_nsec = 0;
+      timespec.clock_type = GPR_TIMESPAN;
+
+ //   ClientContext context;
+
+
+
+    while(!QThread::isInterruptionRequested())
+    {
+        std::this_thread::sleep_for(std::chrono::milliseconds(1));
+        if((xTime.elapsed()-nlastsend)<ninterval)
+        {
+            continue;
+        }
+
+            bool bImportant = false;
+            int nkeeptime = 0;
+            iv::cloud::cloudmsg xmsg;
+            xmsg.set_xtime(QDateTime::currentMSecsSinceEpoch());
+            gMutexMsg.lock();
+            for(i=0;i<nsize;i++)
+            {
+                if(mvectormsgunit[i].mbRefresh)
+                {
+                    mvectormsgunit[i].mbRefresh = false;
+                    if(mvectormsgunit[i].mbImportant)
+                    {
+                        bImportant = true;
+                    }
+                    if(mvectormsgunit[i].mnkeeptime > nkeeptime)
+                    {
+                        nkeeptime = mvectormsgunit[i].mnkeeptime;
+                    }
+                    iv::cloud::cloudunit xcloudunit;
+                    xcloudunit.set_msgname(mvectormsgunit[i].mstrmsgname);
+                    xcloudunit.set_data(mvectormsgunit[i].mpstrmsgdata.get(),mvectormsgunit[i].mndatasize);
+                    iv::cloud::cloudunit * pcu = xmsg.add_xclouddata();
+                    pcu->CopyFrom(xcloudunit);
+                }
+
+            }
+            gMutexMsg.unlock();
+
+            int nbytesize = xmsg.ByteSize();
+            char * strbuf = new char[nbytesize];
+            std::shared_ptr<char> pstrbuf;
+            pstrbuf.reset(strbuf);
+            if(xmsg.SerializeToArray(strbuf,nbytesize))
+            {
+
+                ClientContext context ;
+                context.set_deadline(timespec);
+                qint64 time1 = QDateTime::currentMSecsSinceEpoch();
+
+                request.set_id(nid);
+                request.set_ntime(time1);
+                request.set_strquerymd5(gstrqueryMD5);
+                request.set_strctrlmd5(gstrctrlMD5);
+                request.set_strvin(gstrVIN);
+                request.set_xdata(strbuf,nbytesize);
+                request.set_kepptime(nkeeptime);
+                request.set_bimportant(bImportant);
+                nid++;
+
+                nlastsend = xTime.elapsed();
+                // The actual RPC.
+                Status status = stub_->uploaddata(&context, request, &reply);
+                if (status.ok()) {
+                    std::cout<<"  data size is "<<nbytesize<<std::endl;
+                    std::cout<<nid<<" upload successfully"<<std::endl;
+                    if(reply.nres() == 1)
+                    {
+                        iv::cloud::cloudmsg xmsg;
+                        if(xmsg.ParseFromArray(reply.xdata().data(),reply.xdata().size()))
+                        {
+                            sharectrlmsg(&xmsg);
+                        }
+                    }
+                } else {
+                  std::cout << status.error_code() << ": " << status.error_message()
+                            << std::endl;
+                  std::cout<<"RPC failed"<<std::endl;
+                  if(status.error_code() == 4)
+                  {
+                      std::cout<<" RPC Exceed Time, Create New stub_"<<std::endl;
+                      channel = grpc::CreateCustomChannel(
+                               target_str, grpc::InsecureChannelCredentials(),cargs);
+
+                      stub_ = iv::UploadThread::NewStub(channel);
+                  }
+                  std::this_thread::sleep_for(std::chrono::milliseconds(900));
+
+                }
+
+            }
+
+
+    }
+}
+
+
+void grpcclient::dec_yaml(const char * stryamlpath)
+{
+
+    YAML::Node config;
+    try
+    {
+        config = YAML::LoadFile(stryamlpath);
+    }
+    catch(YAML::BadFile e)
+    {
+        qDebug("load error.");
+        return;
+    }
+
+    std::vector<std::string> vecmodulename;
+
+
+    if(config["server"])
+    {
+        gstrserverip = config["server"].as<std::string>();
+    }
+    if(config["port"])
+    {
+        gstrserverport = config["port"].as<std::string>();
+    }
+    if(config["uploadinterval"])
+    {
+        gstruploadinterval = config["uploadinterval"].as<std::string>();
+    }
+
+    if(config["VIN"])
+    {
+        gstrVIN = config["VIN"].as<std::string>();
+    }
+
+    if(config["queryMD5"])
+    {
+        gstrqueryMD5 = config["queryMD5"].as<std::string>();
+    }
+    else
+    {
+        return;
+    }
+
+    if(config["ctrlMD5"])
+    {
+        gstrctrlMD5 = config["ctrlMD5"].as<std::string>();
+    }
+
+
+    std::string strmsgname;
+
+    if(config["uploadmessage"])
+    {
+
+        for(YAML::const_iterator it= config["uploadmessage"].begin(); it != config["uploadmessage"].end();++it)
+        {
+            std::string strtitle = it->first.as<std::string>();
+            std::cout<<strtitle<<std::endl;
+
+            if(config["uploadmessage"][strtitle]["msgname"]&&config["uploadmessage"][strtitle]["buffersize"]&&config["uploadmessage"][strtitle]["buffercount"])
+            {
+                iv::msgunit xmu;
+                strmsgname = config["uploadmessage"][strtitle]["msgname"].as<std::string>();
+                strncpy(xmu.mstrmsgname,strmsgname.data(),255);
+                xmu.mnBufferSize = config["uploadmessage"][strtitle]["buffersize"].as<int>();
+                xmu.mnBufferCount = config["uploadmessage"][strtitle]["buffercount"].as<int>();
+                if(config["uploadmessage"][strtitle]["bimportant"])
+                {
+                   std::string strimportant =    config["uploadmessage"][strtitle]["bimportant"].as<std::string>();
+                   if(strimportant == "true")
+                   {
+                       xmu.mbImportant = true;
+                   }
+                }
+                if(config["uploadmessage"][strtitle]["keeptime"])
+                {
+                   std::string strkeep =    config["uploadmessage"][strtitle]["keeptime"].as<std::string>();
+                   xmu.mnkeeptime = atoi(strkeep.data());
+                }
+                mvectormsgunit.push_back(xmu);
+            }
+        }
+    }
+    else
+    {
+
+
+    }
+
+    if(!config["ctrlMD5"])
+    {
+       return;
+    }
+
+    if(config["ctrlmessage"])
+    {
+        std::string strnodename = "ctrlmessage";
+        for(YAML::const_iterator it= config[strnodename].begin(); it != config[strnodename].end();++it)
+        {
+            std::string strtitle = it->first.as<std::string>();
+            std::cout<<strtitle<<std::endl;
+
+            if(config[strnodename][strtitle]["msgname"]&&config[strnodename][strtitle]["buffersize"]&&config[strnodename][strtitle]["buffercount"])
+            {
+                iv::msgunit xmu;
+                strmsgname = config[strnodename][strtitle]["msgname"].as<std::string>();
+                strncpy(xmu.mstrmsgname,strmsgname.data(),255);
+                xmu.mnBufferSize = config[strnodename][strtitle]["buffersize"].as<int>();
+                xmu.mnBufferCount = config[strnodename][strtitle]["buffercount"].as<int>();
+                mvectorctrlmsgunit.push_back(xmu);
+            }
+        }
+    }
+    else
+    {
+
+    }
+
+    return;
+
+}
+
+void grpcclient::sharectrlmsg(iv::cloud::cloudmsg * pxmsg)
+{
+    int i;
+    int nsize = pxmsg->xclouddata_size();
+    for(i=0;i<nsize;i++)
+    {
+        int j;
+        int nquerysize = mvectorctrlmsgunit.size();
+        for(j=0;j<nquerysize;j++)
+        {
+            if(strncmp(pxmsg->xclouddata(i).msgname().data(), mvectorctrlmsgunit[j].mstrmsgname,255) == 0)
+            {
+ //               qDebug("size is %d ",pxmsg->xclouddata(i).data().size());
+                iv::modulecomm::ModuleSendMsg(mvectorctrlmsgunit[j].mpa,pxmsg->xclouddata(i).data().data(),pxmsg->xclouddata(i).data().size());
+                break;
+            }
+        }
+    }
+}
+
+void grpcclient::UpdateData(const char *strdata, const unsigned int nSize, const char *strmemname)
+{
+    int nsize = mvectormsgunit.size();
+    int i;
+    for(i=0;i<nsize;i++)
+    {
+        if(strncmp(strmemname,mvectormsgunit[i].mstrmsgname,255) == 0)
+        {
+            gMutexMsg.lock();
+            char * strtem = new char[nSize];
+            memcpy(strtem,strdata,nSize);
+            mvectormsgunit[i].mpstrmsgdata.reset(strtem);
+            mvectormsgunit[i].mndatasize = nSize;
+            mvectormsgunit[i].mbRefresh = true;
+            gMutexMsg.unlock();
+            break;
+        }
+    }
+}
+
+void grpcclient::UpdatePicData(const char *strdata, const unsigned int nSize, const char *strmemname)
+{
+    int npos = -1;
+
+    unsigned int i;
+    for(i=0;i<NUM_CAM;i++)
+    {
+        if(strncmp(strmemname,mstrpicmsgname[i].data(),255) == 0)
+        {
+            npos = i;
+            break;
+        }
+    }
+
+    if(npos<0)
+    {
+        std::cout<<"grpcclient::UpdatePicData not found pic. msg name is "<<strmemname<<std::endl;
+        return;
+    }
+
+    if(npos>= NUM_CAM)
+    {
+        std::cout<<"Camera count is "<<NUM_CAM<<" NOW camear is "<<npos<<std::endl;
+        return;
+    }
+
+    mpicbuf[npos].mMutex.lock();
+    mpicbuf[npos].mnMsgTime = QDateTime::currentMSecsSinceEpoch();
+    mpicbuf[npos].mbRefresh = true;
+    mpicbuf[npos].mpstrmsgdata = std::shared_ptr<char>(new char[nSize]);
+    mpicbuf[npos].mDataSize = nSize;
+    memcpy(mpicbuf[npos].mpstrmsgdata.get(),strdata,nSize);
+    mpicbuf[npos].mMutex.unlock();
+}
+
+
+void grpcclient::threadpicupload(int nCamPos)
+{
+    std::cout<<"thread cam "<<nCamPos<<"run"<<std::endl;
+    int nsize = mvectormsgunit.size();
+    int i;
+
+    int ninterval = atoi(gstruploadinterval.data());
+    if(ninterval<=0)ninterval = 100;
+
+    QTime xTime;
+    xTime.start();
+    int nlastsend = xTime.elapsed();
+
+    std::string target_str = gstrserverip+":";
+    target_str = target_str + gstrserverport ;//std::to_string()
+    auto cargs = grpc::ChannelArguments();
+    cargs.SetMaxReceiveMessageSize(1024 * 1024 * 1024); // 1 GB
+    cargs.SetMaxSendMessageSize(1024 * 1024 * 1024);
+
+    std::shared_ptr<Channel> channel = grpc::CreateCustomChannel(
+             target_str, grpc::InsecureChannelCredentials(),cargs);
+
+    std::unique_ptr<iv::UploadThread::Stub> stub_ = iv::UploadThread::NewStub(channel);
+
+
+    iv::PicUpRequestThread request;
+
+    int nid = 0;
+
+    // Container for the data we expect from the server.
+    iv::PicUpReplyThread reply;
+
+    gpr_timespec timespec;
+      timespec.tv_sec = 30;//设置阻塞时间为2秒
+      timespec.tv_nsec = 0;
+      timespec.clock_type = GPR_TIMESPAN;
+
+ //   ClientContext context;
+
+
+
+    while(true)
+    {
+        std::shared_ptr<char> pstr_ptr;
+        if((nCamPos<0)||(nCamPos >= NUM_CAM))
+        {
+            std::cout<<"Cam Pos Error. "<<"Pos: "<<nCamPos<<" TOTAL:"<<NUM_CAM<<std::endl;
+            std::this_thread::sleep_for(std::chrono::milliseconds(100));
+            continue;
+        }
+
+        bool bUpdate = false;
+        qint64 nMsgTime = 0;
+        int nSize = 0;
+        mpicbuf[nCamPos].mMutex.lock();
+        bUpdate = mpicbuf[nCamPos].mbRefresh;
+        if(bUpdate)
+        {
+            nMsgTime = mpicbuf[nCamPos].mnMsgTime;
+            mpicbuf[nCamPos].mbRefresh = false;
+            pstr_ptr = mpicbuf[nCamPos].mpstrmsgdata;
+            nSize = mpicbuf[nCamPos].mDataSize;
+        }
+        mpicbuf[nCamPos].mMutex.unlock();
+        if(bUpdate == false)
+        {
+            std::this_thread::sleep_for(std::chrono::milliseconds(10));
+            continue;
+        }
+
+        ClientContext context ;
+        context.set_deadline(timespec);
+        qint64 time1 = QDateTime::currentMSecsSinceEpoch();
+
+        request.set_npictime(nMsgTime);
+        request.set_ncampos(nCamPos);
+        request.set_strvin(gstrVIN);
+        request.set_xdata(pstr_ptr.get(),nSize);
+        nid++;
+
+        nlastsend = xTime.elapsed();
+        // The actual RPC.
+        Status status = stub_->uploadpic(&context, request, &reply);
+        if (status.ok()) {
+
+            if(reply.nres() == 1)
+            {
+//                iv::cloud::cloudmsg xmsg;
+//                if(xmsg.ParseFromArray(reply.xdata().data(),reply.xdata().size()))
+//                {
+//                    sharectrlmsg(&xmsg);
+//                }
+            }
+        } else {
+          std::cout << status.error_code() << ": " << status.error_message()
+                    << std::endl;
+          std::cout<<"RPC failed"<<std::endl;
+          if(status.error_code() == 4)
+          {
+              std::cout<<nCamPos<<" RPC Exceed Time, Create New stub_"<<std::endl;
+              channel = grpc::CreateCustomChannel(
+                       target_str, grpc::InsecureChannelCredentials(),cargs);
+
+              stub_ = iv::UploadThread::NewStub(channel);
+          }
+          std::this_thread::sleep_for(std::chrono::milliseconds(900));
+
+        }
+
+
+    }
+}

+ 112 - 0
src/driver/driver_cloud_grpc_thread/grpcclient.h

@@ -0,0 +1,112 @@
+#ifndef GRPCCLIENT_H
+#define GRPCCLIENT_H
+
+#include <QThread>
+
+#include <yaml-cpp/yaml.h>
+
+#include <QDateTime>
+
+#include <iostream>
+
+#include <vector>
+
+#include <memory>
+
+#include <QMutex>
+
+#include <thread>
+
+#include "modulecomm.h"
+
+#include "cloud.pb.h"
+
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include <grpcpp/grpcpp.h>
+
+#include "uploadthreadmsg.grpc.pb.h"
+
+#define NUM_CAM 4
+#define NUM_THREAD_PERCAM 4
+
+namespace iv {
+struct msgunit
+{
+    char mstrmsgname[256];
+    int mnBufferSize = 10000;
+    int mnBufferCount = 1;
+    void * mpa;
+    std::shared_ptr<char> mpstrmsgdata;
+    int mndatasize = 0;
+    bool mbRefresh = false;
+    bool mbImportant = false;
+    int mnkeeptime = 100;
+};
+
+struct  threadpicunit
+{
+     bool mbRefresh = false;
+     qint64 mnMsgTime;
+     std::shared_ptr<char> mpstrmsgdata;
+     int mDataSize;
+     QMutex mMutex;
+};
+}
+
+
+using grpc::Channel;
+using grpc::ClientContext;
+using grpc::Status;
+
+class grpcclient : public QThread
+{
+public:
+    grpcclient(std::string stryamlpath);
+
+private:
+    std::string gstrserverip =  "0.0.0.0";//"123.57.212.138";
+    std::string gstrserverport = "50051";//"9000";
+    std::string gstruploadinterval = "1000";
+    void * gpa;
+    QMutex gMutexMsg;
+    std::thread * guploadthread;
+
+
+
+
+    std::vector<iv::msgunit> mvectormsgunit;
+
+    std::vector<iv::msgunit> mvectorctrlmsgunit;
+
+
+    std::string gstrVIN = "AAAAAAAAAAAAAAAAA";
+    std::string gstrqueryMD5 = "5d41402abc4b2a76b9719d911017c591";//"5d41402abc4b2a76b9719d911017c592";
+    std::string gstrctrlMD5 = "5d41402abc4b2a76b9719d911017c591";
+
+
+
+    int gindex = 0;
+public:
+    void UpdateData(const char * strdata,const unsigned int nSize,const char * strmemname);
+    void UpdatePicData(const char * strdata,const unsigned int nSize,const char * strmemname);
+private:
+    void run();
+    void dec_yaml(const char * stryamlpath);
+    void sharectrlmsg(iv::cloud::cloudmsg * pxmsg);
+
+private:
+    void threadpicupload(int nCamPos);
+
+    iv::threadpicunit mpicbuf[NUM_CAM];
+
+    void * mpaPic[NUM_CAM];
+    std::string mstrpicmsgname[NUM_CAM];
+
+    std::thread * mpThread[NUM_CAM * NUM_THREAD_PERCAM];
+
+};
+
+#endif // GRPCCLIENT_H

+ 472 - 0
src/driver/driver_cloud_grpc_thread/main.cpp

@@ -0,0 +1,472 @@
+#include <QCoreApplication>
+
+#include "grpcclient.h"
+
+#include "ivversion.h"
+
+/*
+#include <yaml-cpp/yaml.h>
+
+#include <QDateTime>
+
+#include <iostream>
+
+#include <vector>
+
+#include <memory>
+
+#include <QMutex>
+
+#include <thread>
+
+#include "modulecomm.h"
+
+#include "cloud.pb.h"
+
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include <grpcpp/grpcpp.h>
+
+#include "uploadmsg.grpc.pb.h"
+
+
+using grpc::Channel;
+using grpc::ClientContext;
+using grpc::Status;
+
+
+void test()
+{
+    std::string target_str = "0.0.0.0:50051";
+
+    auto cargs = grpc::ChannelArguments();
+    cargs.SetMaxReceiveMessageSize(1024 * 1024 * 1024); // 1 GB
+    cargs.SetMaxSendMessageSize(1024 * 1024 * 1024);
+
+    std::shared_ptr<Channel> channel = grpc::CreateCustomChannel(
+             target_str, grpc::InsecureChannelCredentials(),cargs);
+
+    std::unique_ptr<iv::Upload::Stub> stub_ = iv::Upload::NewStub(channel);
+
+
+    iv::UploadRequest request;
+
+
+
+    // Container for the data we expect from the server.
+    iv::UploadReply reply;
+
+    int nid = 0;
+
+    nid = 1;
+
+    while(1)
+    {
+
+
+
+
+        // Context for the client. It could be used to convey extra information to
+        // the server and/or tweak certain RPC behaviors.
+
+
+        ClientContext context ;
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+        qint64 time1 = QDateTime::currentMSecsSinceEpoch();
+
+        request.set_id(nid);
+        request.set_ntime(time1);
+        nid++;
+        // The actual RPC.
+        Status status = stub_->upload(&context, request, &reply);
+        if (status.ok()) {
+            std::cout<<nid<<" upload successfully"<<std::endl;
+//            qint64 time2;
+
+//            memcpy(&time2,reply.data().data(),8);
+//            qint64 time3 = QDateTime::currentMSecsSinceEpoch();
+//            std::cout<<"reply data size is "<<reply.data().size()<<std::endl;
+//            std::cout<<" latency is "<<(time2 - time1)<<" 2 is "<<(time3 - time2)<<std::endl;
+//          return reply.message();
+        } else {
+          std::cout << status.error_code() << ": " << status.error_message()
+                    << std::endl;
+          std::cout<<"RPC failed"<<std::endl;
+          std::this_thread::sleep_for(std::chrono::milliseconds(900));
+
+//          delete pcontext;
+//          pcontext = new ClientContext;
+
+//          channel = grpc::CreateCustomChannel(
+//                   target_str, grpc::InsecureChannelCredentials(),cargs);
+
+//          stub_ = iv::Upload::NewStub(channel);
+        }
+    }
+}
+
+std::string gstrserverip =  "0.0.0.0";//"123.57.212.138";
+std::string gstrserverport = "50051";//"9000";
+std::string gstruploadinterval = "1000";
+void * gpa;
+QMutex gMutexMsg;
+std::thread * guploadthread;
+
+
+
+
+std::vector<iv::msgunit> mvectormsgunit;
+
+std::vector<iv::msgunit> mvectorctrlmsgunit;
+
+
+std::string gstrVIN = "AAAAAAAAAAAAAAAAA";
+std::string gstrqueryMD5 = "5d41402abc4b2a76b9719d911017c591";//"5d41402abc4b2a76b9719d911017c592";
+std::string gstrctrlMD5 = "5d41402abc4b2a76b9719d911017c591";
+
+
+
+int gindex = 0;
+
+void ListenData(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
+{
+
+    int nsize = mvectormsgunit.size();
+    int i;
+    for(i=0;i<nsize;i++)
+    {
+        if(strncmp(strmemname,mvectormsgunit[i].mstrmsgname,255) == 0)
+        {
+            gMutexMsg.lock();
+            char * strtem = new char[nSize];
+            memcpy(strtem,strdata,nSize);
+            mvectormsgunit[i].mpstrmsgdata.reset(strtem);
+            mvectormsgunit[i].mndatasize = nSize;
+            mvectormsgunit[i].mbRefresh = true;
+            gMutexMsg.unlock();
+            break;
+        }
+    }
+}
+
+
+void sharectrlmsg(iv::cloud::cloudmsg * pxmsg)
+{
+    int i;
+    int nsize = pxmsg->xclouddata_size();
+    for(i=0;i<nsize;i++)
+    {
+        int j;
+        int nquerysize = mvectorctrlmsgunit.size();
+        for(j=0;j<nquerysize;j++)
+        {
+            if(strncmp(pxmsg->xclouddata(i).msgname().data(), mvectorctrlmsgunit[j].mstrmsgname,255) == 0)
+            {
+ //               qDebug("size is %d ",pxmsg->xclouddata(i).data().size());
+                iv::modulecomm::ModuleSendMsg(mvectorctrlmsgunit[j].mpa,pxmsg->xclouddata(i).data().data(),pxmsg->xclouddata(i).data().size());
+                break;
+            }
+        }
+    }
+}
+
+
+void threadupload()
+{
+    int nsize = mvectormsgunit.size();
+    int i;
+
+    int ninterval = atoi(gstruploadinterval.data());
+    if(ninterval<=0)ninterval = 100;
+
+    QTime xTime;
+    xTime.start();
+    int nlastsend = xTime.elapsed();
+
+    std::string target_str = gstrserverip+":";
+    target_str = target_str + gstrserverport ;//std::to_string()
+    auto cargs = grpc::ChannelArguments();
+    cargs.SetMaxReceiveMessageSize(1024 * 1024 * 1024); // 1 GB
+    cargs.SetMaxSendMessageSize(1024 * 1024 * 1024);
+
+    std::shared_ptr<Channel> channel = grpc::CreateCustomChannel(
+             target_str, grpc::InsecureChannelCredentials(),cargs);
+
+    std::unique_ptr<iv::Upload::Stub> stub_ = iv::Upload::NewStub(channel);
+
+
+    iv::UploadRequest request;
+
+    int nid = 0;
+
+    // Container for the data we expect from the server.
+    iv::UploadReply reply;
+
+    gpr_timespec timespec;
+      timespec.tv_sec = 30;//设置阻塞时间为2秒
+      timespec.tv_nsec = 0;
+      timespec.clock_type = GPR_TIMESPAN;
+
+ //   ClientContext context;
+
+
+
+    while(true)
+    {
+        std::this_thread::sleep_for(std::chrono::milliseconds(1));
+        if((xTime.elapsed()-nlastsend)<ninterval)
+        {
+            continue;
+        }
+
+            bool bImportant = false;
+            int nkeeptime = 0;
+            iv::cloud::cloudmsg xmsg;
+            xmsg.set_xtime(QDateTime::currentMSecsSinceEpoch());
+            gMutexMsg.lock();
+            for(i=0;i<nsize;i++)
+            {
+                if(mvectormsgunit[i].mbRefresh)
+                {
+                    mvectormsgunit[i].mbRefresh = false;
+                    if(mvectormsgunit[i].mbImportant)
+                    {
+                        bImportant = true;
+                    }
+                    if(mvectormsgunit[i].mnkeeptime > nkeeptime)
+                    {
+                        nkeeptime = mvectormsgunit[i].mnkeeptime;
+                    }
+                    iv::cloud::cloudunit xcloudunit;
+                    xcloudunit.set_msgname(mvectormsgunit[i].mstrmsgname);
+                    xcloudunit.set_data(mvectormsgunit[i].mpstrmsgdata.get(),mvectormsgunit[i].mndatasize);
+                    iv::cloud::cloudunit * pcu = xmsg.add_xclouddata();
+                    pcu->CopyFrom(xcloudunit);
+                }
+
+            }
+            gMutexMsg.unlock();
+
+            int nbytesize = xmsg.ByteSize();
+            char * strbuf = new char[nbytesize];
+            std::shared_ptr<char> pstrbuf;
+            pstrbuf.reset(strbuf);
+            if(xmsg.SerializeToArray(strbuf,nbytesize))
+            {
+
+                ClientContext context ;
+                context.set_deadline(timespec);
+                qint64 time1 = QDateTime::currentMSecsSinceEpoch();
+
+                request.set_id(nid);
+                request.set_ntime(time1);
+                request.set_strquerymd5(gstrqueryMD5);
+                request.set_strctrlmd5(gstrctrlMD5);
+                request.set_strvin(gstrVIN);
+                request.set_xdata(strbuf,nbytesize);
+                request.set_kepptime(nkeeptime);
+                request.set_bimportant(bImportant);
+                nid++;
+                // The actual RPC.
+                Status status = stub_->upload(&context, request, &reply);
+                if (status.ok()) {
+                    std::cout<<nid<<" upload successfully"<<std::endl;
+                    if(reply.nres() == 1)
+                    {
+                        iv::cloud::cloudmsg xmsg;
+                        if(xmsg.ParseFromArray(reply.xdata().data(),reply.xdata().size()))
+                        {
+                            sharectrlmsg(&xmsg);
+                        }
+                    }
+                } else {
+                  std::cout << status.error_code() << ": " << status.error_message()
+                            << std::endl;
+                  std::cout<<"RPC failed"<<std::endl;
+                  if(status.error_code() == 4)
+                  {
+                      std::cout<<" RPC Exceed Time, Create New stub_"<<std::endl;
+                      channel = grpc::CreateCustomChannel(
+                               target_str, grpc::InsecureChannelCredentials(),cargs);
+
+                      stub_ = iv::Upload::NewStub(channel);
+                  }
+                  std::this_thread::sleep_for(std::chrono::milliseconds(900));
+
+                }
+
+            }
+            nlastsend = xTime.elapsed();
+
+    }
+}
+
+
+void dec_yaml(const char * stryamlpath)
+{
+
+    YAML::Node config;
+    try
+    {
+        config = YAML::LoadFile(stryamlpath);
+    }
+    catch(YAML::BadFile e)
+    {
+        qDebug("load error.");
+        return;
+    }
+
+    std::vector<std::string> vecmodulename;
+
+
+    if(config["server"])
+    {
+        gstrserverip = config["server"].as<std::string>();
+    }
+    if(config["port"])
+    {
+        gstrserverport = config["port"].as<std::string>();
+    }
+    if(config["uploadinterval"])
+    {
+        gstruploadinterval = config["uploadinterval"].as<std::string>();
+    }
+
+    if(config["VIN"])
+    {
+        gstrVIN = config["VIN"].as<std::string>();
+    }
+
+    if(config["queryMD5"])
+    {
+        gstrqueryMD5 = config["queryMD5"].as<std::string>();
+    }
+    else
+    {
+        return;
+    }
+
+    if(config["ctrlMD5"])
+    {
+        gstrctrlMD5 = config["ctrlMD5"].as<std::string>();
+    }
+
+
+    std::string strmsgname;
+
+    if(config["uploadmessage"])
+    {
+
+        for(YAML::const_iterator it= config["uploadmessage"].begin(); it != config["uploadmessage"].end();++it)
+        {
+            std::string strtitle = it->first.as<std::string>();
+            std::cout<<strtitle<<std::endl;
+
+            if(config["uploadmessage"][strtitle]["msgname"]&&config["uploadmessage"][strtitle]["buffersize"]&&config["uploadmessage"][strtitle]["buffercount"])
+            {
+                iv::msgunit xmu;
+                strmsgname = config["uploadmessage"][strtitle]["msgname"].as<std::string>();
+                strncpy(xmu.mstrmsgname,strmsgname.data(),255);
+                xmu.mnBufferSize = config["uploadmessage"][strtitle]["buffersize"].as<int>();
+                xmu.mnBufferCount = config["uploadmessage"][strtitle]["buffercount"].as<int>();
+                if(config["uploadmessage"][strtitle]["bimportant"])
+                {
+                   std::string strimportant =    config["uploadmessage"][strtitle]["bimportant"].as<std::string>();
+                   if(strimportant == "true")
+                   {
+                       xmu.mbImportant = true;
+                   }
+                }
+                if(config["uploadmessage"][strtitle]["keeptime"])
+                {
+                   std::string strkeep =    config["uploadmessage"][strtitle]["keeptime"].as<std::string>();
+                   xmu.mnkeeptime = atoi(strkeep.data());
+                }
+                mvectormsgunit.push_back(xmu);
+            }
+        }
+    }
+    else
+    {
+
+
+    }
+
+    if(!config["ctrlMD5"])
+    {
+       return;
+    }
+
+    if(config["ctrlmessage"])
+    {
+        std::string strnodename = "ctrlmessage";
+        for(YAML::const_iterator it= config[strnodename].begin(); it != config[strnodename].end();++it)
+        {
+            std::string strtitle = it->first.as<std::string>();
+            std::cout<<strtitle<<std::endl;
+
+            if(config[strnodename][strtitle]["msgname"]&&config[strnodename][strtitle]["buffersize"]&&config[strnodename][strtitle]["buffercount"])
+            {
+                iv::msgunit xmu;
+                strmsgname = config[strnodename][strtitle]["msgname"].as<std::string>();
+                strncpy(xmu.mstrmsgname,strmsgname.data(),255);
+                xmu.mnBufferSize = config[strnodename][strtitle]["buffersize"].as<int>();
+                xmu.mnBufferCount = config[strnodename][strtitle]["buffercount"].as<int>();
+                mvectorctrlmsgunit.push_back(xmu);
+            }
+        }
+    }
+    else
+    {
+
+    }
+
+    return;
+
+}
+
+
+*/
+
+int main(int argc, char *argv[])
+{
+    showversion("driver_cloud_grpc_client");
+    QCoreApplication a(argc, argv);
+
+ //   std::thread * ptest = new std::thread(test);
+
+ //   return a.exec();
+
+    char stryamlpath[256];
+    if(argc<2)
+    {
+        snprintf(stryamlpath,255,"driver_cloud_grpc_client.yaml");
+//        strncpy(stryamlpath,abs_ymlpath,255);
+    }
+    else
+    {
+        strncpy(stryamlpath,argv[1],255);
+    }
+//    dec_yaml(stryamlpath);
+
+    grpcclient * pgrpcclient = new grpcclient(stryamlpath);
+    pgrpcclient->start();
+
+//    int i;
+//    for(i=0;i<mvectormsgunit.size();i++)
+//    {
+//        mvectormsgunit[i].mpa = iv::modulecomm::RegisterRecv(mvectormsgunit[i].mstrmsgname,ListenData);
+//    }
+
+//    for(i=0;i<mvectorctrlmsgunit.size();i++)
+//    {
+//        mvectorctrlmsgunit[i].mpa = iv::modulecomm::RegisterSend(mvectorctrlmsgunit[i].mstrmsgname,mvectorctrlmsgunit[i].mnBufferSize,
+//                                                                 mvectorctrlmsgunit[i].mnBufferCount);
+//    }
+
+//    guploadthread = new std::thread(threadupload);
+
+    return a.exec();
+}

+ 4 - 0
src/driver/driver_cloud_grpc_thread/prototocpp.txt

@@ -0,0 +1,4 @@
+protoc -I=./../../include/proto3 --plugin=protoc-gen-grpc=/home/yuchuli/git/grpc-framework/build2/grpc_cpp_plugin --grpc_out=. ./../../include/proto3/uploadthreadmsg.proto
+
+protoc -I=./../../include/proto3 --cpp_out=./../../include/msgtype   ./../../include/proto3/uploadthreadmsg.proto
+

+ 212 - 0
src/driver/driver_cloud_grpc_thread/uploadthreadmsg.grpc.pb.cc

@@ -0,0 +1,212 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: uploadthreadmsg.proto
+
+#include "uploadthreadmsg.pb.h"
+#include "uploadthreadmsg.grpc.pb.h"
+
+#include <functional>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/channel_interface.h>
+#include <grpcpp/impl/codegen/client_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/rpc_service_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+namespace iv {
+
+static const char* UploadThread_method_names[] = {
+  "/iv.UploadThread/uploaddata",
+  "/iv.UploadThread/uploadpic",
+  "/iv.UploadThread/queryctrl",
+  "/iv.UploadThread/querypic",
+};
+
+std::unique_ptr< UploadThread::Stub> UploadThread::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
+  (void)options;
+  std::unique_ptr< UploadThread::Stub> stub(new UploadThread::Stub(channel));
+  return stub;
+}
+
+UploadThread::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel)
+  : channel_(channel), rpcmethod_uploaddata_(UploadThread_method_names[0], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_uploadpic_(UploadThread_method_names[1], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_queryctrl_(UploadThread_method_names[2], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_querypic_(UploadThread_method_names[3], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  {}
+
+::grpc::Status UploadThread::Stub::uploaddata(::grpc::ClientContext* context, const ::iv::UploadRequestThread& request, ::iv::UploadReplyThread* response) {
+  return ::grpc::internal::BlockingUnaryCall< ::iv::UploadRequestThread, ::iv::UploadReplyThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_uploaddata_, context, request, response);
+}
+
+void UploadThread::Stub::experimental_async::uploaddata(::grpc::ClientContext* context, const ::iv::UploadRequestThread* request, ::iv::UploadReplyThread* response, std::function<void(::grpc::Status)> f) {
+  ::grpc::internal::CallbackUnaryCall< ::iv::UploadRequestThread, ::iv::UploadReplyThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_uploaddata_, context, request, response, std::move(f));
+}
+
+void UploadThread::Stub::experimental_async::uploaddata(::grpc::ClientContext* context, const ::iv::UploadRequestThread* request, ::iv::UploadReplyThread* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_uploaddata_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::iv::UploadReplyThread>* UploadThread::Stub::PrepareAsyncuploaddataRaw(::grpc::ClientContext* context, const ::iv::UploadRequestThread& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::iv::UploadReplyThread, ::iv::UploadRequestThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_uploaddata_, context, request);
+}
+
+::grpc::ClientAsyncResponseReader< ::iv::UploadReplyThread>* UploadThread::Stub::AsyncuploaddataRaw(::grpc::ClientContext* context, const ::iv::UploadRequestThread& request, ::grpc::CompletionQueue* cq) {
+  auto* result =
+    this->PrepareAsyncuploaddataRaw(context, request, cq);
+  result->StartCall();
+  return result;
+}
+
+::grpc::Status UploadThread::Stub::uploadpic(::grpc::ClientContext* context, const ::iv::PicUpRequestThread& request, ::iv::PicUpReplyThread* response) {
+  return ::grpc::internal::BlockingUnaryCall< ::iv::PicUpRequestThread, ::iv::PicUpReplyThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_uploadpic_, context, request, response);
+}
+
+void UploadThread::Stub::experimental_async::uploadpic(::grpc::ClientContext* context, const ::iv::PicUpRequestThread* request, ::iv::PicUpReplyThread* response, std::function<void(::grpc::Status)> f) {
+  ::grpc::internal::CallbackUnaryCall< ::iv::PicUpRequestThread, ::iv::PicUpReplyThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_uploadpic_, context, request, response, std::move(f));
+}
+
+void UploadThread::Stub::experimental_async::uploadpic(::grpc::ClientContext* context, const ::iv::PicUpRequestThread* request, ::iv::PicUpReplyThread* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_uploadpic_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::iv::PicUpReplyThread>* UploadThread::Stub::PrepareAsyncuploadpicRaw(::grpc::ClientContext* context, const ::iv::PicUpRequestThread& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::iv::PicUpReplyThread, ::iv::PicUpRequestThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_uploadpic_, context, request);
+}
+
+::grpc::ClientAsyncResponseReader< ::iv::PicUpReplyThread>* UploadThread::Stub::AsyncuploadpicRaw(::grpc::ClientContext* context, const ::iv::PicUpRequestThread& request, ::grpc::CompletionQueue* cq) {
+  auto* result =
+    this->PrepareAsyncuploadpicRaw(context, request, cq);
+  result->StartCall();
+  return result;
+}
+
+::grpc::Status UploadThread::Stub::queryctrl(::grpc::ClientContext* context, const ::iv::queryReqThread& request, ::iv::queryReplyThread* response) {
+  return ::grpc::internal::BlockingUnaryCall< ::iv::queryReqThread, ::iv::queryReplyThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_queryctrl_, context, request, response);
+}
+
+void UploadThread::Stub::experimental_async::queryctrl(::grpc::ClientContext* context, const ::iv::queryReqThread* request, ::iv::queryReplyThread* response, std::function<void(::grpc::Status)> f) {
+  ::grpc::internal::CallbackUnaryCall< ::iv::queryReqThread, ::iv::queryReplyThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_queryctrl_, context, request, response, std::move(f));
+}
+
+void UploadThread::Stub::experimental_async::queryctrl(::grpc::ClientContext* context, const ::iv::queryReqThread* request, ::iv::queryReplyThread* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_queryctrl_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::iv::queryReplyThread>* UploadThread::Stub::PrepareAsyncqueryctrlRaw(::grpc::ClientContext* context, const ::iv::queryReqThread& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::iv::queryReplyThread, ::iv::queryReqThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_queryctrl_, context, request);
+}
+
+::grpc::ClientAsyncResponseReader< ::iv::queryReplyThread>* UploadThread::Stub::AsyncqueryctrlRaw(::grpc::ClientContext* context, const ::iv::queryReqThread& request, ::grpc::CompletionQueue* cq) {
+  auto* result =
+    this->PrepareAsyncqueryctrlRaw(context, request, cq);
+  result->StartCall();
+  return result;
+}
+
+::grpc::Status UploadThread::Stub::querypic(::grpc::ClientContext* context, const ::iv::PicDownReqThread& request, ::iv::PicDownReplyThread* response) {
+  return ::grpc::internal::BlockingUnaryCall< ::iv::PicDownReqThread, ::iv::PicDownReplyThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_querypic_, context, request, response);
+}
+
+void UploadThread::Stub::experimental_async::querypic(::grpc::ClientContext* context, const ::iv::PicDownReqThread* request, ::iv::PicDownReplyThread* response, std::function<void(::grpc::Status)> f) {
+  ::grpc::internal::CallbackUnaryCall< ::iv::PicDownReqThread, ::iv::PicDownReplyThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_querypic_, context, request, response, std::move(f));
+}
+
+void UploadThread::Stub::experimental_async::querypic(::grpc::ClientContext* context, const ::iv::PicDownReqThread* request, ::iv::PicDownReplyThread* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_querypic_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::iv::PicDownReplyThread>* UploadThread::Stub::PrepareAsyncquerypicRaw(::grpc::ClientContext* context, const ::iv::PicDownReqThread& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::iv::PicDownReplyThread, ::iv::PicDownReqThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_querypic_, context, request);
+}
+
+::grpc::ClientAsyncResponseReader< ::iv::PicDownReplyThread>* UploadThread::Stub::AsyncquerypicRaw(::grpc::ClientContext* context, const ::iv::PicDownReqThread& request, ::grpc::CompletionQueue* cq) {
+  auto* result =
+    this->PrepareAsyncquerypicRaw(context, request, cq);
+  result->StartCall();
+  return result;
+}
+
+UploadThread::Service::Service() {
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      UploadThread_method_names[0],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< UploadThread::Service, ::iv::UploadRequestThread, ::iv::UploadReplyThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
+          [](UploadThread::Service* service,
+             ::grpc::ServerContext* ctx,
+             const ::iv::UploadRequestThread* req,
+             ::iv::UploadReplyThread* resp) {
+               return service->uploaddata(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      UploadThread_method_names[1],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< UploadThread::Service, ::iv::PicUpRequestThread, ::iv::PicUpReplyThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
+          [](UploadThread::Service* service,
+             ::grpc::ServerContext* ctx,
+             const ::iv::PicUpRequestThread* req,
+             ::iv::PicUpReplyThread* resp) {
+               return service->uploadpic(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      UploadThread_method_names[2],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< UploadThread::Service, ::iv::queryReqThread, ::iv::queryReplyThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
+          [](UploadThread::Service* service,
+             ::grpc::ServerContext* ctx,
+             const ::iv::queryReqThread* req,
+             ::iv::queryReplyThread* resp) {
+               return service->queryctrl(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      UploadThread_method_names[3],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< UploadThread::Service, ::iv::PicDownReqThread, ::iv::PicDownReplyThread, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(
+          [](UploadThread::Service* service,
+             ::grpc::ServerContext* ctx,
+             const ::iv::PicDownReqThread* req,
+             ::iv::PicDownReplyThread* resp) {
+               return service->querypic(ctx, req, resp);
+             }, this)));
+}
+
+UploadThread::Service::~Service() {
+}
+
+::grpc::Status UploadThread::Service::uploaddata(::grpc::ServerContext* context, const ::iv::UploadRequestThread* request, ::iv::UploadReplyThread* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status UploadThread::Service::uploadpic(::grpc::ServerContext* context, const ::iv::PicUpRequestThread* request, ::iv::PicUpReplyThread* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status UploadThread::Service::queryctrl(::grpc::ServerContext* context, const ::iv::queryReqThread* request, ::iv::queryReplyThread* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status UploadThread::Service::querypic(::grpc::ServerContext* context, const ::iv::PicDownReqThread* request, ::iv::PicDownReplyThread* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+
+}  // namespace iv
+

+ 914 - 0
src/driver/driver_cloud_grpc_thread/uploadthreadmsg.grpc.pb.h

@@ -0,0 +1,914 @@
+// Generated by the gRPC C++ plugin.
+// If you make any local change, they will be lost.
+// source: uploadthreadmsg.proto
+// Original file comments:
+// Copyright 2015 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#ifndef GRPC_uploadthreadmsg_2eproto__INCLUDED
+#define GRPC_uploadthreadmsg_2eproto__INCLUDED
+
+#include "uploadthreadmsg.pb.h"
+
+#include <functional>
+#include <grpc/impl/codegen/port_platform.h>
+#include <grpcpp/impl/codegen/async_generic_service.h>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
+#include <grpcpp/impl/codegen/client_context.h>
+#include <grpcpp/impl/codegen/completion_queue.h>
+#include <grpcpp/impl/codegen/message_allocator.h>
+#include <grpcpp/impl/codegen/method_handler.h>
+#include <grpcpp/impl/codegen/proto_utils.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
+#include <grpcpp/impl/codegen/server_callback.h>
+#include <grpcpp/impl/codegen/server_callback_handlers.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/status.h>
+#include <grpcpp/impl/codegen/stub_options.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+
+namespace iv {
+
+// The Upload service definition.
+class UploadThread final {
+ public:
+  static constexpr char const* service_full_name() {
+    return "iv.UploadThread";
+  }
+  class StubInterface {
+   public:
+    virtual ~StubInterface() {}
+    // Sends a Upload
+    virtual ::grpc::Status uploaddata(::grpc::ClientContext* context, const ::iv::UploadRequestThread& request, ::iv::UploadReplyThread* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::UploadReplyThread>> Asyncuploaddata(::grpc::ClientContext* context, const ::iv::UploadRequestThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::UploadReplyThread>>(AsyncuploaddataRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::UploadReplyThread>> PrepareAsyncuploaddata(::grpc::ClientContext* context, const ::iv::UploadRequestThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::UploadReplyThread>>(PrepareAsyncuploaddataRaw(context, request, cq));
+    }
+    virtual ::grpc::Status uploadpic(::grpc::ClientContext* context, const ::iv::PicUpRequestThread& request, ::iv::PicUpReplyThread* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::PicUpReplyThread>> Asyncuploadpic(::grpc::ClientContext* context, const ::iv::PicUpRequestThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::PicUpReplyThread>>(AsyncuploadpicRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::PicUpReplyThread>> PrepareAsyncuploadpic(::grpc::ClientContext* context, const ::iv::PicUpRequestThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::PicUpReplyThread>>(PrepareAsyncuploadpicRaw(context, request, cq));
+    }
+    virtual ::grpc::Status queryctrl(::grpc::ClientContext* context, const ::iv::queryReqThread& request, ::iv::queryReplyThread* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::queryReplyThread>> Asyncqueryctrl(::grpc::ClientContext* context, const ::iv::queryReqThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::queryReplyThread>>(AsyncqueryctrlRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::queryReplyThread>> PrepareAsyncqueryctrl(::grpc::ClientContext* context, const ::iv::queryReqThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::queryReplyThread>>(PrepareAsyncqueryctrlRaw(context, request, cq));
+    }
+    virtual ::grpc::Status querypic(::grpc::ClientContext* context, const ::iv::PicDownReqThread& request, ::iv::PicDownReplyThread* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::PicDownReplyThread>> Asyncquerypic(::grpc::ClientContext* context, const ::iv::PicDownReqThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::PicDownReplyThread>>(AsyncquerypicRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::PicDownReplyThread>> PrepareAsyncquerypic(::grpc::ClientContext* context, const ::iv::PicDownReqThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::iv::PicDownReplyThread>>(PrepareAsyncquerypicRaw(context, request, cq));
+    }
+    class experimental_async_interface {
+     public:
+      virtual ~experimental_async_interface() {}
+      // Sends a Upload
+      virtual void uploaddata(::grpc::ClientContext* context, const ::iv::UploadRequestThread* request, ::iv::UploadReplyThread* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void uploaddata(::grpc::ClientContext* context, const ::iv::UploadRequestThread* request, ::iv::UploadReplyThread* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void uploaddata(::grpc::ClientContext* context, const ::iv::UploadRequestThread* request, ::iv::UploadReplyThread* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      virtual void uploadpic(::grpc::ClientContext* context, const ::iv::PicUpRequestThread* request, ::iv::PicUpReplyThread* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void uploadpic(::grpc::ClientContext* context, const ::iv::PicUpRequestThread* request, ::iv::PicUpReplyThread* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void uploadpic(::grpc::ClientContext* context, const ::iv::PicUpRequestThread* request, ::iv::PicUpReplyThread* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      virtual void queryctrl(::grpc::ClientContext* context, const ::iv::queryReqThread* request, ::iv::queryReplyThread* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void queryctrl(::grpc::ClientContext* context, const ::iv::queryReqThread* request, ::iv::queryReplyThread* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void queryctrl(::grpc::ClientContext* context, const ::iv::queryReqThread* request, ::iv::queryReplyThread* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      virtual void querypic(::grpc::ClientContext* context, const ::iv::PicDownReqThread* request, ::iv::PicDownReplyThread* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void querypic(::grpc::ClientContext* context, const ::iv::PicDownReqThread* request, ::iv::PicDownReplyThread* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void querypic(::grpc::ClientContext* context, const ::iv::PicDownReqThread* request, ::iv::PicDownReplyThread* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+    };
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    typedef class experimental_async_interface async_interface;
+    #endif
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    async_interface* async() { return experimental_async(); }
+    #endif
+    virtual class experimental_async_interface* experimental_async() { return nullptr; }
+  private:
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::iv::UploadReplyThread>* AsyncuploaddataRaw(::grpc::ClientContext* context, const ::iv::UploadRequestThread& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::iv::UploadReplyThread>* PrepareAsyncuploaddataRaw(::grpc::ClientContext* context, const ::iv::UploadRequestThread& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::iv::PicUpReplyThread>* AsyncuploadpicRaw(::grpc::ClientContext* context, const ::iv::PicUpRequestThread& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::iv::PicUpReplyThread>* PrepareAsyncuploadpicRaw(::grpc::ClientContext* context, const ::iv::PicUpRequestThread& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::iv::queryReplyThread>* AsyncqueryctrlRaw(::grpc::ClientContext* context, const ::iv::queryReqThread& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::iv::queryReplyThread>* PrepareAsyncqueryctrlRaw(::grpc::ClientContext* context, const ::iv::queryReqThread& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::iv::PicDownReplyThread>* AsyncquerypicRaw(::grpc::ClientContext* context, const ::iv::PicDownReqThread& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::iv::PicDownReplyThread>* PrepareAsyncquerypicRaw(::grpc::ClientContext* context, const ::iv::PicDownReqThread& request, ::grpc::CompletionQueue* cq) = 0;
+  };
+  class Stub final : public StubInterface {
+   public:
+    Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);
+    ::grpc::Status uploaddata(::grpc::ClientContext* context, const ::iv::UploadRequestThread& request, ::iv::UploadReplyThread* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::UploadReplyThread>> Asyncuploaddata(::grpc::ClientContext* context, const ::iv::UploadRequestThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::UploadReplyThread>>(AsyncuploaddataRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::UploadReplyThread>> PrepareAsyncuploaddata(::grpc::ClientContext* context, const ::iv::UploadRequestThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::UploadReplyThread>>(PrepareAsyncuploaddataRaw(context, request, cq));
+    }
+    ::grpc::Status uploadpic(::grpc::ClientContext* context, const ::iv::PicUpRequestThread& request, ::iv::PicUpReplyThread* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::PicUpReplyThread>> Asyncuploadpic(::grpc::ClientContext* context, const ::iv::PicUpRequestThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::PicUpReplyThread>>(AsyncuploadpicRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::PicUpReplyThread>> PrepareAsyncuploadpic(::grpc::ClientContext* context, const ::iv::PicUpRequestThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::PicUpReplyThread>>(PrepareAsyncuploadpicRaw(context, request, cq));
+    }
+    ::grpc::Status queryctrl(::grpc::ClientContext* context, const ::iv::queryReqThread& request, ::iv::queryReplyThread* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::queryReplyThread>> Asyncqueryctrl(::grpc::ClientContext* context, const ::iv::queryReqThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::queryReplyThread>>(AsyncqueryctrlRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::queryReplyThread>> PrepareAsyncqueryctrl(::grpc::ClientContext* context, const ::iv::queryReqThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::queryReplyThread>>(PrepareAsyncqueryctrlRaw(context, request, cq));
+    }
+    ::grpc::Status querypic(::grpc::ClientContext* context, const ::iv::PicDownReqThread& request, ::iv::PicDownReplyThread* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::PicDownReplyThread>> Asyncquerypic(::grpc::ClientContext* context, const ::iv::PicDownReqThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::PicDownReplyThread>>(AsyncquerypicRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::PicDownReplyThread>> PrepareAsyncquerypic(::grpc::ClientContext* context, const ::iv::PicDownReqThread& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::iv::PicDownReplyThread>>(PrepareAsyncquerypicRaw(context, request, cq));
+    }
+    class experimental_async final :
+      public StubInterface::experimental_async_interface {
+     public:
+      void uploaddata(::grpc::ClientContext* context, const ::iv::UploadRequestThread* request, ::iv::UploadReplyThread* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void uploaddata(::grpc::ClientContext* context, const ::iv::UploadRequestThread* request, ::iv::UploadReplyThread* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void uploaddata(::grpc::ClientContext* context, const ::iv::UploadRequestThread* request, ::iv::UploadReplyThread* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void uploadpic(::grpc::ClientContext* context, const ::iv::PicUpRequestThread* request, ::iv::PicUpReplyThread* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void uploadpic(::grpc::ClientContext* context, const ::iv::PicUpRequestThread* request, ::iv::PicUpReplyThread* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void uploadpic(::grpc::ClientContext* context, const ::iv::PicUpRequestThread* request, ::iv::PicUpReplyThread* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void queryctrl(::grpc::ClientContext* context, const ::iv::queryReqThread* request, ::iv::queryReplyThread* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void queryctrl(::grpc::ClientContext* context, const ::iv::queryReqThread* request, ::iv::queryReplyThread* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void queryctrl(::grpc::ClientContext* context, const ::iv::queryReqThread* request, ::iv::queryReplyThread* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void querypic(::grpc::ClientContext* context, const ::iv::PicDownReqThread* request, ::iv::PicDownReplyThread* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void querypic(::grpc::ClientContext* context, const ::iv::PicDownReqThread* request, ::iv::PicDownReplyThread* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void querypic(::grpc::ClientContext* context, const ::iv::PicDownReqThread* request, ::iv::PicDownReplyThread* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+     private:
+      friend class Stub;
+      explicit experimental_async(Stub* stub): stub_(stub) { }
+      Stub* stub() { return stub_; }
+      Stub* stub_;
+    };
+    class experimental_async_interface* experimental_async() override { return &async_stub_; }
+
+   private:
+    std::shared_ptr< ::grpc::ChannelInterface> channel_;
+    class experimental_async async_stub_{this};
+    ::grpc::ClientAsyncResponseReader< ::iv::UploadReplyThread>* AsyncuploaddataRaw(::grpc::ClientContext* context, const ::iv::UploadRequestThread& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::iv::UploadReplyThread>* PrepareAsyncuploaddataRaw(::grpc::ClientContext* context, const ::iv::UploadRequestThread& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::iv::PicUpReplyThread>* AsyncuploadpicRaw(::grpc::ClientContext* context, const ::iv::PicUpRequestThread& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::iv::PicUpReplyThread>* PrepareAsyncuploadpicRaw(::grpc::ClientContext* context, const ::iv::PicUpRequestThread& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::iv::queryReplyThread>* AsyncqueryctrlRaw(::grpc::ClientContext* context, const ::iv::queryReqThread& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::iv::queryReplyThread>* PrepareAsyncqueryctrlRaw(::grpc::ClientContext* context, const ::iv::queryReqThread& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::iv::PicDownReplyThread>* AsyncquerypicRaw(::grpc::ClientContext* context, const ::iv::PicDownReqThread& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::iv::PicDownReplyThread>* PrepareAsyncquerypicRaw(::grpc::ClientContext* context, const ::iv::PicDownReqThread& request, ::grpc::CompletionQueue* cq) override;
+    const ::grpc::internal::RpcMethod rpcmethod_uploaddata_;
+    const ::grpc::internal::RpcMethod rpcmethod_uploadpic_;
+    const ::grpc::internal::RpcMethod rpcmethod_queryctrl_;
+    const ::grpc::internal::RpcMethod rpcmethod_querypic_;
+  };
+  static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
+
+  class Service : public ::grpc::Service {
+   public:
+    Service();
+    virtual ~Service();
+    // Sends a Upload
+    virtual ::grpc::Status uploaddata(::grpc::ServerContext* context, const ::iv::UploadRequestThread* request, ::iv::UploadReplyThread* response);
+    virtual ::grpc::Status uploadpic(::grpc::ServerContext* context, const ::iv::PicUpRequestThread* request, ::iv::PicUpReplyThread* response);
+    virtual ::grpc::Status queryctrl(::grpc::ServerContext* context, const ::iv::queryReqThread* request, ::iv::queryReplyThread* response);
+    virtual ::grpc::Status querypic(::grpc::ServerContext* context, const ::iv::PicDownReqThread* request, ::iv::PicDownReplyThread* response);
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_uploaddata : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_uploaddata() {
+      ::grpc::Service::MarkMethodAsync(0);
+    }
+    ~WithAsyncMethod_uploaddata() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status uploaddata(::grpc::ServerContext* /*context*/, const ::iv::UploadRequestThread* /*request*/, ::iv::UploadReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void Requestuploaddata(::grpc::ServerContext* context, ::iv::UploadRequestThread* request, ::grpc::ServerAsyncResponseWriter< ::iv::UploadReplyThread>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_uploadpic : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_uploadpic() {
+      ::grpc::Service::MarkMethodAsync(1);
+    }
+    ~WithAsyncMethod_uploadpic() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status uploadpic(::grpc::ServerContext* /*context*/, const ::iv::PicUpRequestThread* /*request*/, ::iv::PicUpReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void Requestuploadpic(::grpc::ServerContext* context, ::iv::PicUpRequestThread* request, ::grpc::ServerAsyncResponseWriter< ::iv::PicUpReplyThread>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(1, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_queryctrl : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_queryctrl() {
+      ::grpc::Service::MarkMethodAsync(2);
+    }
+    ~WithAsyncMethod_queryctrl() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status queryctrl(::grpc::ServerContext* /*context*/, const ::iv::queryReqThread* /*request*/, ::iv::queryReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void Requestqueryctrl(::grpc::ServerContext* context, ::iv::queryReqThread* request, ::grpc::ServerAsyncResponseWriter< ::iv::queryReplyThread>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(2, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_querypic : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_querypic() {
+      ::grpc::Service::MarkMethodAsync(3);
+    }
+    ~WithAsyncMethod_querypic() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status querypic(::grpc::ServerContext* /*context*/, const ::iv::PicDownReqThread* /*request*/, ::iv::PicDownReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void Requestquerypic(::grpc::ServerContext* context, ::iv::PicDownReqThread* request, ::grpc::ServerAsyncResponseWriter< ::iv::PicDownReplyThread>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(3, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  typedef WithAsyncMethod_uploaddata<WithAsyncMethod_uploadpic<WithAsyncMethod_queryctrl<WithAsyncMethod_querypic<Service > > > > AsyncService;
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_uploaddata : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_uploaddata() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(0,
+          new ::grpc::internal::CallbackUnaryHandler< ::iv::UploadRequestThread, ::iv::UploadReplyThread>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::iv::UploadRequestThread* request, ::iv::UploadReplyThread* response) { return this->uploaddata(context, request, response); }));}
+    void SetMessageAllocatorFor_uploaddata(
+        ::grpc::experimental::MessageAllocator< ::iv::UploadRequestThread, ::iv::UploadReplyThread>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(0);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(0);
+    #endif
+      static_cast<::grpc::internal::CallbackUnaryHandler< ::iv::UploadRequestThread, ::iv::UploadReplyThread>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_uploaddata() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status uploaddata(::grpc::ServerContext* /*context*/, const ::iv::UploadRequestThread* /*request*/, ::iv::UploadReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* uploaddata(
+      ::grpc::CallbackServerContext* /*context*/, const ::iv::UploadRequestThread* /*request*/, ::iv::UploadReplyThread* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* uploaddata(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::iv::UploadRequestThread* /*request*/, ::iv::UploadReplyThread* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_uploadpic : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_uploadpic() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(1,
+          new ::grpc::internal::CallbackUnaryHandler< ::iv::PicUpRequestThread, ::iv::PicUpReplyThread>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::iv::PicUpRequestThread* request, ::iv::PicUpReplyThread* response) { return this->uploadpic(context, request, response); }));}
+    void SetMessageAllocatorFor_uploadpic(
+        ::grpc::experimental::MessageAllocator< ::iv::PicUpRequestThread, ::iv::PicUpReplyThread>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(1);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(1);
+    #endif
+      static_cast<::grpc::internal::CallbackUnaryHandler< ::iv::PicUpRequestThread, ::iv::PicUpReplyThread>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_uploadpic() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status uploadpic(::grpc::ServerContext* /*context*/, const ::iv::PicUpRequestThread* /*request*/, ::iv::PicUpReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* uploadpic(
+      ::grpc::CallbackServerContext* /*context*/, const ::iv::PicUpRequestThread* /*request*/, ::iv::PicUpReplyThread* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* uploadpic(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::iv::PicUpRequestThread* /*request*/, ::iv::PicUpReplyThread* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_queryctrl : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_queryctrl() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(2,
+          new ::grpc::internal::CallbackUnaryHandler< ::iv::queryReqThread, ::iv::queryReplyThread>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::iv::queryReqThread* request, ::iv::queryReplyThread* response) { return this->queryctrl(context, request, response); }));}
+    void SetMessageAllocatorFor_queryctrl(
+        ::grpc::experimental::MessageAllocator< ::iv::queryReqThread, ::iv::queryReplyThread>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(2);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(2);
+    #endif
+      static_cast<::grpc::internal::CallbackUnaryHandler< ::iv::queryReqThread, ::iv::queryReplyThread>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_queryctrl() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status queryctrl(::grpc::ServerContext* /*context*/, const ::iv::queryReqThread* /*request*/, ::iv::queryReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* queryctrl(
+      ::grpc::CallbackServerContext* /*context*/, const ::iv::queryReqThread* /*request*/, ::iv::queryReplyThread* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* queryctrl(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::iv::queryReqThread* /*request*/, ::iv::queryReplyThread* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_querypic : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_querypic() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(3,
+          new ::grpc::internal::CallbackUnaryHandler< ::iv::PicDownReqThread, ::iv::PicDownReplyThread>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::iv::PicDownReqThread* request, ::iv::PicDownReplyThread* response) { return this->querypic(context, request, response); }));}
+    void SetMessageAllocatorFor_querypic(
+        ::grpc::experimental::MessageAllocator< ::iv::PicDownReqThread, ::iv::PicDownReplyThread>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(3);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(3);
+    #endif
+      static_cast<::grpc::internal::CallbackUnaryHandler< ::iv::PicDownReqThread, ::iv::PicDownReplyThread>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_querypic() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status querypic(::grpc::ServerContext* /*context*/, const ::iv::PicDownReqThread* /*request*/, ::iv::PicDownReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* querypic(
+      ::grpc::CallbackServerContext* /*context*/, const ::iv::PicDownReqThread* /*request*/, ::iv::PicDownReplyThread* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* querypic(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::iv::PicDownReqThread* /*request*/, ::iv::PicDownReplyThread* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+  typedef ExperimentalWithCallbackMethod_uploaddata<ExperimentalWithCallbackMethod_uploadpic<ExperimentalWithCallbackMethod_queryctrl<ExperimentalWithCallbackMethod_querypic<Service > > > > CallbackService;
+  #endif
+
+  typedef ExperimentalWithCallbackMethod_uploaddata<ExperimentalWithCallbackMethod_uploadpic<ExperimentalWithCallbackMethod_queryctrl<ExperimentalWithCallbackMethod_querypic<Service > > > > ExperimentalCallbackService;
+  template <class BaseClass>
+  class WithGenericMethod_uploaddata : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_uploaddata() {
+      ::grpc::Service::MarkMethodGeneric(0);
+    }
+    ~WithGenericMethod_uploaddata() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status uploaddata(::grpc::ServerContext* /*context*/, const ::iv::UploadRequestThread* /*request*/, ::iv::UploadReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_uploadpic : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_uploadpic() {
+      ::grpc::Service::MarkMethodGeneric(1);
+    }
+    ~WithGenericMethod_uploadpic() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status uploadpic(::grpc::ServerContext* /*context*/, const ::iv::PicUpRequestThread* /*request*/, ::iv::PicUpReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_queryctrl : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_queryctrl() {
+      ::grpc::Service::MarkMethodGeneric(2);
+    }
+    ~WithGenericMethod_queryctrl() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status queryctrl(::grpc::ServerContext* /*context*/, const ::iv::queryReqThread* /*request*/, ::iv::queryReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_querypic : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_querypic() {
+      ::grpc::Service::MarkMethodGeneric(3);
+    }
+    ~WithGenericMethod_querypic() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status querypic(::grpc::ServerContext* /*context*/, const ::iv::PicDownReqThread* /*request*/, ::iv::PicDownReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_uploaddata : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_uploaddata() {
+      ::grpc::Service::MarkMethodRaw(0);
+    }
+    ~WithRawMethod_uploaddata() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status uploaddata(::grpc::ServerContext* /*context*/, const ::iv::UploadRequestThread* /*request*/, ::iv::UploadReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void Requestuploaddata(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_uploadpic : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_uploadpic() {
+      ::grpc::Service::MarkMethodRaw(1);
+    }
+    ~WithRawMethod_uploadpic() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status uploadpic(::grpc::ServerContext* /*context*/, const ::iv::PicUpRequestThread* /*request*/, ::iv::PicUpReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void Requestuploadpic(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(1, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_queryctrl : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_queryctrl() {
+      ::grpc::Service::MarkMethodRaw(2);
+    }
+    ~WithRawMethod_queryctrl() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status queryctrl(::grpc::ServerContext* /*context*/, const ::iv::queryReqThread* /*request*/, ::iv::queryReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void Requestqueryctrl(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(2, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_querypic : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_querypic() {
+      ::grpc::Service::MarkMethodRaw(3);
+    }
+    ~WithRawMethod_querypic() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status querypic(::grpc::ServerContext* /*context*/, const ::iv::PicDownReqThread* /*request*/, ::iv::PicDownReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void Requestquerypic(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(3, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_uploaddata : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_uploaddata() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(0,
+          new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->uploaddata(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_uploaddata() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status uploaddata(::grpc::ServerContext* /*context*/, const ::iv::UploadRequestThread* /*request*/, ::iv::UploadReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* uploaddata(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* uploaddata(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_uploadpic : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_uploadpic() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(1,
+          new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->uploadpic(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_uploadpic() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status uploadpic(::grpc::ServerContext* /*context*/, const ::iv::PicUpRequestThread* /*request*/, ::iv::PicUpReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* uploadpic(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* uploadpic(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_queryctrl : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_queryctrl() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(2,
+          new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->queryctrl(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_queryctrl() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status queryctrl(::grpc::ServerContext* /*context*/, const ::iv::queryReqThread* /*request*/, ::iv::queryReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* queryctrl(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* queryctrl(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_querypic : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_querypic() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(3,
+          new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->querypic(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_querypic() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status querypic(::grpc::ServerContext* /*context*/, const ::iv::PicDownReqThread* /*request*/, ::iv::PicDownReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* querypic(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* querypic(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_uploaddata : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_uploaddata() {
+      ::grpc::Service::MarkMethodStreamed(0,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::iv::UploadRequestThread, ::iv::UploadReplyThread>(
+            [this](::grpc::ServerContext* context,
+                   ::grpc::ServerUnaryStreamer<
+                     ::iv::UploadRequestThread, ::iv::UploadReplyThread>* streamer) {
+                       return this->Streameduploaddata(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_uploaddata() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status uploaddata(::grpc::ServerContext* /*context*/, const ::iv::UploadRequestThread* /*request*/, ::iv::UploadReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status Streameduploaddata(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::iv::UploadRequestThread,::iv::UploadReplyThread>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_uploadpic : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_uploadpic() {
+      ::grpc::Service::MarkMethodStreamed(1,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::iv::PicUpRequestThread, ::iv::PicUpReplyThread>(
+            [this](::grpc::ServerContext* context,
+                   ::grpc::ServerUnaryStreamer<
+                     ::iv::PicUpRequestThread, ::iv::PicUpReplyThread>* streamer) {
+                       return this->Streameduploadpic(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_uploadpic() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status uploadpic(::grpc::ServerContext* /*context*/, const ::iv::PicUpRequestThread* /*request*/, ::iv::PicUpReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status Streameduploadpic(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::iv::PicUpRequestThread,::iv::PicUpReplyThread>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_queryctrl : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_queryctrl() {
+      ::grpc::Service::MarkMethodStreamed(2,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::iv::queryReqThread, ::iv::queryReplyThread>(
+            [this](::grpc::ServerContext* context,
+                   ::grpc::ServerUnaryStreamer<
+                     ::iv::queryReqThread, ::iv::queryReplyThread>* streamer) {
+                       return this->Streamedqueryctrl(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_queryctrl() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status queryctrl(::grpc::ServerContext* /*context*/, const ::iv::queryReqThread* /*request*/, ::iv::queryReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status Streamedqueryctrl(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::iv::queryReqThread,::iv::queryReplyThread>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_querypic : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_querypic() {
+      ::grpc::Service::MarkMethodStreamed(3,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::iv::PicDownReqThread, ::iv::PicDownReplyThread>(
+            [this](::grpc::ServerContext* context,
+                   ::grpc::ServerUnaryStreamer<
+                     ::iv::PicDownReqThread, ::iv::PicDownReplyThread>* streamer) {
+                       return this->Streamedquerypic(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_querypic() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status querypic(::grpc::ServerContext* /*context*/, const ::iv::PicDownReqThread* /*request*/, ::iv::PicDownReplyThread* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status Streamedquerypic(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::iv::PicDownReqThread,::iv::PicDownReplyThread>* server_unary_streamer) = 0;
+  };
+  typedef WithStreamedUnaryMethod_uploaddata<WithStreamedUnaryMethod_uploadpic<WithStreamedUnaryMethod_queryctrl<WithStreamedUnaryMethod_querypic<Service > > > > StreamedUnaryService;
+  typedef Service SplitStreamedService;
+  typedef WithStreamedUnaryMethod_uploaddata<WithStreamedUnaryMethod_uploadpic<WithStreamedUnaryMethod_queryctrl<WithStreamedUnaryMethod_querypic<Service > > > > StreamedService;
+};
+
+}  // namespace iv
+
+
+#endif  // GRPC_uploadthreadmsg_2eproto__INCLUDED

+ 26 - 0
src/include/proto/threadcloud.proto

@@ -0,0 +1,26 @@
+syntax = "proto2";
+
+package iv.cloud;
+
+message threadcloudunit
+{
+  required string msgname = 1;
+  optional bytes xdata = 2;
+};
+
+message threadpic
+{
+  optional int32 picpos = 1; //0 front  1 rear  2 left 3 right
+  optional int64 pictime = 2;
+  optional bytes xdata = 3;
+};
+
+message threadcloudmsg
+{
+  optional int64 xtime = 1;
+  optional int64 index = 2;
+  optional bool mbPic = 3;
+  optional threadpic xpicdata = 4;
+  repeated threadcloudunit xclouddata = 5; 
+};
+

+ 123 - 0
src/include/proto3/uploadthreadmsg.proto

@@ -0,0 +1,123 @@
+// Copyright 2015 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+option java_package = "io.grpc.adc.uploadthreadmsg";
+option java_outer_classname = "UploadThreadMsgProto";
+option objc_class_prefix = "HLW";
+
+package iv;
+
+// The Upload service definition.
+service UploadThread {
+  // Sends a Upload
+  rpc uploaddata (UploadRequestThread) returns (UploadReplyThread) {}
+  rpc uploadpic (PicUpRequestThread) returns (PicUpReplyThread) {}
+  rpc queryctrl ( queryReqThread) returns (queryReplyThread) {}
+  rpc querypic ( PicDownReqThread) returns (PicDownReplyThread) {}
+  
+}
+
+// The request message containing the user's name.
+message UploadRequestThread {
+ // string name = 1;
+
+ //   int nres; //0 no message 1 have message
+    int32 id = 1;
+    int64 ntime = 2;
+    string strVIN = 3;
+    string strqueryMD5 = 4;
+    string strctrlMD5 = 5;
+    bytes xdata = 6;
+    bool bimportant = 7;  //if 1, is important.
+    int32 kepptime = 8;   //If important keep this data before query ms.
+    float fFrameRate = 9;
+    int64 nSendTime = 10;
+    int64 nLatency = 11;
+}
+
+// The response message containing the greetings
+message UploadReplyThread {
+  int32 nres = 1;  //0 no message 1 have ctrl message
+  bytes xdata = 2;
+  int32 nreqid = 3;  
+  int64 nreqSendTime = 4;  //id and SendTime used for calculate latency. 
+  float framerate = 5;
+  int64 npausetime = 6;  //upload message in server pause time, calculate latency need substract this value.
+  bool mbCamFront = 7;  //if true upload camera, false not need upload
+  bool mbCamRear = 8;    
+  bool mbCamLeft = 9;
+  bool mbCamRight = 10;
+//  string message = 1;
+}
+
+
+message queryReqThread {
+  string strvin = 1;
+  string strqueryMD5 = 2;
+  int64 ntime = 3;  
+  string strctrlMD5 = 4;
+  bytes xdata = 5;
+  bool bimportant = 6;  //if 1, is important.
+  int32 kepptime = 7;   //If important keep this data before ctrl ms.  if -1 must send.
+  int32 ntype = 8;  //0 only query  1 ctrl.
+  float nSuggestFrameRate = 9;
+  int32 nreplyid = 10;  
+  int64 nreplySendTime = 11;  //id and SendTime used for calculate latency. 
+  int64 npausetime = 12;  //upload message in server pause time, calculate latency need substract this value.
+  bool mbCamFront = 13;  //if true upload camera, false not need upload
+  bool mbCamRear = 14;    
+  bool mbCamLeft = 15;
+  bool mbCamRight = 16;
+}
+
+message queryReplyThread {
+    int32 nres = 1;  //0 not online  1 online  -1 querMD5 error  -2 ctrlMD5 error 
+    int32 id = 2;
+    int64 ntime = 3;
+    bytes xdata = 4;
+    int64 nculatency = 5;
+    float ncuFrameRage = 6;
+    int64 nSendTime = 7;
+    int64 nserverLatency = 8;
+}
+
+message PicUpRequestThread{
+  string strVIN = 1;
+  int32 nCamPos = 2; //0 front 1 rear 2 left 3 right
+  int64 nPicTime = 3;
+  bytes xdata = 4;
+}
+
+message PicUpReplyThread{
+  int32 nres = 1; 
+}
+
+message PicDownReqThread{
+  string strVIN = 1;
+  string strqueryMD5 = 2;
+  int32 nCamPos = 3; //0 front 1 rear 2 left 3 right
+  int64 nPicTime = 4;  // > this PicTime
+}
+
+message PicDownReplyThread{
+  int32 nres = 1; // 0 no data   1 have data
+  int32 nCamPos = 2; //0 front 1 rear 2 left 3 right
+  int64 nPicTime = 3;  // > this PicTime
+  bytes xdata = 4;
+}
+
+