diff options
author | Milan Srdinko <msrdinko@alps.cz> | 2017-02-01 13:31:05 +0100 |
---|---|---|
committer | Jan-Simon Moeller <jsmoeller@linuxfoundation.org> | 2017-02-06 20:18:32 +0000 |
commit | 5e433c62b99ed5d85fc1fa61b10551105edf6d6b (patch) | |
tree | 2d04c3f03733a57ae1e3f4e78c1805fb050bf486 | |
parent | b90397fb136d4e8b3bef68dfffd8e0e9b8658f6d (diff) |
WiFi: reworked to support websockets and subscriptions for events
Change-Id: I2d1f2724d7c1efd64c12b7fa639436946209196e
Signed-off-by: Milan Srdinko <msrdinko@alps.cz>
-rw-r--r-- | agent.c | 70 | ||||
-rw-r--r-- | wifi-api.c | 263 | ||||
-rw-r--r-- | wifi-connman.c | 18 | ||||
-rw-r--r-- | wifi-connman.h | 7 |
4 files changed, 283 insertions, 75 deletions
@@ -23,6 +23,8 @@ static GMainLoop *loop = NULL; static GDBusNodeInfo *introspection_data = NULL; +GDBusConnection *connectionAgent; + GDBusMethodInvocation *invocation_passkey = NULL; /* Introspection data for the agent service */ @@ -41,6 +43,7 @@ static const gchar introspection_xml[] = "<node>" "</node>"; callback password_callback; +callback wifiListChanged_callback; static void handle_method_call(GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, @@ -53,10 +56,6 @@ static void handle_method_call(GDBusConnection *connection, const gchar *sender, 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); @@ -81,6 +80,8 @@ static void handle_method_call(GDBusConnection *connection, const gchar *sender, ] */ printf("Passphrase requested for network : %s\n", object_path); + (*password_callback)(0, object_path); + } @@ -97,7 +98,7 @@ static void handle_method_call(GDBusConnection *connection, const gchar *sender, if (g_strcmp0(error_string, "invalid-key") == 0) { printf("Passkey is not correct.\n"); - (*password_callback)(1); + (*password_callback)(1, "invalid-key"); } @@ -142,12 +143,45 @@ static void on_bus_acquired(GDBusConnection *connection, const gchar *name, return NULL; } +static void test_signal_handler (GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { + + //openlog("WIFI Binder", LOG_PID | LOG_CONS, LOG_USER); + + + //do not parse, just check what has changed and make callback - + // we need to refresh completelist anyway.. + if (g_strcmp0(signal_name, "PropertiesChanged") == 0) { + + //syslog(LOG_INFO, "PropertiesChanged"); + (*wifiListChanged_callback)(1, "PropertiesChanged"); + } + else if (g_strcmp0(signal_name, "BSSRemoved") == 0) { + //syslog(LOG_INFO, "BSSRemoved" ); + (*wifiListChanged_callback)(2, "BSSRemoved"); + } + + else if (g_strcmp0(signal_name, "BSSAdded") == 0) { + //syslog(LOG_INFO, "BSSAdded" ); + (*wifiListChanged_callback)(2, "BSSAdded"); + } + else printf ("unhandled signal %s %s %s, %s", sender_name, object_path, interface_name, signal_name);//syslog(LOG_INFO, "unhandled signal %s %s %s, %s", sender_name, object_path, interface_name, signal_name); + + + + //closelog(); + + + + +} + void* register_agent(void *data) { - //printf("Loop start\n"); + printf("Loop start\n"); guint owner_id; - //MyObject *myobj; + + guint networkChangedID; introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL); g_assert(introspection_data != NULL); @@ -165,6 +199,12 @@ void* register_agent(void *data) { NULL); //G_BUS_NAME_OWNER_FLAGS_NONE G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT + + //"net.connman.Manager", "ServicesChanged", + networkChangedID = g_dbus_connection_signal_subscribe(connectionAgent, NULL, "fi.w1.wpa_supplicant1.Interface", NULL, NULL, NULL, G_DBUS_SIGNAL_FLAGS_NONE, test_signal_handler, NULL, NULL); + + g_assert(networkChangedID !=0); + loop = g_main_loop_new(NULL, FALSE); //sleep(10); @@ -189,7 +229,8 @@ GError* create_agent(GDBusConnection *connection) { int err = -1; pthread_t tid[1]; - //struct callbackData *threadData; + + connectionAgent = connection; err = pthread_create((&tid[0]), NULL, register_agent, NULL); @@ -215,11 +256,11 @@ GError* create_agent(GDBusConnection *connection) { if (error) { printf("error: %d:%s\n", error->code, error->message); - + return error; } else { - printf("Agent registered\n"); + printf("Agent registered\n"); return NULL; } @@ -254,9 +295,16 @@ GError* stop_agent(GDBusConnection *connection) { } -void register_callback(callback callback_function) { +void register_callbackSecurity(callback callback_function) { password_callback = callback_function; } +void register_callbackWiFiList(callback callback_function) { + + wifiListChanged_callback = callback_function; + +} + + @@ -42,9 +42,11 @@ static int password_not_correct_flag = 0; char *passkey; callback ptr_my_callback; +callback wifiListChanged_clbck; GSList *wifi_list = NULL; + /** * \brief Read out the passkey from the use and pass it to Agent * @@ -54,74 +56,120 @@ GSList *wifi_list = NULL; * * * */ -void passkey_inserted(void) { +void wifi_passkey(struct afb_req request) { - printf("Passkey inserted: %s\n", passkey); - if (passkey != NULL) { + const char *passkey_from_user; - registerPasskey(passkey); - } else { - printf("Please enter the password first\n"); + /* retrieves the argument, expects password string */ + passkey_from_user = afb_req_value(request, "passkey"); - } + printf("Passkey inserted: %s\n", passkey_from_user); + + sendPasskey(passkey_from_user); + + + if (passkey != NULL) { + + registerPasskey(passkey); + } else { + printf("Please enter the password first\n"); + + } +} + + + +struct event +{ + struct event *next; + struct afb_event event; + char tag[1]; +}; + +static struct event *events = 0; + +/* searchs the event of tag */ +static struct event *event_get(const char *tag) +{ + struct event *e = events; + while(e && strcmp(e->tag, tag)) + e = e->next; + return e; +} + +static int event_push(struct json_object *args, const char *tag) +{ + struct event *e; + e = event_get(tag); + return e ? afb_event_push(e->event, json_object_get(args)) : -1; +} + +static void eventpush (struct afb_req request) +{ + const char *tag = afb_req_value(request, "tag"); + const char *data = afb_req_value(request, "data"); + ///data = "mojedata"; + json_object *object = data ? json_tokener_parse(data) : NULL; + + if (tag == NULL) + afb_req_fail(request, "failed", "bad arguments"); + else if (0 > event_push(object, tag)) + afb_req_fail(request, "failed", "push error"); + else + afb_req_success(request, NULL, NULL); } /** * \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"); +void ask_for_passkey(int number, const char* asciidata) { + //TODO: show network we are asking password for + printf("Insert passkey.\n"); + ERROR(afbitf, "Insert passkey."); - if (!password_rejected_flag) { - need_password_flag = 1; - password_not_correct_flag = 0; - //sleep(1); - passkey_inserted(); + json_object *jresp = json_object_new_object(); - } + json_object *int1 = json_object_new_int(number); + json_object *string = json_object_new_string(asciidata); - else if (password_rejected_flag) { - need_password_flag = 1; - printf("Password not correct!\n"); + json_object_object_add(jresp, "data1", int1); + json_object_object_add(jresp, "data2", string); - } + event_push(jresp, "password"); } /** - * \brief Insert passkey that will be used for connections to secured AP. + * \brief Notify GUI that wifi list has changed * - * \TODO Only temporary, user should enter the password on ask_for_passkey() callback + * This function is called from the registered agent on RequestInput() call. + * \todo Subscribe for this event from GUI. * * */ -void wifi_insertpasskey(struct afb_req request) { +void wifiListChanged(int number, const char* asciidata) { - const char *passkey_from_user; + //WARNING(afbitf, "wifiListChanged, reason:%d, %s",number, asciidata ); - /* 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"); + json_object *jresp = json_object_new_object(); - } else { + json_object *int1 = json_object_new_int(number); + json_object *string = json_object_new_string(asciidata); + + json_object_object_add(jresp, "data1", int1); + json_object_object_add(jresp, "data2", string); + + event_push(jresp, "networkList"); - 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 * @@ -141,23 +189,32 @@ static void wifi_activate(struct afb_req request) /*AFB_SESSION_CHECK*/ printf("Registering callback\n"); - ptr_my_callback = ask_for_passkey; - register_callback(ptr_my_callback); + ptr_my_callback = ask_for_passkey; + register_callbackSecurity(ptr_my_callback); } - jresp = json_object_new_object(); - json_object_object_add(jresp, "activation", json_object_new_string("on")); + if (wifiListChanged_clbck == NULL) { - error = do_wifiActivate(); + printf("Registering callback wifiListChanged_clbck \n"); - if (error == NULL) { + wifiListChanged_clbck = wifiListChanged; + register_callbackWiFiList(wifiListChanged_clbck); - afb_req_success(request, jresp, "Wi-Fi - Activated"); + } - } else + jresp = json_object_new_object(); + json_object_object_add(jresp, "activation", json_object_new_string("on")); - afb_req_fail(request, "failed", error->message); + error = do_wifiActivate(); + + if (error == NULL) { + + afb_req_success(request, jresp, "Wi-Fi - Activated"); + + } else + + afb_req_fail(request, "failed", error->message); } @@ -230,7 +287,7 @@ void wifi_scanResult(struct afb_req request) /*AFB_SESSION_CHECK*/ char *address = NULL; char *security = NULL; char *state = NULL; - int strength = 0; + unsigned int strength = 0; int number = 0; GError *error = NULL; @@ -268,7 +325,7 @@ void wifi_scanResult(struct afb_req request) /*AFB_SESSION_CHECK*/ 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)); + //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; @@ -472,7 +529,91 @@ void wifi_status(struct afb_req request) { } void wifi_reconnect() { - /*TBD*/ + /*TBD*/ +} + + + + +/* deletes the event of tag */ +static int event_del(const char *tag) +{ + struct event *e, **p; + + /* check exists */ + e = event_get(tag); + if (!e) return -1; + + /* unlink */ + p = &events; + while(*p != e) p = &(*p)->next; + *p = e->next; + + /* destroys */ + afb_event_drop(e->event); + free(e); + return 0; +} + +/* creates the event of tag */ +static int event_add(const char *tag, const char *name) +{ + struct event *e; + + /* check valid tag */ + e = event_get(tag); + if (e) return -1; + + /* creation */ + e = malloc(strlen(tag) + sizeof *e); + if (!e) return -1; + strcpy(e->tag, tag); + + /* make the event */ + e->event = afb_daemon_make_event(afbitf->daemon, name); + if (!e->event.closure) { free(e); return -1; } + + /* link */ + e->next = events; + events = e; + return 0; +} + +static void eventadd (struct afb_req request) +{ + const char *tag = afb_req_value(request, "tag"); + const char *name = afb_req_value(request, "name"); + + printf ("Name: %s\n", name); + printf ("Tag: %s\n", tag); + + json_object *query = afb_req_json(request); + + if (tag == NULL || name == NULL) + afb_req_fail(request, "failed", "bad arguments"); + else if (0 != event_add(tag, name)) + afb_req_fail(request, "failed", "creation error"); + else + afb_req_success(request, NULL, NULL); +} + +static int event_subscribe(struct afb_req request, const char *tag) +{ + struct event *e; + e = event_get(tag); + return e ? afb_req_subscribe(request, e->event) : -1; +} + +static void eventsub (struct afb_req request) +{ + const char *tag = afb_req_value(request, "tag"); + + if (tag == NULL) + afb_req_fail(request, "failed", "bad arguments"); + else if (0 != event_subscribe(request, tag)) + afb_req_fail(request, "failed", "subscription error"); + else + afb_req_success(request, NULL, NULL); } @@ -482,15 +623,23 @@ void wifi_reconnect() { */ 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 = "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 = "insertpasskey",.session = AFB_SESSION_NONE, .callback = wifi_passkey, .info ="inputs the passkey after it has been requsted"}, +{ .name = "eventadd", .session = AFB_SESSION_NONE, .callback = eventadd, .info ="adds the event of 'name' for the 'tag'"}, +{ .name = "eventsub", .session = AFB_SESSION_NONE, .callback = eventsub, .info ="unsubscribes to the event of 'tag'"}, +{ .name = "eventpush", .session = AFB_SESSION_NONE, .callback = eventpush, .info ="pushes the event of 'tag' with the 'data'"}, + + + + + { .name = NULL } /* marker for end of the array */ }; diff --git a/wifi-connman.c b/wifi-connman.c index 68e5e3d..7dc2aac 100644 --- a/wifi-connman.c +++ b/wifi-connman.c @@ -25,6 +25,8 @@ #include "wifi-api.h" #include "wifi-connman.h" +//#include "syslog.h" + static __thread struct security_profile Security = { NULL, NULL, NULL, NULL, 0, 0 }; @@ -36,7 +38,7 @@ int extract_values(GVariantIter *content, struct wifi_profile_info* wifiProfile) const gchar *subkey = NULL; const gchar *value_char = NULL; GVariantIter *content_sub; - int value_int; + unsigned int value_int; gsize length; while (g_variant_iter_loop(content, "{sv}", &key, &var)) { @@ -272,7 +274,7 @@ GError* do_displayScan(GSList **wifi_list) { extract_values(content, wifiProfile); wifiProfile->NetworkPath = g_try_malloc0(strlen(object)); strcpy(wifiProfile->NetworkPath, object); - printf( + /*printf( "SSID= %s, security= %s, path= %s, Strength= %d, wps support= %d\n", wifiProfile->ESSID, wifiProfile->Security.sec_type, wifiProfile->NetworkPath, wifiProfile->Strength, @@ -280,7 +282,7 @@ GError* do_displayScan(GSList **wifi_list) { printf("method= %s, ip address= %s, netmask= %s\n", wifiProfile->wifiNetwork.method, wifiProfile->wifiNetwork.IPaddress, - wifiProfile->wifiNetwork.netmask); + wifiProfile->wifiNetwork.netmask);*/ *wifi_list = g_slist_append(*wifi_list, (struct wifi_profile_info *) wifiProfile); } @@ -361,12 +363,18 @@ GError* setHMIStatus(enum wifiStates state) { GVariant *message = NULL; GError *error = NULL; + //openlog("WIFI Binder", LOG_PID | LOG_CONS, LOG_USER); + if (state==BAR_NO) iconString = "qrc:/images/Status/HMI_Status_Wifi_NoBars-01.png"; else if (state==BAR_1) iconString = "qrc:/images/Status/HMI_Status_Wifi_1Bar-01.png"; else if (state==BAR_2) iconString = "qrc:/images/Status/HMI_Status_Wifi_2Bars-01.png"; else if (state==BAR_3) iconString = "qrc:/images/Status/HMI_Status_Wifi_3Bars-01.png"; else if (state==BAR_FULL) iconString = "qrc:/images/Status/HMI_Status_Wifi_Full-01.png"; - else iconString = "qrc:/images/Status/HMI_Status_Wifi_NoBars-01.png"; + //else {syslog(LOG_ERR, "Default value for wifi HMI icon, should not happened.. : %d", state); + // iconString = "qrc:/images/Status/HMI_Status_Wifi_NoBars-01.png"; + //} + + //syslog(LOG_INFO, "%s", iconString); connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error); @@ -385,5 +393,7 @@ GError* setHMIStatus(enum wifiStates state) { return NULL; } + //closelog(); + } diff --git a/wifi-connman.h b/wifi-connman.h index c47cbcd..90533dd 100644 --- a/wifi-connman.h +++ b/wifi-connman.h @@ -104,9 +104,10 @@ struct wifi_profile_info{ enum wifiStates {BAR_NO, BAR_1, BAR_2, BAR_3, BAR_FULL}; -//typedef void(*callback)(void); -typedef void(*callback)(int password_rejected_flag); -void register_callback(callback ptr); +typedef void(*callback)(int number, const char* asciidata); +void register_callbackSecurity(callback ptr); +void register_callbackWiFiList(callback ptr); + int extract_values(GVariantIter *content, struct wifi_profile_info* wifiProfile); |