Add high level client APIs for Samsung CAN DB 29/91029/3 accepted/tizen/ivi/20161011.235859 submit/tizen/20161011.071731
authorSangjung Woo <sangjung.woo@samsung.com>
Wed, 5 Oct 2016 08:29:42 +0000 (17:29 +0900)
committerSangjung Woo <sangjung.woo@samsung.com>
Tue, 11 Oct 2016 06:42:04 +0000 (15:42 +0900)
This patch adds the high level APIs for AMB client. CAN_OBJECT macro
easily makes specific CAN object data structures and its related functions.

Change-Id: I9b41ced7c32fa27ae70c4fe320979d7fad08f270
Signed-off-by: Sangjung Woo <sangjung.woo@samsung.com>
lib/client/CMakeLists.txt
lib/client/libamb-client.c
lib/client/libamb-client.h
lib/client/libamb-common.h [new file with mode: 0644]
lib/client/libamb-objects.h [new file with mode: 0644]
lib/client/libamb-util.h [new file with mode: 0644]
lib/client/test/test.c

index d698746..6d60fe2 100644 (file)
@@ -1,5 +1,5 @@
 set (client_src libamb-client.c)
-set (client_headers libamb-client.h)
+set (client_headers libamb-client.h libamb-util.h libamb-objects.h libamb-common.h)
 
 add_library(amb-client SHARED ${client_src})
 set_target_properties(amb-client PROPERTIES SOVERSION ${PROJECT_VERSION} COMPILE_FLAGS "-fvisibility=hidden")
index 38745e2..58cf8fd 100644 (file)
 #include <gio/gio.h>
 #include <errno.h>
 
+#include "libamb-common.h"
 #include "libamb-client.h"
 
-#ifndef EXPORT
-#  define EXPORT __attribute__((visibility("default")))
-#endif
-
-#if defined DEBUG
-#  define DEBUGOUT(fmt, ...) do { fprintf(stderr, fmt, __VA_ARGS__); } while(0);
-#else
-#  define DEBUGOUT(fmt,...)
-#endif /* DEBUG */
-
-
 #define AMB_BUS_NAME        "org.automotive.message.broker"
 #define AMB_INTERFACE_NAME  "org.automotive.Manager"
 #define DBUS_INTERFACE_NAME "org.freedesktop.DBus.Properties"
@@ -474,3 +464,8 @@ EXPORT int amb_unregister_property_changed_handler(gchar *objname, ZoneType zone
 
        return 0;
 }
+
+EXPORT void amb_release_data(void *retdata)
+{
+       g_free(retdata);
+}
index a4220ac..6f123c5 100644 (file)
@@ -52,7 +52,7 @@ typedef int ZoneType;
  *
  * @see amb_unregister_property_changed_handler(), amb_unregister_property_changed_handler()
  */
-typedef void (*AMB_PROPERTY_CHANGED_CALLBACK)(const gchar *objname, GVariant *data);
+typedef void (*AMB_PROPERTY_CHANGED_CALLBACK)(const gchar *objname, gpointer data);
 
 /**
  * primitive APIs
@@ -156,6 +156,16 @@ int amb_get_object_list(GList **objlist);
  */
 void amb_release_object_list(GList *objlist);
 
