--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <glib.h>
+#include <wifi-manager.h>
+
+#define MAX_SSID_LEN 100
+#define MIN_PASSWORD_LEN 8
+#define MAX_PASSWORD_LEN 100
+#define TIMEOUT 20000
+#define MAX_SCAN_RETRY 3
+
+#define PRINT_ERROR(...) { \
+ printf("[WIFI][ERROR] " __VA_ARGS__); \
+}
+
+#define PRINT_RESULT(...) { \
+ printf("[WIFI] " __VA_ARGS__); \
+}
+
+#define DEBUG(...) { \
+ printf("[WIFI][DEBUG] " __VA_ARGS__); \
+}
+
+#define EXIT_IF_RET_IS_ERROR(ret, msg) do { \
+ if (ret != WIFI_MANAGER_ERROR_NONE) { \
+ PRINT_ERROR("Fail %s (%d:%s)\n", msg, ret, __convert_error_to_string(ret)); \
+ exit(1); \
+ } \
+} while (0)
+
+#define RETURN_IF_RET_IS_ERROR(ret, msg) do { \
+ if (ret != WIFI_MANAGER_ERROR_NONE) { \
+ PRINT_ERROR("Fail %s (%d:%s)\n", msg, ret, __convert_error_to_string(ret)); \
+ return; \
+ } \
+} while (0)
+
+#define RUN_LOOP { \
+ g_wifi_main_loop = g_main_loop_new(NULL, false); \
+ g_timeout_id = g_timeout_add(TIMEOUT, __timeout_cb, g_wifi_main_loop); \
+ g_main_loop_run(g_wifi_main_loop); \
+ g_source_remove(g_timeout_id); \
+ g_wifi_main_loop = NULL; \
+}
+
+#define QUIT_LOOP { \
+ g_main_loop_quit(g_wifi_main_loop); \
+}
+
+static GMainLoop *g_wifi_main_loop;
+static int g_timeout_id;
+
+static wifi_manager_h g_wifi;
+static wifi_manager_ap_h g_wifi_ap;
+static char g_ssid[MAX_SSID_LEN + 1];
+static char g_password[MAX_PASSWORD_LEN + 1];
+
+static const char *__convert_error_to_string(int err)
+{
+ switch (err) {
+ case WIFI_MANAGER_ERROR_NONE:
+ return "NONE";
+ case WIFI_MANAGER_ERROR_INVALID_PARAMETER:
+ return "INVALID_PARAMETER";
+ case WIFI_MANAGER_ERROR_OUT_OF_MEMORY:
+ return "OUT_OF_MEMORY";
+ case WIFI_MANAGER_ERROR_INVALID_OPERATION:
+ return "INVALID_OPERATION";
+ case WIFI_MANAGER_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED:
+ return "ADDRESS_FAMILY_NOT_SUPPORTED";
+ case WIFI_MANAGER_ERROR_OPERATION_FAILED:
+ return "OPERATION_FAILED";
+ case WIFI_MANAGER_ERROR_NO_CONNECTION:
+ return "NO_CONNECTION";
+ case WIFI_MANAGER_ERROR_NOW_IN_PROGRESS:
+ return "NOW_IN_PROGRESS";
+ case WIFI_MANAGER_ERROR_ALREADY_EXISTS:
+ return "ALREADY_EXISTS";
+ case WIFI_MANAGER_ERROR_OPERATION_ABORTED:
+ return "OPERATION_ABORTED";
+ case WIFI_MANAGER_ERROR_DHCP_FAILED:
+ return "DHCP_FAILED";
+ case WIFI_MANAGER_ERROR_INVALID_KEY:
+ return "INVALID_KEY";
+ case WIFI_MANAGER_ERROR_NO_REPLY:
+ return "NO_REPLY";
+ case WIFI_MANAGER_ERROR_SECURITY_RESTRICTED:
+ return "SECURITY_RESTRICTED";
+ case WIFI_MANAGER_ERROR_ALREADY_INITIALIZED:
+ return "ALREADY_INITIALIZED";
+ case WIFI_MANAGER_ERROR_OUT_OF_RANGE:
+ return "OUT_OF_RANGE";
+ case WIFI_MANAGER_ERROR_CONNECT_FAILED:
+ return "CONNECT_FAILED";
+ case WIFI_MANAGER_ERROR_LOGIN_FAILED:
+ return "LOGIN_FAILED";
+ case WIFI_MANAGER_ERROR_AUTHENTICATION_FAILED:
+ return "AUTH_FAILED";
+ case WIFI_MANAGER_ERROR_PIN_MISSING:
+ return "PIN_MISSING";
+ case WIFI_MANAGER_ERROR_WPS_OVERLAP:
+ return "WPS_OVERLAP";
+ case WIFI_MANAGER_ERROR_WPS_TIMEOUT:
+ return "WPS_TIMEOUT";
+ case WIFI_MANAGER_ERROR_WPS_WEP_PROHIBITED:
+ return "WPS_WEP_PROHIBITED";
+ case WIFI_MANAGER_ERROR_PERMISSION_DENIED:
+ return "PERMISSION_DENIED";
+ case WIFI_MANAGER_ERROR_OFFLINE:
+ return "OFFLINE";
+ case WIFI_MANAGER_ERROR_INVALID_GATEWAY:
+ return "INVALID_GATEWAY";
+ case WIFI_MANAGER_ERROR_NOT_SUPPORTED:
+ return "NOT_SUPPORTED";
+ case WIFI_MANAGER_ERROR_NOT_INITIALIZED:
+ return "NOT_INITIALIZED";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+static gboolean __timeout_cb(gpointer data)
+{
+ GMainLoop *main_loop = (GMainLoop *)data;
+ if (main_loop == NULL) {
+ PRINT_ERROR("main_loop is NULL\n");
+ }
+
+ PRINT_ERROR("Callback Timeout\n");
+ g_main_loop_quit(main_loop);
+ exit(1);
+}
+
+
+static void __activate_cb(wifi_manager_error_e error, void *user_data)
+{
+ if (error != WIFI_MANAGER_ERROR_NONE) {
+ PRINT_ERROR("Fail to activate %s\n", __convert_error_to_string(error));
+ exit(1);
+ }
+ QUIT_LOOP;
+}
+
+static void activate()
+{
+ int ret = WIFI_MANAGER_ERROR_NONE;
+ bool power_on = false;
+
+ ret = wifi_manager_is_activated(g_wifi, &power_on);
+ EXIT_IF_RET_IS_ERROR(ret, "wifi_manager_is_activated");
+
+ if (power_on == false) {
+ ret = wifi_manager_activate(g_wifi, __activate_cb, NULL);
+ EXIT_IF_RET_IS_ERROR(ret, "wifi_manager_activate");
+ RUN_LOOP;
+ }
+}
+
+static void __forget_cb(wifi_manager_error_e error, void *user_data)
+{
+ if (error != WIFI_MANAGER_ERROR_NONE) {
+ PRINT_ERROR("Fail to forget %s\n", __convert_error_to_string(error));
+ exit(1);
+ }
+ QUIT_LOOP;
+}
+
+static bool check_connected_ap()
+{
+ int ret = WIFI_MANAGER_ERROR_NONE;
+ wifi_manager_ap_h ap = NULL;
+ char *ap_name;
+ bool already_connected = false;
+
+ ret = wifi_manager_get_connected_ap(g_wifi, &ap);
+ if (ret == WIFI_MANAGER_ERROR_NO_CONNECTION)
+ return false;
+ EXIT_IF_RET_IS_ERROR(ret, "wifi_manager_get_connected_ap");
+
+ if (ap) {
+ ret = wifi_manager_ap_get_essid(ap, &ap_name);
+ if (ret != WIFI_MANAGER_ERROR_NONE)
+ PRINT_ERROR("Fail wifi_manager_ap_get_essid (%d:%s)\n", ret, __convert_error_to_string(ret));
+
+ PRINT_RESULT("Connected to %s\n", ap_name);
+
+ if (!strcmp(ap_name, g_ssid)) {
+ already_connected = true;
+ }
+ else {
+ ret = wifi_manager_forget_ap_async(g_wifi, ap, __forget_cb, NULL);
+ EXIT_IF_RET_IS_ERROR(ret, "wifi_manager_forget_ap_async");
+ RUN_LOOP;
+ PRINT_RESULT("Forget %s\n", ap_name);
+ }
+
+ ret = wifi_manager_ap_destroy(ap);
+ if (ret != WIFI_MANAGER_ERROR_NONE)
+ PRINT_ERROR("Fail wifi_manager_ap_destroy(%d:%s)\n", ret, __convert_error_to_string(ret));
+ }
+
+ return already_connected;
+}
+
+static void __scan_cb(wifi_manager_error_e error, void *user_data)
+{
+ if (error != WIFI_MANAGER_ERROR_NONE) {
+ PRINT_ERROR("Fail to scan %s\n", __convert_error_to_string(error));
+ exit(1);
+ }
+ QUIT_LOOP;
+}
+
+static bool __found_ap_cb(wifi_manager_ap_h ap, void *user_data)
+{
+ char *ap_name;
+ int ret = WIFI_MANAGER_ERROR_NONE;
+
+ if (ap) {
+ ret = wifi_manager_ap_get_essid(ap, &ap_name);
+ if (ret != WIFI_MANAGER_ERROR_NONE) {
+ PRINT_ERROR("Fail wifi_manager_ap_get_essid (%d:%s)\n", ret, __convert_error_to_string(ret));
+ return true;
+ }
+
+ if (!strcmp(ap_name, g_ssid)) {
+ DEBUG("Found %s\n", g_ssid);
+ ret = wifi_manager_ap_clone(&g_wifi_ap, ap);
+ if (ret != WIFI_MANAGER_ERROR_NONE) {
+ PRINT_ERROR("Fail wifi_manager_ap_clone(%d:%s)\n", ret, __convert_error_to_string(ret));
+ return false;
+ }
+
+ if (g_wifi_ap)
+ return false;
+ }
+ }
+ return true;
+}
+
+static void scan()
+{
+ int ret = WIFI_MANAGER_ERROR_NONE;
+ ret = wifi_manager_scan(g_wifi, __scan_cb, NULL);
+ RETURN_IF_RET_IS_ERROR(ret, "wifi_manager_scan");
+ RUN_LOOP;
+
+ ret = wifi_manager_foreach_found_ap(g_wifi, __found_ap_cb, NULL);
+ RETURN_IF_RET_IS_ERROR(ret, "wifi_manager_foreach_found_ap");
+}
+
+static void __connect_cb(wifi_manager_error_e error, void *user_data)
+{
+ if (error != WIFI_MANAGER_ERROR_NONE) {
+ PRINT_ERROR("Fail to connect %s\n", __convert_error_to_string(error));
+ exit(1);
+ }
+ QUIT_LOOP;
+}
+
+static void connect()
+{
+ int ret = WIFI_MANAGER_ERROR_NONE;
+ ret = wifi_manager_ap_set_passphrase(g_wifi_ap, g_password);
+ EXIT_IF_RET_IS_ERROR(ret, "wifi_manager_ap_set_passphrase");
+
+ ret = wifi_manager_connect(g_wifi, g_wifi_ap, __connect_cb, NULL);
+ RUN_LOOP;
+}
+
+static void start()
+{
+ int ret = wifi_manager_initialize(&g_wifi);
+ EXIT_IF_RET_IS_ERROR(ret, "wifi_manager_initialize");
+ PRINT_RESULT("Initialized\n");
+
+ activate();
+ PRINT_RESULT("Activated\n");
+
+ if (!check_connected_ap()) {
+ for (int i = 0; i < MAX_SCAN_RETRY; ++i) {
+ g_wifi_ap = NULL;
+ scan();
+ if (g_wifi_ap)
+ break;
+ else
+ DEBUG("Scan %d: Not found AP %s\n", (i + 1), g_ssid);
+ }
+ if (!g_wifi_ap) {
+ PRINT_ERROR("Not found AP %s\n", g_ssid);
+ exit(1);
+ }
+
+ PRINT_RESULT("Scanned\n");
+
+ connect();
+ }
+ PRINT_RESULT("Connected\n");
+}
+
+int main(int argc, char **argv)
+{
+ int passwd_len = 0;
+
+#if !GLIB_CHECK_VERSION(2, 36, 0)
+ g_type_init();
+#endif
+
+ if (argc != 3) {
+ printf("Usage: %s [SSID] [PASSWORD]\n", argv[0]);
+ return 1;
+ }
+
+ if (strlen(argv[1]) > MAX_SSID_LEN) {
+ PRINT_ERROR("Too long SSID\n");
+ return 1;
+ }
+
+ passwd_len = strlen(argv[2]);
+ if (passwd_len < MIN_PASSWORD_LEN) {
+ PRINT_ERROR("Too short password\n");
+ return 1;
+ }
+
+ if (passwd_len > MAX_PASSWORD_LEN) {
+ PRINT_ERROR("Too long password\n");
+ return 1;
+ }
+
+ strncpy(g_ssid, argv[1], MAX_SSID_LEN);
+ strncpy(g_password, argv[2], MAX_PASSWORD_LEN);
+
+ printf("Start to connect to a Wi-Fi network\n");
+ start();
+
+ return 0;
+}