*
* The request @a req has to be prepared by
* forb_iop_prepare_request(). Then, this function adds a message
- * header connects to the destination FORB and sends the request.
+ * header, connects to the destination FORB and sends the request.
*
- * If no exceptionis reported, ten caller must wait for response by
- * calling forb_wait_for_reply().
+ * If no exception is reported, then the caller must wait for response
+ * by calling forb_wait_for_reply().
*
- * @param req Request prepared by forb_iop_prepare_request()
+ * @param req A request prepared by forb_iop_prepare_request()
* @param env Environment for returning exceptions
*/
void
return;
}
ret = forb_iop_prepend_message_header(req->codec, forb_iop_REQUEST);
- if (!ret || !forb) {
+ if (!ret) {
/* This should never happen */
env->major = FORB_EX_INTERNAL;
return;
env->major = FORB_EX_COMM_FAILURE;
}
exception:
- //forb_put_connection(conn);
;
}
#include <forb/proto.h>
#include <forb/forb-idl.h>
+#include <forb/forb-internal.h>
#include <forb/iop.h>
#include <forb/config.h>
#include <stdio.h>
peers, /* cust_root_node */
node, /* cust_item_node */
server_id, /* cust_item_key */
- forb_server_id_cmp)/* cust_cmp_fnc */
+ forb_server_id_cmp);/* cust_cmp_fnc */
+
+static inline CORBA_boolean
+forb_exception_serialize(CDR_Codec *codec, struct forb_env *env)
+{
+ return CORBA_long_serialize(codec, &env->major);
+}
+
+static void
+send_reply(forb_t *forb,
+ forb_server_id *dest,
+ CDR_Codec *codec,
+ CORBA_long request_id,
+ struct forb_env *env)
+{
+ forb_iop_reply_header reply_header;
+ CORBA_boolean ret;
+ forb_peer_t *peer;
+
+ reply_header.request_id = request_id;
+ reply_header.flags = 0;
+ if (forb_exception_occured(env)) {
+ reply_header.flags |= forb_iop_FLAG_EXCEPTION;
+ forb_exception_serialize(codec, env);
+ }
+ ret = CDR_buffer_prepend(codec, forb_iop_REPLY_HEADER_SIZE);
+ if (!ret) {
+ goto err;
+ }
+ ret = forb_iop_reply_header_serialize(codec, &reply_header);
+ if (!ret) {
+ goto err;
+ }
+ forb_iop_prepend_message_header(codec, forb_iop_REPLY);
+
+ peer = forb_get_next_hop(forb, dest);
+ if (!peer) {
+ goto err;
+ }
+ forb_proto_send(peer, codec);
+err:
+ ;
+}
static void
process_request(forb_port_t *port, CDR_Codec *codec)
{
- forb_iop_request_header rh;
- forb_iop_request_header_deserialize(codec, &rh);
+ forb_iop_request_header request_header;
+ CDR_Codec reply_codec;
+ CORBA_boolean ret;
+ forb_object obj;
+ size_t n;
+ struct forb_env env;
+
+ CDR_codec_init_static(&reply_codec);
+ ret = CDR_buffer_init(&reply_codec, 4096,
+ forb_iop_MESSAGE_HEADER_SIZE +
+ forb_iop_REPLY_HEADER_SIZE);
+ if (!ret)
+ return;
+
+ ret = forb_iop_request_header_deserialize(codec, &request_header);
+ if (!ret) {
+ printf("ERR1\n");
+ env.major = FORB_EX_NO_MEMORY;
+ goto out;
+ }
+
+ obj = forb_key_to_object(request_header.objkey);
+ n = strlen(request_header.iface);
+ if (strncmp(request_header.iface, obj->interface->name, n) != 0) {
+ env.major = FORB_EX_INV_OBJREF;
+ printf("ERR2\n");
+ goto out;
+ }
+ if (request_header.method_index >= obj->interface->num_methods) {
+ env.major = FORB_EX_INV_OBJREF;
+ printf("ERR3\n");
+ goto out;
+ }
+ env.major = FORB_EX_NONE;
+ /* TODO: Introduce forb_request_processor and acompanying
+ * stuff to execute skeletons and implementation in a separate thread. */
+ obj->interface->skeletons[request_header.method_index](codec, &reply_codec, obj, &env);
+out:
+ send_reply(port->forb, &request_header.source, &reply_codec, request_header.request_id, &env);
+ CDR_codec_release_buffer(&reply_codec);
}
static void
static void
process_message(forb_port_t *port, forb_iop_message_header *mh, CDR_Codec *codec)
{
+ /* TODO: Check destination address, whether the message is for
+ * us or should be routed. */
switch (mh->message_type) {
case forb_iop_REQUEST:
process_request(port, codec);
}
+/**
+ * Finds next hop on the way to the particular server.
+ *
+ * Currently, as routing is not implemented, this function searches
+ * only peers.
+ *
+ * @param forb Forb to ask.
+ * @param server_id Destination server.
+ *
+ * @return Next hop peer of NULL, if the destination is not found.
+ */
forb_peer_t *
forb_get_next_hop(forb_t *forb, forb_server_id *server_id)
{