From e1e0839c6c7f523db74519bae053b2c82536605b Mon Sep 17 00:00:00 2001 From: Michal Kolodziejski Date: Wed, 26 Sep 2018 20:46:22 +0200 Subject: [PATCH] Net utils This module allows to: 1. Get access point MAC/SSID 2. Get device IP 3. Set callback for observing wifi changing Change-Id: Id96a2f1ff467f71a8df769da46f109e246846830 Signed-off-by: Michal Kolodziejski --- .gitignore | 1 + CMakeLists.txt | 2 + inc/net-util.h | 66 +++++++++++++ packaging/car-app.spec | 1 + src/app.c | 5 +- src/net-util.c | 252 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 326 insertions(+), 1 deletion(-) create mode 100644 inc/net-util.h create mode 100644 src/net-util.c diff --git a/.gitignore b/.gitignore index 875c80c..59562b8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .sign/ SA_Report /res/ +.vscode/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 37f165f..6c5128b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ pkg_check_modules(APP_PKGS REQUIRED glib-2.0 gio-2.0 capi-network-connection + capi-network-wifi-manager ) FOREACH (flag ${APP_PKGS_CFLAGS}) @@ -48,6 +49,7 @@ ADD_EXECUTABLE(${PROJECT_NAME} ${PROJECT_ROOT_DIR}/src/cloud/car_info_serializer.c ${PROJECT_ROOT_DIR}/src/cloud/cloud_request.c ${PROJECT_ROOT_DIR}/src/cloud/http_request.c + ${PROJECT_ROOT_DIR}/src/net-util.c ) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} -lm) diff --git a/inc/net-util.h b/inc/net-util.h new file mode 100644 index 0000000..3ed82ae --- /dev/null +++ b/inc/net-util.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NET_UTIL_H_ +#define __NET_UTIL_H_ + +#include + +/** + * @brief Called whenever WiFi connection has changed. + * @param[in] ap_mac The MAC address of access point. + * @param[in] ap_ssid The SSID of the access point. + * @param[in] ip_addr Device IP address. + * @param[in] user_data The user defined data. + */ +typedef void (*wifi_connection_changed_cb)(const char *ap_mac, const char *ap_ssid, char *ip_addr, void *user_data); + +/** + * @brief Initializes network utils. +*/ +int net_util_init(); + +/** + * @brief Finalizes network utils. +*/ +void net_util_fini(); + +/** + * @brief Sets WiFi connection changed callback. + * @param[in] callback Callback to be set. + * @param[in] user_data User defined data. +*/ +int net_util_set_wifi_connection_changed_cb(wifi_connection_changed_cb callback, void *user_data); + +/** + * @brief Gets access point MAC address. + * @param[out] mac The MAC address. +*/ +int net_util_get_ap_mac(char **mac); + +/** + * @brief Gets access point SSID. + * @param[out] The SSID. +*/ +int net_util_get_ap_ssid(char **ssid); + +/** + * @brief Gets device IP address. + * @param[out] The IP address +*/ +int net_util_get_ip_addr(char **ip); + +#endif \ No newline at end of file diff --git a/packaging/car-app.spec b/packaging/car-app.spec index 62ea0a2..b57469c 100644 --- a/packaging/car-app.spec +++ b/packaging/car-app.spec @@ -23,6 +23,7 @@ BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(json-glib-1.0) BuildRequires: pkgconfig(libcurl) BuildRequires: pkgconfig(capi-network-connection) +BuildRequires: pkgconfig(capi-network-wifi-manager) %description Car application diff --git a/src/app.c b/src/app.c index 0a161d3..fa9977a 100644 --- a/src/app.c +++ b/src/app.c @@ -27,6 +27,7 @@ #include "receiver.h" #include "message.h" #include "connection_manager.h" +#include "net-util.h" #define ENABLE_MOTOR 1 @@ -139,7 +140,7 @@ static gboolean __message_dispatcher(gpointer user_data) /* TODO : set calibration mode */ break; case MESSAGE_CMD_DRIVE: - /* TODO : driving car */ + /* TODO : driving car */ __driving_motors(msg->servo, msg->speed); break; case MESSAGE_CMD_BYE: @@ -226,6 +227,7 @@ static bool service_app_create(void *data) connection_manager_init(); connection_manager_set_state_changed_cb(__conn_state_changed_cb, ad); + net_util_init(); message_queue_new(); @@ -254,6 +256,7 @@ static void service_app_terminate(void *data) connection_manager_fini(); + net_util_fini(); receiver_fini(RECEIVER_TYPE_UDP); resource_close_all(); diff --git a/src/net-util.c b/src/net-util.c new file mode 100644 index 0000000..1e13c97 --- /dev/null +++ b/src/net-util.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "net-util.h" +#include +#include +#include +#include "log.h" + +typedef struct net_util_ { + wifi_manager_h wifi; + connection_h conn; + connection_type_e net_state; + char *ap_mac; + char *ap_ssid; + char *ip_addr; + wifi_connection_changed_cb cb; + void *cb_user_data; +} net_util_t; + +static net_util_t net_util; + +static int _set_ap_mac(); +static int _set_ap_ssid(); +static int _set_ip_addr(); +static void _connection_changed_cb(connection_type_e type, void *user_data); + +int net_util_init() +{ + int ret = 0; + ret = connection_create(&net_util.conn); + if (ret != CONNECTION_ERROR_NONE) { + _E("connection_create() failed, error: %s", get_error_message(ret)); + return -1; + } + + ret = connection_get_type(net_util.conn, &net_util.net_state); + if (ret != CONNECTION_ERROR_NONE) { + _E("connection_get_type() failed, error: %s", get_error_message(ret)); + goto ERROR_1; + } + + ret = wifi_manager_initialize(&net_util.wifi); + if (ret != WIFI_MANAGER_ERROR_NONE) { + _E("wifi_manager_initialize() failed, error: %s", get_error_message(ret)); + goto ERROR_1; + } + + ret = connection_set_type_changed_cb(net_util.conn, _connection_changed_cb, NULL); + if (ret != CONNECTION_ERROR_NONE) { + _E("connection_set_type_changed_cb() failed, error: %s", get_error_message(ret)); + goto ERROR_2; + } + + _set_ap_mac(); + _set_ap_ssid(); + _set_ip_addr(); + + return 0; + + ERROR_2: + ret = wifi_manager_deinitialize(&net_util.wifi); + if (ret != WIFI_MANAGER_ERROR_NONE) { + _E("wifi_manager_deinitialize() failed, error: %s", get_error_message(ret)); + } + + ERROR_1: + ret = connection_destroy(&net_util.conn); + if (ret != CONNECTION_ERROR_NONE) { + _E("wifi_manager_deinitialize() failed, error: %s", get_error_message(ret)); + } + return -1; +} + +void net_util_fini() +{ + net_util.net_state = CONNECTION_TYPE_DISCONNECTED; + + int ret = 0; + ret = connection_destroy(net_util.conn); + if (ret != CONNECTION_ERROR_NONE) { + _E("connection_set_type_changed_cb() failed, error: %s", get_error_message(ret)); + } + + ret = wifi_manager_deinitialize(&net_util.wifi); + if (ret != WIFI_MANAGER_ERROR_NONE) { + _E("wifi_manager_deinitialize() failed, error: %s", get_error_message(ret)); + } + + free(net_util.ap_mac); + free(net_util.ap_ssid); + free(net_util.ip_addr); +} + +int net_util_set_wifi_connection_changed_cb(wifi_connection_changed_cb callback, void *user_data) +{ + if (net_util.cb) + { + _E("Callback already set"); + return -1; + } + + net_util.cb = callback; + net_util.cb_user_data = user_data; + return 0; +} + +int net_util_get_ap_mac(char **mac) +{ + retv_if(!mac, -1); + + if (!net_util.ap_mac && _set_ap_mac() != 0) { + return -1; + } + + *mac = strdup(net_util.ap_mac); + return 0; +} + +int net_util_get_ap_ssid(char **ssid) +{ + retv_if(!ssid, -1); + + if (!net_util.ap_ssid && _set_ap_ssid() != 0) { + return -1; + } + + *ssid = strdup(net_util.ap_ssid); + return 0; +} + +int net_util_get_ip_addr(char **ip) +{ + retv_if(!ip, -1); + + if (!net_util.ip_addr && _set_ip_addr() != 0) { + return -1; + } + + *ip = strdup(net_util.ip_addr); + return 0; +} + +static int _set_ap_mac() +{ + wifi_manager_ap_h ap_h = NULL; + int ret = WIFI_MANAGER_ERROR_NONE; + + free(net_util.ap_mac); + net_util.ap_mac = NULL; + + if (net_util.net_state != CONNECTION_TYPE_WIFI) { + return -1; + } + + ret = wifi_manager_get_connected_ap(net_util.wifi, &ap_h); + if (ret != WIFI_MANAGER_ERROR_NONE) { + _E("wifi_manager_get_connected_ap() failed, error: %s", get_error_message(ret)); + return -1; + } + + int r_code = 0; + ret = wifi_manager_ap_get_bssid(ap_h, &net_util.ap_mac); + if (ret != WIFI_MANAGER_ERROR_NONE) { + _E("wifi_manager_ap_get_bssid() failed, error: %s", get_error_message(ret)); + r_code = -1; + } + + ret = wifi_manager_ap_destroy(ap_h); + if (ret != WIFI_MANAGER_ERROR_NONE) { + _E("wifi_manager_ap_destroy() failed, error: %s", get_error_message(ret)); + } + return r_code; +} + +static int _set_ap_ssid() +{ + wifi_manager_ap_h ap_h = NULL; + int ssid_len; + int ret = WIFI_MANAGER_ERROR_NONE; + + free(net_util.ap_ssid); + net_util.ap_ssid = NULL; + + if (net_util.net_state != CONNECTION_TYPE_WIFI) { + return -1; + } + + ret = wifi_manager_get_connected_ap(net_util.wifi, &ap_h); + if (ret != WIFI_MANAGER_ERROR_NONE) { + _E("wifi_manager_get_connected_ap() failed, error: %s", get_error_message(ret)); + return -1; + } + + int r_code = 0; + ret = wifi_manager_ap_get_raw_ssid(ap_h, &net_util.ap_ssid, &ssid_len); + if (ret != WIFI_MANAGER_ERROR_NONE) { + _E("wifi_manager_ap_get_raw_ssid() failed, error: %s", get_error_message(ret)); + r_code = -1; + } + + ret = wifi_manager_ap_destroy(ap_h); + if (ret != WIFI_MANAGER_ERROR_NONE) { + _E("wifi_manager_ap_destroy() failed, error: %s", get_error_message(ret)); + } + return r_code; +} + +static int _set_ip_addr() +{ + int ret = 0; + + free(net_util.ip_addr); + net_util.ap_ssid = NULL; + + if (net_util.net_state == CONNECTION_TYPE_DISCONNECTED) { + return -1; + } + + ret = connection_get_ip_address(net_util.conn, CONNECTION_ADDRESS_FAMILY_IPV4, &net_util.ip_addr); + if (CONNECTION_ERROR_NONE != ret) { + _E("connection_get_ip_address() failed, error: %s", get_error_message(ret)); + return -1; + } + + return 0; +} + +static void _connection_changed_cb(connection_type_e type, void *user_data) +{ + net_util.net_state = type; + _set_ap_mac(); + _set_ap_ssid(); + _set_ip_addr(); + + if (type == CONNECTION_TYPE_WIFI && net_util.cb) { + net_util.cb(net_util.ap_mac, net_util.ap_ssid, net_util.ip_addr, net_util.cb_user_data); + } +} \ No newline at end of file -- 2.7.4