From 3b4c855a59964220626bcad871dce701156e1ee1 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Mon, 11 Aug 2014 19:31:40 +0100 Subject: [PATCH] add protocol handler --- include/Makefile.am | 1 + include/tr/proto_message.h | 1 + include/tr/protocol_handler.h | 44 +++++++++++ include/trcomm.h | 1 + src/Makefile.am | 1 + src/comm_manager.c | 4 +- src/protocol_handler.c | 138 ++++++++++++++++++++++++++++++++++ 7 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 include/tr/protocol_handler.h create mode 100644 src/protocol_handler.c diff --git a/include/Makefile.am b/include/Makefile.am index da5c874..b8b6bc9 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -6,6 +6,7 @@ nobase_include_HEADERS = tr/comm_end_point.h \ tr/connector.h \ tr/proto_message.h \ tr/protocol.h \ + tr/protocol_handler.h \ tr/interface/comm_end_point.h \ tr/interface/comm_manager.h \ tr/interface/protocol.h diff --git a/include/tr/proto_message.h b/include/tr/proto_message.h index 84021a7..ca975c0 100644 --- a/include/tr/proto_message.h +++ b/include/tr/proto_message.h @@ -31,6 +31,7 @@ TR_CLASS(TR_ProtoMessage) { TR_Socket remote; int ready; + int close; }; TR_INSTANCE_INIT(TR_ProtoMessage); TR_CLASSVARS_DECL(TR_ProtoMessage) {}; diff --git a/include/tr/protocol_handler.h b/include/tr/protocol_handler.h new file mode 100644 index 0000000..1b23aba --- /dev/null +++ b/include/tr/protocol_handler.h @@ -0,0 +1,44 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2014 Georg Hopp + * + * 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 3 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, see . + */ + +#ifndef __TR_PROTOCOL_HANDLER_H__ +#define __TR_PROTOCOL_HANDLER_H__ + +#include + +#include "trbase.h" +#include "trevent.h" + +#include "tr/comm_end_point.h" + +TR_CLASS(TR_ProtocolHandler) { + TR_EXTENDS(TR_EventHandler); +}; +TR_INSTANCE_INIT(TR_ProtocolHandler); +TR_CLASSVARS_DECL(TR_ProtocolHandler) { + TR_CV_EXTENDS(TR_EventHandler); +}; + +#endif // __TR_PROTOCOL_HANDLER_H__ + +// vim: set ts=4 sw=4: + diff --git a/include/trcomm.h b/include/trcomm.h index fd8b44d..951a576 100644 --- a/include/trcomm.h +++ b/include/trcomm.h @@ -9,6 +9,7 @@ #include "tr/connector.h" #include "tr/proto_message.h" #include "tr/protocol.h" +#include "tr/protocol_handler.h" #include "tr/interface/comm_end_point.h" #include "tr/interface/comm_manager.h" #include "tr/interface/protocol.h" diff --git a/src/Makefile.am b/src/Makefile.am index 0d991be..f188b10 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,6 +17,7 @@ TRCOMM = cep_append_read_data.c \ connector.c \ proto_message.c \ protocol.c \ + protocol_handler.c \ protocol_message_raw.c \ protocol_raw.c \ i_comm_end_point.c \ diff --git a/src/comm_manager.c b/src/comm_manager.c index a9b903b..189f831 100644 --- a/src/comm_manager.c +++ b/src/comm_manager.c @@ -37,6 +37,8 @@ commManagerCtor(void * _this, va_list * params) { TR_CommManager this = _this; + TR_PARENTCALL(_this, TR_Class, ctor, params); + this->n_endpoints = sysconf(_SC_OPEN_MAX); this->endpoints = TR_calloc(sizeof(TR_CommEndPoint), this->n_endpoints); @@ -53,8 +55,6 @@ commManagerDtor(void * _this) for (i = 0; i < this->n_endpoints; i++) { TR_delete(this->endpoints[i]); } - - TR_PARENTCALL(_this, TR_Class, dtor); } static diff --git a/src/protocol_handler.c b/src/protocol_handler.c new file mode 100644 index 0000000..c1207a0 --- /dev/null +++ b/src/protocol_handler.c @@ -0,0 +1,138 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2014 Georg Hopp + * + * 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 3 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, see . + */ + +#include + +#include "trbase.h" +#include "trevent.h" + +#include "tr/protocol.h" +#include "tr/connection.h" +#include "tr/protocol_handler.h" +#include "tr/proto_message.h" +#include "tr/comm_end_point.h" +#include "tr/interface/comm_end_point.h" + +static +int +protocolHandlerCtor(void * _this, va_list * params) +{ + TR_PARENTCALL(_this, TR_Class, ctor, params); + + return 0; +} + +static void protocolHandlerDtor(void * _this) {} + +static +int +protocolHandlerParse(void * _this, TR_Event event) +{ + /** + * TODO No upgrade for now. Add it later on. + */ + TR_CommEndPoint endpoint = (TR_CommEndPoint)event->subject; + TR_ProtoMessage message = TR_cepNextMessage(endpoint); + + while (message) { + TR_eventHandlerIssueEvent( + (TR_EventHandler)_this, + event->subject, + TR_CEP_EVENT_NEW_MSG, + message); + + if (message->close) { + // also check that we are a response. Well this is how it is done + // in the python code... + TR_cepSetClose(endpoint); + } + + message = TR_cepNextMessage(endpoint); + } + + return TRUE; +} + +static +int +protocolHandlerCompose(void * _this, TR_Event event) +{ + TR_CommEndPoint endpoint = (TR_CommEndPoint)event->subject; + TR_ProtoMessage message = (TR_ProtoMessage)event->data; + + if (TR_cepCompose(endpoint, message)) { + TR_eventHandlerIssueEvent( + (TR_EventHandler)_this, + event->subject, + TR_CEP_EVENT_WRITE_READY, + NULL); + } + + if (message->close) { + // also check that we are a response. Well this is how it is done + // in the python code... + TR_cepSetClose(endpoint); + } + + return TRUE; +} + +int +protocolHandlerUpgrade(void * _this, TR_Event event) +{ + return TRUE; +} + +static +void +protocolHandlerCvInit(TR_class_ptr cls) +{ + TR_EVENT_HANDLER_SET_METHOD( + cls, + TR_Connection, + TR_CEP_EVENT_NEW_DATA, + protocolHandlerParse); + + TR_EVENT_HANDLER_SET_METHOD( + cls, + TR_Connection, + TR_CEP_EVENT_SEND_MSG, + protocolHandlerCompose); + + TR_EVENT_HANDLER_SET_METHOD( + cls, + TR_Connection, + TR_CEP_EVENT_UPGRADE, + protocolHandlerUpgrade); +} + +TR_INSTANCE(TR_Hash, protocolHandlerEventMethods); +TR_INIT_IFACE(TR_Class, protocolHandlerCtor, protocolHandlerDtor, NULL); +TR_CREATE_CLASS( + TR_ProtocolHandler, + TR_EventHandler, + protocolHandlerCvInit, + TR_IF(TR_Class)) = { + { &(_protocolHandlerEventMethods.data) } +}; + +// vim: set ts=4 sw=4: