#include <gio/gio.h>
#include <gio/gunixsocketaddress.h>
#include <app_common.h>
+#include <json.h>
#include "log-private.h"
#include "things-service.h"
#include "common-app-inf.h"
struct _ts_data {
char *app_id;
char *token;
+ char *project;
GSocket *socket;
GSocketAddress *addr;
GSocket *cl_socket;
int accept_thread_running;
};
+struct __timebased_int {
+ gint64 i_time;
+ gint value;
+};
+
+struct __timebased_double {
+ gint64 i_time;
+ gdouble value;
+};
+
+struct __timebased_data {
+ ts_value_type_e type;
+ unsigned int length;
+ GList *v_list;
+};
+
static void __quit_n_join_accept_thread(ts_handle handle);
static int _create_accept_thread(ts_handle handle);
+static void __timebase_value_free(gpointer data)
+{
+ g_free(data);
+}
+
+static void
+__add_timebased_int_to_json_object(gpointer data, gpointer user_data)
+{
+ struct __timebased_int *tb_int = data;
+ struct json_object *a_obj = user_data;
+ struct json_object *obj = NULL;
+ struct json_object *value_o = NULL;
+ struct json_object *time_o = NULL;
+
+ ret_if(!tb_int);
+ ret_if(!a_obj);
+
+ obj = json_object_new_object();
+ ret_if(!obj);
+
+ time_o = json_object_new_int64(tb_int->i_time);
+ goto_if(!time_o, ERROR);
+ json_object_object_add(obj, "x", time_o);
+
+ value_o = json_object_new_int64(tb_int->value);
+ goto_if(!value_o, ERROR);
+ json_object_object_add(obj, "y", value_o);
+
+ json_object_array_add(a_obj, obj);
+ return;
+
+ERROR:
+ json_object_put(obj);
+ return;
+}
+
+static void
+__add_timebased_double_to_json_object(gpointer data, gpointer user_data)
+{
+ struct __timebased_double *tb_double = data;
+ struct json_object *a_obj = user_data;
+ struct json_object *obj = NULL;
+ struct json_object *value_o = NULL;
+ struct json_object *time_o = NULL;
+
+ ret_if(!tb_double);
+ ret_if(!a_obj);
+
+ obj = json_object_new_object();
+ ret_if(!obj);
+
+ time_o = json_object_new_int64(tb_double->i_time);
+ goto_if(!time_o, ERROR);
+ json_object_object_add(obj, "x", time_o);
+
+ value_o = json_object_new_double(tb_double->value);
+ goto_if(!value_o, ERROR);
+ json_object_object_add(obj, "y", value_o);
+
+ json_object_array_add(a_obj, obj);
+
+ return;
+
+ERROR:
+ json_object_put(obj);
+ return;
+}
+
+static char *__timebased_data_to_json(timebased_data *tb_data)
+{
+ struct json_object *obj = NULL;
+ struct json_object *a_obj = NULL;
+ char *json_str = NULL;
+
+ retv_if(!tb_data, NULL);
+ retvm_if(!((tb_data->type == TS_VALUE_TYPE_INT) ||
+ (tb_data->type == TS_VALUE_TYPE_DOUBLE)),
+ NULL, "invalid type[%d]", tb_data->type);
+
+ obj = json_object_new_object();
+ retv_if(!obj, NULL);
+
+ a_obj = json_object_new_array();
+ goto_if(!a_obj, ERROR);
+ json_object_object_add(obj, "data", a_obj);
+
+ switch (tb_data->type) {
+ case TS_VALUE_TYPE_INT:
+ g_list_foreach(tb_data->v_list,
+ __add_timebased_int_to_json_object, a_obj);
+ break;
+ case TS_VALUE_TYPE_DOUBLE:
+ g_list_foreach(tb_data->v_list,
+ __add_timebased_double_to_json_object, a_obj);
+ break;
+ default:
+ _E("invalid type [%d]", tb_data->type);
+ goto ERROR;
+ break;
+ }
+
+ json_str = g_strdup(json_object_to_json_string(obj));
+
+ if (obj)
+ json_object_put(obj);
+
+ return json_str;
+
+ERROR:
+ if (obj)
+ json_object_put(obj);
+
+ return NULL;
+}
+
static char *_get_socket_addr_name(const char *appID, const char *token)
{
return common_make_socket_addr_name(token, appID, (guint)getpid());
if (handle->app_id)
g_free(handle->app_id);
+ if (handle->project)
+ g_free(handle->project);
+
if (handle->token)
g_free(handle->token);
{
GVariant *response = NULL;
int ret = 0;
+ const char *ret_msg = 0;
GError *error = NULL;
_D("call method [%s]", method);
response = g_dbus_proxy_call_sync(handle->proxy,
method,
- g_variant_new("(ssu)", handle->token, handle->app_id, (guint)getpid()),
+ g_variant_new("(sssu)",
+ handle->project, handle->token, handle->app_id, (guint)getpid()),
G_DBUS_CALL_FLAGS_NONE,
-1, /* The timeout in milliseconds or -1 to use the proxy default timeout. */
NULL, /* cancellable */
g_error_free(error);
return -1;
}
- g_variant_get(response, "(i)", ret);
- _D("method[%s] get response ret[%d]", method, ret);
+ if (!response)
+ return -1;
+
+ g_variant_get(response, "(i&s)", ret, &ret_msg);
+ _D("method[%s] get response ret[%d] - %s", method, ret, ret_msg);
g_variant_unref(response);
- return 0;
+ return ret;
}
static int _client_call_register(ts_handle handle)
return __client_method_call(TTD_APP_INF_METHOD_UNREG, handle);
}
-int things_service_init(ts_handle *handle)
+int things_service_init(ts_handle *handle, const char *project)
{
ts_handle _handle = NULL;
GError *error = NULL;
retv_if(!handle, -1);
_handle = g_try_malloc0(sizeof(ts_handle));
+ _handle->project = g_strdup(project);
_handle->app_id = _get_app_id();
if (!_handle->app_id) {
_E("failed to get app id");
return 0;
}
-int things_service_send_data(ts_handle handle, const char *json_data)
+static int __ts_send_data(ts_handle handle, const char *json_data)
{
gboolean connected = FALSE;
char *msg = NULL;
return 0;
}
+
+int things_service_send_data(ts_handle handle, const char *json_data)
+{
+ return __ts_send_data(handle, json_data);
+}
+
+timebased_data *thing_service_timebased_data_new(ts_value_type_e type)
+{
+ timebased_data *t_data = NULL;
+
+ retvm_if(!((type == TS_VALUE_TYPE_INT) || (type == TS_VALUE_TYPE_DOUBLE)),
+ NULL, "invalid type[%d]", type);
+
+ t_data = g_try_malloc0(sizeof(timebased_data));
+ if (!t_data)
+ return NULL;
+
+ t_data->type = type;
+ t_data->length = 0;
+
+ return t_data;
+}
+
+void thing_service_timebased_data_free(timebased_data *tb_data)
+{
+ ret_if(!tb_data);
+
+ if (tb_data->v_list)
+ g_list_free_full(tb_data->v_list, __timebase_value_free);
+
+ g_free(tb_data);
+}
+
+int things_service_timebased_data_get_length(timebased_data *tb_data)
+{
+ retv_if(!tb_data, -1);
+
+ return tb_data->length;
+}
+
+int
+things_service_timebased_data_append_int(timebased_data *tb_data, int ivalue)
+{
+ struct __timebased_int *tb_int = NULL;
+
+ retv_if(!tb_data, -1);
+ retv_if(tb_data->type != TS_VALUE_TYPE_INT, -1);
+
+ tb_int = g_try_malloc0(sizeof(struct __timebased_int));
+ retv_if(!tb_int, -1);
+
+ tb_int->i_time = common_get_epoch_coarse_time();
+ tb_int->value = ivalue;
+
+ tb_data->v_list = g_list_append(tb_data->v_list, tb_int);
+ tb_data->length++;
+
+ return 0;
+}
+
+int things_service_timebased_data_append_double(
+ timebased_data *tb_data, double dvalue)
+{
+ struct __timebased_double *tb_double = NULL;
+
+ retv_if(!tb_data, -1);
+ retv_if(tb_data->type != TS_VALUE_TYPE_DOUBLE, -1);
+
+ tb_double = g_try_malloc0(sizeof(struct __timebased_double));
+ retv_if(!tb_double, -1);
+
+ tb_double->i_time = common_get_epoch_coarse_time();
+ tb_double->value = dvalue;
+
+ tb_data->v_list = g_list_append(tb_data->v_list, tb_double);
+ tb_data->length++;
+
+ return 0;
+}
+
+int
+things_service_send_timebased_data(ts_handle handle, timebased_data *tb_data)
+{
+ int ret = 0;
+ char *json_data = NULL;
+
+ retv_if(!handle, -1);
+ retv_if(!tb_data, -1);
+
+ json_data = __timebased_data_to_json(tb_data);
+ ret = __ts_send_data(handle, json_data);
+ g_free(json_data);
+
+ if (!ret) { /* if success to send data, remove all items in tb_data */
+ g_list_free_full(tb_data->v_list, __timebase_value_free);
+ tb_data->v_list = NULL;
+ tb_data->length = 0;
+ }
+
+ return ret;
+}