diff options
Diffstat (limited to 'bin')
-rw-r--r-- | bin/CMakeLists.txt | 4 | ||||
-rw-r--r-- | bin/kiro-camera-server.c | 203 |
2 files changed, 136 insertions, 71 deletions
diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt index acdc243..29e077c 100644 --- a/bin/CMakeLists.txt +++ b/bin/CMakeLists.txt @@ -4,7 +4,7 @@ link_directories(${KIROCS_BINARY_DIR}) add_executable(kiro-camera-server kiro-camera-server.c) target_link_libraries(kiro-camera-server ${KIROCS_DEPS}) -add_executable(test-camera-server test-server.c) -target_link_libraries(test-camera-server ${KIROCS_DEPS}) +#add_executable(test-camera-server test-server.c) +#target_link_libraries(test-camera-server ${KIROCS_DEPS}) install(TARGETS kiro-camera-server RUNTIME DESTINATION ${KIROCS_BINDIR}) diff --git a/bin/kiro-camera-server.c b/bin/kiro-camera-server.c index 80683ac..839c637 100644 --- a/bin/kiro-camera-server.c +++ b/bin/kiro-camera-server.c @@ -19,6 +19,7 @@ #include <stdlib.h> #include <string.h> +#include <unistd.h> #include "uca-kiro-camera.h" #include "uca/uca-plugin-manager.h" @@ -30,6 +31,8 @@ typedef struct { gulong peer_rank; gulong *signal_handlers; GParamSpec **properties; + guint n_properties; + KiroRequest *peer_update_request; } KiroCsData; @@ -70,7 +73,7 @@ pspec_size (GType type) ret = sizeof (GParamSpecDouble); break; default: - ret = sizeof (GParamSpec); + ret = sizeof (GParamSpec); } return ret; @@ -133,35 +136,50 @@ print_cam_name (gchar *name, gpointer unused) static void +send_clear_callback (KiroRequest *request, gpointer data) +{ + (void) data; + if (request->status != KIRO_MESSAGE_SEND_SUCCESS) + g_error ("OH SHIT!"); + else + g_debug ("Peer informed successfully"); + + if (request->message->payload) + g_free (request->message->payload); + g_free (request->message); + g_free (request); +} + + +static void peer_inform_update (UcaCamera *cam, GParamSpec *pspec, KiroCsData *data) { - g_print ("Updated %s.\n", pspec->name); + g_print ("Updated %s.\n", pspec->name); - GError *error = NULL; + gpointer buff = g_malloc0 (sizeof (guint64)); + g_object_get (G_OBJECT (cam), + pspec->name, buff, + NULL); - GVariant *tmp = read_property_scalar (G_OBJECT (cam), pspec->name, pspec->value_type); - gsize data_size = g_variant_get_size (tmp); + KiroMessage *message = g_malloc0 (sizeof (KiroMessage)); + message->msg = KIROCS_UPDATE; + message->size = sizeof (PropUpdateScalar); + message->payload = g_malloc0 (message->size); - PropUpdate *test = g_malloc0 (sizeof (PropUpdate) + data_size); - test->id = property_id_from_name (pspec->name); - test->type[0] = gtype_to_gvariant_class (pspec->value_type); - test->size = data_size; - g_variant_store (tmp, test->val); - g_variant_unref (tmp); + PropUpdateScalar *update = message->payload; + update->base.id = property_id_from_name (pspec->name, data->n_properties, data->properties); + update->base.size = 1; + update->base.scalar = TRUE; - KiroMessage message; - message.peer_rank = data->peer_rank; - message.msg = KIROCS_UPDATE; - message.payload = test; - message.size = sizeof (PropUpdate) + data_size; + memcpy (&update->prop_raw, buff, sizeof (guint64)); - kiro_messenger_send_blocking (data->messenger, &message, &error); + GError *error = NULL; + kiro_messenger_send_blocking (data->messenger, message, data->peer_rank, &error); if (error) { - g_free (test); + g_free (message); g_error ("Oh shit! (%s)", error->message); + g_error_free (error); } - - g_free (test); } @@ -176,26 +194,6 @@ setup_signal_handler (UcaCamera *cam, GParamSpec *pspec, KiroCsData *data) } -static void -null_callback (gpointer unused) -{ - (void)unused; -} - - -static inline gpointer -unpack_scalar (PropUpdate *src) -{ - //Alloc max scalar size - gpointer out = g_malloc0 (sizeof (guint64)); - - GVariant *var = g_variant_new_from_data ((const GVariantType *)src->type, src->val, \ - src->size, TRUE, null_callback, NULL); - g_variant_get (var, src->type, out); - g_variant_unref (var); - return out; -} - static KiroContinueFlag connect_callback (gulong rank, gulong *storage) { @@ -205,36 +203,70 @@ connect_callback (gulong rank, gulong *storage) // MAIN HANDLER // -static KiroContinueFlag -receive_callback (KiroMessageStatus *status, KiroCsData *data) +static void +receive_callback (KiroRequest *request, KiroCsData *data) { - if (status->message->msg == KIROCS_EXIT) { + if (request->message->msg == KIROCS_EXIT) { g_message ("Peer requested shut down..."); data->exit_flag = TRUE; } - if (status->message->msg == KIROCS_UPDATE) { - PropUpdate *update = (PropUpdate *)status->message->payload; - - g_debug ("Unpacking ID %u\n", update->id); - gpointer unpacked = unpack_scalar (update); + if (request->message->msg == KIROCS_UPDATE) { + PropUpdate *update = (PropUpdate *)request->message->payload; + g_signal_handler_block (data->cam, data->signal_handlers[update->id]); //Don't forget the -1, because the index starts at 0, but property IDs //start at 1... - update_property_scalar (G_OBJECT (data->cam), - data->properties[update->id -1]->name, - data->properties[update->id -1]->value_type, - data->signal_handlers[update->id], - unpacked); + const gchar *name = data->properties[update->id -1]->name; + g_debug ("Unpacking '%s' with ID %u\n", name, update->id); + + if (update->scalar == TRUE) { + PropUpdateScalar *scalar_update = (PropUpdateScalar *)update; + GValue tmp = G_VALUE_INIT; + g_value_init (&tmp, data->properties[update->id -1]->value_type); + g_value_set_from_raw_data (&tmp, &scalar_update->prop_raw); + g_object_set_property (G_OBJECT (data->cam), name, &tmp); + } + + g_signal_handler_unblock (data->cam, data->signal_handlers[update->id]); + g_debug ("Done."); + } + + if (request->message->msg == KIROCS_FETCH) { + gchar* property_name = (gchar *)request->message->payload; + + KiroRequest *request = g_malloc0 (sizeof (KiroRequest)); + request->peer_rank = data->peer_rank; + request->callback = send_clear_callback; + request->user_data = NULL; + request->message = g_malloc0 (sizeof (KiroMessage)); - g_free (unpacked); + request->message->msg = KIROCS_UPDATE; + request->message->size = sizeof (PropUpdateScalar); + request->message->payload = g_malloc0 (request->message->size); + PropUpdateScalar *update = (PropUpdateScalar *)request->message->payload; + g_object_get (data->cam, property_name, &update->prop_raw, NULL); + + update->base.id = property_id_from_name (property_name, data->n_properties, data->properties); + update->base.size = 1; + update->base.scalar = TRUE; + + GError *error = NULL; + if (!kiro_messenger_send (data->messenger, request, &error)) { + g_error ("Oh shit! '%s'", error->message); + g_error_free (error); + //TODO + //Things + } } - status->request_cleanup = TRUE; + if (request->message->payload) + g_free (request->message->payload); + g_free (request->message); - return KIRO_CALLBACK_CONTINUE; + kiro_messenger_receive (data->messenger, request); } @@ -316,46 +348,79 @@ over an InfiniBand network and control the loaded remote camera as if it was con // wait for the first peer while (data.peer_rank == 0) {}; - guint num_properties = 0; + + KiroMessage message; data.signal_handlers = NULL; - data.properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (data.cam), &num_properties); + data.properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (data.cam), &data.n_properties); if (!(*data.properties)) { g_object_unref (data.messenger); g_object_unref (data.cam); g_error ("No properties exposed by camera '%s'.", camera_name); } else { - data.signal_handlers = g_malloc0 (sizeof (gulong) * (num_properties + 1)); //0 is not a valid property ID + data.signal_handlers = g_malloc0 (sizeof (gulong) * (data.n_properties + 1)); //0 is not a valid property ID - for (guint idx=0; idx < num_properties; idx++) { + for (guint idx=0; idx < data.n_properties; idx++) { - gint prop_id = property_id_from_name (data.properties[idx]->name); - if (0 >= prop_id) { + if (idx >= N_BASE_PROPERTIES - 1) { //NONE Base Property. //Inform peer and setup - continue; + g_debug ("Asking peer to install property '%s' with ID %u", data.properties[idx]->name, idx + 1); + message.msg = KIROCS_INSTALL; + message.size = sizeof (PropertyRequisition) + strlen (data.properties[idx]->name); + message.payload = g_malloc0 (message.size); + + PropertyRequisition *req = message.payload; + req->id = idx + 1; + req->value_type = data.properties[idx]->value_type; + + switch (req->value_type) { + case G_TYPE_BOOLEAN: + req->spec.bool_spec = *(GParamSpecBoolean *)data.properties[idx]; + break; + default: + g_debug ("FOOBAR"); + } + strcpy (req->name, data.properties[idx]->name); + + if (!kiro_messenger_send_blocking (data.messenger, &message, data.peer_rank, &error)) { + g_error ("Oh shit!"); + //TODO + //Things + } + g_free (req); } + else + peer_inform_update (data.cam, data.properties[idx], &data); - data.signal_handlers[prop_id] = setup_signal_handler (data.cam, data.properties[idx], &data); + guint handler_id = setup_signal_handler (data.cam, data.properties[idx], &data); + data.signal_handlers[idx + 1] = handler_id; + g_debug ("Setup handler for property '%s' with handler ID %u", data.properties[idx]->name, handler_id); } } //All done. Send READY - KiroMessage message; - message.peer_rank = data.peer_rank; message.msg = KIROCS_READY; message.size = 0; message.payload = NULL; - if (!kiro_messenger_send_blocking (data.messenger, &message, &error)) { + if (!kiro_messenger_send_blocking (data.messenger, &message, data.peer_rank, &error)) { g_error ("Oh shit!"); //TODO //Things } + KiroRequest request; + request.id = 0; + request.callback = (KiroMessageCallbackFunc) receive_callback; + request.user_data = (gpointer) &data; - kiro_messenger_add_receive_callback (data.messenger, (KiroMessageCallbackFunc)receive_callback, &data); - while (!(data.exit_flag)) {}; + kiro_messenger_receive (data.messenger, &request); + while (!(data.exit_flag)) { + sleep (5); + //TODO + //Check if connection is still alive, and if not, reinitialize + }; g_free (data.properties); |