Complete timeserver API
[platform/upstream/connman.git] / src / timeserver.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <glib.h>
27
28 #include "connman.h"
29
30 static GSList *driver_list = NULL;
31 static GHashTable *server_hash = NULL;
32
33 static gint compare_priority(gconstpointer a, gconstpointer b)
34 {
35         const struct connman_timeserver_driver *driver1 = a;
36         const struct connman_timeserver_driver *driver2 = b;
37
38         return driver2->priority - driver1->priority;
39 }
40
41 /**
42  * connman_timeserver_driver_register:
43  * @driver: timeserver driver definition
44  *
45  * Register a new timeserver driver
46  *
47  * Returns: %0 on success
48  */
49 int connman_timeserver_driver_register(struct connman_timeserver_driver *driver)
50 {
51         DBG("driver %p name %s", driver, driver->name);
52
53         driver_list = g_slist_insert_sorted(driver_list, driver,
54                                                         compare_priority);
55
56         return 0;
57 }
58
59 /**
60  * connman_timeserver_driver_unregister:
61  * @driver: timeserver driver definition
62  *
63  * Remove a previously registered timeserver driver
64  */
65 void connman_timeserver_driver_unregister(struct connman_timeserver_driver *driver)
66 {
67         DBG("driver %p name %s", driver, driver->name);
68
69         driver_list = g_slist_remove(driver_list, driver);
70 }
71
72 /**
73  * connman_timeserver_append:
74  * @server: server address
75  *
76  * Append time server server address to current list
77  */
78 int connman_timeserver_append(char *server)
79 {
80         GSList *list;
81
82         DBG("server %s", server);
83
84         if (server == NULL)
85                 return -EINVAL;
86
87         /* This server is already handled by a driver */
88         if (g_hash_table_lookup(server_hash, server))
89                 return 0;
90
91         for (list = driver_list; list; list = list->next) {
92                 struct connman_timeserver_driver *driver = list->data;
93
94                 if (driver->append == NULL)
95                         continue;
96
97                 if (driver->append(server) == 0) {
98                         g_hash_table_insert(server_hash, server, driver);
99                         return 0;
100                 }
101         }
102
103         return -ENOENT;
104 }
105
106 /**
107  * connman_timeserver_remove:
108  * @server: server address
109  *
110  * Remover time server server address from current list
111  */
112 int connman_timeserver_remove(char *server)
113 {
114         struct connman_timeserver_driver *driver;
115
116         DBG("server %s", server);
117
118         if (server == NULL)
119                 return -EINVAL;
120
121         driver = g_hash_table_lookup(server_hash, server);
122         if (driver == NULL)
123                 return -EINVAL;
124
125         if (driver->remove == NULL)
126                 return -ENOENT;
127
128         return driver->remove(server);
129 }
130
131 void connman_timeserver_sync(void)
132 {
133         GSList *list;
134
135         DBG("");
136
137         for (list = driver_list; list; list = list->next) {
138                 struct connman_timeserver_driver *driver = list->data;
139
140                 if (driver->sync == NULL)
141                         continue;
142
143                 driver->sync();
144         }
145 }
146
147 int __connman_timeserver_init(void)
148 {
149         DBG("");
150
151         server_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
152                                                 NULL, NULL);
153
154         return 0;
155 }
156
157 void __connman_timeserver_cleanup(void)
158 {
159         DBG("");
160
161         g_hash_table_destroy(server_hash);
162 }