diff options
author | Chengyi Zhao <chengyi1.zhao@archermind.com> | 2013-07-10 20:00:36 +0800 |
---|---|---|
committer | Zhang zhengguang <zhengguang.zhang@intel.com> | 2014-10-31 16:06:20 +0800 |
commit | b846a12300fa054beb16e97add2d13cd8e2496ae (patch) | |
tree | a31aa8928f4b179f15e008106c9ab08472a4901b /src | |
parent | 5bd77bc62bc47d5752a9060cb887883a9d1b9844 (diff) | |
download | connman-b846a12300fa054beb16e97add2d13cd8e2496ae.tar.gz connman-b846a12300fa054beb16e97add2d13cd8e2496ae.tar.bz2 connman-b846a12300fa054beb16e97add2d13cd8e2496ae.zip |
Tethering: Notify listeners when station connection changes
Change-Id: I048c1a8a348b6f862ca104ad2fbe971f580fe180
Diffstat (limited to 'src')
-rw-r--r-- | src/technology.c | 10 | ||||
-rw-r--r-- | src/tethering.c | 85 |
2 files changed, 94 insertions, 1 deletions
diff --git a/src/technology.c b/src/technology.c index d80d9e6d..a06efd3a 100644 --- a/src/technology.c +++ b/src/technology.c @@ -1070,6 +1070,16 @@ static const GDBusMethodTable technology_methods[] = { static const GDBusSignalTable technology_signals[] = { { GDBUS_SIGNAL("PropertyChanged", GDBUS_ARGS({ "name", "s" }, { "value", "v" })) }, + { GDBUS_SIGNAL("DhcpConnected", + GDBUS_ARGS({ "aptype", "s" }, + { "ipaddr", "s" }, + { "macaddr", "s" }, + { "hostname", "s" })) }, + { GDBUS_SIGNAL("DhcpLeaseDeleted", + GDBUS_ARGS({ "aptype", "s" }, + { "ipaddr", "s" }, + { "macaddr", "s" }, + { "hostname", "s" })) }, { }, }; diff --git a/src/tethering.c b/src/tethering.c index 0cbf06cb..c0c97431 100644 --- a/src/tethering.c +++ b/src/tethering.c @@ -89,6 +89,32 @@ struct connman_station_info { char hostname[CONNMAN_STATION_STR_INFO_LEN]; }; +static void emit_station_signal(char *action_str, + const struct connman_station_info *station_info) +{ + char *ip, *mac, *hostname; + + if (station_info->path == NULL || station_info->type == NULL + || station_info->ip == NULL || station_info->mac == NULL + || station_info->hostname == NULL) + return; + + ip = g_strdup(station_info->ip); + mac = g_strdup(station_info->mac); + hostname = g_strdup(station_info->hostname); + + g_dbus_emit_signal(connection, station_info->path, + CONNMAN_TECHNOLOGY_INTERFACE, action_str, + DBUS_TYPE_STRING, &station_info->type, + DBUS_TYPE_STRING, &ip, + DBUS_TYPE_STRING, &mac, + DBUS_TYPE_STRING, &hostname, + DBUS_TYPE_INVALID); + + g_free(ip); + g_free(mac); + g_free(hostname); +} static void destroy_station(gpointer key, gpointer value, gpointer user_data) { struct connman_station_info *station_info; @@ -97,11 +123,59 @@ static void destroy_station(gpointer key, gpointer value, gpointer user_data) station_info = value; + if (station_info->is_connected) { + station_info->is_connected = FALSE; + emit_station_signal("DhcpLeaseDeleted", station_info); + } + g_free(station_info->path); g_free(station_info->type); g_free(station_info); } +static void save_dhcp_ack_lease_info(char *hostname, + unsigned char *mac, unsigned int nip) +{ + char *lower_mac; + const char *ip; + char sta_mac[CONNMAN_STATION_MAC_INFO_LEN]; + struct connman_station_info *info_found; + struct in_addr addr; + int str_len; + + __sync_synchronize(); + + snprintf(sta_mac, CONNMAN_STATION_MAC_INFO_LEN, + "%02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + lower_mac = g_ascii_strdown(sta_mac, -1); + + info_found = g_hash_table_lookup(sta_hash, lower_mac); + if (info_found == NULL) { + g_free(lower_mac); + return; + } + + /* get the ip */ + addr.s_addr = nip; + ip = inet_ntoa(addr); + str_len = strlen(ip) + 1; + if (str_len > CONNMAN_STATION_STR_INFO_LEN) + str_len = CONNMAN_STATION_STR_INFO_LEN - 1; + memcpy(info_found->ip, ip, str_len); + + /* get hostname */ + str_len = strlen(hostname) + 1; + if (str_len > CONNMAN_STATION_STR_INFO_LEN) + str_len = CONNMAN_STATION_STR_INFO_LEN - 1; + memcpy(info_found->hostname, hostname, str_len); + + /* emit a signal */ + info_found->is_connected = TRUE; + emit_station_signal("DhcpConnected", info_found); + g_free(lower_mac); +} + int connman_technology_tethering_add_station(enum connman_service_type type, const char *mac) { @@ -146,9 +220,15 @@ int connman_technology_tethering_remove_station(const char *mac) lower_mac = g_ascii_strdown(mac, -1); info_found = g_hash_table_lookup(sta_hash, lower_mac); - if (info_found == NULL) + if (info_found == NULL) { + g_free(lower_mac); return -EACCES; + } + if (info_found->is_connected) { + info_found->is_connected = FALSE; + emit_station_signal("DhcpLeaseDeleted", info_found); + } g_free(lower_mac); g_hash_table_remove(sta_hash, info_found->mac); g_free(info_found->path); @@ -243,6 +323,9 @@ static GDHCPServer *dhcp_server_start(const char *bridge, g_dhcp_server_set_option(dhcp_server, G_DHCP_DNS_SERVER, dns); g_dhcp_server_set_ip_range(dhcp_server, start_ip, end_ip); + g_dhcp_server_set_save_ack_lease(dhcp_server, + save_dhcp_ack_lease_info, NULL); + g_dhcp_server_start(dhcp_server); return dhcp_server; |