2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
4 * Licensed under the Flora License, Version 1.1 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <glib-unix.h>
24 #include "ttd-cloud-conn-state.h"
26 #include "ttd-queue.h"
27 #include "ttd-conn-mgr.h"
29 #include "ttd-config.h"
31 #include "ttd-parse-cmd.h"
32 #include "ttd-worker-interface.h"
33 #include "ttd-worker-handle.h"
34 #include "common-util.h"
37 /* TODO : remove it after test */
38 #define TEST_SERVER_URL "http://test.showiot.xyz/api/cmd?&target=test-page-device&owner=test-page&state=created"
39 #define SERVER_URL TEST_SERVER_URL
42 typedef struct __ttd_data {
44 GThreadPool *thread_pool;
45 worker_interface_h worker_itf_h;
49 static gboolean __daemon_job_handler(gpointer data);
50 static gboolean __cloud_try_connect(gpointer data);
52 static long long _get_monotonic_time(void)
55 m_time = common_get_monotonic_time();
57 _E("failed to get monotonic time");
62 static const char *__ttd_get_cloud_url(void)
64 const char *url = NULL;
66 /* TODO : get cloud url */
72 static gboolean _handle_sigint(gpointer data)
74 ttd_data *d_data = data;
76 _I("SIGINT received");
78 if (d_data && d_data->mainloop)
79 g_main_loop_quit(d_data->mainloop);
84 static gboolean _handle_sigterm(gpointer data)
86 ttd_data *d_data = data;
88 _I("SIGTERM received");
90 if (d_data && d_data->mainloop)
91 g_main_loop_quit(d_data->mainloop);
96 static void __main_thread_pool_func(gpointer thread_data, gpointer pool_data)
98 ttd_task *task = thread_data;
101 retm_if(!task, "task is NULL");
103 ret = ttd_task_run(task);
105 _E("Failed to ttd_task_func_run()");
110 static ttd_task_func __get_task_func(ttd_cmd_data *cmd)
112 ttd_task_func func = NULL;
115 switch (ttd_cmd_get_type(cmd)) {
116 case TTD_CMD_TYPE_POWER:
118 case TTD_CMD_TYPE_CONFIG:
119 func = ttd_config_write;
121 case TTD_CMD_TYPE_PACKAGE:
122 case TTD_CMD_TYPE_INFO:
123 func = ttd_worker_launch;
125 case TTD_CMD_TYPE_DIAGNOSIS:
127 case TTD_CMD_TYPE_LOCAL:
129 case TTD_CMD_TYPE_UNKNOWN:
130 case TTD_CMD_TYPE_MAX:
138 static gboolean __daemon_job_handler(gpointer data)
140 ttd_data *d_data = data;
142 ttd_cmd_data *cmd_data = NULL;
143 ttd_result_data_s *res_data = NULL;
146 /* Must not reach here */
147 _E("data is NULL, daemon will be stop");
152 res_data = ttd_queue_timeout_pop(TTD_QUEUE_TYPE_RESULT, 500);
154 /* Do something, handles result...jfkdjlfjklajflkdsjfkdslajfkdlsjlk */
155 /* pushes new task? or creates new command? */
158 cmd_data = ttd_queue_timeout_pop(TTD_QUEUE_TYPE_CMD, 500);
160 ttd_task *new_task = NULL;
161 ttd_task_func func = NULL;
162 /* Do something, creates task... */
163 func = __get_task_func(cmd_data);
165 _E("task func is not defined - type[%d]",
166 ttd_cmd_get_type(cmd_data));
168 ttd_cmd_free(cmd_data);
172 new_task = ttd_task_new(TTD_TASK_PRIORITY_NORMAL, func,
173 cmd_data, (ttd_task_data_free_func)ttd_cmd_free);
175 g_thread_pool_push(d_data->thread_pool, new_task, NULL);
180 static int __say_hello_to_cloud(void *data)
186 ret = ttd_http_get_cloud_cmd(__ttd_get_cloud_url(), &cmd, &res_code);
187 retvm_if(ret, -1, "failed to get cmd [%ld]", res_code);
190 GList *cmd_list = NULL;
193 ttd_parse_json_to_cmd(cmd, &cmd_list);
194 for (l = cmd_list; l != NULL; l = l->next) {
195 ttd_cmd_data *cmd_data = NULL;
197 cmd_data = (ttd_cmd_data *)l->data;
199 ttd_queue_push(TTD_QUEUE_TYPE_CMD,
200 cmd_data, (ttd_queue_item_free_func)ttd_cmd_free);
203 _D("there is no cmd now");
208 /*********** FIXME *************/
209 static gboolean __cloud_try_connect(gpointer data)
212 ttd_data *d_data = data;
215 /* Must not reach here */
216 _E("data is NULL, daemon will be stop");
219 ret = __say_hello_to_cloud(data);
222 ttd_cloud_conn_state_set(TTD_CLOUD_CONN_STATE_CONNECTED);
223 g_idle_add(__daemon_job_handler, d_data);
224 } else /* endless retry? */
225 g_timeout_add_seconds(3, __cloud_try_connect, data);
230 static gboolean __do_device_register(gpointer data)
233 ttd_data *d_data = data;
236 /* Must not reach here */
237 _E("data is NULL, daemon will be stop");
243 - check token or auth key
247 /* TODO : start easy setup procedure here !! */
250 ttd_cloud_conn_state_set(TTD_CLOUD_CONN_STATE_CONNECTABLE);
251 __cloud_try_connect(data); /* ???? */
256 static void __time_changed(keynode_t *node, void *data)
258 ttd_data *d_data = data;
259 long long current_time;
260 _D("System time is changed");
262 current_time = common_get_epoch_time();
264 if (current_time > EPOCH_TIME_REF && !d_data->is_time_set) {
265 /* Do something need correct time after here */
266 _D("We assume that system time is correct, because current[%lld] is bigger than 2018-05-17", current_time);
267 d_data->is_time_set = true;
268 g_idle_add(__do_device_register, d_data);
272 int main(int argc, char* argv[])
274 ttd_data *d_data = NULL;
277 start = _get_monotonic_time();
279 d_data = calloc(1, sizeof(ttd_data));
281 log_type_set(LOG_TYPE_DLOG);
283 d_data->mainloop = g_main_loop_new(NULL, FALSE);
285 /* TODO : prepare to start daemon */
286 g_unix_signal_add(SIGINT, _handle_sigint, d_data);
287 g_unix_signal_add(SIGTERM, _handle_sigterm, d_data);
289 vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, __time_changed, d_data);
294 ttd_cloud_conn_state_set(TTD_CLOUD_CONN_STATE_DISCONNECTED);
295 ttd_worker_interface_init(&(d_data->worker_itf_h));
297 d_data->thread_pool =
298 g_thread_pool_new(__main_thread_pool_func, d_data, -1, FALSE, NULL);
299 g_thread_pool_set_sort_function(
300 d_data->thread_pool, ttd_task_sort_func, NULL);
302 _D("[delay] start-to-ready - %.3lf(ms)",
303 (double)(_get_monotonic_time() - start)/1000);
304 g_main_loop_run(d_data->mainloop);
306 g_main_loop_unref(d_data->mainloop);
307 g_thread_pool_free(d_data->thread_pool, FALSE, TRUE);
309 ttd_worker_interface_fini(d_data->worker_itf_h);