+/**
+ * Release allocated memory space from amb_get_OBJECT function that is
+ * generated by CAN_OBJECT macro
+ *
+ * @param[in] Vehicle OBJECT structure type generated by CAN_OBJECT macro
+ *
+ * @see CAN_OBJECT
+ */
+void amb_release_data(void *retdata);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/client/libamb-common.h b/lib/client/libamb-common.h
new file mode 100644 (file)
index 0000000..26616b2
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Automotive Message Broker Client Library
+ *
+ * Copyright (C) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License)
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LIBAMB_COMMON_H__
+#define __LIBAMB_COMMON_H__
+
+#ifndef EXPORT
+#  define EXPORT __attribute__((visibility("default")))
+#endif
+
+#if defined DEBUG
+#  define DEBUGOUT(fmt, ...) do { fprintf(stderr, fmt, __VA_ARGS__); } while(0);
+#else
+#  define DEBUGOUT(fmt,...)
+#endif /* DEBUG */
+
+#endif /* __LIBAMB_COMMON_H__ */
diff --git a/lib/client/libamb-objects.h b/lib/client/libamb-objects.h
new file mode 100644 (file)
index 0000000..c6377ac
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Automotive Message Broker Client Library
+ *
+ * Copyright (C) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License)
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LIBSAMSUNG_CAN_H__
+#define __LIBSAMSUNG_CAN_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "libamb-util.h"
+
+enum GearboxPositionDisplay{
+       PARKING = (1<<3) | (1<<1), // 10, 0x0A
+       DRIVE,                     // 11, 0x0B
+       NEUTRAL,
+       REVERSE,
+};
+
+CAN_OBJECT(VehicleOdometer, guint32, NULL);
+CAN_OBJECT(VehicleSpeed, guint16, Speed);
+CAN_OBJECT(GearboxPositionDisplay, guchar, NULL);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LIBSAMSUNG_CAN_H__ */
diff --git a/lib/client/libamb-util.h b/lib/client/libamb-util.h
new file mode 100644 (file)
index 0000000..5d4844a
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Automotive Message Broker Client Library
+ *
+ * Copyright (C) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License)
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LIBAMB_UTIL_H__
+#define __LIBAMB_UTIL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "libamb-common.h"
+#include "libamb-client.h"
+
+#define g_variant_get_guchar g_variant_get_byte
+#define g_variant_get_gint16 g_variant_get_int16
+#define g_variant_get_guint16 g_variant_get_uint16
+#define g_variant_get_gint32 g_variant_get_int32
+#define g_variant_get_guint32 g_variant_get_uint32
+#define g_variant_get_gint64 g_variant_get_int64
+#define g_variant_get_guint64 g_variant_get_uint64
+#define g_variant_get_gdouble g_variant_get_double
+
+/**
+ * Generate Custom CAN Object data structure and its related utility function.
+ *
+ * @param[in] CAN Object name
+ * @param[in] data type for CAN object
+ * @param[in] Alias name that is used in AMB. If it is NULL, then this value
+ * is ignored.
+ *
+ * @see amb_release_data()
+ */
+#define CAN_OBJECT(obj_name, value_type, alias_name) \
+       struct obj_name ## Type { \
+               gint32  Zone; \
+               gint32  ValueSequence; \
+               gdouble Time; \
+               value_type Value; \
+       }; \
+       int amb_get_ ## obj_name ## _with_zone(struct obj_name ## Type **retobj, int zone) \
+       { \
+               GVariant *variant; \
+               GVariantIter *iter; \
+               gchar *key; \
+               GVariant *value; \
+               GVariant *tmp; \
+               int ret; \
+               struct obj_name ## Type *retdata = NULL; \
+               \
+               retdata = g_malloc0(sizeof(*retdata)); \
+               if (!retdata) { \
+                       return -ENOMEM; \
+               } \
+               ret = amb_get_property_all_with_zone(&variant, #obj_name, zone); \
+               if (ret < 0) { \
+                       return ret; \
+               } \
+               \
+               g_variant_get(variant, "(a{sv})", &iter); \
+               while(g_variant_iter_loop(iter, "{sv}", &key, &value)) { \
+                       if (!g_strcmp0(key, "Zone")) { \
+                               g_variant_get(value, "v", &tmp); \
+                               retdata->Zone = g_variant_get_int32(tmp); \
+                               g_variant_unref(tmp); \
+                       } else if (!g_strcmp0(key, "ValueSequence") || !g_strcmp0(key, #alias_name "Sequence")) { \
+                               g_variant_get(value, "v", &tmp); \
+                               retdata->ValueSequence = g_variant_get_int32(tmp); \
+                               g_variant_unref(tmp); \
+                       } else if (!g_strcmp0(key, "Time")) { \
+                               g_variant_get(value, "v", &tmp); \
+                               retdata->Time = g_variant_get_double(tmp); \
+                               g_variant_unref(tmp); \
+                       } else if (!g_strcmp0(key, "Value") || !g_strcmp0(key, #alias_name)) { \
+                               g_variant_get(value, "v", &tmp); \
+                               retdata->Value = g_variant_get_ ## value_type(tmp); \
+                               g_variant_unref(tmp); \
+                       } \
+               } \
+               \
+               g_variant_iter_free(iter); \
+               amb_release_property_all_with_zone(variant); \
+               *retobj = retdata; \
+               return 0; \
+       } \
+       \
+       int amb_convert_ ## obj_name ## Type (gpointer data, struct obj_name ## Type *retdata) \
+       { \
+               GVariantIter *iter; \
+               gchar *key; \
+               GVariant *value; \
+               GVariant *gdata; \
+               \
+               gdata = (GVariant *)data; \
+               g_variant_get(gdata, "a{sv}", &iter); \
+               while(g_variant_iter_loop(iter, "{sv}", &key, &value)) { \
+                       if (!g_strcmp0(key, "Zone")) { \
+                               g_variant_get(value, "i", &retdata->Zone); \
+                       } else if (!g_strcmp0(key, "ValueSequence") || !g_strcmp0(key, #alias_name "Sequence")) { \
+                               g_variant_get(value, "i", &retdata->ValueSequence); \
+                       } else if (!g_strcmp0(key, "Time")) { \
+                               g_variant_get(value, "d", &retdata->Time); \
+                       } else if (!g_strcmp0(key, "Value") || !g_strcmp0(key, #alias_name)) { \
+                               retdata->Value = g_variant_get_ ## value_type(value); \
+                       } \
+               } \
+               g_variant_iter_free(iter); \
+               return 0; \
+       }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LIBAMB_UTIL_H__ */
index 19b2f6d..bce4a80 100644 (file)
@@ -1,8 +1,9 @@
 #include <stdio.h>
 
 #include <libamb-client.h>
+#include <libamb-objects.h>
 
-void test_get_object_list()
+static void test_get_object_list()
 {
        GList *objlist;
        GList *item;
@@ -26,7 +27,7 @@ void test_get_object_list()
        amb_release_object_list(objlist);
 }
 
-void test_get_property_all(const char *obj_name)
+static void test_get_property_all(const char *obj_name)
 {
        GList *retlist;
        GList *item;
@@ -50,7 +51,7 @@ void test_get_property_all(const char *obj_name)
        amb_release_property_all(retlist);
 }
 
-void test_get_property_all_with_zone(const char *obj_name, int zone)
+static void test_get_property_all_with_zone(const char *obj_name, int zone)
 {
        GVariant *ret;
        int r;
@@ -71,7 +72,7 @@ void test_get_property_all_with_zone(const char *obj_name, int zone)
        amb_release_property_all_with_zone(ret);
 }
 
-void test_set_property(const char *obj_name, const char *prop_name, int zone, GVariant *value)
+static void test_set_property(const char *obj_name, const char *prop_name, int zone, GVariant *value)
 {
        GVariant *ret;
        gchar *s;
@@ -97,14 +98,15 @@ void test_set_property(const char *obj_name, const char *prop_name, int zone, GV
        amb_release_property_all_with_zone(ret);
 }
 
-static void signal_handler(const gchar *objname, GVariant *data)
+static void signal_handler(const gchar *objname, gpointer data)
 {
        gchar *s;
+       GVariant *gdata = (GVariant *)data;
 
        if (!data)
                return ;
 
-       s = g_variant_print(data, TRUE);
+       s = g_variant_print(gdata, TRUE);
        g_print("== signal_handler: %s\n", objname);
        g_print("%s\n", s);
 
@@ -116,6 +118,8 @@ static gboolean timer_callback(gpointer d)
        int rc;
        gchar *objname = (gchar *)d;
 
+        fprintf(stderr, "Enter %s(): %s\n", __func__, objname);
+
        rc = amb_unregister_property_changed_handler(objname, 0);
        if (rc != 0) {
                 fprintf(stderr, "Fail to amb_unregister_property_changed_handler(): %s\n", objname);
@@ -143,10 +147,125 @@ void test_signal_listen(gchar *objname, ZoneType zone)
        g_main_loop_unref(loop);
 }
 
+static void VehicleOdometer_handler(const gchar *objname, gpointer data)
+{
+       struct VehicleOdometerType retdata;
+
+       if (!data)
+               return ;
+
+       amb_convert_VehicleOdometerType(data, &retdata);
+
+       fprintf(stderr, " == VehicleOdometer ==\n");
+       fprintf(stderr, "    Zone: %d\n", retdata.Zone);
+       fprintf(stderr, "    Value: %d\n", retdata.Value);
+       fprintf(stderr, "    ValueSequence: %d\n", retdata.ValueSequence);
+       fprintf(stderr, "    Time: %f\n", retdata.Time);
+}
+
+static void test_VehicleOdometer_listen()
+{
+       GMainLoop *loop;
+       int rc;
+
+       rc = amb_register_property_changed_handler("VehicleOdometer", 0,
+                       (AMB_PROPERTY_CHANGED_CALLBACK)VehicleOdometer_handler);
+       if (rc != 0) {
+                fprintf(stderr, "Fail to amb_register_property_changed_handler(): %s\n", "VehicleOdometer");
+                return ;
+       }
+
+       g_timeout_add_seconds(10, timer_callback, "VehicleOdometer");
+
+       loop = g_main_loop_new(NULL, FALSE);
+       g_main_loop_run(loop);
+
+       g_main_loop_unref(loop);
+}
+
+static void test_samsungcan_GearboxPosition()
+{
+       struct GearboxPositionDisplayType *p;
+       int ret = amb_get_GearboxPositionDisplay_with_zone(&p, None);
+       if (ret != 0) {
+               fprintf(stderr, "Fail to %s\n", __func__);
+               return ;
+       }
+
+       fprintf(stderr, " == GearboxPosition ==\n");
+       fprintf(stderr, "    Time: %f\n", p->Time);
+       fprintf(stderr, "    Zone: %d\n", p->Zone);
+       fprintf(stderr, "    ValueSequence: %d\n", p->ValueSequence);
+       fprintf(stderr, "    Value: ");
+       switch(p->Value) {
+       case PARKING:
+               fprintf(stderr, "PARKING\n");
+               break;
+       case DRIVE:
+               fprintf(stderr, "DRIVE\n");
+               break;
+       case NEUTRAL:
+               fprintf(stderr, "NEUTRAL\n");
+               break;
+       case REVERSE:
+               fprintf(stderr, "REVERSE\n");
+               break;
+       default:
+               fprintf(stderr, "%u (Error)\n", p->Value);
+               break;
+       }
+
+       amb_release_data(p);
+       return ;
+}
+
+static void test_samsungcan_VehicleSpeed()
+{
+       struct VehicleSpeedType *p;
+       int ret = amb_get_VehicleSpeed_with_zone(&p, None);
+       if (ret != 0) {
+               fprintf(stderr, "Fail to %s\n", __func__);
+               return ;
+       }
+       fprintf(stderr, " == VehicleSpeed ==\n");
+       fprintf(stderr, "    Zone: %d\n", p->Zone);
+       fprintf(stderr, "    Value: %d\n", p->Value);
+       fprintf(stderr, "    ValueSequence: %d\n", p->ValueSequence);
+       fprintf(stderr, "    Time: %f\n", p->Time);
+
+       amb_release_data(p);
+       return ;
+}
+
+static void test_samsungcan_VehicleOdometer()
+{
+       struct VehicleOdometerType *p;
+       int ret = amb_get_VehicleOdometer_with_zone(&p, None);
+       if (ret != 0) {
+               fprintf(stderr, "Fail to %s\n", __func__);
+               return ;
+       }
+       fprintf(stderr, " == VehicleOdometer ==\n");
+       fprintf(stderr, "    Zone: %d\n", p->Zone);
+       fprintf(stderr, "    Value: %d\n", p->Value);
+       fprintf(stderr, "    ValueSequence: %d\n", p->ValueSequence);
+       fprintf(stderr, "    Time: %f\n", p->Time);
+
+       amb_release_data(p);
+       return ;
+}
+
 int main()
 {
        test_get_object_list();
 
+       test_samsungcan_VehicleOdometer();
+       test_samsungcan_VehicleSpeed();
+       test_samsungcan_GearboxPosition();
+
+       test_VehicleOdometer_listen();
+
+#ifdef EXAMPLE_PLUGIN
        test_get_property_all("ClimateControl");
        test_get_property_all("VehicleSpeed");
 
@@ -156,5 +275,8 @@ int main()
 
        test_signal_listen("VehicleSpeed", 0);
 
+       test_samsungcan_GearboxPosition();
+#endif
+
        return 0;
 }