new fremantle branch
[libicd-wpa] / dbus-handler.c
1 /**
2   @file dbus-helper.c
3
4   Copyright (C) 2004 Nokia Corporation. All rights reserved.
5   
6   Copyright (C) 2009 Javier S. Pedro
7
8   @author Janne Ylalehto <janne.ylalehto@nokia.com>
9   @author Johan Hedberg <johan.hedberg@nokia.com> 
10   
11   @author Javier S. Pedro <javispedro@javispedro.com>
12
13   This program is free software; you can redistribute it and/or modify it
14   under the terms of the GNU General Public License as published by the
15   Free Software Foundation; either version 2 of the License, or (at your
16   option) any later version.
17
18   This program is distributed in the hope that it will be useful, but
19   WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21   General Public License for more details.
22
23   You should have received a copy of the GNU General Public License along
24   with this program; if not, write to the Free Software Foundation, Inc.,
25   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26
27 */
28 #include <glib.h>
29
30 #include <wlancond-dbus.h>
31
32 #include "dbus-helper.h"
33 #include "dbus-handler.h"
34 #include "wlan.h"
35 #include "supp.h"
36 #include "log.h"
37
38 static DBusHandlerResult wlancond_scan_results_handler(DBusMessage *message) {
39         DBusMessageIter iter;
40         gint32 number_of_results, i;
41         
42         if (!wlan_is_scanning()) {
43                 DLOG_DEBUG("Received scan results we didn't ask for");
44                 // TODO: Somehow use them
45                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
46         }
47         
48         dbus_message_iter_init(message, &iter);
49         
50         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32)
51                 goto param_err;
52                 
53         dbus_message_iter_get_basic(&iter, &number_of_results);
54         
55         dbus_message_iter_next(&iter);
56         
57         for (i = 0; i < number_of_results; i++) {
58                 DBusMessageIter array_iter;
59                 gint32 ssid_len, bssid_len;
60                 gchar * ssid, * bssid;
61                 gint32 rssi;
62                 guint32 channel, cap_bits;
63                 
64                 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
65                         dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE) {
66                         
67                         goto param_err;
68                 }
69                 
70                 dbus_message_iter_recurse(&iter, &array_iter);
71                 dbus_message_iter_get_fixed_array(&array_iter, &ssid, &ssid_len);
72                 dbus_message_iter_next(&iter);
73                 
74                 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
75                         dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE) {
76                         
77                         goto param_err;
78                 }
79                 
80                 dbus_message_iter_recurse(&iter, &array_iter);
81                 dbus_message_iter_get_fixed_array(&array_iter, &bssid, &bssid_len);
82                 dbus_message_iter_next(&iter);
83
84                 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32)
85                         goto param_err;
86                 dbus_message_iter_get_basic(&iter, &rssi);
87                 dbus_message_iter_next(&iter);
88                 
89                 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
90                         goto param_err;
91                 dbus_message_iter_get_basic(&iter, &channel);
92                 dbus_message_iter_next(&iter);
93
94                 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
95                         goto param_err;
96                 dbus_message_iter_get_basic(&iter, &cap_bits);
97                 dbus_message_iter_next(&iter);
98                 
99                 DLOG_INFO("Scan result with %s.", ssid);
100                 wlan_notify_ap(ssid, bssid,
101                         rssi, channel, cap_bits);
102         }
103         
104         DLOG_DEBUG("Handled scan result, results=%ld.", 
105                 (long) number_of_results);
106                 
107         wlan_notify_end_of_search();
108         
109         return DBUS_HANDLER_RESULT_HANDLED;
110 param_err:
111         DLOG_WARN("Parameter error in scan request");
112         
113         wlan_notify_end_of_search();
114         
115         return DBUS_HANDLER_RESULT_HANDLED;
116 }
117
118 static DBusHandlerResult supp_state_change_handler(DBusMessage *message) {
119         gchar *old_state, *new_state;
120         
121         if (!dbus_message_get_args(
122                         message, NULL,
123                         DBUS_TYPE_STRING, &new_state,
124                         DBUS_TYPE_STRING, &old_state,
125                         DBUS_TYPE_INVALID))
126         {
127                 DLOG_WARN("Supplicant StateChange signal format error");
128                 return DBUS_HANDLER_RESULT_HANDLED;
129         }
130         
131         supp_handle_signal(old_state, new_state);
132         
133         return DBUS_HANDLER_RESULT_HANDLED;
134 }
135
136 static DBusHandlerResult wlancond_sig_handler(DBusConnection *connection,
137                                                 DBusMessage *message,
138                                                 void *user_data) {
139         if (dbus_message_is_signal(message,
140                 WLANCOND_SIG_INTERFACE,
141                 WLANCOND_SCAN_RESULTS_SIG))
142                 return wlancond_scan_results_handler(message);
143                 
144         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
145 }
146
147 static DBusHandlerResult supp_sig_handler(DBusConnection *connection,
148                                                 DBusMessage *message,
149                                                 void *user_data) {
150         if (dbus_message_is_signal(message,
151                 WPAS_DBUS_IFACE_INTERFACE,
152                 WPAS_STATE_CHANGE_SIG))
153                 return supp_state_change_handler(message);
154                 
155         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
156 }
157
158 /** 
159     Create bindings for D-BUS handlers.
160     @param connection DBUS connection.
161 */
162 void init_dbus_handlers(DBusConnection *connection) {
163         gboolean ret;
164         /*dbus_bool_t ret;
165         ret = dbus_connection_register_object_path(connection,
166                                                    WLANCOND_REQ_PATH,
167                                                    &wlancond_req_vtable,
168                                                    NULL);
169         if (ret == FALSE) {
170                 DLOG_ERR("dbus_connection_register_object_path failed");
171         }*/
172
173         dbus_bus_add_match(connection, 
174                            "interface=" WLANCOND_SIG_INTERFACE
175                            ",member=" WLANCOND_SCAN_RESULTS_SIG, NULL);        
176         
177         ret = dbus_connection_add_filter(connection, 
178                 (DBusHandleMessageFunction)wlancond_sig_handler, NULL, NULL);
179         
180         if (!ret) {
181                 DLOG_ERR("dbus_connection_add_filter failed");
182         }
183         
184         dbus_bus_add_match(connection, 
185                            "interface=" WPAS_DBUS_IFACE_INTERFACE
186                            ",member=" WPAS_STATE_CHANGE_SIG, NULL);        
187         
188         ret = dbus_connection_add_filter(connection,
189                 (DBusHandleMessageFunction)supp_sig_handler, NULL, NULL);
190         
191         if (!ret) {
192                 DLOG_ERR("dbus_connection_add_filter failed");
193         }
194 }
195
196 /**
197    Destroy D-BUS handlers.
198    @param connection DBUS connection.
199 */
200 void destroy_dbus_handlers(DBusConnection *connection) {
201         //dbus_connection_unregister_object_path(connection, WLANCOND_REQ_PATH);
202 }