Adding connman-test subpackage
[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 <errno.h>
27
28 #include <glib.h>
29
30 #include "connman.h"
31
32 static GSList *driver_list = NULL;
33 static GHashTable *server_hash = NULL;
34
35 static gint compare_priority(gconstpointer a, gconstpointer b)
36 {
37         const struct connman_timeserver_driver *driver1 = a;
38         const struct connman_timeserver_driver *driver2 = b;
39
40         return driver2->priority - driver1->priority;
41 }
42
43 /**
44  * connman_timeserver_driver_register:
45  * @driver: timeserver driver definition
46  *
47  * Register a new timeserver driver
48  *
49  * Returns: %0 on success
50  */
51 int connman_timeserver_driver_register(struct connman_timeserver_driver *driver)
52 {
53         DBG("driver %p name %s", driver, driver->name);
54
55         driver_list = g_slist_insert_sorted(driver_list, driver,
56                                                         compare_priority);
57
58         return 0;
59 }
60
61 /**
62  * connman_timeserver_driver_unregister:
63  * @driver: timeserver driver definition
64  *
65  * Remove a previously registered timeserver driver
66  */
67 void connman_timeserver_driver_unregister(struct connman_timeserver_driver *driver)
68 {
69         DBG("driver %p name %s", driver, driver->name);
70
71         driver_list = g_slist_remove(driver_list, driver);
72 }
73
74 /**
75  * connman_timeserver_append:
76  * @server: server address
77  *
78  * Append time server server address to current list
79  */
80 int connman_timeserver_append(const char *server)
81 {
82         GSList *list;
83
84         DBG("server %s", server);
85
86         if (server == NULL)
87                 return -EINVAL;
88
89         /* This server is already handled by a driver */
90         if (g_hash_table_lookup(server_hash, server))
91                 return 0;
92
93         for (list = driver_list; list; list = list->next) {
94                 struct connman_timeserver_driver *driver = list->data;
95                 char *new_server;
96
97                 if (driver->append == NULL)
98                         continue;
99
100                 new_server = g_strdup(server);
101                 if (new_server == NULL)
102                         return -ENOMEM;
103
104                 if (driver->append(server) == 0) {
105                         g_hash_table_insert(server_hash, new_server, driver);
106                         return 0;
107                 } else {
108                         g_free(new_server);
109                 }
110         }
111
112         return -ENOENT;
113 }
114
115 /**
116  * connman_timeserver_remove:
117  * @server: server address
118  *
119  * Remover time server server address from current list
120  */
121 int connman_timeserver_remove(const char *server)
122 {
123         struct connman_timeserver_driver *driver;
124
125         DBG("server %s", server);
126
127         if (server == NULL)
128                 return -EINVAL;
129
130         driver = g_hash_table_lookup(server_hash, server);
131         if (driver == NULL)
132                 return -EINVAL;
133
134         g_hash_table_remove(server_hash, server);
135
136         if (driver->remove == NULL)
137                 return -ENOENT;
138
139         return driver->remove(server);
140 }
141
142 void connman_timeserver_sync(void)
143 {
144         GSList *list;
145
146         DBG("");
147
148         for (list = driver_list; list; list = list->next) {
149                 struct connman_timeserver_driver *driver = list->data;
150
151                 if (driver->sync == NULL)
152                         continue;
153
154                 driver->sync();
155         }
156 }
157
158 int __connman_timeserver_init(void)
159 {
160         DBG("");
161
162         server_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
163                                                 g_free, NULL);
164
165         return 0;
166 }
167
168 void __connman_timeserver_cleanup(void)
169 {
170         DBG("");
171
172         g_hash_table_destroy(server_hash);
173 }