diff options
author | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2013-02-12 13:47:03 +0200 |
---|---|---|
committer | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2013-02-12 13:47:03 +0200 |
commit | b568c0cab255aefd400d48c05e2cabc6ca96c270 (patch) | |
tree | 471e2794310b6bb6a53d013327122f43d5518685 /proto_lib/packet.cpp | |
parent | 224d96964ea3c9e541fcd5caa2778af25f71ba2e (diff) |
some work with proto library done
Diffstat (limited to 'proto_lib/packet.cpp')
-rw-r--r-- | proto_lib/packet.cpp | 205 |
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; +} |