Integrated controller connection manager
[apps/native/gear-racing-car.git] / src / connection_manager.c
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://floralicense.org/license/
9  *
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.
15  */
16
17 #include <net_connection.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21 #include "log.h"
22 #include "connection_manager.h"
23
24 struct conn_mgr_s {
25         connection_h connection;
26         connection_type_e net_state;
27         connection_wifi_state_e wifi_state;
28         char *ip_addr;
29         connection_state_changed_cb state_cb;
30         void *state_cb_data;
31 };
32
33 struct conn_mgr_s conn_mgr = {
34         NULL,
35         CONNECTION_TYPE_DISCONNECTED,
36         CONNECTION_WIFI_STATE_DEACTIVATED,
37         NULL,
38         NULL,
39         NULL
40 };
41
42 static const char *__connection_error_to_string(connection_error_e error)
43 {
44         switch (error) {
45         case CONNECTION_ERROR_NONE:
46                 return "CONNECTION_ERROR_NONE";
47         case CONNECTION_ERROR_INVALID_PARAMETER:
48                 return "CONNECTION_ERROR_INVALID_PARAMETER";
49         case CONNECTION_ERROR_OUT_OF_MEMORY:
50                 return "CONNECTION_ERROR_OUT_OF_MEMORY";
51         case CONNECTION_ERROR_INVALID_OPERATION:
52                 return "CONNECTION_ERROR_INVALID_OPERATION";
53         case CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED:
54                 return "CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED";
55         case CONNECTION_ERROR_OPERATION_FAILED:
56                 return "CONNECTION_ERROR_OPERATION_FAILED";
57         case CONNECTION_ERROR_ITERATOR_END:
58                 return "CONNECTION_ERROR_ITERATOR_END";
59         case CONNECTION_ERROR_NO_CONNECTION:
60                 return "CONNECTION_ERROR_NO_CONNECTION";
61         case CONNECTION_ERROR_NOW_IN_PROGRESS:
62                 return "CONNECTION_ERROR_NOW_IN_PROGRESS";
63         case CONNECTION_ERROR_ALREADY_EXISTS:
64                 return "CONNECTION_ERROR_ALREADY_EXISTS";
65         case CONNECTION_ERROR_OPERATION_ABORTED:
66                 return "CONNECTION_ERROR_OPERATION_ABORTED";
67         case CONNECTION_ERROR_DHCP_FAILED:
68                 return "CONNECTION_ERROR_DHCP_FAILED";
69         case CONNECTION_ERROR_INVALID_KEY:
70                 return "CONNECTION_ERROR_INVALID_KEY";
71         case CONNECTION_ERROR_NO_REPLY:
72                 return "CONNECTION_ERROR_NO_REPLY";
73         case CONNECTION_ERROR_PERMISSION_DENIED:
74                 return "CONNECTION_ERROR_PERMISSION_DENIED";
75         case CONNECTION_ERROR_NOT_SUPPORTED:
76                 return "CONNECTION_ERROR_NOT_SUPPORTED";
77         default:
78                 return "CONNECTION_ERROR_UNKNOWN";
79         }
80 }
81
82 static void __conn_mgr_connection_changed_cb(connection_type_e type,
83          void* user_data)
84 {
85         int ret = CONNECTION_ERROR_NONE;
86         connection_state_e state = CONNECTION_STATE_DISCONNECTED;
87         _D("connection changed from[%d] to[%d]", conn_mgr.net_state, type);
88
89         conn_mgr.net_state = type;
90
91         ret = connection_get_wifi_state(conn_mgr.connection,
92                 &conn_mgr.wifi_state);
93
94         if (CONNECTION_ERROR_NONE != ret)
95                 _E("failed to connection_get_wifi_state - [%s]",
96                         __connection_error_to_string(ret));
97
98         free(conn_mgr.ip_addr);
99         conn_mgr.ip_addr = NULL;
100
101         if (conn_mgr.net_state != CONNECTION_TYPE_DISCONNECTED) {
102                 state = CONNECTION_STATE_CONNECTED;
103                 ret = connection_get_ip_address(conn_mgr.connection,
104                                 CONNECTION_ADDRESS_FAMILY_IPV4, &conn_mgr.ip_addr);
105
106                 if ((CONNECTION_ERROR_NONE != ret) || (conn_mgr.ip_addr == NULL))
107                         _E("failed to connection_get_ip_address() - [%s]",
108                                 __connection_error_to_string(ret));
109         }
110
111         if (conn_mgr.state_cb)
112                 conn_mgr.state_cb(state, conn_mgr.ip_addr, conn_mgr.state_cb_data);
113
114         return;
115 }
116
117 int connection_manager_get_ip(const char **ip)
118 {
119         int ret = CONNECTION_ERROR_NONE;
120
121         retv_if(conn_mgr.connection == NULL, -1);
122         retv_if(ip == NULL, -1);
123
124         if (conn_mgr.ip_addr) {
125                 *ip = conn_mgr.ip_addr;
126                 return 0;
127         }
128
129         if (conn_mgr.net_state == CONNECTION_TYPE_DISCONNECTED) {
130                 _W("disconnected now");
131
132                 free(conn_mgr.ip_addr);
133                 conn_mgr.ip_addr = NULL;
134
135                 return -1;
136         }
137
138         ret = connection_get_ip_address(conn_mgr.connection,
139                         CONNECTION_ADDRESS_FAMILY_IPV4, &conn_mgr.ip_addr);
140
141         if ((CONNECTION_ERROR_NONE != ret) || (conn_mgr.ip_addr == NULL)) {
142                 _E("failed to connection_get_ip_address() - [%s]",
143                         __connection_error_to_string(ret));
144                 return -1;
145         }
146
147         *ip = conn_mgr.ip_addr;
148
149         return 0;
150 }
151
152 int connection_manager_init(void)
153 {
154         int ret = CONNECTION_ERROR_NONE;
155         if (conn_mgr.connection) {
156                 _W("connection manager is already initialized");
157                 return 0;
158         }
159
160         ret = connection_create(&conn_mgr.connection);
161         if (CONNECTION_ERROR_NONE != ret) {
162                 _E("failed to create connection - [%s]",
163                         __connection_error_to_string(ret));
164                 return -1;
165         }
166
167         ret = connection_get_type(conn_mgr.connection, &conn_mgr.net_state);
168         if (CONNECTION_ERROR_NONE != ret) {
169                 _E("failed to connection_get_type - [%s]",
170                         __connection_error_to_string(ret));
171         }
172
173         if (conn_mgr.net_state != CONNECTION_TYPE_DISCONNECTED) {
174                 ret = connection_get_ip_address(conn_mgr.connection,
175                         CONNECTION_ADDRESS_FAMILY_IPV4, &conn_mgr.ip_addr);
176                 if ((CONNECTION_ERROR_NONE != ret) || (conn_mgr.ip_addr == NULL))
177                         _E("failed to connection_get_ip_address() - [%s]",
178                                 __connection_error_to_string(ret));
179         }
180
181         ret = connection_get_wifi_state(conn_mgr.connection, &conn_mgr.wifi_state);
182         if (CONNECTION_ERROR_NONE != ret)
183                 _E("failed to connection_get_wifi_state - [%s]",
184                         __connection_error_to_string(ret));
185
186         _D("net_state[%d], wifi_state[%d], ip address[%s]",
187                 conn_mgr.net_state, conn_mgr.wifi_state, conn_mgr.ip_addr);
188
189         ret = connection_set_type_changed_cb(conn_mgr.connection,
190                         __conn_mgr_connection_changed_cb, &conn_mgr);
191         if (CONNECTION_ERROR_NONE != ret)
192                 _E("failed to connection_set_type_changed_cb - [%s]",
193                         __connection_error_to_string(ret));
194
195         return 0;
196 }
197
198 int connection_manager_fini(void)
199 {
200         if (conn_mgr.connection) {
201                 int ret = 0;
202                 ret = connection_destroy(conn_mgr.connection);
203                 _D("connection_destroy - [%s]", __connection_error_to_string(ret));
204         }
205
206         conn_mgr.net_state = CONNECTION_TYPE_DISCONNECTED;
207         conn_mgr.wifi_state = CONNECTION_WIFI_STATE_DEACTIVATED;
208
209         if (conn_mgr.ip_addr) {
210                 free(conn_mgr.ip_addr);
211                 conn_mgr.ip_addr = NULL;
212         }
213
214         conn_mgr.state_cb = NULL;
215         conn_mgr.state_cb_data = NULL;
216
217         return 0;
218 }
219
220 int connection_manager_set_state_changed_cb(
221         connection_state_changed_cb state_cb, void *user_data)
222 {
223         conn_mgr.state_cb = state_cb;
224
225         if (state_cb) {
226                 connection_state_e state = CONNECTION_STATE_DISCONNECTED;
227
228                 conn_mgr.state_cb_data = user_data;
229                 if (conn_mgr.net_state != CONNECTION_TYPE_DISCONNECTED)
230                         state = CONNECTION_STATE_CONNECTED;
231
232                 conn_mgr.state_cb(state, conn_mgr.ip_addr, conn_mgr.state_cb_data);
233         } else
234                 conn_mgr.state_cb_data = NULL;
235
236         return 0;
237 }