Browse Source

Some stuff.
Mostly build-fixes.

Timo Dritschler 8 years ago
parent
commit
f888aff829
5 changed files with 340 additions and 1146 deletions
  1. 5 2
      CMakeLists.txt
  2. 4 16
      bin/kiro-camera-server.c
  3. 6 6
      src/CMakeLists.txt
  4. 0 1115
      src/uca-kiro-camera.cpp
  5. 325 7
      src/uca-kiro-camera.h

+ 5 - 2
CMakeLists.txt

@@ -3,14 +3,14 @@ project(KIROCS C)
 
 set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
 
-set(TARNAME "kiro-camera-server")
+set(TARNAME "uca-kiro")
 set(LIBKIROCS_VERSION_MAJOR "0")
 set(LIBKIROCS_VERSION_MINOR "0")
 set(LIBKIROCS_VERSION_PATCH "1")
 set(LIBKIROCS_VERSION_RELEASE "0")
 set(LIBKIROCS_VERSION_STRING "${LIBKIROCS_VERSION_MAJOR}.${LIBKIROCS_VERSION_MINOR}.${LIBKIROCS_VERSION_PATCH}")
 set(VERSION "${LIBKIROCS_VERSION_STRING}")
-set(LIBKIROCS_DESCRIPTION "Small InfiniBand communication Server and Client")
+set(LIBKIROCS_DESCRIPTION "KIRO InfiniBand camera remote control server and plugin for libuca")
 
 # Increase the ABI version when binary compatibility cannot be guaranteed, e.g.
 # symbols have been removed, function signatures, structures, constants etc.
@@ -31,6 +31,8 @@ pkg_check_modules(GIO2 gio-2.0>=2.32 REQUIRED)
 pkg_check_modules(LIBUCA libuca>=2.0 REQUIRED)
 pkg_check_modules(KIRO kiro>=1.4 REQUIRED)
 
+pkg_check_variable(libuca plugindir)
+
 include_directories(
     SYSTEM
     ${CMAKE_CURRENT_SOURCE_DIR}/src
@@ -62,3 +64,4 @@ set(LIBKIROCS_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
 add_definitions(-Wall -Wextra -std=c99)
 
 add_subdirectory(bin)
+add_subdirectory(src)

+ 4 - 16
bin/kiro-camera-server.c

@@ -19,7 +19,7 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include "kiro-camera-server.h"
+#include "uca-kiro-camera.h"
 #include "uca/uca-plugin-manager.h"
 
 
@@ -124,20 +124,6 @@ gtype_size (GType type)
 }
 
 
-gint
-property_id_from_name(const gchar* name)
-{
-    gint idx = 0;
-    gboolean found = FALSE;
-    for (;idx < N_BASE_PROPERTIES; ++idx) {
-        if (0 == g_strcmp0(name, uca_camera_props[idx])) {
-            found = TRUE;
-            break;
-        }
-    }
-    return found ? idx : -1;
-}
-
 static void
 print_cam_name (gchar *name, gpointer unused)
 {
@@ -222,7 +208,6 @@ connect_callback (gulong rank, gulong *storage)
 static KiroContinueFlag
 receive_callback (KiroMessageStatus *status, KiroCsData *data)
 {
-    PropUpdate *update = (PropUpdate *)status->message->payload; 
 
     if (status->message->msg == KIROCS_EXIT) {
         g_message ("Peer requested shut down...");
@@ -230,6 +215,8 @@ receive_callback (KiroMessageStatus *status, KiroCsData *data)
     }
 
     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); 
 
@@ -240,6 +227,7 @@ receive_callback (KiroMessageStatus *status, KiroCsData *data)
                                 data->properties[update->id -1]->value_type,
                                 data->signal_handlers[update->id],
                                 unpacked);
+
         g_free (unpacked);
 
     }

+ 6 - 6
src/CMakeLists.txt

@@ -1,13 +1,13 @@
-include_directories(${KIROCS_SOURCE_DIR})
+include_directories(${KIROCS_INCLUDE_DIR} ${KIROCS_SOURCE_DIR})
 link_directories(${KIROCS_BINARY_DIR})
 
-add_library(libucakiro SHARED uca-kiro-camera.c)
-target_link_libraries(libucakiro ${KIROCS_DEPS})
+add_library(ucakiro SHARED uca-kiro-camera.c)
+target_link_libraries(ucakiro ${KIROCS_DEPS})
 
