Fix timeserver API
[framework/connectivity/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(const 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                 char *new_server;
94
95                 if (driver->append == NULL)
96                         continue;
97
98                 new_server = g_strdup(server);
99                 if (new_server == NULL)
100                         return -ENOMEM;
101
102                 if (driver->append(server) == 0) {
103                         g_hash_table_insert(server_hash, new_server, driver);
104                         return 0;
105                 }
106         }
107
108         return -ENOENT;
109 }
110
111 /**
112  * connman_timeserver_remove:
113  * @server: server address
114  *
115  * Remover time server server address from current list
116  */
117 int connman_timeserver_remove(const char *server)
118 {
119         struct connman_timeserver_driver *driver;
120
121         DBG("server %s", server);
122
123         if (server == NULL)
124                 return -EINVAL;
125
126         driver = g_hash_table_lookup(server_hash, server);
127         if (driver == NULL)
128                 return -EINVAL;
129
130         g_hash_table_remove(server_hash, server);
131
132         if (driver->remove == NULL)
133                 return -ENOENT;
134
135         return driver->remove(server);
136 }
137
138 void connman_timeserver_sync(void)
139 {
140         GSList *list;
141
142         DBG("");
143
144         for (list = driver_list; list; list = list->next) {
145                 struct connman_timeserver_driver *driver = list->data;
146
147                 if (driver->sync == NULL)
148                         continue;
149
150                 driver->sync();
151         }
152 }
153
154 int __connman_timeserver_init(void)
155 {
156         DBG("");
157
158         server_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
159                                                 g_free, NULL);
160
161         return 0;
162 }
163
164 void __connman_timeserver_cleanup(void)
165 {
166         DBG("");
167
168         g_hash_table_destroy(server_hash);
169 }