摘要
Google Protocol Buffer 是一個優秀的基於二進制的網絡消息編解碼框架。應用於項目時,可以節省不少的人力資源、開發時間和程序BUG。但其不足之處是protobuf編譯器生成的C++消息類(或者Java等其他語言的消息類)冗余數據過多,需要依賴於protobuf的編解碼庫,一般情況下都不能用於作為業務邏輯對象。因此大部分情況下,程序都需要另外獨立定義業務邏輯對象,並且使用protobuf定義相應(不一定100%相同)的消息,並手寫代碼,在protobuf消息對象和C++/Java業務對象之間進行轉換。
protobuf消息還有另外一個缺點,是數據類型不夠豐富,特別是指針,map集合不支持,你支持繼承。通過required、optional屬性的擴展可以讓其支持指針,通過多字段,也可以讓其支持map集合。
因在工程中,有太多的,太過於相似的轉換代碼,因此才有想法寫一個C++類與google protobuf消息直接進行轉換的工具。當然一次為藍本,還可以轉換為Java、C#等其他語言。當然轉換後的代碼不可能100%的可以直接工作,但是可以肯定的是已經完成了99%的工作,就剩下1%一點點的手動修改即可。
關於繼承的映射。基類消息作為子類消息的第一個字段,明白字段名稱為base;
數據類型映射規則
編號 C++數據類型 限制 protobuf數據類型 備注
1 bool required bool
2 (unsigned) char required uint32 or int32 protobuf 不支持char類型,建議使用int替代
3 (unsigned) short required uint32 or int32 protobuf 不支持short類型,建議使用int替代
4 (unsigned) int required sfixed32 or fixed32
5 (unsigned) long required sfixed32 or fixed32 建議使用 int替代
6 std::string required bytes bytes可以更好的支持中文,protobuf string只支持asscii
不要使用char * ,char[] 等,使用std::string 替代
7 類對象 required 子message 自定義類,而不是系統類對象,需要包含在同一個文件裡面,
再次沒有遞歸處理其他包含的頭文件。後續可能支持
類被映射為一個消息(只映射一次)
並再次映射為消息的成員(子消息)
8 指針類型,支持2種指針:
shared_ptr<T>
weak_ptr<T> optional 根據T的實際類型進行映射 T的類型為上面 編號1~7中的任意一種。
9 集合類型,包含一下幾種:
std::vector<T>
std::list<T>
std::set<T>
std::multiset<T> required
repeated bool include_${filename}字段
根據T的實際類型進行映射 包含一個bool類型的include字段,用於指示消息傳遞的過程中是
否包含本字段(protobuf repeated 字段存在二義性
,在消息不包含repeated字段時,究竟時刪除還是保留不變)
T的類型為上面 編號1~8中的任意一種。
10 map類型,包含2種:
std::map<KEY,VALUE>
std::multimap<KEY,VALUE> optional
repeated
repeated boo include_${filename}
reptead KEY ${filename}_key
reptead VALUE ${filename}_value KEY和VALUE各自映射為一個字段。在傳輸過程中,
通過下標一一匹配.
KEY,VALUE的類型為上面 編號1~8中的任意一種。
3. 自動化工具
工具使用Scala BNF語法進行構建,對C++頭文件進行詞法語法分析(主要分析類的聲明和枚舉的定義),並提取類的相關信息用於生成代碼。
4.工具測試結果。
4.1 測試內容[cpp] view plaincopyprint?
#ifndef __FOCUS_ENTITY_H__
#define __FOCUS_ENTITY_H__
#include <string>
#include <memory>
#include <set>
#include <odb/database.hxx>
#include <odb/tr1/memory.hxx>
#include <odb/callback.hxx>
#ifdef N_ODB
#include <Mutex.h>
#include <functional>
#include "Focus3800B.h"
#include "EntityBuild.h"
#endif
using std::tr1::shared_ptr;
using std::tr1::enable_shared_from_this;
using std::tr1::weak_ptr;
using std::tr1::dynamic_pointer_cast;
class CFocusEntity;
class CFocusZone;
class CFocusTerminal;
class CFocusUser;
inline shared_ptr<CFocusZone> toZone( const shared_ptr<CFocusEntity> & en)
{
return dynamic_pointer_cast<CFocusZone,CFocusEntity>(en);
}
inline shared_ptr<CFocusTerminal> toTerminal( const shared_ptr<CFocusEntity> & en)
{
return dynamic_pointer_cast<CFocusTerminal,CFocusEntity>(en);
}
inline shared_ptr<CFocusUser> toUser( const shared_ptr<CFocusEntity> & en)
{
return dynamic_pointer_cast<CFocusUser,CFocusEntity>(en);
}
enum MsgNumPCtoTer {
terminal_config = 1,
network_basic_config = 2,
timenow_config = 3,
video_source_config = 16,
video_output_config = 17,
video_option_config = 18,
network_advanced_config = 19,
compatibility_config = 20,
network_dial_config = 21,
fire_wall_config = 22,
communication_config = 23,
video_config = 24,
e1_config = 25,
web_config = 26,
command_config = 27,
camera_select = 256,
camera_advance = 257,
camera_advance_active = 258,
camera_up = 259,
camera_down = 260,
camera_left = 261,
camera_right = 262,
camera_near = 263,
camera_far = 264,
floor_apply = 512,
chair_apply = 513,
chair_release = 514,
chair_viewed = 515,
timer_preview = 516,
auto_switch_time = 517,
broacast_local = 518,
force_exit = 519,
volume_set = 520,
mute_in_set = 521,
mute_out_set = 522,
dualstream_set = 523,
conf_call_set = 524,
accept_in_call = 525,
reject_in_call = 526,
conf_drop = 527,
phone_modify = 528,
phone_add = 529,
feec_apply = 530,
phone_histroy_del = 531,
picture_show = 532,
near_key = 533,
far_key = 534,
OK_key = 535,
Ping = 768,
video_loop = 769,
restore = 770,
out_test = 771,
login_console = 1024,
logout_console = 1025,
restart = 1281
};
#pragma db object polymorphic callback(dbevent) table("tblEntity")
class CFocusEntity : public enable_shared_from_this<CFocusEntity>
{
friend class odb::access;
public:
CFocusEntity();
virtual ~CFocusEntity();
unsigned int GetId() const { return id_; }
void SetId(unsigned int val) { id_ = val; }
const std::string & GetName() const { return name_; }
void SetName(const std::string & val) { name_ = val; }
shared_ptr<CFocusZone> GetParent() const;
void SetParent(const shared_ptr<CFocusZone> & val) { parent_ = val; }
virtual void dbevent( odb::callback_event e, odb::database& db );
virtual void dbevent( odb::callback_event e, odb::database& db ) const;
bool persist();
bool update();
bool erase();
#ifdef N_ODB
virtual shared_ptr<CProtobufEntityBuild> CreateBuild() { return nullptr;}
#endif
void SendIndication();
protected:
void InternalSendIndcation();
private:
#pragma db id auto
unsigned int id_;
std::string name_;
weak_ptr<CFocusZone> parent_;
};
#pragma db object callback(dbevent) table("tblZone")
class CFocusZone : public CFocusEntity
{
friend class odb::access;
public:
CFocusZone();
~CFocusZone();
void AddEntity( const shared_ptr<CFocusEntity> & en);
void DelEntity( const shared_ptr<CFocusEntity> & en );
void dbevent( odb::callback_event e, odb::database& db );
void dbevent( odb::callback_event e, odb::database& db ) const;
shared_ptr<CFocusEntity> FindEntity( unsigned int id, bool recursive = false) ;
shared_ptr<CFocusEntity> FindEntity( const std::string & name, bool recursive = false) ;
#ifdef N_ODB
void foreach( const std::function<void( const shared_ptr<CFocusEntity> & ) > & callback , bool recursive = false, bool isCallItself = false);
virtual shared_ptr<CProtobufEntityBuild> CreateBuild();
#endif
static void SetRootZone( const shared_ptr<CFocusZone> & rootZone_);
static const shared_ptr<CFocusZone> & GetRootZone();
protected:
static shared_ptr<CFocusZone> rootZone;
private:
#pragma db inverse(parent_)
std::set< shared_ptr<CFocusEntity> > members_;
std::set< int > int_members_;
std::set< CFocusEntity > raw_members_;
std::map< int ,shared_ptr<CFocusEntity> > map_members_;
std::map< int ,int > map_int_members_;
std::map< int ,CFocusEntity > map_raw_members_;
#ifdef N_ODB
mutable dv::CMutex members_mutex;
#endif
};
#pragma db object callback(dbevent) table("tblTerminal")
class CFocusTerminal : public CFocusEntity
{
friend class odb::access;
public:
CFocusTerminal();
~CFocusTerminal();
const std::string & GetAddress() const { return address_; }
void SetAddress(const std::string & val) { address_ = val; }
unsigned short GetPort() const { return port_; }
void SetPort(unsigned short val) { port_ = val; }
const std::string & GetUsername() const { return username_; }
void SetUsername(const std::string & val) { username_ = val; }
const std::string & GetPassword() const { return password_; }
void SetPassword(const std::string & val) { password_ = val; }
void dbevent( odb::callback_event e, odb::database& db );
void dbevent( odb::callback_event e, odb::database& db ) const;
void keepalive_init();
void clear_status();
void send_keepalive();
void remote_login();
void release_connect();
bool IsOnline() const { return recv_service_ok_;}
#ifdef N_ODB
void OnRecvMessage( T_Message &recvMsg );
// bool IsDualEnable() const { return IsOnline () && dual_stream_status_ ;}
bool IsLogin() const { return remote_login_ok_; }
//bool IsAdmin() const { return remote_login_ok_ && adminstartor_ok_;}
virtual shared_ptr<CProtobufEntityBuild> CreateBuild();
void SetDualEnable( DualLevel level );
//bool IsInConfing() const { return conf_status_.ConfStatus > 0 ? true : false;}
void SetCommand( unsigned long ulCommand);
void DisConnect();
const T_InformTerConfig & GetTerConfig() const { return ter_config_;}
const T_InformSysStatus & GetSysStatus() const { return sys_status_;}
const T_InformConfStatus & GetConfStatus() const { return conf_status_;}
//const T_InformVideoConfig & GetVideoConfig() const { return video_config_; }
const T_VideoOption & GetVideoOption() const { return video_option_; }
const T_SetupSoftware & GetSoftwareVersion() const { return software_version_; }
void clear_resource();
bool CanSendMediaInfo() const { return is_recv_sys_status_;}
unsigned int GetValveRecvRate() const { return valveRecvRate_; }
void SetValveRecvRate(unsigned int val) { valveRecvRate_ = val; }
unsigned int GetValveSendRate() const { return valveSendRate_; }
void SetValveSendRate(unsigned int val) { valveSendRate_ = val; }
unsigned int GetValveRecvFrame() const { return valveRecvFrame_; }
void SetValveRecvFrame(unsigned int val) { valveRecvFrame_ = val; }
unsigned int GetValveSendFrame() const { return valveSendFrame_; }
void SetValveSendFrame(unsigned int val) { valveSendFrame_ = val; }
unsigned int GetValveLostRate() const { return valveLostRate_; }
void SetValveLostRate(unsigned int val) { valveLostRate_ = val; }
#endif
const std::string & GetH323id() const { return h323id_; }
// void SetH323id(std::string val) { h323id_ = val; }
const std::string & GetE164() const { return e164_; }
//void SetE164(std::string val) { e164_ = val; }
unsigned int GetNo() const { return No_; }
void SetNo(unsigned int val) { No_ = val; }
const std::string & GetContacter() const { return contacter_; }
void SetContacter(const std::string & val) { contacter_ = val; }
const std::string & GetPhone() const { return phone_; }
void SetPhone(const std::string & val) { phone_ = val; }
private:
std::string address_;
unsigned short port_;
std::string username_;
std::string password_;
unsigned int No_;
std::string contacter_;
std::string phone_;
unsigned int valveRecvRate_ ;
unsigned int valveSendRate_;
unsigned int valveRecvFrame_;
unsigned int valveSendFrame_;
unsigned int valveLostRate_;
#pragma db transient
unsigned int connect_id_;
#pragma db transient
unsigned int timer_id_;
#pragma db transient
bool recv_service_ok_;
#pragma db transient
bool remote_login_ok_;
#pragma db transient
bool adminstartor_ok_;
#pragma db transient
bool dual_stream_status_;
#pragma db transient
std::string h323id_;
#pragma db transient
std::string e164_;
#ifdef N_ODB
T_InformTerConfig ter_config_;
T_InformSysStatus sys_status_;
T_InformConfStatus conf_status_;
T_VideoOption video_option_;
T_Message lastRecvMsg_;
T_SetupSoftware software_version_;
bool is_recv_sys_status_;
#endif
};
#pragma db object callback(dbevent) table("tblUser")
class CFocusUser : public CFocusEntity
{
friend class odb::access;
public:
CFocusUser();
~CFocusUser();
const std::string & GetPassword() const { return password_; }
void SetPassword(const std::string & val) { password_ = val; }
void dbevent( odb::callback_event e, odb::database& db );
void dbevent( odb::callback_event e, odb::database& db ) const;
#ifdef N_ODB
virtual shared_ptr<CProtobufEntityBuild> CreateBuild();
#endif
protected:
private:
std::string password_;
};
#endif
#ifndef __FOCUS_ENTITY_H__
#define __FOCUS_ENTITY_H__
#include <string>
#include <memory>
#include <set>
#include <odb/database.hxx>
#include <odb/tr1/memory.hxx>
#include <odb/callback.hxx>
#ifdef N_ODB
#include <Mutex.h>
#include <functional>
#include "Focus3800B.h"
#include "EntityBuild.h"
#endif
using std::tr1::shared_ptr;
using std::tr1::enable_shared_from_this;
using std::tr1::weak_ptr;
using std::tr1::dynamic_pointer_cast;
class CFocusEntity;
class CFocusZone;
class CFocusTerminal;
class CFocusUser;
inline shared_ptr<CFocusZone> toZone( const shared_ptr<CFocusEntity> & en)
{
return dynamic_pointer_cast<CFocusZone,CFocusEntity>(en);
}
inline shared_ptr<CFocusTerminal> toTerminal( const shared_ptr<CFocusEntity> & en)
{
return dynamic_pointer_cast<CFocusTerminal,CFocusEntity>(en);
}
inline shared_ptr<CFocusUser> toUser( const shared_ptr<CFocusEntity> & en)
{
return dynamic_pointer_cast<CFocusUser,CFocusEntity>(en);
}
enum MsgNumPCtoTer {
terminal_config = 1,
network_basic_config = 2,
timenow_config = 3,
video_source_config = 16,
video_output_config = 17,
video_option_config = 18,
network_advanced_config = 19,
compatibility_config = 20,
network_dial_config = 21,
fire_wall_config = 22,
communication_config = 23,
video_config = 24,
e1_config = 25,
web_config = 26,
command_config = 27,
camera_select = 256,
camera_advance = 257,
camera_advance_active = 258,
camera_up = 259,
camera_down = 260,
camera_left = 261,
camera_right = 262,
camera_near = 263,
camera_far = 264,
floor_apply = 512,
chair_apply = 513,
chair_release = 514,
chair_viewed = 515,
timer_preview = 516,
auto_switch_time = 517,
broacast_local = 518,
force_exit = 519,
volume_set = 520,
mute_in_set = 521,
mute_out_set = 522,
dualstream_set = 523,
conf_call_set = 524,
accept_in_call = 525,
reject_in_call = 526,
conf_drop = 527,
phone_modify = 528,
phone_add = 529,
feec_apply = 530,
phone_histroy_del = 531,
picture_show = 532,
near_key = 533,
far_key = 534,
OK_key = 535,
Ping = 768,
video_loop = 769,
restore = 770,
out_test = 771,
login_console = 1024,
logout_console = 1025,
restart = 1281
};
#pragma db object polymorphic callback(dbevent) table("tblEntity")
class CFocusEntity : public enable_shared_from_this<CFocusEntity>
{
friend class odb::access;
public:
CFocusEntity();
virtual ~CFocusEntity();
unsigned int GetId() const { return id_; }
void SetId(unsigned int val) { id_ = val; }
const std::string & GetName() const { return name_; }
void SetName(const std::string & val) { name_ = val; }
shared_ptr<CFocusZone> GetParent() const;
void SetParent(const shared_ptr<CFocusZone> & val) { parent_ = val; }
virtual void dbevent( odb::callback_event e, odb::database& db );
virtual void dbevent( odb::callback_event e, odb::database& db ) const;
bool persist();
bool update();
bool erase();
#ifdef N_ODB
virtual shared_ptr<CProtobufEntityBuild> CreateBuild() { return nullptr;}
#endif
void SendIndication();
protected:
void InternalSendIndcation();
private:
#pragma db id auto
unsigned int id_;
std::string name_;
weak_ptr<CFocusZone> parent_;
};
#pragma db object callback(dbevent) table("tblZone")
class CFocusZone : public CFocusEntity
{
friend class odb::access;
public:
CFocusZone();
~CFocusZone();
void AddEntity( const shared_ptr<CFocusEntity> & en);
void DelEntity( const shared_ptr<CFocusEntity> & en );
void dbevent( odb::callback_event e, odb::database& db );
void dbevent( odb::callback_event e, odb::database& db ) const;
shared_ptr<CFocusEntity> FindEntity( unsigned int id, bool recursive = false) ;
shared_ptr<CFocusEntity> FindEntity( const std::string & name, bool recursive = false) ;
#ifdef N_ODB
void foreach( const std::function<void( const shared_ptr<CFocusEntity> & ) > & callback , bool recursive = false, bool isCallItself = false);
virtual shared_ptr<CProtobufEntityBuild> CreateBuild();
#endif
static void SetRootZone( const shared_ptr<CFocusZone> & rootZone_);
static const shared_ptr<CFocusZone> & GetRootZone();
protected:
static shared_ptr<CFocusZone> rootZone;
private:
#pragma db inverse(parent_)
std::set< shared_ptr<CFocusEntity> > members_;
std::set< int > int_members_;
std::set< CFocusEntity > raw_members_;
std::map< int ,shared_ptr<CFocusEntity> > map_members_;
std::map< int ,int > map_int_members_;
std::map< int ,CFocusEntity > map_raw_members_;
#ifdef N_ODB
mutable dv::CMutex members_mutex;
#endif
};
#pragma db object callback(dbevent) table("tblTerminal")
class CFocusTerminal : public CFocusEntity
{
friend class odb::access;
public:
CFocusTerminal();
~CFocusTerminal();
const std::string & GetAddress() const { return address_; }
void SetAddress(const std::string & val) { address_ = val; }
unsigned short GetPort() const { return port_; }
void SetPort(unsigned short val) { port_ = val; }
const std::string & GetUsername() const { return username_; }
void SetUsername(const std::string & val) { username_ = val; }
const std::string & GetPassword() const { return password_; }
void SetPassword(const std::string & val) { password_ = val; }
void dbevent( odb::callback_event e, odb::database& db );
void dbevent( odb::callback_event e, odb::database& db ) const;
void keepalive_init();
void clear_status();
void send_keepalive();
void remote_login();
void release_connect();
bool IsOnline() const { return recv_service_ok_;}
#ifdef N_ODB
void OnRecvMessage( T_Message &recvMsg );
// bool IsDualEnable() const { return IsOnline () && dual_stream_status_ ;}
bool IsLogin() const { return remote_login_ok_; }
//bool IsAdmin() const { return remote_login_ok_ && adminstartor_ok_;}
virtual shared_ptr<CProtobufEntityBuild> CreateBuild();
void SetDualEnable( DualLevel level );
//bool IsInConfing() const { return conf_status_.ConfStatus > 0 ? true : false;}
void SetCommand( unsigned long ulCommand);
void DisConnect();
const T_InformTerConfig & GetTerConfig() const { return ter_config_;}
const T_InformSysStatus & GetSysStatus() const { return sys_status_;}
const T_InformConfStatus & GetConfStatus() const { return conf_status_;}
//const T_InformVideoConfig & GetVideoConfig() const { return video_config_; }
const T_VideoOption & GetVideoOption() const { return video_option_; }
const T_SetupSoftware & GetSoftwareVersion() const { return software_version_; }
void clear_resource();
bool CanSendMediaInfo() const { return is_recv_sys_status_;}
unsigned int GetValveRecvRate() const { return valveRecvRate_; }
void SetValveRecvRate(unsigned int val) { valveRecvRate_ = val; }
unsigned int GetValveSendRate() const { return valveSendRate_; }
void SetValveSendRate(unsigned int val) { valveSendRate_ = val; }
unsigned int GetValveRecvFrame() const { return valveRecvFrame_; }
void SetValveRecvFrame(unsigned int val) { valveRecvFrame_ = val; }
unsigned int GetValveSendFrame() const { return valveSendFrame_; }
void SetValveSendFrame(unsigned int val) { valveSendFrame_ = val; }
unsigned int GetValveLostRate() const { return valveLostRate_; }
void SetValveLostRate(unsigned int val) { valveLostRate_ = val; }
#endif
const std::string & GetH323id() const { return h323id_; }
// void SetH323id(std::string val) { h323id_ = val; }
const std::string & GetE164() const { return e164_; }
//void SetE164(std::string val) { e164_ = val; }
unsigned int GetNo() const { return No_; }
void SetNo(unsigned int val) { No_ = val; }
const std::string & GetContacter() const { return contacter_; }
void SetContacter(const std::string & val) { contacter_ = val; }
const std::string & GetPhone() const { return phone_; }
void SetPhone(const std::string & val) { phone_ = val; }
private:
std::string address_;
unsigned short port_;
std::string username_;
std::string password_;
unsigned int No_;
std::string contacter_;
std::string phone_;
unsigned int valveRecvRate_ ;
unsigned int valveSendRate_;
unsigned int valveRecvFrame_;
unsigned int valveSendFrame_;
unsigned int valveLostRate_;
#pragma db transient
unsigned int connect_id_;
#pragma db transient
unsigned int timer_id_;
#pragma db transient
bool recv_service_ok_;
#pragma db transient
bool remote_login_ok_;
#pragma db transient
bool adminstartor_ok_;
#pragma db transient
bool dual_stream_status_;
#pragma db transient
std::string h323id_;
#pragma db transient
std::string e164_;
#ifdef N_ODB
T_InformTerConfig ter_config_;
T_InformSysStatus sys_status_;
T_InformConfStatus conf_status_;
T_VideoOption video_option_;
T_Message lastRecvMsg_;
T_SetupSoftware software_version_;
bool is_recv_sys_status_;
#endif
};
#pragma db object callback(dbevent) table("tblUser")
class CFocusUser : public CFocusEntity
{
friend class odb::access;
public:
CFocusUser();
~CFocusUser();
const std::string & GetPassword() const { return password_; }
void SetPassword(const std::string & val) { password_ = val; }
void dbevent( odb::callback_event e, odb::database& db );
void dbevent( odb::callback_event e, odb::database& db ) const;
#ifdef N_ODB
virtual shared_ptr<CProtobufEntityBuild> CreateBuild();
#endif
protected:
private:
std::string password_;
};
#endif
4.2輸出結果
[plain] view plaincopyprint?
package pbmsg;
enum MsgNumPCtoTer
{
terminal_config = 1;
network_basic_config = 2;
timenow_config = 3;
video_source_config = 16;
video_output_config = 17;
video_option_config = 18;
network_advanced_config = 19;
compatibility_config = 20;
network_dial_config = 21;
fire_wall_config = 22;
communication_config = 23;
video_config = 24;
e1_config = 25;
web_config = 26;
command_config = 27;
camera_select = 256;
camera_advance = 257;
camera_advance_active = 258;
camera_up = 259;
camera_down = 260;
camera_left = 261;
camera_right = 262;
camera_near = 263;
camera_far = 264;
floor_apply = 512;
chair_apply = 513;
chair_release = 514;
chair_viewed = 515;
timer_preview = 516;
auto_switch_time = 517;
broacast_local = 518;
force_exit = 519;
volume_set = 520;
mute_in_set = 521;
mute_out_set = 522;
dualstream_set = 523;
conf_call_set = 524;
accept_in_call = 525;
reject_in_call = 526;
conf_drop = 527;
phone_modify = 528;
phone_add = 529;
feec_apply = 530;
phone_histroy_del = 531;
picture_show = 532;
near_key = 533;
far_key = 534;
OK_key = 535;
Ping = 768;
video_loop = 769;
restore = 770;
out_test = 771;
login_console = 1024;
logout_console = 1025;
restart = 1281;
};
message CFocusEntity
{
optional fixed32 id = 1;
required bytes name = 2;
optional CFocusEntity parent = 3;
};
message CFocusZone
{
required CFocusEntity base = 1;
optional bool include_members = 2;
repeated CFocusEntity members =3;
optional bool include_int_members = 4;
repeated sfixed32 int_members =5;
optional bool include_raw_members = 6;
repeated CFocusEntity raw_members =7;
optional bool include_map_members = 8;
repeated sfixed32 map_members_key =9;
repeated CFocusEntity map_members_value =10;
optional bool include_map_int_members = 11;
repeated sfixed32 map_int_members_key =12;
repeated sfixed32 map_int_members_value =13;
optional bool include_map_raw_members = 14;
repeated sfixed32 map_raw_members_key =15;
repeated CFocusEntity map_raw_members_value =16;
};
message CFocusTerminal
{
required CFocusEntity base = 1;
required bytes address = 2;
optional uint32 port = 3;
required bytes username = 4;
required bytes password = 5;
optional fixed32 No = 6;
required bytes contacter = 7;
required bytes phone = 8;
optional fixed32 valveRecvRate = 9;
optional fixed32 valveSendRate = 10;
optional fixed32 valveRecvFrame = 11;
optional fixed32 valveSendFrame = 12;
optional fixed32 valveLostRate = 13;
optional fixed32 connect_id = 14;
optional fixed32 timer_id = 15;
optional bool recv_service_ok = 16;
optional bool remote_login_ok = 17;
optional bool adminstartor_ok = 18;
optional bool dual_stream_status = 19;
required bytes h323id = 20;
required bytes e164 = 21;
};
message CFocusUser
{
required CFocusEntity base = 1;
required bytes password = 2;
};