summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTasuku Suzuki <tasuku.suzuki@qt.io>2016-12-14 18:10:54 +0900
committerTasuku Suzuki <tasuku.suzuki@qt.io>2016-12-14 23:23:02 +0900
commitf67d4105a572345d1fed1231e06b99bd9411d040 (patch)
tree134fef0892a481d9cbbd7633feb40ae5b2439650
merge the Settings in CES2017 and bindings from ALPS
Change-Id: I00a7a6c5dae1cd579f91d543b0f5fba4616a633b Signed-off-by: Tasuku Suzuki <tasuku.suzuki@qt.io>
-rw-r--r--agent.c262
-rw-r--r--binding-wifi.pro11
-rw-r--r--binding.pri6
-rw-r--r--export.map1
-rw-r--r--wifi-api.c489
-rw-r--r--wifi-api.h38
-rw-r--r--wifi-connman.c354
-rw-r--r--wifi-connman.h126
8 files changed, 1287 insertions, 0 deletions
diff --git a/agent.c b/agent.c
new file mode 100644
index 0000000..a22dc31
--- /dev/null
+++ b/agent.c
@@ -0,0 +1,262 @@
+/* Copyright 2016 ALPS ELECTRIC 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 <errno.h>
+
+#include <gio/gio.h>
+#include "wifi-connman.h"
+
+static GMainLoop *loop = NULL;
+
+static GDBusNodeInfo *introspection_data = NULL;
+
+GDBusMethodInvocation *invocation_passkey = NULL;
+
+/* Introspection data for the agent service */
+static const gchar introspection_xml[] = "<node>"
+ " <interface name='net.connman.Agent'>"
+ " <method name='RequestInput'>"
+ " <arg type='o' name='service' direction='in'/>"
+ " <arg type='a{sv}' name='fields' direction='in'/>"
+ " <arg type='a{sv}' name='fields' direction='out'/>"
+ " </method>"
+ " <method name='ReportError'>"
+ " <arg type='o' name='service' direction='in'/>"
+ " <arg type='s' name='error' direction='in'/>"
+ " </method>"
+ " </interface>"
+ "</node>";
+
+callback password_callback;
+
+static void handle_method_call(GDBusConnection *connection, const gchar *sender,
+ const gchar *object_path, const gchar *interface_name,
+ const gchar *method_name, GVariant *parameters,
+ GDBusMethodInvocation *invocation, gpointer user_data) {
+ //MyObject *myobj = user_data;
+
+ if (g_strcmp0(method_name, "RequestInput") == 0) {
+ printf("Input requested\n");
+
+ invocation_passkey = invocation;
+
+ //TODO: send the name of the network to callback
+
+ (*password_callback)(0);
+
+ GVariantIter *array;
+ gchar * object_path;
+ g_variant_get(parameters, "(oa{sv})", &object_path, &array);
+ //TODO: get only object path for now, complete parameters are
+
+ /*
+ object path "/net/connman/service/wifi_d85d4c880b1a_4c656e6f766f204b3520506c7573_managed_psk"
+ array [
+ dict entry(
+ string "Passphrase"
+ variant array [
+ dict entry(
+ string "Type"
+ variant string "psk"
+ )
+ dict entry(
+ string "Requirement"
+ variant string "mandatory"
+ )
+ ]
+ )
+ ]
+ */
+ printf("Passphrase requested for network : %s\n", object_path);
+
+ }
+
+ if (g_strcmp0(method_name, "ReportError") == 0) {
+ printf("Error reported\n");
+
+ gchar *error_string; // = NULL;
+
+ gchar * object_path;
+ g_variant_get(parameters, "(os)", &object_path, &error_string);
+
+ printf("Error %s for %s\n", error_string, object_path);
+
+ if (g_strcmp0(error_string, "invalid-key") == 0) {
+
+ printf("Passkey is not correct.\n");
+ (*password_callback)(1);
+
+ }
+
+ }
+}
+
+GError* sendPasskey(gchar *passkey) {
+
+ GVariantBuilder *builder;
+ GVariant *value = NULL;
+
+ printf("Passkey to send: %s\n", passkey);
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+
+ g_variant_builder_add(builder, "{sv}", "Passphrase",
+ g_variant_new_string(passkey));
+
+ value = g_variant_new("(a{sv})", builder);
+
+ g_dbus_method_invocation_return_value(invocation_passkey, value);
+
+ return NULL;
+
+}
+
+static const GDBusInterfaceVTable interface_vtable = { handle_method_call, NULL,
+ NULL };
+
+static void on_bus_acquired(GDBusConnection *connection, const gchar *name,
+ gpointer user_data) {
+ //MyObject *myobj = user_data;
+ guint registration_id;
+
+ registration_id = g_dbus_connection_register_object(connection,
+ "/net/connman/Agent", introspection_data->interfaces[0],
+ &interface_vtable, NULL, NULL, /* user_data_free_func */
+ NULL); /* GError** */
+ //TODO: make some proper error message rather than exiting
+ //g_assert(registration_id > 0);
+
+ return NULL;
+}
+
+void* register_agent(void *data) {
+
+ //printf("Loop start\n");
+
+ guint owner_id;
+ //MyObject *myobj;
+
+ introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
+ g_assert(introspection_data != NULL);
+
+ //myobj = g_object_new(my_object_get_type(), NULL);
+
+// owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, "org.agent",
+// G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired, on_name_acquired,
+// on_name_lost, myobj,
+// NULL);
+
+//FIXME: ALLOW_REPLACEMENT for now, make proper deinitialization
+ owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, AGENT_SERVICE,
+ G_BUS_NAME_OWNER_FLAGS_REPLACE, on_bus_acquired, NULL, NULL, NULL,
+ NULL);
+ //G_BUS_NAME_OWNER_FLAGS_NONE G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT
+
+ loop = g_main_loop_new(NULL, FALSE);
+
+ //sleep(10);
+ g_main_loop_run(loop);
+
+ printf("Loop running\n");
+
+ g_bus_unown_name(owner_id);
+
+ g_dbus_node_info_unref(introspection_data);
+
+ //g_object_unref(myobj);
+
+ //printf("Loop end\n");
+
+ return NULL;
+
+}
+
+GError* create_agent(GDBusConnection *connection) {
+
+ int err = -1;
+ pthread_t tid[1];
+
+ //struct callbackData *threadData;
+
+ err = pthread_create((&tid[0]), NULL, register_agent, NULL);
+
+ if (err != 0) {
+ printf("\ncan't create thread :[%d]", err);
+ printf("Fatal error!\n\n");
+ return NULL;
+ }
+
+ GVariant *message = NULL;
+ GError *error = NULL;
+
+ GVariant *params = NULL;
+
+ char *agent_path = AGENT_PATH;
+
+ params = g_variant_new("(o)", agent_path);
+
+ message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE,
+ CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, "RegisterAgent", params,
+ NULL, G_DBUS_CALL_FLAGS_NONE,
+ DBUS_REPLY_TIMEOUT, NULL, &error);
+
+ if (error) {
+ printf("error: %d:%s\n", error->code, error->message);
+
+ return error;
+
+ } else {
+ printf("Agent registered\n");
+ return NULL;
+ }
+
+}
+
+GError* stop_agent(GDBusConnection *connection) {
+
+ GVariant *message = NULL;
+ GError *error = NULL;
+
+
+ GVariant *params = NULL;
+
+ char *agent_path = AGENT_PATH;
+
+
+ params = g_variant_new("(o)", agent_path);
+
+ message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE,
+ CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, "UnregisterAgent", params,
+ NULL, G_DBUS_CALL_FLAGS_NONE,
+ DBUS_REPLY_TIMEOUT, NULL, &error);
+
+ if (error) {
+ printf("error: %d:%s\n", error->code, error->message);
+ return error;
+
+ } else {
+ printf("Agent unregistered\n");
+ return NULL;
+ }
+
+}
+
+void register_callback(callback callback_function) {
+
+ password_callback = callback_function;
+
+}
+
diff --git a/binding-wifi.pro b/binding-wifi.pro
new file mode 100644
index 0000000..09c54b4
--- /dev/null
+++ b/binding-wifi.pro
@@ -0,0 +1,11 @@
+TARGET = serttings-wifi-binding
+
+HEADERS = wifi-api.h wifi-connman.h
+SOURCES = agent.c wifi-api.c wifi-connman.c
+
+LIBS += -Wl,--version-script=$$PWD/export.map
+
+CONFIG += link_pkgconfig
+PKGCONFIG += json-c afb-daemon glib-2.0 gio-2.0 gobject-2.0 zlib
+
+include(binding.pri)
diff --git a/binding.pri b/binding.pri
new file mode 100644
index 0000000..3448a56
--- /dev/null
+++ b/binding.pri
@@ -0,0 +1,6 @@
+TEMPLATE = lib
+CONFIG += plugin use_c_linker
+CONFIG -= qt
+QMAKE_CFLAGS += -Wextra -Wconversion -Wno-unused-parameter -Werror=maybe-uninitialized -Werror=implicit-function-declaration -ffunction-sections -fdata-sections -Wl,--as-needed -Wl,--gc-sections
+
+DESTDIR = $${OUT_PWD}/../package/root/lib
diff --git a/export.map b/export.map
new file mode 100644
index 0000000..0ef1ac7
--- /dev/null
+++ b/export.map
@@ -0,0 +1 @@
+{ global: afbBindingV1Register; local: *; };
diff --git a/wifi-api.c b/wifi-api.c
new file mode 100644
index 0000000..2d9748f
--- /dev/null
+++ b/wifi-api.c
@@ -0,0 +1,489 @@
+/* Copyright 2016 ALPS ELECTRIC 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.
+*/
+
+/**
+ * file
+ *
+ * \brief Implementation of WiFi Binder for AGL's App Framework
+ *
+ * \author ALPS Electric
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <json-c/json.h>
+#include <afb/afb-binding.h>
+
+#include "wifi-api.h"
+#include "wifi-connman.h"
+
+/*
+ * the interface to afb-daemon
+ */
+const struct afb_binding_interface *afbitf;
+
+static int need_password_flag = 0;
+static int password_not_correct_flag = 0;
+
+char *passkey;
+callback ptr_my_callback;
+
+GSList *wifi_list = NULL;
+
+/**
+ * \brief Read out the passkey from the use and pass it to Agent
+ *
+ * \todo Since I do not know how to subscribe for the events from framework,
+ * it is necessary first to register the password http://IP_ADDRESS:PORT/api/wifi-manager/security?passkey=mypassword.
+ * Then this function is called automatically.
+ *
+ *
+ * */
+void passkey_inserted(void) {
+
+ printf("Passkey inserted: %s\n", passkey);
+
+ if (passkey != NULL) {
+
+ registerPasskey(passkey);
+ } else {
+ printf("Please enter the password first\n");
+
+ }
+}
+
+/**
+ * \brief Notify user that password is necessary
+ *
+ * This function is called from the registered agent on RequestInput() call.
+ * \todo Subscribe for this event from GUI.
+ *
+ * */
+void ask_for_passkey(int password_rejected_flag) {
+ //TODO: show network we are asking password for
+ printf("Insert passkey.\n");
+
+ if (!password_rejected_flag) {
+ need_password_flag = 1;
+ password_not_correct_flag = 0;
+ //sleep(1);
+ passkey_inserted();
+
+ }
+
+ else if (password_rejected_flag) {
+ need_password_flag = 1;
+ printf("Password not correct!\n");
+
+ }
+
+}
+
+/**
+ * \brief Insert passkey that will be used for connections to secured AP.
+ *
+ * \TODO Only temporary, user should enter the password on ask_for_passkey() callback
+ *
+ * */
+void wifi_insertpasskey(struct afb_req request) {
+
+ const char *passkey_from_user;
+
+ /* retrieves the argument, expects password string */
+ passkey_from_user = afb_req_value(request, "passkey");
+
+ if (passkey_from_user == NULL) {
+ //TODO:better error message
+ afb_req_fail(request, "failed", "specify a security key");
+
+ } else {
+
+ passkey = g_try_malloc0(256);
+ strcpy(passkey, passkey_from_user);
+ printf("Passkey is %s\n", passkey);
+
+ }
+
+ afb_req_success(request, NULL, NULL);
+}
+
+/**
+ * \brief initialize the binder and activates the WiFi HW, should be called first
+ *
+ * This will fail if
+ * - agent for handling password requests cannot be registered
+ * - some error is returned from connman
+ *
+ *
+ * \return result of the request, either "success" or "failed" with description
+ */
+static void wifi_activate(struct afb_req request) /*AFB_SESSION_CHECK*/
+{
+ json_object *jresp;
+ GError *error = NULL;
+
+ if (ptr_my_callback == NULL) {
+
+ printf("Registering callback\n");
+
+ ptr_my_callback = ask_for_passkey;
+ register_callback(ptr_my_callback);
+
+ }
+
+ jresp = json_object_new_object();
+ json_object_object_add(jresp, "activation", json_object_new_string("on"));
+
+ error = do_wifiActivate();
+
+ if (error == NULL) {
+
+ afb_req_success(request, jresp, "Wi-Fi - Activated");
+
+ } else
+
+ afb_req_fail(request, "failed", error->message);
+
+}
+
+/**
+ * \brief deinitialize the binder and activates the WiFi HW
+ *
+ * This will fail if
+ * - agent for handling password requests cannot be unregistered
+ * - some error is returned from connman
+ *
+ *
+ * \return result of the request, either "success" or "failed" with description
+ */
+static void wifi_deactivate(struct afb_req request) /*AFB_SESSION_CHECK*/
+{
+
+ json_object *jresp;
+ GError *error = NULL;
+
+ ptr_my_callback = NULL;
+
+ jresp = json_object_new_object();
+ json_object_object_add(jresp, "deactivation", json_object_new_string("on"));
+
+ error = do_wifiDeactivate();
+
+ if (error == NULL) {
+
+ afb_req_success(request, jresp, "Wi-Fi - Activated");
+
+ } else
+
+ afb_req_fail(request, "failed", error->message);
+}
+
+/**
+ * \brief starts scan
+ *
+ * \return result of the request, either "success" or "failed" with description
+ */
+void wifi_scan(struct afb_req request) /*AFB_SESSION_NONE*/
+{
+ GError *error = NULL;
+
+ error = do_wifiScan();
+
+ if (error == NULL) {
+
+ afb_req_success(request, NULL, "Wi-Fi - Scan success");
+
+ } else
+
+ afb_req_fail(request, "failed", error->message);
+
+}
+
+/**
+ * \brief return network list
+ *
+ *
+ * \return result of the request, either "success" or "failed" with description
+ */
+void wifi_scanResult(struct afb_req request) /*AFB_SESSION_CHECK*/
+{
+ struct wifi_profile_info *wifiProfile = NULL;
+ GSList *list = NULL;
+ GSList *holdMe = NULL;
+ wifi_list = NULL;
+ char *essid = NULL;
+ char *address = NULL;
+ char *security = NULL;
+ char *state = NULL;
+ int strength = 0;
+ int number = 0;
+ GError *error = NULL;
+
+ error = do_displayScan(&wifi_list); /*Get wifi scan list*/
+ if (error == NULL) {
+ json_object *my_array = json_object_new_array();
+
+ for (list = wifi_list; list; list = list->next) { /*extract wifi scan result*/
+ wifiProfile = (struct wifi_profile_info *) list->data;
+ security = wifiProfile->Security.sec_type;
+ strength = wifiProfile->Strength;
+ //if (essid == NULL || security == NULL)
+ // continue;
+
+ essid = wifiProfile->ESSID == NULL ?
+ "HiddenSSID" : wifiProfile->ESSID;
+ address =
+ wifiProfile->wifiNetwork.IPaddress == NULL ?
+ "unsigned" : wifiProfile->wifiNetwork.IPaddress;
+ state = wifiProfile->state;
+ //TODO: is there a case when security is NULL?
+
+ json_object *int1 = json_object_new_int(number);
+ json_object *int2 = json_object_new_int(strength);
+ json_object *jstring1 = json_object_new_string(essid);
+ json_object *jstring2 = json_object_new_string(security);
+ json_object *jstring3 = json_object_new_string(address);
+ json_object *jstring4 = json_object_new_string(state);
+
+ json_object *jresp = json_object_new_object();
+ json_object_object_add(jresp, "Number", int1);
+ json_object_object_add(jresp, "Strength", int2);
+ json_object_object_add(jresp, "ESSID", jstring1);
+ json_object_object_add(jresp, "Security", jstring2);
+ json_object_object_add(jresp, "IPAddress", jstring3);
+ json_object_object_add(jresp, "State", jstring4);
+
+ printf("The object json: %s\n", json_object_to_json_string(jresp));
+ /*input each scan result into my_array*/
+ json_object_array_add(my_array, jresp);
+ number += 1;
+ }
+ while (list != NULL) {
+ printf("Should be freed");
+ holdMe = list->next;
+ g_free(list);
+ list = holdMe;
+ }
+ afb_req_success(request, my_array, "Wi-Fi - Scan Result is Displayed");
+ } else
+ afb_req_fail(request, "failed", error->message);
+}
+
+/**
+ * \brief connects to network
+ *
+ * \param[in] request number of network to connect to
+ *
+ * specify number of network to connect to obtained by scan_result() like this,
+ * http://IP_ADDRESS:PORT/api/wifi-manager/connect?network=1
+ */
+void wifi_connect(struct afb_req request) {
+
+ struct wifi_profile_info *wifiProfileToConnect = NULL;
+
+ const char *network;
+ int network_index = 0;
+ GError *error = NULL;
+ GSList *item = NULL;
+
+ /* retrieves the argument, expects the network number */
+ network = afb_req_value(request, "network");
+
+ if (network == NULL)
+ //TODO:better error message
+ afb_req_fail(request, "failed",
+ "specify a network number to connect to");
+
+ else {
+ network_index = atoi(network);
+ printf("Joining network number %d\n", network_index);
+
+ }
+
+ //get information about desired network
+ item = g_slist_nth_data(wifi_list, network_index);
+
+ if (item == NULL) {
+ //Index starts from 1
+ printf("Network with number %d not found.\n", network_index + 1);
+ //TODO:better error message
+ afb_req_fail(request, "failed", "bad arguments");
+ }
+
+ else {
+ wifiProfileToConnect = (struct wifi_profile_info *) item;
+ printf("Name: %s, strength: %d, %s\n", wifiProfileToConnect->ESSID,
+ wifiProfileToConnect->Strength,
+ wifiProfileToConnect->NetworkPath);
+ //printf ("Connecting to %s\n", wifiProfileToConnect->NetworkPath);
+ }
+ error = do_connectNetwork(wifiProfileToConnect->NetworkPath);
+
+ if (error == NULL)
+ afb_req_success(request, NULL, NULL);
+
+ else if (password_not_correct_flag) {
+ need_password_flag = 0;
+ password_not_correct_flag = 0;
+ afb_req_fail(request, "password-incorrect", NULL);
+ } else if (need_password_flag) {
+ need_password_flag = 0;
+ afb_req_fail(request, "need-password", NULL);
+
+ } else
+ afb_req_fail(request, "failed", error->message);
+}
+
+/**
+ * \brief disconnect from network
+ *
+ * \param[in] request number of network to disconnect from
+ *
+ * specify number of network to disconnect from obtained by scan_result() like this,
+ * http://IP_ADDRESS:PORT/api/wifi-manager/discnnect?network=1
+ */
+void wifi_disconnect(struct afb_req request) {
+
+ struct wifi_profile_info *wifiProfileToConnect = NULL;
+
+ const char *network;
+ int network_index = 0;
+ GError *error = NULL;
+ GSList *item = NULL;
+
+ /* retrieves the argument, expects the network number */
+ network = afb_req_value(request, "network");
+
+ if (network == NULL)
+ //TODO:better error message
+ afb_req_fail(request, "failed",
+ "specify a network number to disconnect from");
+
+ else {
+ network_index = atoi(network);
+ printf("Joining network number %d\n", network_index);
+
+ }
+
+ //get information about desired network
+ item = g_slist_nth_data(wifi_list, network_index);
+
+ if (item == NULL) {
+ //Index starts from 1
+ printf("Network with number %d not found.\n", network_index + 1);
+ //TODO:better error message
+ afb_req_fail(request, "failed", "bad arguments");
+ }
+
+ else {
+ wifiProfileToConnect = (struct wifi_profile_info *) item;
+ printf("Name: %s, strength: %d, %s\n", wifiProfileToConnect->ESSID,
+ wifiProfileToConnect->Strength,
+ wifiProfileToConnect->NetworkPath);
+ //printf ("Connecting to %s\n", wifiProfileToConnect->NetworkPath);
+ }
+ error = do_disconnectNetwork(wifiProfileToConnect->NetworkPath);
+
+ if (error == NULL)
+ afb_req_success(request, NULL, NULL);
+ else
+ afb_req_fail(request, "failed", error->message);
+}
+
+/**
+ * \brief return current status of connection
+ *
+ * \return result of the request, either "success" or "failed" with description
+ */
+void wifi_status(struct afb_req request) {
+ int error = 0;
+ wifi_list = NULL;
+ struct wifiStatus *status;
+ json_object *jresp = json_object_new_object();
+
+ status = g_try_malloc0(sizeof(struct wifiStatus));
+ error = wifi_state(status); /*get current status of power and connection*/
+ if (!error) {
+ if (status->state == 0) {/*Wi-Fi is OFF*/
+ json_object_object_add(jresp, "Power",
+ json_object_new_string("OFF"));
+ //json_object_object_add(jresp, "Connection", json_object_new_string("Disconnected"));
+ printf("Wi-Fi OFF\n");
+ } else {/*Wi-Fi is ON*/
+ json_object_object_add(jresp, "Power",
+ json_object_new_string("ON"));
+ if (status->connected == 0) {/*disconnected*/
+ json_object_object_add(jresp, "Connection",
+ json_object_new_string("Disconnected"));
+ printf("Wi-Fi ON - Disconnected \n");
+ } else {/*Connected*/
+ json_object_object_add(jresp, "Connection",
+ json_object_new_string("Connected"));
+ printf("Wi-Fi ON - Connected \n");
+ }
+ }
+ afb_req_success(request, jresp, "Wi-Fi - Connection Status Checked");
+ } else {
+ afb_req_fail(request, "failed", "Wi-Fi - Connection Status unknown");
+ }
+}
+
+void wifi_reconnect() {
+ /*TBD*/
+}
+
+
+
+/*
+ * array of the verbs exported to afb-daemon
+ */
+static const struct afb_verb_desc_v1 binding_verbs[] = {
+/* VERB'S NAME SESSION MANAGEMENT FUNCTION TO CALL SHORT DESCRIPTION */
+{ .name = "activate", .session = AFB_SESSION_NONE, .callback = wifi_activate, .info = "Activate Wi-Fi" },
+{ .name = "deactivate", .session = AFB_SESSION_NONE, .callback = wifi_deactivate, .info ="Deactivate Wi-Fi" },
+{ .name = "scan", .session = AFB_SESSION_NONE, .callback = wifi_scan, .info = "Scanning Wi-Fi" },
+{ .name = "scan_result",.session = AFB_SESSION_NONE, .callback = wifi_scanResult, .info = "Get scan result Wi-Fi" },
+{ .name = "connect", .session = AFB_SESSION_NONE, .callback = wifi_connect, .info ="Connecting to Access Point" },
+{ .name = "status", .session = AFB_SESSION_NONE, .callback = wifi_status, .info ="Check connection status" },
+{ .name = "disconnect", .session = AFB_SESSION_NONE, .callback = wifi_disconnect, .info ="Disconnecting connection" },
+{ .name = "reconnect", .session = AFB_SESSION_NONE, .callback = wifi_reconnect, .info ="Reconnecting to Access Point" },
+{ .name = "security", .session = AFB_SESSION_NONE, .callback = wifi_insertpasskey, .info ="Insert passkey" },
+
+{ .name = NULL } /* marker for end of the array */
+};
+
+/*
+ * description of the binding for afb-daemon
+ */
+static const struct afb_binding binding_description = {
+/* description conforms to VERSION 1 */
+.type = AFB_BINDING_VERSION_1, .v1 = { /* fills the v1 field of the union when AFB_BINDING_VERSION_1 */
+.prefix = "wifi-manager", /* the API name (or binding name or prefix) */
+.info = "wifi API", /* short description of of the binding */
+.verbs = binding_verbs /* the array describing the verbs of the API */
+} };
+
+/*
+ * activation function for registering the binding called by afb-daemon
+ */
+const struct afb_binding *afbBindingV1Register(
+ const struct afb_binding_interface *itf) {
+ afbitf = itf; // records the interface for accessing afb-daemon
+ return &binding_description; // returns the description of the binding
+}
+
diff --git a/wifi-api.h b/wifi-api.h
new file mode 100644
index 0000000..429211b
--- /dev/null
+++ b/wifi-api.h
@@ -0,0 +1,38 @@
+/* Copyright 2016 ALPS ELECTRIC 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.
+*/
+
+#ifndef WIFI_API_H
+#define WIFI_API_H
+
+/* global plugin handle, should store everything we may need */
+typedef struct {
+ int devCount;
+} pluginHandleT;
+
+/* private client context [will be destroyed when client leaves] */
+typedef struct {
+ unsigned char activate;
+ unsigned char connected;
+} wifiCtxHandleT;
+
+
+struct scan_list_info {
+ int number;
+ char *SSID;
+ char *Security;
+ int Strength;
+};
+
+#endif /* AUDIO_API_H */
diff --git a/wifi-connman.c b/wifi-connman.c
new file mode 100644
index 0000000..74d2be7
--- /dev/null
+++ b/wifi-connman.c
@@ -0,0 +1,354 @@
+/* Copyright 2016 ALPS ELECTRIC 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 <string.h>
+#include <unistd.h>
+#include <glib.h>
+//#include <dbus/dbus.h>
+#include <gio/gio.h>
+#include <glib-object.h>
+
+#include "wifi-api.h"
+#include "wifi-connman.h"
+
+static __thread struct security_profile Security = { NULL, NULL, NULL, NULL, 0,
+ 0 };
+
+int extract_values(GVariantIter *content, struct wifi_profile_info* wifiProfile) {
+ GVariant *var = NULL;
+ GVariant *subvar = NULL;
+ GVariantIter *array;
+ const gchar *key = NULL;
+ const gchar *subkey = NULL;
+ const gchar *value_char = NULL;
+ GVariantIter *content_sub;
+ int value_int;
+ gsize length;
+
+ while (g_variant_iter_loop(content, "{sv}", &key, &var)) {
+ if (g_strcmp0(key, "Name") == 0) {
+ value_char = g_variant_get_string(var, &length);
+ wifiProfile->ESSID = (char *) value_char;
+ } else if (g_strcmp0(key, "Security") == 0) {
+ g_variant_get(var, "as", &content_sub);
+ while (g_variant_iter_loop(content_sub, "s", &value_char)) {
+ if (g_strcmp0(value_char, "none") == 0)
+ wifiProfile->Security.sec_type = "Open";
+ else if (g_strcmp0(value_char, "wep") == 0)
+ wifiProfile->Security.sec_type = "WEP";
+ else if (g_strcmp0(value_char, "psk") == 0)
+ wifiProfile->Security.sec_type = "WPA-PSK";
+ else if (g_strcmp0(value_char, "ieee8021x") == 0)
+ wifiProfile->Security.sec_type = "ieee8021x";
+ else if (g_strcmp0(value_char, "wpa") == 0)
+ wifiProfile->Security.sec_type = "WPA-PSK";
+ else if (g_strcmp0(value_char, "rsn") == 0)
+ wifiProfile->Security.sec_type = "WPA2-PSK";
+ else if (g_strcmp0(value_char, "wps") == 0)
+ wifiProfile->Security.wps_support = 1;
+ else
+ Security.sec_type = "Open";
+ }
+ } else if (g_strcmp0(key, "Strength") == 0) {
+ value_int = (unsigned int) g_variant_get_byte(var);
+ wifiProfile->Strength = value_int;
+ } else if (g_strcmp0(key, "State") == 0) {
+ value_char = g_variant_get_string(var, &length);
+ wifiProfile->state = (char *) value_char;
+ } else if (g_strcmp0(key, "IPv4") == 0) {
+ g_variant_get(var, "a{sv}", &array);
+ while (g_variant_iter_loop(array, "{sv}", &subkey, &subvar)) {
+ if (g_strcmp0(subkey, "Method") == 0) {
+ value_char = g_variant_get_string(subvar, &length);
+ if (g_strcmp0(value_char, "dhcp") == 0)
+ wifiProfile->wifiNetwork.method = "dhcp";
+ else if (g_strcmp0(value_char, "manual") == 0)
+ wifiProfile->wifiNetwork.method = "manual";
+ else if (g_strcmp0(value_char, "fixed") == 0)
+ wifiProfile->wifiNetwork.method = "fix";
+ else if (g_strcmp0(value_char, "off") == 0)
+ wifiProfile->wifiNetwork.method = "off";
+ } else if (g_strcmp0(subkey, "Address") == 0) {
+ value_char = g_variant_get_string(subvar, &length);
+ wifiProfile->wifiNetwork.IPaddress = (char *) value_char;
+ } else if (g_strcmp0(subkey, "Netmask") == 0) {
+ value_char = g_variant_get_string(subvar, &length);
+ wifiProfile->wifiNetwork.netmask = (char *) value_char;
+ }
+ }
+ }
+ }
+ //printf ("SSID= %s, security= %s, Strength= %d, wps support= %d\n", wifiProfile->ESSID, wifiProfile->Security.sec_type, wifiProfile->Strength, wifiProfile->Security.wps_support);
+ return 0;
+}
+
+int wifi_state(struct wifiStatus *status) {
+ GError *error = NULL;
+ GVariant *message = NULL;
+ GVariantIter *array;
+ GDBusConnection *connection;
+ GVariant *var = NULL;
+ const gchar *key = NULL;
+ gboolean value_bool;
+
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (connection == NULL) {
+ printf("GDBusconnection is NULL");
+ return -1;
+ }
+ message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE,
+ CONNMAN_TECHNOLOGY_PATH, CONNMAN_TECHNOLOGY_INTERFACE, "GetProperties",
+ NULL, NULL, G_DBUS_CALL_FLAGS_NONE,
+ DBUS_REPLY_TIMEOUT, NULL, &error);
+ if (message == NULL) {
+ printf("message is NULL");
+ return -1;
+ }
+ g_variant_get(message, "(a{sv})", &array);
+ while (g_variant_iter_loop(array, "{sv}", &key, &var)) {
+ if (g_strcmp0(key, "Powered") == 0) {
+ value_bool = g_variant_get_boolean(var);
+ if (value_bool)
+ status->state = 1;
+ else
+ status->state = 0;
+ } else if (g_strcmp0(key, "Connected") == 0) {
+ value_bool = g_variant_get_boolean(var);
+ if (value_bool)
+ status->connected = 1;
+ else
+ status->connected = 0;
+ }
+ }
+ g_variant_iter_free(array);
+ g_variant_unref(message);
+
+ return 0;
+}
+
+GError* do_wifiActivate() {
+ GVariant *params = NULL;
+ params = g_variant_new("(sv)", "Powered", g_variant_new_boolean(TRUE));
+ GDBusConnection *connection;
+ GError *error = NULL;
+
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+
+ if (connection == NULL) {
+ printf("GDBusconnection is NULL");
+ return error;
+ }
+
+ //create the agent to handle security
+ error = create_agent(connection);
+
+ if (error)
+ //This is fatal error, without agent secured networks can not be handled
+ return error;
+
+ g_dbus_connection_call(connection, CONNMAN_SERVICE,
+ CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE, "SetProperty",
+ params, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, &error);
+
+ if (error) {
+ printf("error: %d:%s\n", error->code, error->message);
+
+ return error;
+ }
+
+ else {
+ printf("Power ON succeeded\n");
+ return NULL;
+ }
+
+}
+
+GError* do_wifiDeactivate() {
+ GVariant *params = NULL;
+ params = g_variant_new("(sv)", "Powered", g_variant_new_boolean(FALSE));
+ GDBusConnection *connection;
+ GError *error = NULL;
+
+ /*connection = gdbus_conn->connection;*/
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (connection == NULL) {
+ printf("GDBusconnection is NULL");
+ return error;
+ }
+
+ //create the agent to handle security
+ error = stop_agent(connection);
+
+ if (error) {
+ printf("Error while unregistering the agent, ignoring.");
+
+ }
+
+ g_dbus_connection_call(connection, CONNMAN_SERVICE,
+ CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE, "SetProperty",
+ params, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, &error);
+
+ if (error) {
+ printf("error: %d:%s\n", error->code, error->message);
+
+ return error;
+ }
+
+ else {
+ printf("Power OFF succeeded\n");
+ return NULL;
+ }
+}
+
+GError* do_wifiScan() {
+ GDBusConnection *connection;
+ GError *error = NULL;
+
+ /*connection = gdbus_conn->connection;*/
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (connection == NULL) {
+ printf("GDBusconnection is NULL");
+ return error;
+ }
+
+ g_dbus_connection_call(connection, CONNMAN_SERVICE,
+ CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE, "Scan", NULL,
+ NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, NULL, &error);
+ if (error) {
+ printf("error: %d:%s\n", error->code, error->message);
+
+ return error;
+ }
+
+ else {
+ printf("Scan succeeded\n");
+ return NULL;
+ }
+}
+
+GError* do_displayScan(GSList **wifi_list) {
+ GError *error = NULL;
+ GVariant *message = NULL;
+ GVariantIter *array;
+ gchar *object;
+ GVariantIter *content = NULL;
+ GDBusConnection *connection;
+ struct wifi_profile_info *wifiProfile = NULL;
+
+ /*connection = gdbus_conn->connection;*/
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (connection == NULL) {
+ printf("GDBusconnection is NULL");
+ return error;
+ }
+ message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE,
+ CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, "GetServices", NULL, NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_REPLY_TIMEOUT, NULL, &error);
+ if (message == NULL) {
+ printf("message is NULL");
+ return error;
+ }
+ g_variant_get(message, "(a(oa{sv}))", &array);
+ while (g_variant_iter_loop(array, "(oa{sv})", &object, &content)) {
+ if (g_str_has_prefix(object,
+ CONNMAN_WIFI_SERVICE_PROFILE_PREFIX) == TRUE) {
+ wifiProfile = g_try_malloc0(sizeof(struct wifi_profile_info));
+
+ extract_values(content, wifiProfile);
+ wifiProfile->NetworkPath = g_try_malloc0(strlen(object));
+ strcpy(wifiProfile->NetworkPath, object);
+ printf(
+ "SSID= %s, security= %s, path= %s, Strength= %d, wps support= %d\n",
+ wifiProfile->ESSID, wifiProfile->Security.sec_type,
+ wifiProfile->NetworkPath, wifiProfile->Strength,
+ wifiProfile->Security.wps_support);
+ printf("method= %s, ip address= %s, netmask= %s\n",
+ wifiProfile->wifiNetwork.method,
+ wifiProfile->wifiNetwork.IPaddress,
+ wifiProfile->wifiNetwork.netmask);
+ *wifi_list = g_slist_append(*wifi_list,
+ (struct wifi_profile_info *) wifiProfile);
+ }
+ }
+ g_variant_iter_free(array);
+
+ return NULL;
+}
+
+GError* do_connectNetwork(gchar *networkPath) {
+
+ printf("Connecting to: %s\n", networkPath);
+
+ GVariant *message = NULL;
+ GError *error = NULL;
+ GDBusConnection *connection;
+
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+
+ message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE,
+ networkPath, CONNMAN_SERVICE_INTERFACE, "Connect", NULL, NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_REPLY_TIMEOUT_SHORT, NULL, &error);
+
+ //printf("message error %s\n", message);
+ //TODO: do we need retunrn value in message
+
+ if (error) {
+ printf("do_connectNetwork error: %s\n", error->message);
+ return error;
+ } else {
+ printf("Connection succeeded\n");
+ return NULL;
+ }
+
+}
+
+GError* do_disconnectNetwork(gchar *networkPath) {
+
+ printf("Connecting to: %s\n", networkPath);
+
+ GVariant *message = NULL;
+ GError *error = NULL;
+ GDBusConnection *connection;
+
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+
+ message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE,
+ networkPath, CONNMAN_SERVICE_INTERFACE, "Disconnect", NULL, NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_REPLY_TIMEOUT, NULL, &error);
+
+ //TODO: do we need return value in message
+
+ if (error) {
+ printf("error: %s\n", error->message);
+ return error;
+ } else {
+ printf("Disconnected\n");
+ return NULL;
+ }
+
+}
+
+void registerPasskey(gchar *passkey) {
+
+ printf("Passkey: %s\n", passkey);
+ sendPasskey(passkey);
+
+}
+
diff --git a/wifi-connman.h b/wifi-connman.h
new file mode 100644
index 0000000..bd83821
--- /dev/null
+++ b/wifi-connman.h
@@ -0,0 +1,126 @@
+/* Copyright 2016 ALPS ELECTRIC 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 <dlog.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <gio/gio.h>
+#include <glib-object.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Maximum Profile Count */
+#define CONNMAN_MAX_BUFLEN 512
+
+#define CONNMAN_STATE_STRLEN 16
+
+#define CONNMAN_SERVICE "net.connman"
+#define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager"
+#define CONNMAN_TECHNOLOGY_INTERFACE CONNMAN_SERVICE ".Technology"
+#define CONNMAN_SERVICE_INTERFACE CONNMAN_SERVICE ".Service"
+#define CONNMAN_PROFILE_INTERFACE CONNMAN_SERVICE ".Profile"
+#define CONNMAN_COUNTER_INTERFACE CONNMAN_SERVICE ".Counter"
+#define CONNMAN_ERROR_INTERFACE CONNMAN_SERVICE ".Error"
+#define CONNMAN_AGENT_INTERFACE CONNMAN_SERVICE ".Agent"
+
+#define CONNMAN_MANAGER_PATH "/"
+#define CONNMAN_PATH "/net/connman"
+#define CONNMAN_TECHNOLOGY_PATH "/net/connman/technology/wifi"
+
+/** ConnMan technology and profile prefixes for ConnMan 0.78 */
+
+#define CONNMAN_WIFI_TECHNOLOGY_PREFIX CONNMAN_PATH "/technology/wifi"
+#define CONNMAN_WIFI_SERVICE_PROFILE_PREFIX CONNMAN_PATH "/service/wifi_"
+
+#define WIFI_ESSID_LEN 128
+#define WIFI_MAX_WPSPIN_LEN 8
+#define WIFI_BSSID_LEN 17
+#define WIFI_MAX_PSK_PASSPHRASE_LEN 65
+#define WIFI_MAX_WEP_KEY_LEN 26
+
+#define AGENT_PATH "/net/connman/Agent"
+#define AGENT_SERVICE "org.agent"
+
+#define DBUS_REPLY_TIMEOUT (120 * 1000)
+#define DBUS_REPLY_TIMEOUT_SHORT (10 * 1000)
+
+
+struct gdbus_connection_data_s{
+ GDBusConnection *connection;
+ int conn_ref_count;
+ GCancellable *cancellable;
+ void *handle_libnetwork;
+};
+
+
+struct wifiStatus {
+ unsigned int state;
+ unsigned int connected;
+};
+
+struct security_profile{
+ char *sec_type;
+ char *enc_type;
+ char *wepKey;
+ char *pskKey;
+ unsigned int PassphraseRequired;
+ unsigned int wps_support;
+};
+
+struct wifi_net{
+ char *method;
+ char *IPaddress;
+ char *netmask;
+};
+
+struct wifi_profile_info{
+ char *ESSID;
+ char *NetworkPath;
+ char *state;
+ unsigned int Strength;
+ struct security_profile Security;
+ struct wifi_net wifiNetwork;
+};
+
+//typedef void(*callback)(void);
+typedef void(*callback)(int password_rejected_flag);
+void register_callback(callback ptr);
+
+
+int extract_values(GVariantIter *content, struct wifi_profile_info* wifiProfile);
+int wifi_state(struct wifiStatus *status);
+GError* do_wifiActivate();
+GError* do_wifiDeactivate();
+GError* do_wifiScan();
+GError* do_displayScan(GSList **wifi_list);
+GError* do_connectNetwork(gchar *object);
+GError* do_disconnectNetwork(gchar *object);
+
+GError* create_agent(GDBusConnection *connection);
+GError* stop_agent(GDBusConnection *connection);
+
+
+void registerPasskey(gchar *object);
+GError* sendPasskey(gchar *object);
+
+GError* do_initialize();
+GError* do_initialize();
+
+
+
+
+