* limitations under the License.
*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <glib-unix.h>
+#include "ttd-log.h"
+#include "ttd-cloud-conn-state.h"
+#include "ttd-cmd-type.h"
+#include "ttd-queue.h"
+#include "ttd-conn-mgr.h"
+#include "ttd-task.h"
+#include "ttd-http.h"
+#include "ttd-parse-cmd.h"
+
+
+#ifndef SERVER_URL
+/* TODO : remove it after test */
+#define TEST_SERVER_URL "https://test.showiot.xyz/api/package/metadata?id=test-page1523426067178&key=7138e585cc75f480094a9dc5d8719e925c24b435"
+#define SERVER_URL TEST_SERVER_URL
+#endif
+
+typedef struct __ttd_data {
+ GMainLoop *mainloop;
+ GThreadPool *thread_pool;
+} ttd_data;
+
+static gboolean __daemon_job_handler(gpointer data);
+static gboolean __cloud_try_connect(gpointer data);
+
+static unsigned long long _get_monotonic_time(void)
+{
+ struct timespec ts;
+ int result;
+
+ result = clock_gettime(CLOCK_MONOTONIC, &ts);
+
+ if (result != 0) {
+ _E("failed to get monotonic time");
+ return 0;
+ }
+
+ return (((unsigned long long) ts.tv_sec) * 1000000) + (ts.tv_nsec / 1000);
+}
+
+static const char *__ttd_get_cloud_url(void)
+{
+ const char *url = NULL;
+
+ /* TODO : get cloud url */
+ url = SERVER_URL;
+
+ return url;
+}
+
+static gboolean _handle_sigint(gpointer data)
+{
+ ttd_data *d_data = data;
+
+ _I("SIGINT received");
+
+ if (d_data && d_data->mainloop)
+ g_main_loop_quit(d_data->mainloop);
+
+ return FALSE;
+}
+
+static gboolean _handle_sigterm(gpointer data)
+{
+ ttd_data *d_data = data;
+
+ _I("SIGTERM received");
+
+ if (d_data && d_data->mainloop)
+ g_main_loop_quit(d_data->mainloop);
+
+ return FALSE;
+}
+
+static void __main_thread_pool_func(gpointer thread_data, gpointer pool_data)
+{
+ ttd_task *task = thread_data;
+ int ret = 0;
+
+ retm_if(!task, "task is NULL");
+
+ ret = ttd_task_run(task);
+ if (ret)
+ _E("Failed to ttd_task_func_run()");
+}
+
+static gboolean __daemon_job_handler(gpointer data)
+{
+ ttd_data *d_data = data;
+ ttd_cmd_data_s *cmd_data = NULL;
+ ttd_result_data_s *res_data = NULL;
+
+ if (!data) {
+ /* Must not reach here */
+ _E("data is NULL, daemon will be stop");
+ abort();
+ return FALSE;
+ }
+
+ res_data = ttd_queue_timeout_pop(TTD_QUEUE_TYPE_RESULT, 500);
+ if (res_data) {
+ /* Do something, handles result...jfkdjlfjklajflkdsjfkdslajfkdlsjlk */
+ /* pushes new task? or creates new command? */
+ }
+
+ cmd_data = ttd_queue_timeout_pop(TTD_QUEUE_TYPE_CMD, 500);
+ if (cmd_data) {
+ ttd_task *new_task = NULL;
+ /* Do something, creates task... */
+
+ g_thread_pool_push(d_data->thread_pool, new_task, NULL);
+ }
+ return TRUE;
+}
+
+static int __say_hello_to_cloud(void *data)
+{
+ int ret = 0;
+ char *cmd = NULL;
+
+ ret = ttd_http_get_cloud_cmd(__ttd_get_cloud_url(), &cmd);
+
+ retvm_if(ret, -1, "failed to get cmd");
+
+ if (cmd) {
+ ttd_cmd_data_s *cmd_data = NULL;
+ ttd_parse_json_to_cmd(cmd, &cmd_data);
+ ttd_queue_push(TTD_QUEUE_TYPE_CMD, cmd_data);
+ }else
+ _D("there is no cmd now");
+
+ return 0;
+}
+
+/*********** FIXME *************/
+static gboolean __cloud_try_connect(gpointer data)
+{
+ int ret = 0;
+ ttd_data *d_data = data;
+
+ if (!data) {
+ /* Must not reach here */
+ _E("data is NULL, daemon will be stop");
+ abort();
+ }
+ ret = __say_hello_to_cloud(data);
+
+ if (!ret) {
+ ttd_cloud_conn_state_set(TTD_CLOUD_CONN_STATE_CONNECTED);
+ g_idle_add(__daemon_job_handler, d_data);
+ } else /* endless retry? */
+ g_timeout_add_seconds(3, __cloud_try_connect, data);
+
+ return FALSE;
+}
+
+static gboolean __do_device_register(gpointer data)
+{
+ int registered = 0;
+ ttd_data *d_data = data;
+
+ if (!d_data) {
+ /* Must not reach here */
+ _E("data is NULL, daemon will be stop");
+ abort();
+ }
+
+ /* TODO
+ - check device ID
+ - check token or auth key
+ */
+
+ if (!registered) {
+ /* TODO : start easy setup procedure here !! */
+ }
+
+ ttd_cloud_conn_state_set(TTD_CLOUD_CONN_STATE_CONNECTABLE);
+ __cloud_try_connect(data); /* ???? */
+
+ return FALSE;
+}
int main(int argc, char* argv[])
{
+ ttd_data *d_data = NULL;
+ unsigned long long start = 0;
+
+ start = _get_monotonic_time();
+
+ d_data = calloc(1, sizeof(ttd_data));
+
+ log_type_set(LOG_TYPE_DLOG);
+
+ d_data->mainloop = g_main_loop_new(NULL, FALSE);
+
+ /* TODO : prepare to start daemon */
+ g_unix_signal_add(SIGINT, _handle_sigint, d_data);
+ g_unix_signal_add(SIGTERM, _handle_sigterm, d_data);
+
+ ttd_queue_init();
+ ttd_conn_mgr_init();
+ ttd_http_init();
+ ttd_cloud_conn_state_set(TTD_CLOUD_CONN_STATE_DISCONNECTED);
+ d_data->thread_pool =
+ g_thread_pool_new(__main_thread_pool_func, d_data, -1, FALSE, NULL);
+ g_thread_pool_set_sort_function(d_data->thread_pool, ttd_task_sort_func, NULL);
+
+ _D("[delay] start-to-ready - %.3lf(ms)",
+ (double)(_get_monotonic_time()- start)/1000);
+ g_idle_add(__do_device_register, d_data);
+
+ g_main_loop_run(d_data->mainloop);
+
+ g_main_loop_unref(d_data->mainloop);
+ g_thread_pool_free(d_data->thread_pool, FALSE, TRUE);
+
+ free(d_data);
+ d_data = NULL;
+
+ ttd_queue_fini();
+ ttd_conn_mgr_fini();
+ ttd_http_fini();
+
+ log_file_close();
return 0;
}