summaryrefslogtreecommitdiff
path: root/proto_lib/packet.cpp
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/packet.cpp
parent224d96964ea3c9e541fcd5caa2778af25f71ba2e (diff)
some work with proto library done
Diffstat (limited to 'proto_lib/packet.cpp')
-rw-r--r--proto_lib/packet.cpp205
1 files changed, 205 insertions, 0 deletions
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;
+}