diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 107 | ||||
-rw-r--r-- | src/af-steering-wheel-binding.c | 426 | ||||
-rw-r--r-- | src/af-steering-wheel-binding.h | 35 | ||||
-rw-r--r-- | src/bind_event.c | 114 | ||||
-rw-r--r-- | src/bind_event.h | 33 | ||||
-rw-r--r-- | src/export.map | 1 | ||||
-rw-r--r-- | src/icon.png | bin | 0 -> 10651 bytes | |||
-rw-r--r-- | src/js_raw.c | 174 | ||||
-rw-r--r-- | src/js_raw.h | 27 | ||||
-rw-r--r-- | src/js_signal_event.c | 328 | ||||
-rw-r--r-- | src/js_signal_event.h | 25 | ||||
-rw-r--r-- | src/prop_info.c | 103 | ||||
-rw-r--r-- | src/prop_info.h | 70 | ||||
-rw-r--r-- | src/prop_search.c | 128 | ||||
-rw-r--r-- | src/prop_search.h | 27 | ||||
-rw-r--r-- | src/steering_wheel_json.c | 346 | ||||
-rw-r--r-- | src/steering_wheel_json.h | 27 |
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 Binary files differnew file mode 100644 index 0000000..def888b --- /dev/null +++ b/src/icon.png 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 |