-set_target_properties(libucakiro PROPERTIES
+set_target_properties(ucakiro PROPERTIES
     VERSION "${LIBKIROCS_VERSION_MAJOR}.${LIBKIROCS_VERSION_MINOR}"
     SOVERSION ${LIBKIROCS_VERSION_PATCH}
 )
 
-install(FILES uca-kiro-camera.h DESTINATION ${KIROCS_BINDIR})
-install(TARGETS uca-kiro-camera LIBRARY DESTINATION ${LIBUCA_LIBDIR}/uca)
+install(TARGETS ucakiro LIBRARY DESTINATION ${LIBUCA_PLUGINDIR})
+install(FILES uca-kiro-camera.h DESTINATION ${KIROCS_INCLUDEDIR})

+ 0 - 1115
src/uca-kiro-camera.cpp

@@ -1,1115 +0,0 @@
-/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu>
-   (Karlsruhe Institute of Technology)
-
-   This library is free software; you can redistribute it and/or modify it
-   under the terms of the GNU Lesser General Public License as published by the
-   Free Software Foundation; either version 2.1 of the License, or (at your
-   option) any later version.
-
-   This library 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 Lesser General Public License for more
-   details.
-
-   You should have received a copy of the GNU Lesser General Public License along
-   with this library; if not, write to the Free Software Foundation, Inc., 51
-   Franklin St, Fifth Floor, Boston, MA 02110, USA */
-
-
-#include <tango.h>
-
-extern "C" {
-#include <gmodule.h>
-#include <gio/gio.h>
-#include <string.h>
-#include <math.h>
-#include <kiro/kiro-sb.h>
-#include "uca-kiro-camera.h"
-} // EXTERN  C
-
-#define UCA_KIRO_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), UCA_TYPE_KIRO_CAMERA, UcaKiroCameraPrivate))
-
-static void uca_kiro_initable_iface_init (GInitableIface *iface);
-GError *initable_iface_error = NULL;
-
-G_DEFINE_TYPE_WITH_CODE (UcaKiroCamera, uca_kiro_camera, UCA_TYPE_CAMERA,
-                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
-                                                uca_kiro_initable_iface_init))
-
-
-/**
- * UcaCameraError:
-   @UCA_KIRO_CAMERA_ERROR_MISSING_TANGO_ADDRESS: No TANGO address ('kiro-tango-address') property was supplied during camera creation
-   @UCA_KIRO_CAMERA_ERROR_TANGO_CONNECTION_FAILED: Could not connect to the given TANGO address
-   @UCA_KIRO_CAMERA_ERROR_KIRO_CONNECTION_FAILED: Failed to establish a KIRO connection to the given TANGO server
-   @UCA_KIRO_CAMERA_ERROR_TANGO_EXCEPTION_OCCURED: A TANGO exception was raised during communication with the server
-   @UCA_KIRO_CAMERA_ERROR_BAD_CAMERA_INTERFACE: The given TANGO server does not expose the expected UcaCamera base interface
- */
-GQuark uca_kiro_camera_error_quark()
-{
-    return g_quark_from_static_string ("uca-kiro-camera-error-quark");
-}
-
-
-enum {
-    PROP_KIRO_ADDRESS = N_BASE_PROPERTIES,
-    PROP_KIRO_PORT,
-    PROP_KIRO_TANGO_ADDRESS,
-    PROP_KIRO_REMOTE_NAME,
-    N_PROPERTIES
-};
-
-static const gint kiro_overrideables[] = {
-    PROP_NAME,
-    0,
-};
-
-static GParamSpec *kiro_properties[N_PROPERTIES] = { NULL, };
-
-struct _UcaKiroCameraPrivate {
-    guint8 *dummy_data;
-    guint current_frame;
-    gchar *kiro_address;
-    gchar *kiro_port;
-    guint kiro_port_uint;
-    gchar *kiro_tango_address;
-    gchar *remote_name;
-    Tango::DeviceProxy *tango_device;
-    GParamSpec **kiro_dynamic_attributes;
-
-    gboolean thread_running;
-    gboolean kiro_connected;
-    gboolean construction_error;
-
-    GThread *grab_thread;
-    KiroSb *receive_buffer;
-
-    guint roi_height;
-    guint roi_width;
-    guint bytes_per_pixel;
-};
-
-static gpointer
-kiro_grab_func(gpointer data)
-{
-    UcaKiroCamera *kiro_camera = UCA_KIRO_CAMERA (data);
-    g_return_val_if_fail (UCA_IS_KIRO_CAMERA (kiro_camera), NULL);
-
-    UcaKiroCameraPrivate *priv = UCA_KIRO_CAMERA_GET_PRIVATE (kiro_camera);
-    UcaCamera *camera = UCA_CAMERA (kiro_camera);
-    gdouble fps;
-    g_object_get (G_OBJECT (data), "frames-per-second", &fps, NULL);
-    const gulong sleep_time = (gulong) G_USEC_PER_SEC / fps;
-
-    while (priv->thread_running) {
-        camera->grab_func (NULL, camera->user_data);
-        g_usleep (sleep_time);
-    }
-
-    return NULL;
-}
-
-static void
-uca_kiro_camera_start_recording(UcaCamera *camera, GError **error)
-{
-    gboolean transfer_async = FALSE;
-    UcaKiroCameraPrivate *priv;
-    g_return_if_fail(UCA_IS_KIRO_CAMERA (camera));
-
-    priv = UCA_KIRO_CAMERA_GET_PRIVATE (camera);
-    g_object_get (G_OBJECT(camera),
-            "transfer-asynchronously", &transfer_async,
-            NULL);
-
-    //'Cache' ROI settings from TANGO World
-    g_object_get (G_OBJECT(camera),
-            "roi-width", &priv->roi_width,
-            NULL);
-    g_object_get (G_OBJECT(camera),
-            "roi-height", &priv->roi_height,
-            NULL);
-
-    size_t bits = 0;
-    g_object_get (G_OBJECT(camera),
-            "sensor-bitdepth", &bits,
-            NULL);
-
-    priv->bytes_per_pixel = 1;
-    if (bits > 8) priv->bytes_per_pixel++;
-    if (bits > 16) priv->bytes_per_pixel++;
-    if (bits > 24) priv->bytes_per_pixel++;
-
-    Tango::DevState state;
-    g_object_get (G_OBJECT(camera),
-            "State", &state,
-            NULL);
-    try {
-        if (Tango::DevState::STANDBY == state)
-            priv->tango_device->command_inout ("StartRecording");
-    }
-    catch (Tango::DevFailed &e) {
-        g_warning ("Failed to execute 'StartRecording' on the remote camera due to a TANGO exception.\n");
-        g_set_error (error, UCA_KIRO_CAMERA_ERROR, UCA_KIRO_CAMERA_ERROR_TANGO_EXCEPTION_OCCURED,
-                     "A TANGO exception was raised: '%s'", (const char *)e.errors[0].desc);
-        return;
-    }
-
-
-    /*
-     * In case asynchronous transfer is requested, we start a new thread that
-     * invokes the grab callback, otherwise nothing will be done here.
-     */
-    if (transfer_async) {
-        GError *tmp_error = NULL;
-        priv->thread_running = TRUE;
-        priv->grab_thread = g_thread_create (kiro_grab_func, camera, TRUE, &tmp_error);
-
-        if (tmp_error != NULL) {
-            priv->thread_running = FALSE;
-            g_propagate_error (error, tmp_error);
-            try {
-                priv->tango_device->command_inout ("StopRecording");
-            }
-            catch (Tango::DevFailed &e) {
-                g_warning ("Failed to execute 'StopRecording' on the remote camera due to a TANGO exception: '%s'\n", (const char *)e.errors[0].desc);
-            }
-        }
-    }
-
-    kiro_sb_thaw (priv->receive_buffer);
-}
-
-static void
-uca_kiro_camera_stop_recording(UcaCamera *camera, GError **error)
-{
-    g_return_if_fail(UCA_IS_KIRO_CAMERA (camera));
-    UcaKiroCameraPrivate *priv;
-    priv = UCA_KIRO_CAMERA_GET_PRIVATE (camera);
-
-    Tango::DevState state;
-    g_object_get (G_OBJECT(camera),
-            "State", &state,
-            NULL);
-
-    try {
-        if (Tango::DevState::RUNNING == state)
-            priv->tango_device->command_inout ("StopRecording");
-    }
-    catch (Tango::DevFailed &e) {
-        g_warning ("Failed to execute 'StopRecording' on the remote camera due to a TANGO exception.\n");
-        g_set_error (error, UCA_KIRO_CAMERA_ERROR, UCA_KIRO_CAMERA_ERROR_TANGO_EXCEPTION_OCCURED,
-                     "A TANGO exception was raised: '%s'", (const char *)e.errors[0].desc);
-    }
-
-    gboolean transfer_async = FALSE;
-    g_object_get(G_OBJECT (camera),
-            "transfer-asynchronously", &transfer_async,
-            NULL);
-
-    if (transfer_async) {
-        priv->thread_running = FALSE;
-        g_thread_join (priv->grab_thread);
-    }
-
-    kiro_sb_freeze (priv->receive_buffer);
-    g_free (priv->dummy_data);
-}
-
-static void
-uca_kiro_camera_trigger (UcaCamera *camera, GError **error)
-{
-}
-
-static gboolean
-uca_kiro_camera_grab (UcaCamera *camera, gpointer data, GError **error)
-{
-    g_return_val_if_fail (UCA_IS_KIRO_CAMERA (camera), FALSE);
-
-    UcaKiroCameraPrivate *priv = UCA_KIRO_CAMERA_GET_PRIVATE (camera);
-
-    //This is a hack to make sure we actually wait for a new frame;
-    gpointer frame = kiro_sb_get_data_blocking (priv->receive_buffer);
-
-    kiro_sb_freeze (priv->receive_buffer);
-    //Element 0 might still be in the process of being written. 
-    //Therefore, we take Element 1, to be sure this one is finished.
-    if (data)
-        g_memmove (data, frame, priv->roi_width * priv->roi_height * priv->bytes_per_pixel);
-    kiro_sb_thaw (priv->receive_buffer);
-
-    return TRUE;
-}
-
-
-
-// ---------------------------------------------------------- //
-//                      TANGO <-> GLib                        //
-// ---------------------------------------------------------- //
-gboolean
-unpack_gvaluearray_from_tango (GValue *value, Tango::DeviceAttribute &t_attr, GParamSpec *pspec)
-{
-    GType value_type = ((GParamSpecValueArray*)pspec)->element_spec->value_type;
-    if (G_TYPE_UINT != value_type) {
-        g_print ("Array type attribue '%s' holds elements of type '%s' which can't be handled.\n", pspec->name, g_type_name (value_type) );
-        return FALSE;
-    }
-
-    guint array_length = t_attr.get_dim_x ();
-    GValueArray *gvalarray = g_value_array_new (array_length);
-
-    //Convenience Macro to prevent either having to rewrite this block
-    //of code over and over again, or creating two almost identical
-    // switch-cases...
-    //UNPACK TANGO GVALUEARRAY
-    #define __U_T_GVA(__GTYPE, __GFUNC) { \
-        vector<__GTYPE> t_vect; \
-        t_attr >> t_vect; \
-        for (guint idx = 0; idx < array_length; idx++) { \
-            g_value_array_append (gvalarray, NULL); \
-            GValue *val = g_value_array_get_nth (gvalarray, idx); \
-            g_value_init (val, value_type); \
-            __GFUNC (val, t_vect[idx]); \
-        } \
-    }
-
-    switch (value_type) {
-        case G_TYPE_BOOLEAN:
-            //We need to to this manualy since there is no implicit conversion from c++ bool to gboolean
-            {
-                vector<bool> t_vect;
-                t_attr >> t_vect;
-                for (guint idx = 0; idx < array_length; idx++) {
-                    g_value_array_append (gvalarray, NULL);
-                    GValue *val = g_value_array_get_nth (gvalarray, idx);
-                    g_value_init (val, value_type);
-                    g_value_set_boolean (val, (t_vect[idx] ? TRUE : FALSE));
-                }
-            }
-            break;
-        case G_TYPE_STRING:
-            //We need to to this manualy since there is no implicit conversion from c++ string to gchar*
-            {
-                vector<string> t_vect;
-                t_attr >> t_vect;
-                for (guint idx = 0; idx < array_length; idx++) {
-                    g_value_array_append (gvalarray, NULL);
-                    GValue *val = g_value_array_get_nth (gvalarray, idx);
-                    g_value_init (val, value_type);
-                    g_value_set_string (val, t_vect[idx].c_str ());
-                }
-            }
-            break;
-        case G_TYPE_UCHAR:
-            __U_T_GVA (guchar, g_value_set_uchar);
-            break;
-        case G_TYPE_INT:
-            __U_T_GVA (gint, g_value_set_int);
-            break;
-        case G_TYPE_UINT:
-            __U_T_GVA (guint, g_value_set_uint);
-            break;
-        case G_TYPE_INT64:
-            __U_T_GVA (gint64, g_value_set_int64);
-            break;
-        case G_TYPE_UINT64:
-            __U_T_GVA (guint64, g_value_set_uint64);
-            break;
-        case G_TYPE_LONG:
-            __U_T_GVA (glong, g_value_set_long);
-            break;
-        case G_TYPE_ULONG:
-            __U_T_GVA (gulong, g_value_set_ulong);
-            break;
-        case G_TYPE_FLOAT:
-            __U_T_GVA (gfloat, g_value_set_float);
-            break;
-        case G_TYPE_DOUBLE:
-            __U_T_GVA (gdouble, g_value_set_double);
-            break;
-        default:
-            g_print ("Array type attribue '%s' holds elements of type '%s' which can't be handled.\n", pspec->name, g_type_name (value_type) );
-            return FALSE;
-    }
-
-    g_value_set_boxed_take_ownership (value, gvalarray);
-    return TRUE;
-}
-
-
-void
-try_handle_read_tango_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
-    Tango::DeviceAttribute t_attr;
-    UcaKiroCamera *camera = UCA_KIRO_CAMERA (object);
-    UcaKiroCameraPrivate *priv = UCA_KIRO_CAMERA_GET_PRIVATE (camera);
-
-    bool property_is_handled = (property_id >= N_PROPERTIES) ? (bool)priv->kiro_dynamic_attributes[property_id] : (bool)kiro_properties[property_id];
-
-    if (property_is_handled) {
-        try {
-            priv->tango_device->read_attribute (pspec->name, t_attr);
-        }
-        catch (Tango::DevFailed &e) {
-            g_warning ("Property '%s' could not be read due to an unexpected TANGO error...\n", pspec->name);
-            Tango::Except::print_exception (e);
-            return;
-        }
-
-        //Stupid workaround for TANGO::State attribute...
-        //Because they just HAD to make a special case
-        //for that one specific Enum...
-        if (0 == g_strcmp0 (pspec->name, "State")) {
-            Tango::DevState state;
-            t_attr >> state;
-            g_value_set_uint (value, (unsigned int)state);
-            return;
-        }
-
-        //Convenience Macro to prevent having to write this block
-        //of code over and over again
-        #define T_TO_G_CONVERT(GTYPE, T_ATTR, FUNCTION, TARGET) { \
-            GTYPE t_val; \
-            T_ATTR >> t_val; \
-            FUNCTION (TARGET, t_val); \
-        }
-
-        // 17.06.2015
-        // Somehow the implicit conversions from the glib types to any datatype
-        // known by TANGO got broken. We need to use the explicit C++ types here
-        // to make TANGO happy and then rely on the implicit conversion back to
-        // glib types when the call to g_value_set_XXX occurs...
-        switch (value->g_type) {
-        case G_TYPE_FLOAT:
-            T_TO_G_CONVERT (float, t_attr, g_value_set_float, value);
-            break;
-        case G_TYPE_DOUBLE:
-            T_TO_G_CONVERT (double, t_attr, g_value_set_double, value);
-            break;
-        case G_TYPE_UCHAR:
-            T_TO_G_CONVERT (unsigned char, t_attr, g_value_set_uchar, value);
-            break;
-        case G_TYPE_INT:
-            T_TO_G_CONVERT (short int, t_attr, g_value_set_int, value);
-            break;
-        case G_TYPE_UINT:
-            T_TO_G_CONVERT (unsigned short int, t_attr, g_value_set_uint, value);
-            break;
-        case G_TYPE_LONG:
-            T_TO_G_CONVERT (long int, t_attr, g_value_set_long, value);
-            break;
-        case G_TYPE_ULONG:
-            T_TO_G_CONVERT (unsigned long int, t_attr, g_value_set_ulong, value);
-            break;
-        case G_TYPE_INT64:
-            T_TO_G_CONVERT (int64_t, t_attr, g_value_set_int64, value);
-            break;
-        case G_TYPE_UINT64:
-            T_TO_G_CONVERT (uint64_t, t_attr, g_value_set_uint64, value);
-            break;
-        case G_TYPE_BOOLEAN:
-            {
-                bool t_val;
-                t_attr >> t_val;
-                g_value_set_boolean (value, (t_val ? TRUE : FALSE));
-            }
-            break;
-        case G_TYPE_STRING:
-            {
-                string t_val;
-                t_attr >> t_val;
-                g_value_set_string (value, t_val.c_str ());
-            }
-            break;
-        default:
-            {
-                if (g_type_parent (value->g_type) == G_TYPE_ENUM) {
-                    T_TO_G_CONVERT (gint, t_attr, g_value_set_enum, value);
-                    break;
-                }
-
-                if (G_TYPE_VALUE_ARRAY == value->g_type) {
-                    if (Tango::AttrDataFormat::SPECTRUM != t_attr.get_data_format ()) {
-                        g_warning ("TANGO attribute '%s' is not of type SPECTRUM! (Not a 1-dimensional array, yet libuca was expecting one.)\n", pspec->name);
-                        return;
-                    }
-
-                    if (0 == unpack_gvaluearray_from_tango (value, t_attr, pspec))
-                        g_warning ("Failed to read property '%s'\n", pspec->name);
-
-                    return;
-                }
-
-                GType unhandled = pspec->value_type;
-                if (G_TYPE_GTYPE == unhandled) {
-                    unhandled = ((GParamSpecGType*)pspec)->is_a_type;
-                }
-                g_print ("GType '%s' can't be handled...\n", g_type_name (unhandled));
-                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-            }
-        }
-    }
-    else {
-        g_print ("Unhandled property...\n");
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-    }
-
-#undef T_TO_G_CONVERT
-}
-
-
-gboolean
-pack_gvaluearray_to_tango (const GValue *value, Tango::DeviceAttribute &t_attr, GParamSpec *pspec)
-{
-
-    GType value_type = ((GParamSpecValueArray*)pspec)->element_spec->value_type;
-    GValueArray *gvalarray = (GValueArray *) g_value_get_boxed (value);
-    guint array_length = gvalarray->n_values;
-
-    //Convenience Macro to prevent either having to rewrite this block
-    //of code over and over again, or creating two almost identical
-    // switch-cases...
-    #define __P_GVA_T(__GTYPE, __GFUNC) { \
-        vector<__GTYPE> t_vect (array_length); \
-        for (guint idx = 0; idx < array_length; idx++) { \
-            GValue *val = g_value_array_get_nth (gvalarray, idx); \
-            t_vect[idx] = __GFUNC (val); \
-        } \
-        t_attr << t_vect; \
-    }
-
-    switch (value_type) {
-        case G_TYPE_BOOLEAN:
-            __P_GVA_T (bool, g_value_get_boolean); //This relys on the implicit conversion from int to c++ bool
-            break;
-        case G_TYPE_UCHAR:
-            __P_GVA_T (guchar, g_value_get_uchar);
-            break;
-        case G_TYPE_STRING:
-            __P_GVA_T (string, g_value_get_string); //This relys on the implicit conversion from char* to c++ string
-            break;
-        case G_TYPE_INT:
-            __P_GVA_T (gint, g_value_get_int);
-            break;
-        case G_TYPE_UINT:
-            __P_GVA_T (guint, g_value_get_uint);
-            break;
-        case G_TYPE_INT64:
-            __P_GVA_T (gint64, g_value_get_int64);
-            break;
-        case G_TYPE_UINT64:
-            __P_GVA_T (guint64, g_value_get_uint64);
-            break;
-        case G_TYPE_LONG:
-            __P_GVA_T (glong, g_value_get_long);
-            break;
-        case G_TYPE_ULONG:
-            __P_GVA_T (gulong, g_value_get_ulong);
-            break;
-        case G_TYPE_FLOAT:
-            __P_GVA_T (gfloat, g_value_get_float);
-            break;
-        case G_TYPE_DOUBLE:
-            __P_GVA_T (gdouble, g_value_get_double);
-            break;
-        default:
-            g_print ("Array type attribue '%s' holds elements of type '%s' which can't be handled.\n", pspec->name, g_type_name (value_type) );
-            return FALSE;
-    }
-
-    t_attr.data_format = Tango::AttrDataFormat::SPECTRUM;
-    t_attr.dim_x = array_length;
-    return TRUE;
-
-#undef __P_GVA_T
-}
-
-
-void
-try_handle_write_tango_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
-    Tango::DeviceAttribute t_attr;
-    UcaKiroCamera *camera = UCA_KIRO_CAMERA (object);
-    UcaKiroCameraPrivate *priv = UCA_KIRO_CAMERA_GET_PRIVATE (camera);
-
-    bool property_is_handled = (property_id > N_PROPERTIES) ? (bool)priv->kiro_dynamic_attributes[property_id] : (bool)kiro_properties[property_id];
-
-    if (property_is_handled) {
-
-        // 17.06.2015
-        // Implicit conversions from glib types to TANGO C++ types are broken.
-        // We need to to a manual cast for each one to make TANGO happy again...
-        switch (value->g_type) {
-            case G_TYPE_BOOLEAN:
-                {
-                    bool t_val = (g_value_get_boolean (value) == TRUE);
-                    t_attr << t_val;
-                }
-                break;
-            case G_TYPE_INT:
-                t_attr << (int)g_value_get_int (value);
-                break;
-            case G_TYPE_FLOAT:
-                t_attr << (float)g_value_get_float (value);
-                break;
-            case G_TYPE_DOUBLE:
-                t_attr << (double)g_value_get_double (value);
-                break;
-            case G_TYPE_UINT:
-                t_attr << (unsigned short int)g_value_get_uint (value);
-                break;
-            case G_TYPE_ULONG:
-                t_attr << (unsigned long int)g_value_get_ulong (value);
-                break;
-            case G_TYPE_STRING:
-                t_attr << g_value_get_string (value);
-                break;
-            case G_TYPE_UCHAR:
-                t_attr << (unsigned char)g_value_get_uchar (value);
-                break;
-            case G_TYPE_INT64:
-                t_attr << (int64_t)g_value_get_int64 (value);
-                break;
-            case G_TYPE_UINT64:
-                t_attr << (uint64_t)g_value_get_uint64 (value);
-                break;
-            case G_TYPE_LONG:
-                t_attr << (long int)g_value_get_long (value);
-                break;
-            case G_TYPE_ENUM:
-                t_attr << g_value_get_enum (value);
-                break;
-            default:
-                {
-                    if (g_type_parent (value->g_type) == G_TYPE_ENUM) {
-                        t_attr << g_value_get_enum (value);
-                        break;
-                    }
-
-                    if (value->g_type == G_TYPE_VALUE_ARRAY) {
-                        if (0 == pack_gvaluearray_to_tango (value, t_attr, pspec)) {
-                            g_warning ("Failed to write property '%s'.\n", pspec->name);
-                            return;
-                        }
-                        break;
-                    }
-
-                    GType unhandled = value->g_type;
-                    if (G_TYPE_GTYPE == unhandled) {
-                        unhandled = ((GParamSpecGType*)pspec)->is_a_type;
-                    }
-                    g_print ("GType '%s' can't be handled...\n", g_type_name (unhandled));
-                    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-                }
-                break;
-        }
-
-        t_attr.set_name (pspec->name);
-
-        try {
-            priv->tango_device->write_attribute (t_attr);
-        }
-        catch (Tango::DevFailed &e) {
-            g_warning ("Property '%s' could not be written due to a TANGO exception: '%s'\n", pspec->name, (const char *)e.errors[0].desc);
-            Tango::Except::print_exception (e);
-            return;
-        }
-    }
-    else
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-
-GType
-gtype_from_tango_type (Tango::CmdArgType t)
-{
-    using namespace Tango;
-        switch (t) {
-            case DEV_VOID:
-                return G_TYPE_NONE;
-            case DEV_BOOLEAN:
-                return G_TYPE_BOOLEAN;
-            case DEV_SHORT:
-                //Fall-through intentional
-            case DEV_INT:
-                //Fall-through intentional
-            case DEV_LONG:
-                return G_TYPE_INT;
-            case DEV_FLOAT:
-                return G_TYPE_FLOAT;
-            case DEV_DOUBLE:
-                return G_TYPE_DOUBLE;
-            case DEV_ULONG:
-                //return G_TYPE_ULONG;
-                //Fall-through intentional
-                //NOTE: There seems to be a bug somewhere either in TANGO or in GLib or in Pyhton that
-                //Breaks the functionality of the G_TYPE_ULONG properties. Using a G_TYPE_UINT instead
-                //works around this problem but might provoke potential overflows...
-            case DEV_USHORT:
-                return G_TYPE_UINT;
-            case CONST_DEV_STRING:
-                //Fall-through intentional
-            case DEV_STRING:
-                return G_TYPE_STRING;
-            case DEV_UCHAR:
-                return G_TYPE_UCHAR;
-            case DEV_LONG64:
-                return G_TYPE_INT64;
-            case DEV_ULONG64:
-                return G_TYPE_UINT64;
-            case DEV_STATE:
-                return G_TYPE_UINT;
-            /*
-            DEV_ENCODED
-            DEVVAR_CHARARRAY
-            DEVVAR_SHORTARRAY
-            DEVVAR_LONGARRAY
-            DEVVAR_FLOATARRAY
-            DEVVAR_DOUBLEARRAY
-            DEVVAR_USHORTARRAY
-            DEVVAR_ULONGARRAY
-            DEVVAR_STRINGARRAY
-            DEVVAR_LONGSTRINGARRAY
-            DEVVAR_DOUBLESTRINGARRAY
-            DEVVAR_BOOLEANARRAY
-            DEVVAR_LONG64ARRAY
-            DEVVAR_ULONG64ARRAY
-            */
-            default:
-                return G_TYPE_INVALID;
-        };
-}
-
-
-gint
-get_property_id_from_name(const gchar* name)
-{
-    guint idx = 0;
-    gboolean found = FALSE;
-    for (;idx < N_PROPERTIES; ++idx) {
-        if (0 == g_strcmp0(name, uca_camera_props[idx])) {
-            found = TRUE;
-            break;
-        }
-    }
-    return (TRUE == found) ? idx : -1;
-}
-
-
-void
-build_param_spec(GParamSpec **pspec, const Tango::AttributeInfoEx *attrInfo)
-{
-    GType type = gtype_from_tango_type ((Tango::CmdArgType)attrInfo->data_type);
-    const gchar *name = attrInfo->name.c_str ();
-    GParamFlags flags = G_PARAM_READABLE;
-    if (attrInfo->writable == Tango::AttrWriteType::WRITE)
-        flags = (GParamFlags) G_PARAM_READWRITE;
-
-
-    //Convenience Macro to prevent having to rewrite this block
-    //of code over and over again..
-    #define __M_PSCPEC(__SPEC_TYPE, __LIMITS_1, __LIMITS_2, __LIMITS_3) { \
-        *pspec = \
-        __SPEC_TYPE (name, \
-            attrInfo->description.c_str (), \
-            g_strconcat ("KIRO TANGO <-> GLib interface of ", name, NULL), \
-            __LIMITS_1, __LIMITS_2, __LIMITS_3,\
-            flags); \
-    }
-
-    switch (type) {
-        case G_TYPE_INT:
-            __M_PSCPEC (g_param_spec_int, G_MININT32, G_MAXINT32, 0);
-            break;
-        case G_TYPE_FLOAT:
-            __M_PSCPEC (g_param_spec_float, G_MINFLOAT, G_MAXFLOAT, 0.);
-            break;
-        case G_TYPE_DOUBLE:
-            __M_PSCPEC (g_param_spec_double, G_MINDOUBLE, G_MAXDOUBLE, 0.)
-            break;
-        case G_TYPE_UINT:
-            __M_PSCPEC (g_param_spec_uint, 0, G_MAXUINT, 0)
-            break;
-        case G_TYPE_ULONG:
-            __M_PSCPEC (g_param_spec_ulong, 0, G_MAXULONG, 0)
-            break;
-        case G_TYPE_UCHAR:
-            __M_PSCPEC (g_param_spec_uchar, 0x00, 0xff, 0x42)
-            break;
-        case G_TYPE_INT64:
-            __M_PSCPEC (g_param_spec_int64, G_MININT64, G_MAXINT64, 0)
-            break;
-        case G_TYPE_UINT64:
-            __M_PSCPEC (g_param_spec_uint64, 0, G_MAXUINT64, 0)
-            break;
-        case G_TYPE_LONG:
-            __M_PSCPEC (g_param_spec_long, G_MININT64, G_MAXINT64, 1)
-            break;
-        case G_TYPE_ENUM:
-            __M_PSCPEC (g_param_spec_int, 0, G_MAXUINT, 0)
-            break;
-        case G_TYPE_STRING:
-            *pspec =
-            g_param_spec_string (name,
-                attrInfo->description.c_str (),
-                g_strconcat ("KIRO TANGO <-> GLib interface of ", name, NULL),
-                "DEFAULT",
-                flags);
-            break;
-        case G_TYPE_BOOLEAN:
-            *pspec =
-            g_param_spec_boolean (name,
-                attrInfo->description.c_str (),
-                g_strconcat ("KIRO TANGO <-> GLib interface of ", name, NULL),
-                FALSE,
-                flags);
-            break;
-        default:
-            *pspec =
-            g_param_spec_gtype (name,
-                attrInfo->description.c_str (),
-                g_strconcat ("KIRO TANGO <-> GLib interface of ", name, NULL),
-                type,
-                flags);
-    }
-
-#undef __M_PSCPEC
-}
-
-
-void
-uca_kiro_camera_clone_interface(const gchar* address, UcaKiroCamera *kiro_camera)
-{
-    UcaKiroCameraPrivate *priv = UCA_KIRO_CAMERA_GET_PRIVATE (kiro_camera);
-    UcaKiroCameraClass *klass = UCA_KIRO_CAMERA_GET_CLASS (kiro_camera);
-    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-    gboolean start_found, stop_found, readout_found, unit_found = FALSE;
-
-    try {
-        Tango::CommandInfoList *cmd_list = priv->tango_device->command_list_query ();
-        for (vector<Tango::CommandInfo>::iterator iter = cmd_list->begin (); iter != cmd_list->end (); ++iter) {
-            gint start_cmp = g_strcmp0((*iter).cmd_name.c_str (), "StartRecording");
-            if (0 == start_cmp) {
-                start_found = TRUE;
-            }
-            gint stop_cmp = g_strcmp0 ((*iter).cmd_name.c_str (), "StopRecording");
-            if (0 == stop_cmp) {
-                stop_found = TRUE;
-            }
-            gint unit_cmp = g_strcmp0((*iter).cmd_name.c_str (), "GetAttributeUnit");
-            if (0 == unit_cmp) {
-                unit_found = TRUE;
-            }
-            gint readout_cmp = g_strcmp0((*iter).cmd_name.c_str (), "Readout");
-            if (0 == readout_cmp) {
-                readout_found = TRUE;
-            }
-        }
-
-        if ( !start_found || !stop_found ) {
-            g_warning ("The Server at '%s' does not provide the necessary 'StartRecording' and 'StopRecording' interface\n", priv->kiro_tango_address);
-            g_set_error (&initable_iface_error, UCA_KIRO_CAMERA_ERROR, UCA_KIRO_CAMERA_ERROR_BAD_CAMERA_INTERFACE,
-                         "The Server at '%s' does not provide the necessary 'StartRecording' and 'StopRecording' interface\n", priv->kiro_tango_address);
-            priv->construction_error = TRUE;
-            return;
-        }
-
-        vector<string> *attr_list = priv->tango_device->get_attribute_list ();
-        GList *non_base_attributes = NULL;
-        guint non_base_attributes_count = 0;
-
-        for (vector<string>::iterator iter = attr_list->begin (); iter != attr_list->end (); ++iter) {
-            Tango::AttributeInfoEx attrInfo =  priv->tango_device->attribute_query (*iter);
-            gint uca_base_prop_id = get_property_id_from_name ((*iter).c_str ());
-            if (-1 < uca_base_prop_id) {
-                guint is_name_attr = g_strcmp0 ((*iter).c_str (), "name");
-                if (0 == is_name_attr) {
-                    Tango::DeviceAttribute t_attr;
-                    priv->tango_device->read_attribute ("name", t_attr);
-                    string reply_name;
-                    t_attr >> reply_name;
-                    g_free (priv->remote_name);
-                    priv->remote_name = g_strdup (reply_name.c_str ());
-                }
-                kiro_properties[uca_base_prop_id] = g_object_class_find_property (gobject_class, uca_camera_props[uca_base_prop_id]);
-                g_object_class_override_property(G_OBJECT_CLASS (UCA_KIRO_CAMERA_GET_CLASS (kiro_camera)), uca_base_prop_id, uca_camera_props[uca_base_prop_id]);
-            }
-            else {
-                non_base_attributes = g_list_append (non_base_attributes, (gpointer)(*iter).c_str ());
-                non_base_attributes_count++;
-            }
-        }
-
-        if (non_base_attributes_count > 0) {
-            priv->kiro_dynamic_attributes = new GParamSpec* [N_PROPERTIES + non_base_attributes_count];
-            UcaKiroCameraClass *klass = UCA_KIRO_CAMERA_GET_CLASS (kiro_camera);
-            GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
-            for (guint idx = 0; idx < non_base_attributes_count; idx++) {
-                const gchar *attr_name = (const gchar*)g_list_nth_data (non_base_attributes, idx);
-                Tango::AttributeInfoEx attrInfo = priv->tango_device->attribute_query (string(attr_name));
-                
-                if (Tango::AttrDataFormat::IMAGE == attrInfo.data_format || Tango::AttrDataFormat::FMT_UNKNOWN == attrInfo.data_format) {
-                    g_print ("Attribute '%s' has unknown DataFormat. Skipping.\n", attr_name);
-                    continue;
-                }
-                
-                build_param_spec (&(priv->kiro_dynamic_attributes[N_PROPERTIES + idx]), &attrInfo);
-                g_object_class_install_property (gobject_class, N_PROPERTIES + idx, priv->kiro_dynamic_attributes[N_PROPERTIES + idx]);
-
-                if (unit_found) {
-                    Tango::DeviceData arg_name;
-                    arg_name << attr_name;
-                    Tango::DeviceData cmd_reply = priv->tango_device->command_inout("GetAttributeUnit", arg_name);
-                    gint unit;
-                    cmd_reply >> unit;
-                    uca_camera_register_unit (UCA_CAMERA (kiro_camera), attr_name, (UcaUnit)unit);
-                }
-            }
-        }
-    }
-    catch (Tango::DevFailed &e) {
-        Tango::Except::print_exception (e);
-        g_set_error (&initable_iface_error, UCA_KIRO_CAMERA_ERROR, UCA_KIRO_CAMERA_ERROR_TANGO_EXCEPTION_OCCURED,
-                     "A TANGO exception was raised: '%s'", (const char *)e.errors[0].desc);
-        priv->construction_error = TRUE;
-    }
-}
-// ---------------------------------------------------------- //
-//                  END: TANGO <-> GLib                       //
-// ---------------------------------------------------------- //
-
-
-
-static void
-uca_kiro_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
-    g_return_if_fail(UCA_IS_KIRO_CAMERA (object));
-    UcaKiroCameraPrivate *priv = UCA_KIRO_CAMERA_GET_PRIVATE (object);
-
-    switch (property_id) {
-        case PROP_KIRO_TANGO_ADDRESS:
-            priv->kiro_tango_address = g_value_dup_string (value);
-            break;
-        default:
-            try_handle_write_tango_property (object, property_id, value, pspec);
-            return;
-    }
-}
-
-
-static void
-uca_kiro_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
-    UcaKiroCameraPrivate *priv = UCA_KIRO_CAMERA_GET_PRIVATE (object);
-
-    switch (property_id) {
-        case PROP_NAME:
-            g_value_set_string (value, "KIRO camera");
-            break;
-        case PROP_KIRO_ADDRESS:
-            g_value_set_string (value, priv->kiro_address);
-            break;
-        case PROP_KIRO_PORT:
-            g_value_set_uint (value, priv->kiro_port_uint);
-            break;
-        case PROP_KIRO_TANGO_ADDRESS:
-            g_value_set_string (value, priv->kiro_tango_address);
-            break;
-        case PROP_KIRO_REMOTE_NAME:
-            g_value_set_string (value, priv->remote_name);
-            break;
-        default:
-            try_handle_read_tango_property (object, property_id, value, pspec);
-            break;
-    }
-}
-
-static void
-uca_kiro_camera_finalize(GObject *object)
-{
-    UcaKiroCameraPrivate *priv = UCA_KIRO_CAMERA_GET_PRIVATE(object);
-
-    if (priv->thread_running) {
-        priv->thread_running = FALSE;
-        g_thread_join (priv->grab_thread);
-    }
-
-    if (priv->receive_buffer) {
-        kiro_sb_free (priv->receive_buffer);
-        priv->receive_buffer = NULL;
-    }
-    priv->kiro_connected = FALSE;
-
-    if (priv->dummy_data) {
-        g_free (priv->dummy_data);
-        priv->dummy_data = NULL;
-    }
-
-    if (priv->tango_device) {
-        delete (priv->tango_device);
-        priv->tango_device = NULL;
-    }
-
-    g_free (priv->kiro_address);
-    g_free (priv->kiro_port);
-    g_free (priv->kiro_tango_address);
-
-    G_OBJECT_CLASS (uca_kiro_camera_parent_class)->finalize(object);
-}
-
-static gboolean
-ufo_kiro_camera_initable_init (GInitable *initable,
-                               GCancellable *cancellable,
-                               GError **error)
-{
-    g_return_val_if_fail (UCA_IS_KIRO_CAMERA (initable), FALSE);
-    
-    UcaKiroCameraPrivate *priv = UCA_KIRO_CAMERA_GET_PRIVATE (UCA_KIRO_CAMERA (initable));
-    if(priv->construction_error) {
-        g_propagate_error (error, initable_iface_error);
-        return FALSE;
-    }
-    
-    return TRUE;
-}
-
-static void
-uca_kiro_initable_iface_init (GInitableIface *iface)
-{
-    iface->init = ufo_kiro_camera_initable_init;
-}
-
-static void
-uca_kiro_camera_constructed (GObject *object)
-{
-    //Initialization for the KIRO Server and TANGO Interface cloning is moved
-    //here and done early!
-    //We want to add dynamic properties and it is too late to do so in the
-    //real initable part. Therefore, we do it here and 'remember' any errors
-    //that occur and check them later in the initable part.
-    
-    UcaKiroCamera *self = UCA_KIRO_CAMERA (object);
-    UcaKiroCameraPrivate *priv = UCA_KIRO_CAMERA_GET_PRIVATE (self);
-    
-    GValue address = G_VALUE_INIT;
-    g_value_init(&address, G_TYPE_STRING);
-    uca_kiro_camera_get_property (object, PROP_KIRO_TANGO_ADDRESS, &address, NULL);
-    gint address_not_none = g_strcmp0(g_value_get_string (&address), "NONE");
-    if (0 == address_not_none) {
-        g_warning ("kiro-tango-address was not set! Can not connect to server...\n");
-        priv->construction_error = TRUE;
-        g_set_error (&initable_iface_error, UCA_KIRO_CAMERA_ERROR, UCA_KIRO_CAMERA_ERROR_MISSING_TANGO_ADDRESS,
-             "'kiro-tango-address' property was not set during construction.");
-    }
-    else {
-        try {
-            priv->tango_device = new Tango::DeviceProxy(g_value_get_string (&address));
-            Tango::DbData kiro_credentials;
-            kiro_credentials.push_back (Tango::DbDatum("KiroAddress"));
-            kiro_credentials.push_back (Tango::DbDatum("KiroPort"));
-            priv->tango_device->get_property(kiro_credentials);
-            string kiro_address, kiro_port;
-            kiro_credentials[0] >> kiro_address;
-            kiro_credentials[1] >> kiro_port;
-
-            if (0 > kiro_sb_clone (priv->receive_buffer, kiro_address.c_str (), kiro_port.c_str ())) {
-                g_warning ("Unable to connect to server at address: %s, port: %s\n", kiro_address.c_str (), kiro_port.c_str ());
-                priv->construction_error = TRUE;
-                g_set_error (&initable_iface_error, UCA_KIRO_CAMERA_ERROR, UCA_KIRO_CAMERA_ERROR_KIRO_CONNECTION_FAILED,
-                             "Failed to establish a KIRO InfiniBand connection.");
-            }
-            else {
-                priv->kiro_connected = TRUE;
-                uca_kiro_camera_clone_interface (g_value_get_string (&address), self);
-            }
-        }
-        catch (Tango::DevFailed &e) {
-            Tango::Except::print_exception (e);
-            g_set_error (&initable_iface_error, UCA_KIRO_CAMERA_ERROR, UCA_KIRO_CAMERA_ERROR_TANGO_EXCEPTION_OCCURED,
-                             "A TANGO exception was raised: '%s'", (const char *)e.errors[0].desc);
-            priv->construction_error = TRUE;
-        }
-    }
-
-    G_OBJECT_CLASS (uca_kiro_camera_parent_class)->constructed(object);
-}
-
-
-
-static void
-uca_kiro_camera_class_init(UcaKiroCameraClass *klass)
-{
-    GObjectClass *gobject_class = G_OBJECT_CLASS( klass);
-    gobject_class->set_property = uca_kiro_camera_set_property;
-    gobject_class->get_property = uca_kiro_camera_get_property;
-    gobject_class->finalize = uca_kiro_camera_finalize;
-    gobject_class->constructed = uca_kiro_camera_constructed;
-
-    UcaCameraClass *camera_class = UCA_CAMERA_CLASS (klass);
-    camera_class->start_recording = uca_kiro_camera_start_recording;
-    camera_class->stop_recording = uca_kiro_camera_stop_recording;
-    camera_class->grab = uca_kiro_camera_grab;
-    camera_class->trigger = uca_kiro_camera_trigger;
-
-    for (guint i = 0; kiro_overrideables[i] != 0; i++)
-        g_object_class_override_property (gobject_class, kiro_overrideables[i], uca_camera_props[kiro_overrideables[i]]);
-                
-    kiro_properties[PROP_KIRO_ADDRESS] =
-        g_param_spec_string("kiro-address",
-                "KIRO Server Address",
-                "Address of the KIRO Server to grab images from",
-                "NONE",
-                G_PARAM_READABLE);
-                
-    kiro_properties[PROP_KIRO_PORT] =
-        g_param_spec_uint("kiro-port",
-                "KIRO Server Port",
-                "Port of the KIRO Server to grab images from",
-                1, 65535, 60010,
-                G_PARAM_READABLE);
-                
-    kiro_properties[PROP_KIRO_TANGO_ADDRESS] =
-        g_param_spec_string("kiro-tango-address",
-                "KIRO TANGO address",
-                "Address of the KIRO Server in the TANGO environment",
-                "NONE",
-                (GParamFlags) (G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
-    kiro_properties[PROP_KIRO_REMOTE_NAME] =
-        g_param_spec_string("remote-name",
-                "Name of the remot camera",
-                "Name of the camera plugin that is loaded on the KIRO remote site",
-                "NONE",
-                G_PARAM_READABLE);
-
-    for (guint id = N_BASE_PROPERTIES; id < N_PROPERTIES; id++)
-        g_object_class_install_property (gobject_class, id, kiro_properties[id]);
-
-    g_type_class_add_private (klass, sizeof(UcaKiroCameraPrivate));
-}
-
-static void
-uca_kiro_camera_init(UcaKiroCamera *self)
-{
-    self->priv = UCA_KIRO_CAMERA_GET_PRIVATE(self);
-    self->priv->grab_thread = NULL;
-    self->priv->current_frame = 0;
-    self->priv->kiro_address = g_strdup ("NONE");
-    self->priv->kiro_port = g_strdup ("NONE");
-    self->priv->remote_name = g_strdup ("NONE");
-    self->priv->kiro_port_uint = 60010;
-    self->priv->kiro_tango_address = g_strdup ("NONE");
-    self->priv->construction_error = FALSE;
-    self->priv->kiro_dynamic_attributes = NULL;
-
-    self->priv->receive_buffer = kiro_sb_new ();
-    kiro_sb_freeze (self->priv->receive_buffer);
-}
-
-
-G_MODULE_EXPORT GType
-uca_camera_get_type (void)
-{
-    return UCA_TYPE_KIRO_CAMERA;
-}
-

+ 325 - 7
src/uca-kiro-camera.h

@@ -19,7 +19,8 @@
 #define __UCA_KIRO_CAMERA_H
 
 #include <glib-object.h>
-#include "uca-camera.h"
+#include "uca/uca-camera.h"
+#include "kiro/kiro-messenger.h"
 
 G_BEGIN_DECLS
 
@@ -35,11 +36,9 @@ G_BEGIN_DECLS
 GQuark uca_kiro_camera_error_quark(void);
 
 typedef enum {
-    UCA_KIRO_CAMERA_ERROR_MISSING_TANGO_ADDRESS = UCA_CAMERA_ERROR_END_OF_STREAM,
-    UCA_KIRO_CAMERA_ERROR_TANGO_CONNECTION_FAILED,
-    UCA_KIRO_CAMERA_ERROR_KIRO_CONNECTION_FAILED,
-    UCA_KIRO_CAMERA_ERROR_TANGO_EXCEPTION_OCCURED,
-    UCA_KIRO_CAMERA_ERROR_BAD_CAMERA_INTERFACE
+    UCA_KIRO_CAMERA_ERROR_MISSING_ADDRESS = UCA_CAMERA_ERROR_END_OF_STREAM,
+    UCA_KIRO_CAMERA_ERROR_ADDRESS_WRONG_FORMAT,
+    UCA_KIRO_CAMERA_ERROR_KIRO_CONNECTION_FAILED
 } UcaKiroCameraError;
 
 
@@ -74,7 +73,326 @@ struct _UcaKiroCameraClass {
 G_END_DECLS
 
 
-void uca_kiro_camera_clone_interface (const gchar* address, UcaKiroCamera *kiro_camera);
+//HELPER FUNCTIONS AND CONSTRUCTS FOR SERVER AND CAMERA PLUGIN
+typedef enum {
+    KIROCS_UPDATE,
+    KIROCS_INSTALL,
+    KIROCS_READY,
+    KIROCS_RPC,
+    KIROCS_EXIT
+}KiroCsCommands;
+
+typedef struct {
+    guint32 id;
+    guint32 size;
+    gboolean scalar;
+    gchar type[2];
+    gchar val[1];
+} PropUpdate;
+
+typedef struct {
+    guint32 str_len;
+    gchar str[1];
+}StrProp;
+
+typedef struct {
+    GType value_type;
+    guint32 name_len;
+    union PSpecs {
+        GParamSpecBoolean bool_spec;
+        GParamSpecChar char_spec;
+        GParamSpecInt int_spec;
+        GParamSpecUInt uint_spec;
+        GParamSpecLong long_spec;
+        GParamSpecULong ulong_spec;
+        GParamSpecInt64 int64_spec;
+        GParamSpecUInt64 uint64_spec;
+        GParamSpecFloat float_spec;
+        GParamSpecDouble double_spec;
+        StrProp str_spec;
+    } spec;
+    gchar name[1];
+} PropertyRequisition;
+
+
+//Forward declaration of the trigger enums for type handling
+GType uca_camera_trigger_source_get_type (void) G_GNUC_CONST;
+#define UCA_TYPE_CAMERA_TRIGGER_SOURCE (uca_camera_trigger_source_get_type ())
+GType uca_camera_trigger_type_get_type (void) G_GNUC_CONST;
+#define UCA_TYPE_CAMERA_TRIGGER_TYPE (uca_camera_trigger_type_get_type ())
+
+
+gchar
+gtype_to_gvariant_class (GType type)
+{
+    gchar ret = '*';
+
+    switch (type) {
+        case G_TYPE_BOOLEAN:
+            ret = G_VARIANT_CLASS_BOOLEAN;
+            break;
+        case G_TYPE_CHAR:
+            ret = G_VARIANT_CLASS_BYTE;
+            break;
+        case G_TYPE_INT:
+            ret = G_VARIANT_CLASS_INT32;
+            break;
+        case G_TYPE_ENUM:
+            ret = G_VARIANT_CLASS_INT32;
+            break;
+        case G_TYPE_UINT:
+            ret = G_VARIANT_CLASS_UINT32;
+            break;
+        case G_TYPE_LONG:
+            ret = G_VARIANT_CLASS_INT64;
+            break;
+        case G_TYPE_ULONG:
+            ret = G_VARIANT_CLASS_UINT64;
+            break;
+        case G_TYPE_INT64:
+            ret = G_VARIANT_CLASS_INT64;
+            break;
+        case G_TYPE_UINT64:
+            ret = G_VARIANT_CLASS_UINT64;
+            break;
+        case G_TYPE_FLOAT:
+            ret = G_VARIANT_CLASS_DOUBLE;
+            break;
+        case G_TYPE_DOUBLE:
+            ret = G_VARIANT_CLASS_DOUBLE;
+            break;
+        default:
+            //ERROR
+            break;
+    }
+
+    return ret;
+}
+
+
+#define GOBJECT_SET(OBJ, PROP, TYPE, DATA) { \
+    g_object_set (OBJ, \
+                  PROP, *(TYPE *)DATA, \
+                  NULL); \
+}
+
+void
+update_property_scalar (GObject *cam, const gchar *prop, GType type, gulong handler, gpointer data)
+{
+    g_debug ("Updating %s, with handler %lu", prop, handler);
+
+    g_signal_handler_block (cam, handler);
+
+    switch (type) {
+        case G_TYPE_BOOLEAN:
+            GOBJECT_SET (cam, prop, gboolean, data);
+            break;
+        case G_TYPE_CHAR:
+            GOBJECT_SET (cam, prop, gchar, data);
+            break;
+        case G_TYPE_INT:
+            GOBJECT_SET (cam, prop, gint, data);
+            break;
+        case G_TYPE_ENUM:
+            GOBJECT_SET (cam, prop, gint, data);
+            break;
+        case G_TYPE_UINT:
+            GOBJECT_SET (cam, prop, guint, data);
+            break;
+        case G_TYPE_LONG:
+            GOBJECT_SET (cam, prop, glong, data);
+            break;
+        case G_TYPE_ULONG:
+            GOBJECT_SET (cam, prop, gulong, data);
+            break;
+        case G_TYPE_INT64:
+            GOBJECT_SET (cam, prop, gint64, data);
+            break;
+        case G_TYPE_UINT64:
+            GOBJECT_SET (cam, prop, guint64, data);
+            break;
+        case G_TYPE_FLOAT:
+            GOBJECT_SET (cam, prop, gfloat, data);
+            break;
+        case G_TYPE_DOUBLE:
+            GOBJECT_SET (cam, prop, gdouble, data);
+            break;
+        default:
+            //TRIGGER_TYPE and TRIGGER_SOURCE are not statically typed and can
+            //not be used in a switch statement...
+            if (type == UCA_TYPE_CAMERA_TRIGGER_SOURCE) {
+                GOBJECT_SET (cam, prop, gint, data);
+                break;
+            }
+
+            if (type ==  UCA_TYPE_CAMERA_TRIGGER_TYPE) {
+                GOBJECT_SET (cam, prop, gint, data);
+                break;
+            }
+
+            g_critical ("Type %s not handled! (SET)", g_type_name (type));
+            break;
+    }
+
+    g_signal_handler_unblock (cam, handler);
+}
+
+
+#define GOBJECT_GET(OBJ, PROP, TYPE, GTYPE) { \
+    TYPE tmp; \
+    gchar *gvclass = g_malloc0 (2); \
+    gvclass[0] = gtype_to_gvariant_class (GTYPE); \
+    g_object_get (OBJ, \
+                  PROP, &tmp, \
+                  NULL); \
+    ret = g_variant_new (gvclass, tmp); \
+    g_free (gvclass); \
+}
+
+GVariant*
+read_property_scalar (GObject *cam, const gchar *prop, GType type)
+{
+    GVariant *ret = NULL;
+
+    switch (type) {
+        case G_TYPE_BOOLEAN:
+            GOBJECT_GET (cam, prop, gboolean, type);
+            break;
+        case G_TYPE_CHAR:
+            GOBJECT_GET (cam, prop, gchar, type);
+            break;
+        case G_TYPE_INT:
+            GOBJECT_GET (cam, prop, gint, type);
+            break;
+        case G_TYPE_ENUM:
+            GOBJECT_GET (cam, prop, gint, type);
+            break;
+        case G_TYPE_UINT:
+            GOBJECT_GET (cam, prop, guint, type);
+            break;
+        case G_TYPE_LONG:
+            GOBJECT_GET (cam, prop, glong, type);
+            break;
+        case G_TYPE_ULONG:
+            GOBJECT_GET (cam, prop, gulong, type);
+            break;
+        case G_TYPE_INT64:
+            GOBJECT_GET (cam, prop, gint64, type);
+            break;
+        case G_TYPE_UINT64:
+            GOBJECT_GET (cam, prop, guint64, type);
+            break;
+        case G_TYPE_FLOAT:
+            GOBJECT_GET (cam, prop, gfloat, type);
+            break;
+        case G_TYPE_DOUBLE:
+            GOBJECT_GET (cam, prop, gdouble, type);
+            break;
+        default:
+            //TRIGGER_TYPE and TRIGGER_SOURCE are not statically typed and can
+            //not be used in a switch statement...
+            if (type == UCA_TYPE_CAMERA_TRIGGER_SOURCE) {
+                GOBJECT_GET (cam, prop, gint, type);
+                break;
+            }
+
+            if (type ==  UCA_TYPE_CAMERA_TRIGGER_TYPE) {
+                GOBJECT_GET (cam, prop, gint, type);
+                break;
+            }
+
+            g_critical ("Type %s not handled! (GET)", g_type_name (type));
+            break;
+    }
+
+    return ret;
+}
+
+
+
+#define GVALUE_TO_GVARIANT(VALUE, FUNC, TYPE, GTYPE) { \
+    TYPE tmp; \
+    gchar *gvclass = g_malloc0 (2); \
+    gvclass[0] = gtype_to_gvariant_class (GTYPE); \
+    tmp = FUNC (VALUE); \
+    ret = g_variant_new (gvclass, tmp); \
+    g_free (gvclass); \
+}
+
+GVariant*
+variant_from_scalar (GValue *value)
+{
+    GVariant *ret = NULL;
+
+    GType type = G_VALUE_TYPE (value);
+
+    switch (type) {
+        case G_TYPE_BOOLEAN:
+            GVALUE_TO_GVARIANT (value, g_value_get_boolean, gboolean, type);
+            break;
+        case G_TYPE_CHAR:
+            GVALUE_TO_GVARIANT (value, g_value_get_char, gchar, type);
+            break;
+        case G_TYPE_INT:
+            GVALUE_TO_GVARIANT (value, g_value_get_int, gint, type);
+            break;
+        case G_TYPE_ENUM:
+            GVALUE_TO_GVARIANT (value, g_value_get_int, gint, type);
+            break;
+        case G_TYPE_UINT:
+            GVALUE_TO_GVARIANT (value, g_value_get_uint, guint, type);
+            break;
+        case G_TYPE_LONG:
+            GVALUE_TO_GVARIANT (value, g_value_get_long, glong, type);
+            break;
+        case G_TYPE_ULONG:
+            GVALUE_TO_GVARIANT (value, g_value_get_ulong, gulong, type);
+            break;
+        case G_TYPE_INT64:
+            GVALUE_TO_GVARIANT (value, g_value_get_int64, gint64, type);
+            break;
+        case G_TYPE_UINT64:
+            GVALUE_TO_GVARIANT (value, g_value_get_uint64, guint64, type);
+            break;
+        case G_TYPE_FLOAT:
+            GVALUE_TO_GVARIANT (value, g_value_get_float, gfloat, type);
+            break;
+        case G_TYPE_DOUBLE:
+            GVALUE_TO_GVARIANT (value, g_value_get_double, gdouble, type);
+            break;
+        default:
+            //TRIGGER_TYPE and TRIGGER_SOURCE are not statically typed and can
+            //not be used in a switch statement...
+            if (type == UCA_TYPE_CAMERA_TRIGGER_SOURCE) {
+                GVALUE_TO_GVARIANT (value, g_value_get_int, gint, type);
+                break;
+            }
+
+            if (type ==  UCA_TYPE_CAMERA_TRIGGER_TYPE) {
+                GVALUE_TO_GVARIANT (value, g_value_get_int, gint, type);
+                break;
+            }
+
+            g_critical ("Type %s not handled! (GET)", g_type_name (type));
+            break;
+    }
+
+    return ret;
+}
+
 
+gint
+property_id_from_name(const gchar* name)
+{
+    gint idx = 0;
+    gboolean found = FALSE;
+    for (;idx < N_BASE_PROPERTIES; ++idx) {
+        if (0 == g_strcmp0(name, uca_camera_props[idx])) {
+            found = TRUE;
+            break;
+        }
+    }
+    return found ? idx : -1;
+}
 
 #endif