summaryrefslogtreecommitdiff
path: root/proto_lib
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2013-02-12 13:47:03 +0200
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2013-02-12 13:47:03 +0200
commitb568c0cab255aefd400d48c05e2cabc6ca96c270 (patch)
tree471e2794310b6bb6a53d013327122f43d5518685 /proto_lib
parent224d96964ea3c9e541fcd5caa2778af25f71ba2e (diff)
some work with proto library done
Diffstat (limited to 'proto_lib')
-rw-r--r--proto_lib/api_protocol.h32
-rw-r--r--proto_lib/lib.project5
-rw-r--r--proto_lib/packet.cpp205
-rw-r--r--proto_lib/packet.h2
-rw-r--r--proto_lib/protocol.cpp64
5 files changed, 229 insertions, 79 deletions
diff --git a/proto_lib/api_protocol.h b/proto_lib/api_protocol.h
index 39681e4..452d6dc 100644
--- a/proto_lib/api_protocol.h
+++ b/proto_lib/api_protocol.h
@@ -29,11 +29,11 @@ struct service_s
};
enum packet_type {AUTH_REPLY, AUTH_REQUEST, SERVICES_REPLY, SERVICES_REQUEST, COMMAND_REPLY, COMMAND_REQUEST, UNKNOWN};
+enum status {failure = 0x00, success = 0x01};
class packet
{
public:
- packet();
packet(std::vector<unsigned char>&);
const std::vector<unsigned char> &raw();
packet_type get_type();
@@ -42,21 +42,31 @@ public:
bool is_client_packet();
bool assign(packet&);
bool assign(std::vector<unsigned char>&);
+
+ //helper functions:
+ //client functions
+ static packet *cli_make_auth_packet(); //should be first packet to server
+ static packet *cli_make_command_packet(std::string &service, std::string &command);
+ static packet *cli_make_request_services_packet();
+
+ static std::list<service_s> *cli_extract_services(packet&);
+ static std::string cli_parse_command_reply(packet&);
+
+ //server functions
+ static bool serv_validate_client_proto(packet&);
+ static packet *serv_make_services_packet(std::list<service_s>&);
+
+ //generic
+ static packet *make_status_packet(const unsigned char* type, status s);
+ static bool check_status_packet(const unsigned char *type, packet&); //false on fail
+
+
private:
+ packet();
std::vector<unsigned char> data;
};
-//server functions
-bool serv_validate_client_proto(packet&);
-
-//client functions
-packet *cli_make_auth_packet(); //should be first packet to server
-packet *cli_make_command_packet(std::string &service, std::string &command);
-packet *cli_request_services();
-std::list<service_s> cli_extract_services(packet&);
-bool cli_check_auth_reply(packet&); //false on fail
-std::string cli_parse_command_reply(packet&);
#endif
diff --git a/proto_lib/lib.project b/proto_lib/lib.project
index d8e56a4..a8ab117 100644
--- a/proto_lib/lib.project
+++ b/proto_lib/lib.project
@@ -8,7 +8,6 @@
<Description/>
<Dependencies/>
<VirtualDirectory Name="src">
- <File Name="protocol.cpp"/>
<File Name="api_protocol.h"/>
<File Name="packet.cpp"/>
<File Name="packet.h"/>
@@ -59,8 +58,7 @@
<ClangCmpFlagsC/>
<ClangCmpFlags/>
<ClangPP/>
- <SearchPaths>/usr/include
-/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.3/include</SearchPaths>
+ <SearchPaths/>
</Completion>
</Configuration>
<Configuration Name="Release" CompilerType="gnu g++" DebuggerType="GNU gdb debugger" Type="" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
@@ -72,6 +70,7 @@
<General OutputFile="$(IntermediateDirectory)/$(ProjectName)" IntermediateDirectory="./Release" Command="./$(ProjectName)" CommandArguments="" UseSeparateDebugArgs="no" DebugArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
<Environment EnvVarSetName="&lt;Use Defaults&gt;" DbgSetName="&lt;Use Defaults&gt;">
<![CDATA[
+
]]>
</Environment>
<Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
diff --git a/proto_lib/packet.cpp b/proto_lib/packet.cpp
index 3e0d676..c52c24d 100644
--- a/proto_lib/packet.cpp
+++ b/proto_lib/packet.cpp
@@ -17,6 +17,7 @@
#include <list>
#include <vector>
#include <algorithm>
+#include <string.h>
#include "api_protocol.h"
#include "packet.h"
@@ -96,3 +97,207 @@ packet_type packet::get_type()
return cli?COMMAND_REQUEST:COMMAND_REPLY;
return UNKNOWN;
}
+
+void pack_cli_header(std::vector<unsigned char> &v)
+{
+ int size = sizeof(proto_header);
+ for(int i = 0; i < size; i++)
+ v.push_back(proto_header[i]);
+ size = sizeof(cli_packet);
+ for(int i = 0; i < size; i++)
+ v.push_back(cli_packet[i]);
+}
+
+void pack_serv_header(std::vector<unsigned char> &v)
+{
+ int size = sizeof(proto_header);
+ for(int i = 0; i < size; i++)
+ v.push_back(proto_header[i]);
+ size = sizeof(serv_packet);
+ for(int i = 0; i < size; i++)
+ v.push_back(serv_packet[i]);
+}
+
+
+void pack_buffer(const unsigned char *buf, size_t len, std::vector<unsigned char> &v)
+{
+ for(size_t i = 0; i < len; i++)
+ v.push_back(buf[i]);
+}
+
+void pack_buffer(std::vector<unsigned char> &source, std::vector<unsigned char> &dest)
+{
+ dest.insert(dest.end(), source.begin(), source.end());
+}
+
+void pack_buffer(std::string &str, std::vector<unsigned char> &v)
+{
+ for(size_t i = 0; i < str.length(); i++)
+ v.push_back(str[i]);
+}
+
+void pack_buffer(const char* str, std::vector<unsigned char> &v)
+{
+ size_t len = strlen(str);
+ for(size_t i = 0; i < len; i++)
+ v.push_back(str[i]);
+}
+
+packet *packet::cli_make_auth_packet()
+{
+ std::vector<unsigned char> v;
+ pack_cli_header(v);
+ pack_buffer(type_auth, sizeof(type_auth), v);
+ v.push_back(proto_version);
+ pack_buffer(proto_footer, sizeof(proto_footer), v);
+ return new packet(v);
+}
+
+packet *packet::cli_make_command_packet(std::string &service, std::string &command)
+{
+ std::vector<unsigned char> v;
+ pack_cli_header(v);
+ pack_buffer(type_command, sizeof(type_command), v);
+ pack_buffer(service, v);
+ v.push_back(delimiter);
+ pack_buffer(command, v);
+ pack_buffer(proto_footer, sizeof(proto_footer), v);
+ return new packet(v);
+}
+
+packet *packet::cli_make_request_services_packet()
+{
+ std::vector<unsigned char> v;
+ pack_cli_header(v);
+ pack_buffer(type_services, sizeof(type_services), v);
+ pack_buffer(proto_footer, sizeof(proto_footer), v);
+ return new packet(v);
+}
+
+std::list<service_s> *packet::cli_extract_services(packet& p)
+{
+ std::list<service_s> *list = new std::list<service_s>;
+ std::vector<unsigned char>::const_iterator i = std::search(p.raw().begin(), p.raw().end(), type_services, type_services + sizeof(type_services));
+ if(i != p.raw().end())
+ {
+ i+= sizeof(type_services);
+ std::vector<unsigned char>::const_iterator i2 = std::find(i, p.raw().end(), delimiter), i3 = std::find(i, p.raw().end(), block_end);
+ while(i2 != p.raw().end() || i3 != p.raw().end())
+ {
+ std::string service;
+ std::list<service_s::cmd> cmds;
+ if(i3 != p.raw().end() && i2 != p.raw().end())
+ {
+ if(i2 < i3) //found service with commands
+ {
+ for(; i < i2; ++i)
+ service.push_back((char)*i);
+ i2++;
+ i2 = std::find(i2, i3, delimiter);
+ bool bdesc = false;
+ while(i2 < i3)
+ {
+ std::string cmd, desc;
+ if(!bdesc)
+ {
+ for(; i < i2; ++i)
+ cmd.push_back((char)*i);
+ bdesc = true;
+ }
+ else
+ {
+ for(; i < i2; ++i)
+ desc.push_back((char)*i);
+ bdesc = false;
+ service_s::cmd c;
+ c.command = cmd;
+ c.description = desc;
+ cmds.push_back(c);
+ }
+ i2++;
+ i2 = std::find(i2, i3, delimiter);
+ }
+ }
+ else //found service without commands
+ {
+ for(; i < i3; ++i)
+ service.push_back((char)*i);
+ }
+ i = i3;
+ i2 = std::find(i, p.raw().end(), delimiter);
+ i3 = std::find(i, p.raw().end(), block_end);
+ }
+ service_s s;
+ s.cmds = cmds;
+ s.service = service;
+ list->push_back(s);
+ }
+ }
+ return list;
+}
+
+bool packet::serv_validate_client_proto(packet &p)
+{
+ const std::vector<unsigned char> &data = p.raw();
+ if(data.empty())
+ return false;
+ if(std::search(data.begin(), data.end(), proto_header, proto_header + sizeof(proto_header)) == data.end())
+ return false;
+ if(std::search(data.begin(), data.end(), proto_footer, proto_footer + sizeof(proto_footer)) == data.end())
+ return false;
+ std::vector<unsigned char>::const_iterator i = std::search(data.begin(), data.end(), cli_packet, cli_packet + sizeof(cli_packet));
+ if(i == data.end())
+ return false;
+ i += sizeof(cli_packet);
+ if(*i < proto_version)
+ return false;
+ return true;
+}
+
+packet *packet::serv_make_services_packet(std::list<service_s> &slist)
+{
+ std::vector<unsigned char> v;
+ if(slist.empty())
+ return new packet(v);
+ pack_serv_header(v);
+ pack_buffer(type_services, sizeof(type_services), v);
+ for(std::list<service_s>::iterator i = slist.begin(), end = slist.end(); i != end; ++i)
+ {
+ pack_buffer(i->service, v);
+ if(!i->cmds.empty())
+ {
+ for(std::list<service_s::cmd>::iterator ii = i->cmds.begin(), eend = i->cmds.end(); ii != eend; ++ii)
+ {
+ v.push_back(delimiter);
+ pack_buffer(ii->command, v);
+ v.push_back(delimiter);
+ pack_buffer(ii->description, v);
+ }
+ }
+ v.push_back(block_end);
+ }
+ pack_buffer(proto_footer, sizeof(proto_footer), v);
+ return new packet(v);
+}
+
+packet *packet::make_status_packet(const unsigned char* type, status s)
+{
+ std::vector<unsigned char> v;
+ pack_serv_header(v);
+ pack_buffer(type, sizeof(type), v);
+ v.push_back(s);
+ pack_buffer(proto_footer, sizeof(proto_footer), v);
+ return new packet(v);
+}
+
+bool packet::check_status_packet(const unsigned char *type, packet& p)
+{
+ std::vector<unsigned char>::const_iterator i = std::search(p.raw().begin(), p.raw().end(), type, type + sizeof(type));
+ if(i != p.raw().end())
+ {
+ i += sizeof(type);
+ if(*i == success)
+ return true;
+ }
+ return false;
+}
diff --git a/proto_lib/packet.h b/proto_lib/packet.h
index 6ef9094..aedb63f 100644
--- a/proto_lib/packet.h
+++ b/proto_lib/packet.h
@@ -26,7 +26,7 @@ const unsigned char serv_packet [] = {0xF0, 0X00};
const unsigned char proto_version = 0x03;
const unsigned char delimiter = 0x01;
-
+const unsigned char block_end = 0x02;
diff --git a/proto_lib/protocol.cpp b/proto_lib/protocol.cpp
deleted file mode 100644
index 991f4e4..0000000
--- a/proto_lib/protocol.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright © 2013 sss
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#include <string>
-#include <list>
-#include <vector>
-#include <algorithm>
-#include "api_protocol.h"
-#include "packet.h"
-
-
-
-bool serv_validate_client_proto(packet &p)
-{
- const std::vector<unsigned char> &data = p.raw();
- if(data.empty())
- return false;
- if(std::search(data.begin(), data.end(), proto_header, proto_header + sizeof(proto_header)) == data.end())
- return false;
- if(std::search(data.begin(), data.end(), proto_footer, proto_footer + sizeof(proto_footer)) == data.end())
- return false;
- std::vector<unsigned char>::const_iterator i = std::search(data.begin(), data.end(), cli_packet, cli_packet + sizeof(cli_packet));
- if(i == data.end())
- return false;
- i += sizeof(cli_packet);
- if(*i < proto_version)
- return false;
- return true;
-}
-
-packet *cli_make_auth_packet()
-{
- std::vector<unsigned char> v;
- int size = sizeof(proto_header);
- for(int i = 0; i < size; i++)
- v.push_back(proto_header[i]);
- size = sizeof(cli_packet);
- for(int i = 0; i < size; i++)
- v.push_back(cli_packet[i]);
- size = sizeof(type_auth);
- for(int i = 0; i < size; i++)
- v.push_back(type_auth[i]);
- v.push_back(proto_version);
- size = sizeof(proto_footer);
- for(int i = 0; i < size; i++)
- v.push_back(proto_footer[i]);
- packet *p = new packet;
- p->assign(v);
- return p;
-}
-