summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt107
-rw-r--r--src/af-steering-wheel-binding.c426
-rw-r--r--src/af-steering-wheel-binding.h35
-rw-r--r--src/bind_event.c114
-rw-r--r--src/bind_event.h33
-rw-r--r--src/export.map1
-rw-r--r--src/icon.pngbin0 -> 10651 bytes
-rw-r--r--src/js_raw.c174
-rw-r--r--src/js_raw.h27
-rw-r--r--src/js_signal_event.c328
-rw-r--r--src/js_signal_event.h25
-rw-r--r--src/prop_info.c103
-rw-r--r--src/prop_info.h70
-rw-r--r--src/prop_search.c128
-rw-r--r--src/prop_search.h27
-rw-r--r--src/steering_wheel_json.c346
-rw-r--r--src/steering_wheel_json.h27
17 files changed, 1971 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..71168a3
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,107 @@
+#
+# Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+#
+# 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.
+#
+
+cmake_minimum_required(VERSION 2.8)
+
+###########################################################################
+
+link_libraries(-Wl,--as-needed -Wl,--gc-sections)
+
+add_compile_options(-Wall -Wextra -Wconversion)
+add_compile_options(-Wno-unused-parameter) # frankly not using a parameter does it care?
+add_compile_options(-Werror=maybe-uninitialized)
+add_compile_options(-Werror=implicit-function-declaration)
+add_compile_options(-ffunction-sections -fdata-sections)
+add_compile_options(-Wl,--as-needed -Wl,--gc-sections)
+add_compile_options(-fPIC)
+
+set(CMAKE_C_FLAGS_PROFILING "-g -O0 -pg -Wp,-U_FORTIFY_SOURCE")
+set(CMAKE_C_FLAGS_DEBUG "-g -O0 -ggdb -Wp,-U_FORTIFY_SOURCE")
+set(CMAKE_C_FLAGS_RELEASE "-g -O2")
+set(CMAKE_C_FLAGS_CCOV "-g -O2 --coverage")
+set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/package/root/lib)
+
+###########################################################################
+
+include(FindPkgConfig)
+
+#*<NESSARY> pkg_check_modules(EXTRAS REQUIRED json-c libsystemd afb-daemon)
+#pkg_check_modules(EXTRAS REQUIRED json-c)
+add_compile_options(${EXTRAS_CFLAGS})
+include_directories(${EXTRAS_INCLUDE_DIRS})
+link_libraries(${EXTRAS_LIBRARIES})
+
+message(STATUS "${EXTRAS_CFLAGS}")
+message(STATUS "${EXTRAS_INCLUDE_DIRS}")
+message(STATUS "${EXTRAS_LIBRARIES}")
+message(STATUS "${EXTRAS_LIBRARY_DIRS}")
+
+pkg_check_modules(GIO_UNIX REQUIRED gio-unix-2.0)
+include_directories(${GIO_UNIX_INCLUDE_DIRS})
+link_libraries(${GIO_UNIX_LIBRARIES})
+message(STATUS "${GIO_UNIX_INCLUDE_DIRS}")
+
+#set(VAR "")
+#get_target_property(VAR target INCLUDE_DIRECTORIES)
+#message(STATUS "${VAR}")
+
+###########################################################################
+# the binding for afb
+
+message(STATUS "Creation af-steering-wheel-binding for AFB-DAEMON")
+
+###############################################################
+#pkg_get_variable(afb_binding_install_dir afb-daemon binding_install_dir)
+
+#*<NESSARY>
+#* execute_process(
+#* COMMAND pkg-config --variable binding_install_dir afb-daemon
+#* OUTPUT_VARIABLE afb_binding_install_dir OUTPUT_STRIP_TRAILING_WHITESPACE
+#* )
+
+###############################################################
+add_library(af-steering-wheel-binding MODULE af-steering-wheel-binding.c bind_event.c steering_wheel_json.c prop_info.c prop_search.c js_signal_event.c js_raw.c)
+set_target_properties(af-steering-wheel-binding PROPERTIES
+ PREFIX ""
+ LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/export.map"
+)
+
+#add_custom_command(TARGET af-steering-wheel-binding POST_BUILD
+# COMMAND cp -f ${CMAKE_CURRENT_SOURCE_DIR}/config.xml ${CMAKE_CURRENT_SOURCE_DIR}/steering_wheel.json ${CMAKE_CURRENT_SOURCE_DIR}/icon.png ${PROJECT_BINARY_DIR}/package/root
+# COMMAND cp -f ${CMAKE_CURRENT_SOURCE_DIR}/steering_wheel_map.json ${CMAKE_CURRENT_SOURCE_DIR}/gear_shift_para.json ${PROJECT_BINARY_DIR}/package/root)
+
+add_custom_target(package DEPENDS ${PROJECT_BINARY_DIR}/package/root
+ COMMAND wgtpkg-pack -f -o ${PROJECT_BINARY_DIR}/package/${PROJECT_NAME}.wgt ${PROJECT_BINARY_DIR}/package/root)
+
+#*<NESSARY> install(TARGETS af-canivi-binding LIBRARY DESTINATION ${afb_binding_install_dir})
+# <OR following packaging>
+##############################################################
+# WGT packaging
+
+#message(STATUS "Creation of af-canivi.wgt package for AppFW")
+##############################################################
+#configure_file(config.xml.in config.xml)
+#add_custom_command(
+# OUTPUT af-canivi.wgt
+# COMMAND rm -rf package
+# COMMAND mkdir -p package/libs package/htdocs
+# COMMAND cp config.xml package/
+# COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_ICON} package/icon.png
+# COMMAND cp af-canivi-binding.so package
+# COMMAND wgtpkg-pack -f -o af-canivi.wgt package
+#)
+#add_custom_target(widget ALL DEPENDS af-canivi.wgt)
+
diff --git a/src/af-steering-wheel-binding.c b/src/af-steering-wheel-binding.c
new file mode 100644
index 0000000..908bf71
--- /dev/null
+++ b/src/af-steering-wheel-binding.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <math.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <json-c/json.h>
+
+#include <systemd/sd-event.h>
+
+#include "af-steering-wheel-binding.h"
+#include "bind_event.h"
+#include "steering_wheel_json.h"
+#include "prop_search.h"
+#include "js_raw.h"
+
+#define ENABLE_EVENT_DROP
+
+struct wheel_conf
+{
+ char *devname;
+};
+
+int notify_property_changed(struct prop_info_t *property_info)
+{
+ struct bind_event_t *event;
+
+ //NOTICEMSG("notify_property_changed %s", property_info->name);
+ event = get_event(property_info->name);
+ if (event == NULL)
+ {
+ DBGMSG("<IGNORE event>: event(\"%s\") is not subscribed", property_info->name);
+ return 1;
+ }
+
+ if (afb_event_is_valid(event->event))
+ {
+ int recved_client;
+
+ recved_client = afb_event_push(event->event, property2json(property_info));
+ if(recved_client < 1)
+ {
+ if(recved_client == 0)
+ {
+ DBGMSG("event(\"%s\") is no client.", property_info->name);
+#ifdef ENABLE_EVENT_DROP
+ /* Drop event */
+ remove_event(property_info->name);
+#endif
+ }
+ else
+ {
+ ERRMSG("count of clients that received the event : %d",recved_client);
+ }
+
+ return 1;
+ } /* else (1 <= recved_lient)
+ * NORMAL
+ */
+ }
+ else
+ {
+ ERRMSG("event(\"%s\") is invalid. don't adb_event_push()", property_info->name);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int connection(struct wheel_conf *conf)
+{
+ int js;
+ int ret;
+ sd_event_source *source;
+
+ js = js_open(conf->devname);
+ if (js < 0)
+ {
+ js_close(js);
+ ERRMSG("can't connect to joy stick, the event loop failed");
+ return 0;
+ }
+
+ ret = sd_event_add_io(
+ afb_daemon_get_event_loop(),
+ &source,
+ js,
+ EPOLLIN,
+ on_event, NULL);
+ if (ret < 0)
+ {
+ js_close(js);
+ ERRMSG("can't add event, the event loop failed");
+ return 0;
+ }
+
+ NOTICEMSG("connect to JS(%s), event loop started",conf->devname);
+
+ return 0;
+}
+
+/***************************************************************************************/
+/** **/
+/** **/
+/** SECTION: BINDING VERBS IMPLEMENTATION **/
+/** **/
+/** **/
+/***************************************************************************************/
+/**
+ * get method.
+ */
+static void get(struct afb_req req)
+{
+
+}
+
+///**
+// * set method.
+// */
+//static void set(struct afb_req req)
+//{
+//
+//}
+
+/**
+ * list method.
+ */
+static struct json_object *tmplists;
+
+static void _listup_properties(struct prop_info_t *property_info)
+{
+ if (property_info->name == NULL)
+ {
+ return;
+ }
+ else
+ {
+ json_object_array_add(tmplists, json_object_new_string(property_info->name));
+ }
+}
+
+static void list(struct afb_req req)
+{
+ if (tmplists != NULL)
+ {
+ json_object_put(tmplists);
+ }
+ tmplists = json_object_new_array();
+ if (tmplists == NULL)
+ {
+ ERRMSG("not enough memory");
+ afb_req_fail(req,"not enough memory", NULL);
+ return;
+ }
+ (void)canid_walker(_listup_properties);
+ afb_req_success(req, tmplists, NULL);
+}
+
+/**
+ * subscribe method.
+ */
+static int subscribe_all(struct afb_req req, struct json_object *apply);
+
+static int subscribe_signal(struct afb_req req, const char *name, struct json_object *apply)
+{
+ struct bind_event_t *event;
+
+ if(strcmp(name, "*") == 0)
+ {
+ return subscribe_all(req, apply);
+ }
+
+ event = get_event(name);
+ if (event == NULL)
+ {
+ event = register_event(name);
+ if (event == NULL)
+ {
+ ERRMSG("register event failed: %s", name);
+ return 1;
+ }
+ }
+ else
+ {
+ DBGMSG("subscribe event: \"%s\" alrady exist", name);
+ }
+
+ if (afb_req_subscribe(req, event->event) != 0)
+ {
+ ERRMSG("afb_req_subscrive() is failed.");
+ return 1;
+ }
+
+ json_object_object_add(apply, event->name, property2json(event->raw_info));
+
+ return 0;
+}
+
+static int subscribe_all(struct afb_req req, struct json_object *apply)
+{
+ int i;
+ int nProp;
+ const char **list = getSupportPropertiesList(&nProp);
+ int err = 0;
+ for(i = 0; i < nProp; i++)
+ err += subscribe_signal(req, list[i], apply);
+
+ return err;
+}
+
+static void subscribe(struct afb_req req)
+{
+ struct json_object *apply;
+ int err = 0;
+ const char *event;
+
+ event = afb_req_value(req, "event");
+ if (event == NULL)
+ {
+ ERRMSG("Unknwon subscrive event args");
+ afb_req_fail(req, "error", NULL);
+ return;
+ }
+ apply = json_object_new_object();
+ err = subscribe_signal(req, event, apply);
+
+ if (!err)
+ {
+ afb_req_success(req, apply, NULL);
+ }
+ else
+ {
+ json_object_put(apply);
+ afb_req_fail(req, "error", NULL);
+ }
+}
+
+/**
+ * unsubscribe method.
+ */
+
+static int unsubscribe_all(struct afb_req req);
+
+static int unsubscribe_signal(struct afb_req req, const char *name)
+{
+ struct bind_event_t *event;
+ if(strcmp(name, "*") == 0)
+ {
+ return unsubscribe_all(req);
+ }
+
+ event = get_event(name);
+ if (event == NULL)
+ {
+ ERRMSG("not subscribed event \"%s\"", name);
+ return 0; /* Alrady unsubscribed */
+ }
+ if (afb_req_unsubscribe(req, event->event) != 0)
+ {
+ ERRMSG("afb_req_subscrive() is failed.");
+ return 1;
+ }
+
+ return 0;
+}
+
+static int unsubscribe_all(struct afb_req req)
+{
+ int i;
+ int nProp;
+ const char **list = getSupportPropertiesList(&nProp);
+ int err = 0;
+ for(i = 0; i < nProp; i++)
+ {
+ err += unsubscribe_signal(req, list[i]);
+ }
+
+ return err;
+}
+
+static void unsubscribe(struct afb_req req)
+{
+ struct json_object *args, *val;
+ int n,i;
+ int err = 0;
+
+ args = afb_req_json(req);
+ if ((args == NULL) || !json_object_object_get_ex(args, "event", &val))
+ {
+ err = unsubscribe_all(req);
+ }
+ else if (json_object_get_type(val) != json_type_array)
+ {
+ err = unsubscribe_signal(req, json_object_get_string(val));
+ }
+ else
+ {
+ struct json_object *ent;
+ n = json_object_array_length(val);
+ for (i = 0; i < n; i++)
+ {
+ ent = json_object_array_get_idx(val,i);
+ err += unsubscribe_signal(req, json_object_get_string(ent));
+ }
+ }
+
+ if (!err)
+ afb_req_success(req, NULL, NULL);
+ else
+ afb_req_fail(req, "error", NULL);
+}
+
+/*
+ * parse configuration file (steering_wheel.json)
+ */
+static int init_conf(int fd_conf, struct wheel_conf *conf)
+{
+#define CONF_FILE_MAX (1024)
+ char filebuf[CONF_FILE_MAX];
+ json_object *jobj;
+
+ memset(filebuf,0, sizeof(filebuf));
+ FILE *fp = fdopen(fd_conf,"r");
+ if (fp == NULL)
+ {
+ ERRMSG("canno read configuration file(steering_wheel.json)");
+ return -1;
+ }
+
+ fread(filebuf, 1, sizeof(filebuf), fp);
+ fclose(fp);
+
+ jobj = json_tokener_parse(filebuf);
+ if (jobj == NULL)
+ {
+ ERRMSG("json: Invalid steering_wheel.json format");
+ return -1;
+ }
+ json_object_object_foreach(jobj, key, val)
+ {
+ if (strcmp(key,"dev_name") == 0)
+ {
+ conf->devname = strdup(json_object_get_string(val));
+ }
+ else if (strcmp(key,"wheel_map") == 0)
+ {
+ wheel_define_init(json_object_get_string(val));
+ }
+ else if (strcmp(key,"gear_para") == 0)
+ {
+ wheel_gear_para_init(json_object_get_string(val));
+ }
+ }
+ json_object_put(jobj);
+
+ return 0;
+}
+
+static int init()
+{
+ NOTICEMSG("init");
+
+ int fd_conf;
+ struct wheel_conf conf;
+ fd_conf = afb_daemon_rootdir_open_locale("steering_wheel.json", O_RDONLY, NULL);
+ if (fd_conf < 0)
+ {
+ ERRMSG("wheel configuration (steering_wheel.json) is not access");
+ return -1;
+ }
+ if (init_conf(fd_conf, &conf))
+ {
+ return -1;
+ }
+ return connection(&conf);
+}
+
+/*
+ * array of the verbs exported to afb-daemon
+ */
+static const struct afb_verb_v2 binding_verbs[] =
+{
+ /* VERB'S NAME SESSION MANAGEMENT FUNCTION TO CALL Authorization */
+ { .verb= "get", .session= AFB_SESSION_NONE, .callback= get, .info = "get", .auth = NULL },
+// { .name= "set", .session= AFB_SESSION_NONE, .callback= set, .auth = NULL },
+ { .verb= "list", .session= AFB_SESSION_NONE, .callback= list, .info = "list", .auth = NULL },
+ { .verb= "subscribe", .session= AFB_SESSION_NONE, .callback= subscribe, .info = "subscribe", .auth = NULL },
+ { .verb= "unsubscribe", .session= AFB_SESSION_NONE, .callback= unsubscribe, .info = "unsubscribe", .auth = NULL },
+ { .verb= NULL } /* marker for end of the array */
+};
+
+/*
+ * description of the binding for afb-daemon
+ */
+const struct afb_binding_v2 afbBindingV2 =
+{
+ .api = "steering-wheel",
+ .specification = NULL,
+ .verbs = binding_verbs, /* the array describing the verbs of the API */
+ .preinit = NULL,
+ .init = init,
+ .onevent = NULL,
+ .noconcurrency = 1
+};
diff --git a/src/af-steering-wheel-binding.h b/src/af-steering-wheel-binding.h
new file mode 100644
index 0000000..1b7323c
--- /dev/null
+++ b/src/af-steering-wheel-binding.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * 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 _AF_WHEEL_BINDING_H_
+#define _AF_WHEEL_BINDING_H_
+
+#define AFB_BINDING_VERSION 2
+#include <afb/afb-binding.h>
+
+#include "prop_info.h"
+
+#if !defined(NO_BINDING_VERBOSE_MACRO)
+#define ERRMSG(msg, ...) AFB_ERROR(msg,##__VA_ARGS__)
+#define WARNMSG(msg, ...) AFB_WARNING(msg,##__VA_ARGS__)
+#define DBGMSG(msg, ...) AFB_DEBUG(msg,##__VA_ARGS__)
+#define INFOMSG(msg, ...) AFB_INFO(msg,##__VA_ARGS__)
+#define NOTICEMSG(msg, ...) AFB_NOTICE(msg,##__VA_ARGS__)
+#endif
+
+extern int notify_property_changed(struct prop_info_t *property_info);
+
+#endif
diff --git a/src/bind_event.c b/src/bind_event.c
new file mode 100644
index 0000000..01887cd
--- /dev/null
+++ b/src/bind_event.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <search.h>
+
+#include "af-steering-wheel-binding.h"
+#include "bind_event.h"
+#include "prop_search.h"
+
+static void *bind_event_root = NULL;
+
+static int compare(const void *pa, const void *pb)
+{
+ struct bind_event_t *a = (struct bind_event_t *)pa;
+ struct bind_event_t *b = (struct bind_event_t *)pb;
+ return strcmp(a->name, b->name);
+}
+
+struct bind_event_t *get_event(const char *name)
+{
+ struct bind_event_t key;
+ void *ent;
+
+ /*
+ * search subscribed event.
+ */
+ key.name = name;
+ ent = tfind(&key, &bind_event_root, compare);
+ if (ent != NULL)
+ return *(struct bind_event_t **)ent; /* found */
+ return NULL; /* not found */
+}
+
+struct bind_event_t *register_event(const char *name)
+{
+ struct bind_event_t *evt;
+ struct prop_info_t *property_info;
+ void *ent;
+
+ property_info = getProperty_dict(name);
+ if (property_info == NULL)
+ {
+ ERRMSG("NOT Supported property:\"%s\".", name);
+ return NULL;
+ }
+ evt = calloc(1, sizeof(*evt));
+ if (evt == NULL)
+ {
+ ERRMSG("not enough memory");
+ return NULL;
+ }
+
+ evt->event = afb_daemon_make_event(property_info->name);
+ if (!afb_event_is_valid(evt->event))
+ {
+ free(evt);
+ ERRMSG("afb_daemon_make_event failed");
+ return NULL;
+ }
+
+ evt->name = property_info->name;
+ evt->raw_info = property_info;
+ ent = tsearch(evt, &bind_event_root, compare);
+ if (ent == NULL)
+ {
+ ERRMSG("not enough memory");
+ afb_event_drop(evt->event);
+ free(evt);
+ return NULL;
+ }
+#ifdef DEBUG /* double check */
+ if ((*(struct bind_event_t **)ent) != evt)
+ ERRMSG("event \"%s\" is duplicate?", property_info->name);
+#endif
+
+ return evt;
+}
+
+int remove_event(const char *name)
+{
+ struct bind_event_t *dnode;
+ struct bind_event_t key;
+ void *p;
+
+ key.name = name;
+ p = tfind(&key, &bind_event_root, compare);
+ if (p == NULL)
+ {
+ return 0;
+ }
+ dnode = *(struct bind_event_t **)p;
+ afb_event_drop(dnode->event);
+ tdelete(&key, &bind_event_root, compare);
+ free(dnode);
+
+ return 0;
+}
diff --git a/src/bind_event.h b/src/bind_event.h
new file mode 100644
index 0000000..5e44a5b
--- /dev/null
+++ b/src/bind_event.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * 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 _BIND_EVENT_H_
+#define _BIND_EVENT_H_
+
+#include "prop_info.h"
+
+struct bind_event_t {
+ const char *name; /* name of the event : IvI Property-Name */
+ struct afb_event event; /* the event for the binder */
+ struct prop_info_t *raw_info;
+};
+
+extern struct bind_event_t *get_event(const char *name);
+extern struct bind_event_t *register_event(const char *name);
+extern int remove_event(const char *name);
+
+#endif
+
diff --git a/src/export.map b/src/export.map
new file mode 100644
index 0000000..ee2f413
--- /dev/null
+++ b/src/export.map
@@ -0,0 +1 @@
+{ global: afbBindingV*; local: *; };
diff --git a/src/icon.png b/src/icon.png
new file mode 100644
index 0000000..def888b
--- /dev/null
+++ b/src/icon.png
Binary files differ
diff --git a/src/js_raw.c b/src/js_raw.c
new file mode 100644
index 0000000..5541162
--- /dev/null
+++ b/src/js_raw.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <alloca.h>
+
+#include <linux/input.h>
+#include <linux/joystick.h>
+
+#include "af-steering-wheel-binding.h"
+#include "js_raw.h"
+#include "js_signal_event.h"
+
+#define JSNAMELEN 128
+
+static int *axis;
+static char *button;
+
+int js_signal_read(int fd)
+{
+ ssize_t size;
+ struct js_event jsEvent;
+ int rc = 0;
+
+ size = read(fd, &jsEvent, sizeof(struct js_event));
+ if(size != 0)
+ {
+ switch (jsEvent.type & ~JS_EVENT_INIT)
+ {
+ case JS_EVENT_BUTTON:
+ button[jsEvent.number] = (char)jsEvent.value;
+ //NOTICEMSG("JS_EVENT_BUTTON %d\n", button[jsEvent.number]);
+ newButtonValue(jsEvent.number, jsEvent.value);
+ break;
+ case JS_EVENT_AXIS:
+ axis[jsEvent.number] = jsEvent.value;
+ //NOTICEMSG("JS_EVENT_AXIS %d\n", axis[jsEvent.number]);
+ newAxisValue(jsEvent.number, jsEvent.value);
+ break;
+ default:
+ break;
+ }
+
+ rc = 0;
+ }
+ else
+ {
+ rc = -1;
+ }
+
+ return rc;
+}
+
+int on_event(sd_event_source *s, int fd, uint32_t revents, void *userdata)
+{
+ if ((revents & EPOLLIN) != 0)
+ {
+ //NOTICEMSG("on_event!\n");
+ int rc = 0;
+
+ rc = js_signal_read(fd);
+ if(rc == -1)
+ {
+ ERRMSG("JS Frame Read failed");
+
+ return -1;
+ }
+ }
+ if ((revents & (EPOLLERR|EPOLLRDHUP|EPOLLHUP)) != 0)
+ {
+ /* T.B.D
+ * if error or hungup */
+ ERRMSG("Error or Hunup: rvent=%08x", revents);
+ }
+
+ return 0;
+}
+
+int js_open(const char *devname)
+{
+ unsigned char numAxes = 0;
+ unsigned char numButtons = 0;
+ int version = 0;
+ int fd;
+ char name[JSNAMELEN] = "Unknown";
+
+ struct js_corr cal[6];
+ int i, j;
+ unsigned int calData[36] =
+ {
+ 1, 0, 8191, 8192, 65542, 65534,
+ 1, 0, 127, 128, 4227201, 4194176,
+ 1, 0, 127, 128, 4227201, 4194176,
+ 1, 0, 127, 128, 4227201, 4194176,
+ 1, 0, 0, 0, 536854528, 536854528,
+ 1, 0, 0, 0, 536854528, 536854528
+ };
+
+ if ((fd = open(devname, O_RDONLY)) < 0)
+ {
+ return -1;
+ }
+
+ ioctl(fd, JSIOCGVERSION, &version);
+ ioctl(fd, JSIOCGAXES, &numAxes);
+ ioctl(fd, JSIOCGBUTTONS, &numButtons);
+ ioctl(fd, JSIOCGNAME(JSNAMELEN), name);
+
+ for (i = 0; i < 6; i++)
+ {
+ int k = 0;
+ cal[i].type = (__u16)calData[(i*6)+k];
+ k++;
+ cal[i].prec = (__s16)calData[(i*6)+k];
+ k++;
+
+ for(j = 0; j < 4; j++)
+ {
+ cal[i].coef[j] = (__s32)calData[(i*6)+k];
+ k++;
+ }
+ }
+
+ if (ioctl(fd, JSIOCSCORR, &cal) < 0)
+ {
+ return -1;
+ }
+
+ axis = (int *)calloc(numAxes, sizeof(int));
+ button = (char *)calloc(numButtons, sizeof(char));
+#if 0
+ gis = g_unix_input_stream_new(fd, TRUE);
+ if(gis == NULL)
+ {
+ ERRMSG("g_unix_input_stream_new() failed!");
+ }
+ else
+ {
+ NOTICEMSG("g_unix_input_stream_new() succeed!");
+ }
+ g_input_stream_read_async(gis, &jsEvent, sizeof(struct js_event), G_PRIORITY_DEFAULT, NULL, &readCallback, NULL);
+#endif
+
+ return fd;
+}
+
+void js_close(int js)
+{
+ if (js < 0)
+ {
+ return;
+ }
+
+ close(js);
+}
diff --git a/src/js_raw.h b/src/js_raw.h
new file mode 100644
index 0000000..79db219
--- /dev/null
+++ b/src/js_raw.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * 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 _JS_RAW_H_
+#define _JS_RAW_H_
+
+#include <sys/time.h>
+#include <systemd/sd-event.h>
+
+extern int on_event(sd_event_source *s, int fd, uint32_t revents, void *userdata);
+extern int js_open(const char *devname);
+extern void js_close(int js);
+
+#endif
diff --git a/src/js_signal_event.c b/src/js_signal_event.c
new file mode 100644
index 0000000..712d51c
--- /dev/null
+++ b/src/js_signal_event.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <alloca.h>
+
+#include "af-steering-wheel-binding.h"
+#include "js_signal_event.h"
+
+// Axis
+#define JS_STEERING 0
+#define JS_THROTTLE 2
+#define JS_BRAKE 3
+// Button
+#define JS_LEFT_PADDLE_SHIFTER 4
+#define JS_RIGHT_PADDLE_SHIFTER 5
+#define JS_TURN_SIGNAL_RIGHT 6
+#define JS_TURN_SIGNAL_LEFT 7
+
+// Property string
+#define VEHICLE_SPEED "VehicleSpeed"
+#define ENGINE_SPEED "EngineSpeed"
+#define ACCELERATOR_PEDAL_POSITION "AcceleratorPedalPosition"
+#define TRANSMISSION_GEAR_INFO "TransmissionGearInfo"
+#define TRANSMISSION_MODE "TransmissionMode"
+#define STEERING_WHEEL_ANGLE "SteeringWheelAngle"
+#define TURN_SIGNAL_STATUS "TurnSignalStatus"
+#define LIGHT_STATUS_BRAKE "LightStatusBrake"
+
+#define MAX_TRANSMISSION_GEAR_INFO 6
+#define MIN_TRANSMISSION_GEAR_INFO 0
+
+enum eTransmissionGearInfo
+{
+ eTransmissionGearInfoLeft = 0,
+ eTransmissionGearInfoRight = 1,
+};
+
+enum eTurnSignalStatus
+{
+ eTurnSignalStatusOff = 0,
+ eTurnSignalStatusRight = 1,
+ eTurnSignalStatusLeft = 2,
+ eTurnSignalStatusHazard = 3
+};
+
+double gearRatio[8] =
+{
+ 0.0, //Neutral
+ 1.0/4.12, //First
+ 1.0/2.84, //Second
+ 1.0/2.28, //Third
+ 1.0/1.45, //Fourth
+ 1.0/1.0, //Fifth
+ 1.0/0.69, //Sixth
+ 1.0/3.21 //Reverse
+};
+
+static int gAcceleratorPedalPosition = 0;
+static int gLightStatusBrake = 0;
+static int gTransmissionGearInfo = 1;
+static int gSteeringWheelAngle = 0;
+static enum eTurnSignalStatus gTurnSignalStatus = eTurnSignalStatusOff;
+
+// Method to set value
+static void setAcceleratorPedalPosition(int val)
+{
+ if(gAcceleratorPedalPosition != val)
+ {
+ gAcceleratorPedalPosition = val;
+ }
+}
+
+static void setLightStatusBrake(int val)
+{
+ if(gLightStatusBrake != val)
+ {
+ gLightStatusBrake = val;
+ }
+}
+
+static void setTransmissionGearInfo(int val, enum eTransmissionGearInfo eGear)
+{
+ if(eGear == eTransmissionGearInfoLeft)
+ {
+ if(val && gTransmissionGearInfo < MAX_TRANSMISSION_GEAR_INFO)
+ {
+ gTransmissionGearInfo = gTransmissionGearInfo + 1;
+ }
+ }
+ else if(eGear == eTransmissionGearInfoRight)
+ {
+ if(val && gTransmissionGearInfo > MIN_TRANSMISSION_GEAR_INFO)
+ {
+ gTransmissionGearInfo = gTransmissionGearInfo - 1;
+ }
+ }
+}
+
+static void setSteeringWheelAngle(int val)
+{
+ if(gSteeringWheelAngle != val)
+ {
+ gSteeringWheelAngle = val;
+ }
+}
+
+static void setTurnSignalStatus(int val, enum eTurnSignalStatus turn)
+{
+ if(val)
+ {
+ if(turn == eTurnSignalStatusRight)
+ {
+ gTurnSignalStatus = eTurnSignalStatusRight;
+ }
+ else if(turn == eTurnSignalStatusLeft)
+ {
+ gTurnSignalStatus = eTurnSignalStatusLeft;
+ }
+ }
+ else
+ {
+ gTurnSignalStatus = eTurnSignalStatusOff;
+ }
+}
+
+// Method to calculate property
+static int calcAcceleratorPedalPosition()
+{
+ return (int)(((double)(gAcceleratorPedalPosition - 32767)/(double)-65534.0)*(double)100.0);
+}
+
+static int calcEngineSpeed()
+{
+ int acceleratorPedalPosition = calcAcceleratorPedalPosition();
+ int engineSpeed = (int)acceleratorPedalPosition * 100;
+
+ return engineSpeed;
+}
+
+static int calcVehicleSpeed()
+{
+ int engineSpeed = calcEngineSpeed();
+ double transmissionGearInfoRatio = gearRatio[(gTransmissionGearInfo == 128 ? 7 : gTransmissionGearInfo)];
+ int vehicleSpeed = (int)(engineSpeed * transmissionGearInfoRatio / 100);
+
+ return vehicleSpeed;
+}
+
+static int calcSteeringWheelAngle()
+{
+ double steeringWheelAngle = (((double)gSteeringWheelAngle / (double)32767.0) + (double)1.0) * (double)180.0;
+
+ return (int)steeringWheelAngle;
+}
+
+// Method to update property
+static void updateValue(char *prop, int val)
+{
+ unsigned int nProp = wheel_info->nData;
+ for(unsigned int i = 0; i < nProp; i++)
+ {
+ if(strcmp(prop, wheel_info->property[i].name) == 0)
+ {
+ if(wheel_info->property[i].curValue.int16_val != val)
+ {
+ wheel_info->property[i].curValue.int16_val = (int16_t)val;
+ //NOTICEMSG("Update property %s", wheel_info->property[i].name);
+ notify_property_changed(&wheel_info->property[i]);
+ }
+ }
+ }
+}
+
+void updateTransmissionGearInfo()
+{
+ updateValue(TRANSMISSION_GEAR_INFO, gTransmissionGearInfo);
+}
+
+void updateTransmissionMode()
+{
+ updateValue(TRANSMISSION_MODE, gTransmissionGearInfo);
+}
+
+static void updateAcceleratorPedalPosition()
+{
+ int acceleratorPedalPosition;
+
+ acceleratorPedalPosition = calcAcceleratorPedalPosition();
+ updateValue(ACCELERATOR_PEDAL_POSITION, acceleratorPedalPosition);
+}
+
+static void updateEngineSpeed()
+{
+ // Update EngineSpeed
+ int engineSpeed;
+
+ engineSpeed = calcEngineSpeed();
+ updateValue(ENGINE_SPEED, engineSpeed);
+}
+
+static void updateVehicleSpeed()
+{
+ // Update VehicleSpeed
+ int vehicleSpeed;
+
+ vehicleSpeed = calcVehicleSpeed();
+ updateValue(VEHICLE_SPEED, vehicleSpeed);
+}
+
+static void updateLightStatusBrake()
+{
+ int lightStatusBrake;
+
+ lightStatusBrake = (gLightStatusBrake < 20000);
+ updateValue(LIGHT_STATUS_BRAKE, lightStatusBrake);
+}
+
+static void updateSteeringWheelAngle()
+{
+ int steering = calcSteeringWheelAngle();
+ updateValue(STEERING_WHEEL_ANGLE, steering);
+}
+
+static void updateTurnSignalStatus()
+{
+ updateValue(TURN_SIGNAL_STATUS, gTurnSignalStatus);
+}
+
+// Method to handle joy stick event
+void newButtonValue(char number, int val)
+{
+ switch (number)
+ {
+ case JS_LEFT_PADDLE_SHIFTER: //Left paddle shifter
+ // Set gear position
+ setTransmissionGearInfo(val, eTransmissionGearInfoLeft);
+
+ // Update property
+ updateTransmissionGearInfo();
+ updateTransmissionMode();
+ updateVehicleSpeed();
+ break;
+
+ case JS_RIGHT_PADDLE_SHIFTER: //Right paddle shifter
+ // Set gear position
+ setTransmissionGearInfo(val, eTransmissionGearInfoRight);
+
+ // Update property
+ updateTransmissionGearInfo();
+ updateTransmissionMode();
+ updateVehicleSpeed();
+ break;
+
+ case JS_TURN_SIGNAL_RIGHT: //Right upper wheel button
+ // Set value
+ setTurnSignalStatus(val, eTurnSignalStatusRight);
+
+ // Update property
+ updateTurnSignalStatus();
+ break;
+
+ case JS_TURN_SIGNAL_LEFT: //Left upper wheel button
+ // Set value
+ setTurnSignalStatus(val, eTurnSignalStatusLeft);
+
+ // Update property
+ updateTurnSignalStatus();
+ break;
+
+ default:
+ break;
+ }
+}
+
+void newAxisValue(char number, int val)
+{
+ switch (number)
+ {
+ case JS_STEERING: //Wheel angle, -32767 - 32767
+ // Set value
+ setSteeringWheelAngle(val);
+
+ // Update property
+ updateSteeringWheelAngle();
+ break;
+
+ case JS_THROTTLE: //Throttle, -32767 (depressed) - 32767 (undepressed)
+ // Set origin value
+ setAcceleratorPedalPosition(val);
+
+ // Update property
+ updateAcceleratorPedalPosition();
+ updateEngineSpeed();
+ updateVehicleSpeed();
+ break;
+
+ case JS_BRAKE:
+ // Set value
+ setLightStatusBrake(val);
+
+ // Update property
+ updateLightStatusBrake();
+ break; //Brake, -32767 (depressed) - 32767 (undepressed)
+
+ default:
+ break;
+ }
+}
diff --git a/src/js_signal_event.h b/src/js_signal_event.h
new file mode 100644
index 0000000..3cff704
--- /dev/null
+++ b/src/js_signal_event.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * 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 _JS_SIGNAL_EVENT_H_
+#define _JS_SIGNAL_EVENT_H_
+
+extern struct wheel_info_t *wheel_info;
+
+extern void newButtonValue(char number, int val);
+extern void newAxisValue(char number, int val);
+
+#endif
diff --git a/src/prop_info.c b/src/prop_info.c
new file mode 100644
index 0000000..95d4f58
--- /dev/null
+++ b/src/prop_info.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "prop_info.h"
+#include "af-steering-wheel-binding.h"
+
+#define ENABLE1_TYPENAME "ENABLE-1" /* spec. type1.json original type name */
+
+static const char *vartype_strings[] = {
+/* 0 */ "void",
+/* 1 */ "int8_t",
+/* 2 */ "int16_t",
+/* 3 */ "int",
+/* 4 */ "int32_t",
+/* 5 */ "int64_t",
+/* 6 */ "uint8_t",
+/* 7 */ "uint16_t",
+/* 8 */ "uint",
+/* 9 */ "uint32_t",
+/* 10 */"uint64_t",
+/* 11 */ "string",
+/* 12 */ "bool",
+/* 13 */ "LIST",
+/* 14 */ ENABLE1_TYPENAME
+};
+
+int string2vartype(const char *varname)
+{
+ unsigned int i;
+ if (varname == NULL)
+ {
+ return -1;
+ }
+
+ for(i=0; i < (sizeof(vartype_strings)/sizeof(char *)); i++)
+ {
+ if (strcmp(varname, vartype_strings[i]) == 0)
+ return (int)i;
+ }
+
+ return -1;
+};
+
+int propertyValue_int(struct prop_info_t *property_info)
+{
+ int x = -1;
+ switch(property_info->var_type) {
+ case INT8_T:
+ x = (int)property_info->curValue.int8_val;
+ break;
+ case INT16_T:
+ x = (int)property_info->curValue.int16_val;
+ break;
+ case VOID_T:/* FALLTHROGH */
+ case INT_T: /* FALLTHROGH */
+ case INT32_T:/* FALLTHROGH */
+ x = (int)property_info->curValue.int32_val;
+ break;
+ case UINT8_T:
+ x = (int)property_info->curValue.uint8_val;
+ break;
+ case UINT16_T:
+ x = (int)property_info->curValue.uint16_val;
+ break;
+ case UINT_T:
+ case UINT32_T:
+ x = (int)property_info->curValue.uint32_val;
+ break;
+ case BOOL_T:
+ x = (int)property_info->curValue.bool_val;
+ break;
+ case ENABLE1_T:
+ x = (int)property_info->curValue.int32_val;
+ break;
+
+ default:
+ case STRING_T:
+ case ARRAY_T:
+ case UINT64_T:
+ case INT64_T:
+ ERRMSG("Getting property Value:NOT SUPPORT vartype contents:%s %d", property_info->name, property_info->var_type);
+ break;
+ }
+ return x;
+}
diff --git a/src/prop_info.h b/src/prop_info.h
new file mode 100644
index 0000000..3d6bb5c
--- /dev/null
+++ b/src/prop_info.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * 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 _CANID_INFO_H_
+#define _CANID_INFO_H_
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdint.h>
+
+enum var_type_t {
+/* 0 */ VOID_T,
+/* 1 */ INT8_T,
+/* 2 */ INT16_T,
+/* 3 */ INT_T,
+/* 4 */ INT32_T,
+/* 5 */ INT64_T,
+/* 6 */ UINT8_T,
+/* 7 */ UINT16_T,
+/* 8 */ UINT_T,
+/* 9 */ UINT32_T,
+/* 10 */ UINT64_T,
+/* 11 */ STRING_T,
+/* 12 */ BOOL_T,
+/* 13 */ ARRAY_T,
+/* 14 */ ENABLE1_T /* AMB#CANRawPlugin original type */
+};
+
+union data_content_t {
+ uint32_t uint32_val;
+ int32_t int32_val;
+ uint16_t uint16_val;
+ int16_t int16_val;
+ uint8_t uint8_val;
+ int8_t int8_val;
+ int8_t bool_val;
+};
+
+struct prop_info_t {
+ const char * name;
+ unsigned char var_type;
+ union data_content_t curValue;
+
+ struct prop_info_t *next;
+};
+
+struct wheel_info_t {
+ unsigned int nData;
+ struct prop_info_t property[0];
+ /* This is variable structure */
+};
+
+extern const char * vartype2string(unsigned int t);
+extern int string2vartype(const char *varname);
+extern int propertyValue_int(struct prop_info_t *property_info);
+
+#endif
diff --git a/src/prop_search.c b/src/prop_search.c
new file mode 100644
index 0000000..f88de8a
--- /dev/null
+++ b/src/prop_search.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <search.h>
+#include <string.h>
+
+#include "af-steering-wheel-binding.h"
+#include "prop_search.h"
+
+#define SUPPORT_PROPERTY_LIMIT 512
+
+static void *property_root = NULL;
+static const char *support_property_list[SUPPORT_PROPERTY_LIMIT];
+static int nProperties = 0;
+static void (*_walker_action)(struct prop_info_t *);
+
+static int property_compare(const void *pa, const void *pb)
+{
+ struct prop_info_t *a =(struct prop_info_t *)pa;
+ struct prop_info_t *b =(struct prop_info_t *)pb;
+ return strcmp(a->name,b->name);
+}
+
+static int addProperty_dict(struct prop_info_t *prop_info)
+{
+ void *v;
+ v = tfind((void *)prop_info, &property_root, property_compare);
+ if (v == NULL)
+ {
+ v = tsearch((void *)prop_info, &property_root, property_compare);
+ if (v == NULL)
+ {
+ ERRMSG("add property failed: not enogh memory?");
+ return -1;
+ }
+ if (nProperties >= SUPPORT_PROPERTY_LIMIT)
+ {
+ ERRMSG("Reach properties limit");
+ return -1;
+ }
+ support_property_list[nProperties] = prop_info->name;
+ ++nProperties;
+ return 0;
+ } /* else Multi entry */
+
+ return 1;
+}
+
+int addAllPropDict(struct wheel_info_t *wheel_info)
+{
+ unsigned int maxEntry = wheel_info->nData;
+
+ for(unsigned int i=0; i < maxEntry ; i++)
+ {
+ int ret;
+ ret = addProperty_dict(&wheel_info->property[i]);
+ if (!ret)
+ {
+ continue;
+ }
+ }
+
+ return 0;
+}
+
+const char **getSupportPropertiesList(int *nEntry)
+{
+ *nEntry = nProperties;
+ return support_property_list;
+}
+
+struct prop_info_t * getProperty_dict(const char *propertyName)
+{
+ struct prop_info_t key;
+ void *v;
+
+ key.name = propertyName;
+ v = tfind((void *)&key, &property_root, property_compare);
+ if (v == NULL) {
+ return NULL;
+ }
+ return (*(struct prop_info_t **)v);
+}
+
+static void canid_walk_action(const void *nodep, const VISIT which , const int depth)
+{
+ struct prop_info_t *datap;
+
+ switch (which) {
+ case preorder:
+ break;
+ case postorder:
+ datap = *(struct prop_info_t **) nodep;
+ _walker_action(datap);
+ break;
+ case endorder:
+ break;
+ case leaf:
+ datap = *(struct prop_info_t **) nodep;
+ _walker_action(datap);
+ break;
+ }
+}
+
+void canid_walker(void (*walker_action)(struct prop_info_t *))
+{
+ if (walker_action == NULL)
+ return;
+ _walker_action = walker_action;
+ twalk(property_root, canid_walk_action);
+}
diff --git a/src/prop_search.h b/src/prop_search.h
new file mode 100644
index 0000000..85791e5
--- /dev/null
+++ b/src/prop_search.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * 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 _PROP_SEARCH_H_
+#define _PROP_SEARCH_H_
+
+#include "prop_info.h"
+
+extern int addAllPropDict(struct wheel_info_t *wheel_info);
+extern struct prop_info_t * getProperty_dict(const char *propertyName);
+const char **getSupportPropertiesList(int *nEntry);
+extern void canid_walker(void (*walker_action)(struct prop_info_t *));
+
+#endif
diff --git a/src/steering_wheel_json.c b/src/steering_wheel_json.c
new file mode 100644
index 0000000..9d72284
--- /dev/null
+++ b/src/steering_wheel_json.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <json-c/json.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include "af-steering-wheel-binding.h"
+#include "steering_wheel_json.h"
+#include "prop_info.h"
+#include "prop_search.h"
+
+extern double gearRatio[];
+
+struct wheel_info_t *wheel_info;
+
+static int parse_property(struct wheel_info_t *wheel_info, int idx, json_object *obj_property)
+{
+ int var_type = 0;
+ char *name = NULL;
+
+ if(obj_property)
+ {
+ json_object_object_foreach(obj_property, key, val)
+ {
+ if (strcmp("PROPERTY", key) == 0)
+ {
+ name = (char *)json_object_get_string(val);
+ }
+ else if(strcmp("TYPE", key) == 0)
+ {
+ const char *_varname = json_object_get_string(val);
+ var_type = string2vartype(_varname);
+ }
+ }
+
+ wheel_info->property[idx].name = strdup(name);
+ wheel_info->property[idx].var_type = (unsigned char)var_type;
+ }
+
+ return 0;
+}
+
+#define DEFAULT_PROP_CNT (16)
+static int parse_propertys(json_object *obj_propertys)
+{
+ int err = 0;
+ json_object * obj_property;
+ size_t ms = sizeof(struct wheel_info_t) + (size_t)(DEFAULT_PROP_CNT*sizeof(struct prop_info_t));
+
+ if(obj_propertys)
+ {
+ wheel_info = malloc(ms);
+ if (wheel_info == NULL)
+ {
+ ERRMSG("Not enogh memory");
+ return 1;
+ }
+ memset(wheel_info, 0 , ms);
+
+ enum json_type type = json_object_get_type(obj_propertys);
+ if (type == json_type_array)
+ {
+ int array_len = json_object_array_length(obj_propertys);
+ if(array_len > DEFAULT_PROP_CNT)
+ {
+ wheel_info = realloc(wheel_info, sizeof(struct wheel_info_t) + ((size_t)array_len * sizeof(struct prop_info_t)));
+ if (wheel_info == NULL)
+ {
+ ERRMSG("not enogh memory");
+ exit(1);
+ }
+
+ memset(&wheel_info->property[DEFAULT_PROP_CNT], 0, (size_t)(array_len - DEFAULT_PROP_CNT)*sizeof(struct prop_info_t));
+ }
+
+ for (int i = 0; i < array_len; i++)
+ {
+ obj_property = json_object_array_get_idx(obj_propertys, i);
+ err = parse_property(wheel_info, i, obj_property);
+ }
+
+ wheel_info->nData = (unsigned int)array_len;
+ addAllPropDict(wheel_info);
+ }
+ }
+
+ return err;
+}
+
+static int parse_json(json_object *obj)
+{
+ int err = 0;
+ json_object_object_foreach(obj, key, val)
+ {
+ if (strcmp(key,"PROPERTYS") == 0)
+ {
+ err += parse_propertys(val);
+ }
+ else
+ {
+ ++err;
+ ERRMSG("json: Unknown key \"%s\"", key);
+ }
+ }
+ return err;
+}
+
+int wheel_define_init(const char *fname)
+{
+ struct json_object *jobj;
+ int fd_wheel_map;
+ struct stat stbuf;
+ char *filebuf;
+
+ fd_wheel_map = afb_daemon_rootdir_open_locale(fname, O_RDONLY, NULL);
+ if (fd_wheel_map < 0)
+ {
+ ERRMSG("wheel map is not access");
+ return -1;
+ }
+
+ FILE *fp = fdopen(fd_wheel_map,"r");
+ if (fp == NULL)
+ {
+ ERRMSG("canno read wheel map file");
+ return -1;
+ }
+
+ if (fstat(fd_wheel_map, &stbuf) == -1)
+ {
+ ERRMSG("cant get file state");
+ return -1;
+ }
+
+ filebuf = (char *)malloc(stbuf.st_size);
+ fread(filebuf, 1, stbuf.st_size, fp);
+ fclose(fp);
+
+ jobj = json_tokener_parse(filebuf);
+ if (jobj == NULL)
+ {
+ ERRMSG("cannot data from file \"%s\"",fname);
+ free(filebuf);
+ return 1;
+ }
+
+ parse_json(jobj);
+
+ json_object_put(jobj);
+
+ free(filebuf);
+ return 0;
+}
+
+static int parse_gear_para_json(json_object *obj)
+{
+ int err = 0;
+ json_object * obj_speed_para;
+ char *pos_name = NULL;
+ double pos_val = 0;
+
+ json_object_object_foreach(obj, key, val)
+ {
+ if (strcmp(key,"GEAR_PARA") == 0)
+ {
+ enum json_type type = json_object_get_type(val);
+ if (type == json_type_array)
+ {
+ int array_len = json_object_array_length(val);
+ NOTICEMSG("array_len:%d!", array_len);
+ for (int i = 0; i < array_len; i++)
+ {
+ obj_speed_para = json_object_array_get_idx(val, i);
+ if(obj_speed_para)
+ {
+ json_object_object_foreach(obj_speed_para, key, val)
+ {
+ ///
+ if (strcmp("POS", key) == 0)
+ {
+ pos_name = (char *)json_object_get_string(val);
+ }
+ else if(strcmp("VAL", key) == 0)
+ {
+ pos_val = json_object_get_double(val);
+ }
+
+ ///
+ if(strcmp("First", pos_name) == 0)
+ {
+ gearRatio[1] = (double)(1.0 / pos_val);
+ }
+ else if(strcmp("Second", pos_name) == 0)
+ {
+ gearRatio[2] = (double)(1.0 / pos_val);
+ }
+ else if(strcmp("Third", pos_name) == 0)
+ {
+ gearRatio[3] = (double)(1.0 / pos_val);
+ }
+ else if(strcmp("Fourth", pos_name) == 0)
+ {
+ gearRatio[4] = (double)(1.0 / pos_val);
+ }
+ else if(strcmp("Fifth", pos_name) == 0)
+ {
+ gearRatio[5] = (double)(1.0 / pos_val);
+ }
+ else if(strcmp("Sixth", pos_name) == 0)
+ {
+ gearRatio[6] = (double)(1.0 / pos_val);
+ }
+ else if(strcmp("Reverse", pos_name) == 0)
+ {
+ gearRatio[7] = (double)(1.0 / pos_val);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ ERRMSG("json: Need array \"%s\"", key);
+ }
+ }
+ else
+ {
+ ERRMSG("json: Unknown key \"%s\"", key);
+ }
+ }
+ return err;
+}
+
+int wheel_gear_para_init(const char *fname)
+{
+ struct json_object *jobj;
+ int fd_gear_para;
+ struct stat stbuf;
+ char *filebuf;
+
+ fd_gear_para = afb_daemon_rootdir_open_locale(fname, O_RDONLY, NULL);
+ if (fd_gear_para < 0)
+ {
+ ERRMSG("gear para is not access");
+ return -1;
+ }
+
+ FILE *fp = fdopen(fd_gear_para,"r");
+ if (fp == NULL)
+ {
+ ERRMSG("canno read gear para file");
+ return -1;
+ }
+
+ if (fstat(fd_gear_para, &stbuf) == -1)
+ {
+ ERRMSG("cant get file state.\n");
+ return -1;
+ }
+
+ filebuf = (char*)malloc(stbuf.st_size);
+ fread(filebuf, 1, stbuf.st_size, fp);
+ fclose(fp);
+
+ jobj = json_tokener_parse(filebuf);
+ if (jobj == NULL)
+ {
+ ERRMSG("cannot data from file \"%s\"",fname);
+ free(filebuf);
+ return 1;
+ }
+ parse_gear_para_json(jobj);
+
+ json_object_put(jobj);
+
+ free(filebuf);
+ return 0;
+}
+
+struct json_object *property2json(struct prop_info_t *property)
+{
+ struct json_object *jobj;
+ struct json_object *nameObject = NULL;
+ struct json_object *valueObject = NULL;
+
+ if (property == NULL)
+ return NULL;
+
+ jobj = json_object_new_object();
+ if (jobj == NULL)
+ return NULL;
+ switch(property->var_type)
+ {
+ case VOID_T: /* FALLTHROUGH */
+ case INT8_T: /* FALLTHROUGH */
+ case INT16_T: /* FALLTHROUGH */
+ case INT_T: /* FALLTHROUGH */
+ case INT32_T: /* FALLTHROUGH */
+ case INT64_T: /* FALLTHROUGH */
+ case UINT8_T: /* FALLTHROUGH */
+ case UINT16_T: /* FALLTHROUGH */
+ case UINT_T: /* FALLTHROUGH */
+ case UINT32_T: /* FALLTHROUGH */
+ case ENABLE1_T:
+ valueObject = json_object_new_int(propertyValue_int(property));
+ break;
+
+ case BOOL_T:
+ valueObject = json_object_new_boolean(property->curValue.bool_val);
+ break;
+
+ default:
+ ERRMSG("Unknown value type:%d", property->var_type);
+ break;
+ }
+
+ if (valueObject == NULL)
+ {
+ ERRMSG("fail json ValueObject");
+ json_object_put(jobj);
+ return NULL;
+ }
+
+ nameObject = json_object_new_string(property->name);
+
+ json_object_object_add(jobj, "name", nameObject);
+ json_object_object_add(jobj, "value", valueObject);
+
+ return jobj;
+}
diff --git a/src/steering_wheel_json.h b/src/steering_wheel_json.h
new file mode 100644
index 0000000..3c2c8c9
--- /dev/null
+++ b/src/steering_wheel_json.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * 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 _WHEEL_JSON_H_
+#define _WHEEL_JSON_H_
+
+#include <fcntl.h>
+#include <json-c/json.h>
+
+extern int wheel_define_init(const char *fname);
+extern int wheel_gear_para_init(const char *fname);
+extern struct json_object *property2json(struct prop_info_t *property);
+
+#endif