static GDBusProxy *_gproxy_connman_technology = NULL;
static int _meshd_close_gdbus_call(mesh_service *service);
+static int _mesh_ipc_get_mesh_network_property(mesh_service *service,
+ const gchar* object_path, mesh_network_info_s *result);
static int __channel_to_frequency(int channel, enum nl80211_band band)
{
const gchar *signal_name, GVariant *parameters, gpointer user_data)
{
mesh_service *service = (mesh_service*)user_data;
+ mesh_network_info_s network_info = { 0, 0, 0, 0, 0 };
+ int ret = MESHD_ERROR_NONE;
meshd_check_null_ret("user_data", user_data);
- //meshd_check_null_ret("event_handler", service->event_handler);
NOTUSED(connection);
NOTUSED(sender_name);
- NOTUSED(object_path);
NOTUSED(interface_name);
- NOTUSED(signal_name);
- NOTUSED(parameters);
-
- NOTUSED(service);
MESH_LOGD("signal received = %s", signal_name);
if (0 == g_strcmp0(signal_name, "ScanDone")) {
/* TODO: Handle event */
mesh_notify_scan_done();
+ } else if (0 == g_strcmp0(signal_name, "PropertyChanged")) {
+ const gchar* var = NULL;
+ gchar* key = NULL;
+ GVariant *variant = NULL;
+ meshd_connection_state_e state = MESHD_CONNECTION_STATE_DISCONNECTED;
+
+ if (NULL == parameters) {
+ MESH_LOGE("Unexpected parameter");
+ return;
+ }
+
+ g_variant_get(parameters, "(sv)", &key, &variant);
+ if (NULL == variant) {
+ MESH_LOGE("Invalid variant");
+ return;
+ }
+
+ /* State [???] */
+ var = g_variant_get_string(variant, NULL);
+ MESH_LOGD(" %s [%s]", key, var);
+ MESH_LOGD(" %s", object_path);
+
+ ret = _mesh_ipc_get_mesh_network_property(service, object_path, &network_info);
+ if (MESHD_ERROR_NONE != ret)
+ MESH_LOGE("Cannot get valid network property !");
+
+ if (g_strcmp0("association", var) == 0) {
+ /* Joined mesh network */
+ state = MESHD_CONNECTION_STATE_ASSOCIATION;
+ } else if (g_strcmp0("configuration", var) == 0) {
+ /* Trying to get IP address */
+ state = MESHD_CONNECTION_STATE_CONFIGURATION;
+ } else if (g_strcmp0("ready", var) == 0 || g_strcmp0("online", var) == 0) {
+ /* IP address is obtained */
+ state = MESHD_CONNECTION_STATE_CONNECTED;
+ } else if (g_strcmp0("disconnect", var) == 0 || g_strcmp0("failure", var) == 0) {
+ state = MESHD_CONNECTION_STATE_DISCONNECTED;
+ } else {
+ MESH_LOGE(" Unhandled state !");
+ g_free(network_info.mesh_id);
+ g_free(network_info.bssid);
+ return;
+ }
+
+ mesh_notify_connection_state(network_info.mesh_id, network_info.bssid,
+ network_info.channel, state);
+
+ g_free(network_info.mesh_id);
+ g_free(network_info.bssid);
}
}
static void _meshd_subscribe_event(mesh_service *service)
{
- unsigned int id;
+ unsigned int id = 0;
+
+ meshd_check_null_ret("service", service);
id = g_dbus_connection_signal_subscribe(
(GDBusConnection *)service->connection,
service->dbus_sub_ids = g_list_append(service->dbus_sub_ids, GUINT_TO_POINTER(id));
MESH_LOGD("[Signal subscribe] : ScanDone (%d)", id);
+ /* To monitor mesh profiles */
+ id = g_dbus_connection_signal_subscribe(
+ (GDBusConnection *)service->connection,
+ CONNMAN_SERVER_NAME,
+ CONNMAN_INTERFACE_MESH,
+ "PropertyChanged",
+ NULL, /* Path */
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE, _meshd_signal_handler, service, NULL);
+ if (0 == id) {
+ MESH_LOGE("g_dbus_connection_signal_subscribe(ScanDone) Fail(%d)", errno);
+ return;
+ }
+ service->dbus_sub_ids = g_list_append(service->dbus_sub_ids, GUINT_TO_POINTER(id));
+ MESH_LOGD("[Signal subscribe] : PropertyChanged (%d)", id);
+
/* End of subscription */
}
+static void _on_unsubscribe_ids(gpointer data, gpointer user_data)
+{
+ unsigned int id = GPOINTER_TO_UINT(data);
+ mesh_service *service = (mesh_service*)user_data;
+
+ MESH_LOGD("[Signal unsubscribe] : %d", id);
+ g_dbus_connection_signal_unsubscribe(
+ (GDBusConnection *)service->connection, id);
+}
+
+static void _meshd_unsubscribe_event(mesh_service *service)
+{
+ meshd_check_null_ret("service", service);
+
+ g_list_foreach(service->dbus_sub_ids, _on_unsubscribe_ids, service);
+
+ g_list_free(service->dbus_sub_ids);
+ service->dbus_sub_ids = NULL;
+}
+
int meshd_dbus_start(mesh_service *service)
{
int rv;
if (NULL == service)
return MESHD_ERROR_INVALID_PARAMETER;
+ /* Unsubscribe events */
+ _meshd_unsubscribe_event(service);
+
/* Unref all proxies here */
if (_gproxy_connman) {
g_object_unref(_gproxy_connman);
|| g_strcmp0(buf, "failure") == 0) {
valid_state = FALSE;
break;
+ } else if (g_strcmp0(buf, "association") == 0) {
+ joined_info->state = MESHD_CONNECTION_STATE_ASSOCIATION;
+ } else if (g_strcmp0(buf, "configuration") == 0) {
+ joined_info->state = MESHD_CONNECTION_STATE_CONFIGURATION;
+ } else if (g_strcmp0(buf, "ready") == 0 || g_strcmp0(buf, "online") == 0) {
+ joined_info->state = MESHD_CONNECTION_STATE_CONNECTED;
}
}
else if (strcasecmp(key, "Frequency") == 0) {
else if (strcasecmp(key, "State") == 0) {
const char *buf = g_variant_get_string(val, &len);
MESH_LOGD(" State : %s", buf);
+
+ if (g_strcmp0(buf, "idle") == 0
+ || g_strcmp0(buf, "disconnect") == 0
+ || g_strcmp0(buf, "failure") == 0) {
+ scan_info->state = MESHD_CONNECTION_STATE_DISCONNECTED;
+ } else if (g_strcmp0(buf, "association") == 0) {
+ scan_info->state = MESHD_CONNECTION_STATE_ASSOCIATION;
+ } else if (g_strcmp0(buf, "configuration") == 0) {
+ scan_info->state = MESHD_CONNECTION_STATE_CONFIGURATION;
+ } else if (g_strcmp0(buf, "ready") == 0 || g_strcmp0(buf, "online") == 0) {
+ scan_info->state = MESHD_CONNECTION_STATE_CONNECTED;
+ }
}
else if (strcasecmp(key, "Security") == 0) {
const char *buf = g_variant_get_string(val, &len);
return MESHD_ERROR_NONE;
}
+static void _get_mesh_property(GVariant *variant, mesh_network_info_s *result)
+{
+ GVariantIter *property = NULL;
+ gchar *key = NULL;
+ GVariant *val = NULL;
+ gsize len = 0;
+
+ MESH_LOGD("Type [%s]", g_variant_get_type_string(variant));
+
+ g_variant_get(variant, "(a{sv})", &property);
+
+ while (g_variant_iter_loop(property, "{sv}", &key, &val)) {
+ if (strcasecmp(key, "Name") == 0) {
+ const char *buf = g_variant_get_string(val, &len);
+ result->mesh_id = g_strdup(buf);
+ MESH_LOGD(" Mesh ID : %s", result->mesh_id);
+ }
+ else if (strcasecmp(key, "Address") == 0) {
+ const char *buf = g_variant_get_string(val, &len);
+ result->bssid = g_strdup(buf);
+ MESH_LOGD(" BSSID : %s", result->bssid);
+ }
+ else if (strcasecmp(key, "State") == 0) {
+ const char *buf = g_variant_get_string(val, &len);
+ MESH_LOGD(" State : %s", buf);
+
+ if (g_strcmp0(buf, "idle") == 0
+ || g_strcmp0(buf, "disconnect") == 0
+ || g_strcmp0(buf, "failure") == 0) {
+ result->state = MESHD_CONNECTION_STATE_DISCONNECTED;
+ } else if (g_strcmp0(buf, "association") == 0) {
+ result->state = MESHD_CONNECTION_STATE_ASSOCIATION;
+ } else if (g_strcmp0(buf, "configuration") == 0) {
+ result->state = MESHD_CONNECTION_STATE_CONFIGURATION;
+ } else if (g_strcmp0(buf, "ready") == 0 || g_strcmp0(buf, "online") == 0) {
+ result->state = MESHD_CONNECTION_STATE_CONNECTED;
+ }
+ }
+ else if (strcasecmp(key, "Security") == 0) {
+ const char *buf = g_variant_get_string(val, &len);
+ MESH_LOGD(" Security : %s", buf);
+ }
+ else if (strcasecmp(key, "Frequency") == 0) {
+ result->channel = __frequency_to_channel(g_variant_get_uint16(val));
+ MESH_LOGD(" Channel : %d", result->channel);
+ }
+ else if (strcasecmp(key, "Favorite") == 0) {
+ const char *buf = g_variant_get_string(val, &len);
+ MESH_LOGD(" Favorite : %s", buf);
+ }
+ else if (strcasecmp(key, "Strength") == 0) {
+ gint rssi = (gint)g_variant_get_byte(val);
+ MESH_LOGD(" RSSI : %d", rssi);
+ }
+ }
+ g_variant_iter_free(property);
+}
+
+static int _mesh_ipc_get_mesh_network_property(mesh_service *service,
+ const gchar* object_path, mesh_network_info_s *result)
+{
+ GVariant *variant = NULL;
+ GError *error = NULL;
+
+ meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
+ meshd_check_null_ret_error("connection", service->connection,
+ MESHD_ERROR_INVALID_PARAMETER);
+ meshd_check_null_ret_error("result", result, MESHD_ERROR_INVALID_PARAMETER);
+
+ variant = g_dbus_connection_call_sync(service->connection,
+ CONNMAN_SERVER_NAME,
+ object_path,
+ CONNMAN_INTERFACE_MESH,
+ "GetProperties",
+ NULL, NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, &error);
+ if (variant) {
+ MESH_LOGD("Successfully requested. [GetProperties]");
+
+ /* Get properties */
+ _get_mesh_property(variant, result);
+ } else if (error) {
+ LOGE("Failed DBus call [%s]", error->message);
+ g_error_free(error);
+ return MESHD_ERROR_IO_ERROR;
+ }
+
+ return MESHD_ERROR_NONE;
+}
+
int mesh_ipc_create_network(mesh_service *service, gchar *mesh_id, gint channel,
gint security)
{
return MESHD_ERROR_NONE;
}
-
+#if 0
static void on_response_connect_network(GObject *source_object,
GAsyncResult *res, gpointer user_data)
{
G_DBUS_CONNECTION(source_object), res, &error);
if (variant) {
MESH_LOGD("Successfully requested. [Connect]");
+
+ /* TODO: Unregister property change event */
} else if (error) {
ret = MESHD_ERROR_IO_ERROR;
LOGE("Failed DBus call [%s]", error->message);
g_error_free(error);
}
-
- mesh_notify_mesh_connected(ret);
}
+#endif
int mesh_ipc_connect_network(mesh_service *service, mesh_scan_result_s *info)
{
"Connect",
NULL, NULL,
G_DBUS_CALL_FLAGS_NONE,
- MESH_DBUS_PROXY_TIMEOUT * 2, /* Waits for long time */
- NULL,
- on_response_connect_network, service);
+ -1,
+ NULL, /* G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED */
+ NULL, NULL);
+ MESH_LOGD("Successfully requested. [Connect]");
return MESHD_ERROR_NONE;
}