summaryrefslogtreecommitdiffstats
path: root/bin/kiro-camera-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/kiro-camera-server.c')
-rw-r--r--bin/kiro-camera-server.c203
1 files changed, 134 insertions, 69 deletions
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);