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>
22 #include "ttd-cloud-conn-state.h"
24 #include "ttd-queue.h"
25 #include "ttd-conn-mgr.h"
28 #include "ttd-parse-cmd.h"
29 #include "ttd-worker-interface.h"
30 #include "ttd-worker-handle.h"
31 #include "common-util.h"
34 /* TODO : remove it after test */
35 #define TEST_SERVER_URL "http://test.showiot.xyz/api/cmd?&target=test-page-device&owner=test-page&state=created"
36 #define SERVER_URL TEST_SERVER_URL
39 typedef struct __ttd_data {
41 GThreadPool *thread_pool;
42 worker_interface_h worker_itf_h;
45 static gboolean __daemon_job_handler(gpointer data);
46 static gboolean __cloud_try_connect(gpointer data);
48 static unsigned long long _get_monotonic_time(void)
50 unsigned long long m_time = 0;
51 m_time = common_get_monotonic_time();
53 _E("failed to get monotonic time");
58 static const char *__ttd_get_cloud_url(void)
60 const char *url = NULL;
62 /* TODO : get cloud url */
68 static gboolean _handle_sigint(gpointer data)
70 ttd_data *d_data = data;
72 _I("SIGINT received");
74 if (d_data && d_data->mainloop)
75 g_main_loop_quit(d_data->mainloop);
80 static gboolean _handle_sigterm(gpointer data)
82 ttd_data *d_data = data;
84 _I("SIGTERM received");
86 if (d_data && d_data->mainloop)
87 g_main_loop_quit(d_data->mainloop);
92 static void __main_thread_pool_func(gpointer thread_data, gpointer pool_data)
94 ttd_task *task = thread_data;
97 retm_if(!task, "task is NULL");
99 ret = ttd_task_run(task);
101 _E("Failed to ttd_task_func_run()");
106 static ttd_task_func __get_task_func(ttd_cmd_data *cmd)
108 ttd_task_func func = NULL;
111 switch (ttd_cmd_get_type(cmd)) {
112 case TTD_CMD_TYPE_POWER:
114 case TTD_CMD_TYPE_CONFIG:
116 case TTD_CMD_TYPE_PACKAGE:
117 case TTD_CMD_TYPE_INFO:
118 func = ttd_worker_launch;
120 case TTD_CMD_TYPE_DIAGNOSIS:
122 case TTD_CMD_TYPE_LOCAL:
124 case TTD_CMD_TYPE_UNKNOWN:
125 case TTD_CMD_TYPE_MAX:
132 static gboolean __daemon_job_handler(gpointer data)
134 ttd_data *d_data = data;
136 ttd_cmd_data *cmd_data = NULL;
137 ttd_result_data_s *res_data = NULL;
140 /* Must not reach here */
141 _E("data is NULL, daemon will be stop");
146 res_data = ttd_queue_timeout_pop(TTD_QUEUE_TYPE_RESULT, 500);
148 /* Do something, handles result...jfkdjlfjklajflkdsjfkdslajfkdlsjlk */
149 /* pushes new task? or creates new command? */
152 cmd_data = ttd_queue_timeout_pop(TTD_QUEUE_TYPE_CMD, 500);
154 ttd_task *new_task = NULL;
155 ttd_task_func func = NULL;
156 /* Do something, creates task... */
157 func = __get_task_func(cmd_data);
159 _E("task func is not defined - type[%d]",
160 ttd_cmd_get_type(cmd_data));
162 ttd_cmd_free(cmd_data);
166 new_task = ttd_task_new(TTD_TASK_PRIORITY_NORMAL, func,
167 cmd_data, (ttd_task_data_free_func)ttd_cmd_free);
169 g_thread_pool_push(d_data->thread_pool, new_task, NULL);
174 static int __say_hello_to_cloud(void *data)
180 ret = ttd_http_get_cloud_cmd(__ttd_get_cloud_url(), &cmd, &res_code);
181 retvm_if(ret, -1, "failed to get cmd [%ld]", res_code);
184 GList *cmd_list = NULL;
187 ttd_parse_json_to_cmd(cmd, &cmd_list);
188 for (l = cmd_list; l != NULL; l = l->next) {
189 ttd_cmd_data *cmd_data = NULL;
191 cmd_data = (ttd_cmd_data *)l->data;
193 ttd_queue_push(TTD_QUEUE_TYPE_CMD,
194 cmd_data, (ttd_queue_item_free_func)ttd_cmd_free);
197 _D("there is no cmd now");
202 /*********** FIXME *************/
203 static gboolean __cloud_try_connect(gpointer data)
206 ttd_data *d_data = data;
209 /* Must not reach here */
210 _E("data is NULL, daemon will be stop");
213 ret = __say_hello_to_cloud(data);
216 ttd_cloud_conn_state_set(TTD_CLOUD_CONN_STATE_CONNECTED);
217 g_idle_add(__daemon_job_handler, d_data);
218 } else /* endless retry? */
219 g_timeout_add_seconds(3, __cloud_try_connect, data);
224 static gboolean __do_device_register(gpointer data)
227 ttd_data *d_data = data;
230 /* Must not reach here */
231 _E("data is NULL, daemon will be stop");
237 - check token or auth key
241 /* TODO : start easy setup procedure here !! */
244 ttd_cloud_conn_state_set(TTD_CLOUD_CONN_STATE_CONNECTABLE);
245 __cloud_try_connect(data); /* ???? */
250 int main(int argc, char* argv[])
252 ttd_data *d_data = NULL;
253 unsigned long long start = 0;
255 start = _get_monotonic_time();
257 d_data = calloc(1, sizeof(ttd_data));
259 log_type_set(LOG_TYPE_DLOG);
261 d_data->mainloop = g_main_loop_new(NULL, FALSE);
263 /* TODO : prepare to start daemon */
264 g_unix_signal_add(SIGINT, _handle_sigint, d_data);
265 g_unix_signal_add(SIGTERM, _handle_sigterm, d_data);
270 ttd_cloud_conn_state_set(TTD_CLOUD_CONN_STATE_DISCONNECTED);
272 if (ttd_worker_interface_init(&(d_data->worker_itf_h)) < 0)
273 _E("Failed to initialize worker interface");
275 d_data->thread_pool =
276 g_thread_pool_new(__main_thread_pool_func, d_data, -1, FALSE, NULL);
277 g_thread_pool_set_sort_function(
278 d_data->thread_pool, ttd_task_sort_func, NULL);
280 _D("[delay] start-to-ready - %.3lf(ms)",
281 (double)(_get_monotonic_time() - start)/1000);
282 g_idle_add(__do_device_register, d_data);
284 g_main_loop_run(d_data->mainloop);
286 g_main_loop_unref(d_data->mainloop);
287 g_thread_pool_free(d_data->thread_pool, FALSE, TRUE);
289 ttd_worker_interface_fini(d_data->worker_itf_h);