summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Xu <martin.xu@intel.com>2013-07-03 17:44:47 -0700
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>2013-07-03 17:44:47 -0700
commitdd894d763e92f36ac9e746c0e06531e6188548e2 (patch)
treeb406eff19058bc8dd2a0e80567f3f99c11f559fd
parenta42a42900114a39a03fcf44d22d971dfc961bd67 (diff)
parent3e078e46d0cba52b4fc04c62085bd82fbd4fab26 (diff)
downloadconnman-dd894d763e92f36ac9e746c0e06531e6188548e2.tar.gz
connman-dd894d763e92f36ac9e746c0e06531e6188548e2.tar.bz2
connman-dd894d763e92f36ac9e746c0e06531e6188548e2.zip
Merge changes I3e078e46,I74aa0e84,I936ec03d,I2d63b07b,I9dabc5af,Ie151cda8,Ia5eded6f,I0b571435 into tizen
* changes: Tizen: Export network proxy API for telephony plugin Fix Wi-Fi WEP OPEN and WEP SHARED Add safe checks to validate DNS buffer Tizen: Add refcount for cellular service connection Tizen: Fix reply pending bug Tizen: Add last known address in DHCP discovery request Tizen: Append extra wifi service property Tizen: Export more wifi info in ConnMan network API
-rw-r--r--doc/service-api.txt26
-rw-r--r--gdhcp/client.c51
-rw-r--r--gdhcp/gdhcp.h4
-rw-r--r--gsupplicant/gsupplicant.h9
-rw-r--r--gsupplicant/supplicant.c66
-rw-r--r--gweb/gresolv.c10
-rw-r--r--include/network.h20
-rw-r--r--include/service.h21
-rw-r--r--plugins/wifi.c43
-rw-r--r--src/connman.h4
-rw-r--r--src/dhcp.c12
-rw-r--r--src/network.c94
-rw-r--r--src/service.c161
13 files changed, 521 insertions, 0 deletions
diff --git a/doc/service-api.txt b/doc/service-api.txt
index 54b77a4b..4fe6b32d 100644
--- a/doc/service-api.txt
+++ b/doc/service-api.txt
@@ -176,6 +176,32 @@ Properties string State [readonly]
This property might be only present for WiFi
services.
+ string BSSID [readonly]
+
+ If the service type is WiFi, then this property
+ indicates the BSSID of the service.
+
+ uint32 MaxRate [readonly]
+
+ If the service type is WiFi, then this property
+ indicates the Maximum speed(bps) of the service.
+
+ uint16 Frequency [readonly]
+
+ If the service type is WiFi, then this property
+ indicates the frequency band(MHz) of the service.
+
+ string EncryptionMode [readonly]
+
+ If the service type is WiFi, then this property
+ indicates the key encryption mode.
+
+ Possible values are "none", "wep", "tkip", "aes"
+ and "mixed".
+
+ This property might be only present for WiFi
+ services.
+
uint8 Strength [readonly]
Indicates the signal strength of the service. This
diff --git a/gdhcp/client.c b/gdhcp/client.c
index a41e1678..c64d7130 100644
--- a/gdhcp/client.c
+++ b/gdhcp/client.c
@@ -149,6 +149,9 @@ struct _GDHCPClient {
time_t expire;
gboolean retransmit;
struct timeval start_time;
+#if defined TIZEN_EXT
+ gboolean init_reboot;
+#endif
};
static inline void debug(GDHCPClient *client, const char *format, ...)
@@ -436,6 +439,9 @@ static int send_select(GDHCPClient *dhcp_client)
dhcp_add_option_uint32(&packet, DHCP_REQUESTED_IP,
dhcp_client->requested_ip);
+#if defined TIZEN_EXT
+ if (dhcp_client->init_reboot != TRUE)
+#endif
dhcp_add_option_uint32(&packet, DHCP_SERVER_ID,
dhcp_client->server_ip);
@@ -1322,6 +1328,21 @@ static gboolean request_timeout(gpointer user_data)
{
GDHCPClient *dhcp_client = user_data;
+#if defined TIZEN_EXT
+ if (dhcp_client->init_reboot == TRUE) {
+ debug(dhcp_client, "DHCPREQUEST of INIT-REBOOT has failed");
+
+ /* Start DHCPDISCOVERY when DHCPREQUEST of INIT-REBOOT has failed */
+ g_dhcp_client_set_address_known(dhcp_client, FALSE);
+
+ dhcp_client->retry_times = 0;
+ dhcp_client->requested_ip = 0;
+
+ g_dhcp_client_start(dhcp_client, dhcp_client->last_address);
+
+ return FALSE;
+ }
+#endif
debug(dhcp_client, "request timeout (retries %d)",
dhcp_client->retry_times);
@@ -2041,6 +2062,9 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
dhcp_client->lease_seconds = get_lease(&packet);
+#if defined TIZEN_EXT
+ debug(dhcp_client, "lease %d secs", dhcp_client->lease_seconds);
+#endif
get_request(dhcp_client, &packet);
switch_listening_mode(dhcp_client, L_NONE);
@@ -2060,6 +2084,9 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
if (dhcp_client->timeout > 0)
g_source_remove(dhcp_client->timeout);
+#if defined TIZEN_EXT
+ g_dhcp_client_set_address_known(dhcp_client, FALSE);
+#endif
dhcp_client->timeout = g_timeout_add_seconds_full(
G_PRIORITY_HIGH, 3,
restart_dhcp_timeout,
@@ -2410,6 +2437,15 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address)
dhcp_client->last_address = g_strdup(last_address);
}
}
+#if defined TIZEN_EXT
+ if (dhcp_client->init_reboot == TRUE) {
+ dhcp_client->requested_ip = addr;
+
+ start_request(dhcp_client);
+
+ return 0;
+ }
+#endif
send_discover(dhcp_client, addr);
dhcp_client->timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH,
@@ -2789,3 +2825,18 @@ void g_dhcp_client_set_debug(GDHCPClient *dhcp_client,
dhcp_client->debug_func = func;
dhcp_client->debug_data = user_data;
}
+#if defined TIZEN_EXT
+void g_dhcp_client_set_address_known(GDHCPClient *dhcp_client, gboolean known)
+{
+ /* DHCPREQUEST during INIT-REBOOT state (rfc2131)
+ * 4.4.3 Initialization with known network address
+ * 4.3.2 DHCPREQUEST generated during INIT-REBOOT state
+ */
+ debug(dhcp_client, "known network address (%d)", known);
+
+ if (dhcp_client->init_reboot == known)
+ return;
+
+ dhcp_client->init_reboot = known;
+}
+#endif
diff --git a/gdhcp/gdhcp.h b/gdhcp/gdhcp.h
index ba47eaff..71431f5a 100644
--- a/gdhcp/gdhcp.h
+++ b/gdhcp/gdhcp.h
@@ -197,6 +197,10 @@ void g_dhcp_server_set_lease_time(GDHCPServer *dhcp_server,
unsigned int lease_time);
void g_dhcp_server_set_save_lease(GDHCPServer *dhcp_server,
GDHCPSaveLeaseFunc func, gpointer user_data);
+#if defined TIZEN_EXT
+void g_dhcp_client_set_address_known(GDHCPClient *client, gboolean known);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h
index da45075a..18dd0422 100644
--- a/gsupplicant/gsupplicant.h
+++ b/gsupplicant/gsupplicant.h
@@ -243,6 +243,15 @@ dbus_bool_t g_supplicant_network_is_wps_active(GSupplicantNetwork *network);
dbus_bool_t g_supplicant_network_is_wps_pbc(GSupplicantNetwork *network);
dbus_bool_t g_supplicant_network_is_wps_advertizing(GSupplicantNetwork *network);
+#if defined TIZEN_EXT
+/*
+ * Description: Network client requires additional wifi specific info
+ */
+const unsigned char *g_supplicant_network_get_bssid(GSupplicantNetwork *network);
+unsigned int g_supplicant_network_get_maxrate(GSupplicantNetwork *network);
+const char *g_supplicant_network_get_enc_mode(GSupplicantNetwork *network);
+#endif
+
struct _GSupplicantCallbacks {
void (*system_ready) (void);
void (*system_killed) (void);
diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c
index 30f0660b..0f625bcb 100644
--- a/gsupplicant/supplicant.c
+++ b/gsupplicant/supplicant.c
@@ -916,6 +916,55 @@ dbus_bool_t g_supplicant_network_is_wps_advertizing(GSupplicantNetwork *network)
return FALSE;
}
+#if defined TIZEN_EXT
+/*
+ * Description: Network client requires additional wifi specific info
+ */
+const unsigned char *g_supplicant_network_get_bssid(GSupplicantNetwork *network)
+{
+ if (network == NULL || network->best_bss == NULL)
+ return NULL;
+
+ return (const unsigned char *)network->best_bss->bssid;
+}
+
+unsigned int g_supplicant_network_get_maxrate(GSupplicantNetwork *network)
+{
+ if (network == NULL || network->best_bss == NULL)
+ return 0;
+
+ return network->best_bss->maxrate;
+}
+
+const char *g_supplicant_network_get_enc_mode(GSupplicantNetwork *network)
+{
+ if (network == NULL || network->best_bss == NULL)
+ return NULL;
+
+ if (network->best_bss->security == G_SUPPLICANT_SECURITY_PSK ||
+ network->best_bss->security == G_SUPPLICANT_SECURITY_IEEE8021X) {
+ unsigned int pairwise;
+
+ pairwise = network->best_bss->rsn_pairwise |
+ network->best_bss->wpa_pairwise;
+
+ if ((pairwise & G_SUPPLICANT_PAIRWISE_CCMP) &&
+ (pairwise & G_SUPPLICANT_PAIRWISE_TKIP))
+ return "mixed";
+ else if (pairwise & G_SUPPLICANT_PAIRWISE_CCMP)
+ return "aes";
+ else if (pairwise & G_SUPPLICANT_PAIRWISE_TKIP)
+ return "tkip";
+
+ } else if (network->best_bss->security == G_SUPPLICANT_SECURITY_WEP)
+ return "wep";
+ else if (network->best_bss->security == G_SUPPLICANT_SECURITY_NONE)
+ return "none";
+
+ return NULL;
+}
+#endif
+
static void merge_network(GSupplicantNetwork *network)
{
GString *str;
@@ -3381,6 +3430,17 @@ static void add_network_security_proto(DBusMessageIter *dict,
g_free(proto);
}
+#if defined TIZEN_EXT
+static void add_network_security_none(DBusMessageIter *dict,
+ GSupplicantSSID *ssid)
+{
+ const char *auth_alg = "OPEN";
+
+ supplicant_dbus_dict_append_basic(dict, "auth_alg",
+ DBUS_TYPE_STRING, &auth_alg);
+}
+#endif
+
static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
{
char *key_mgmt;
@@ -3388,6 +3448,12 @@ static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
switch (ssid->security) {
case G_SUPPLICANT_SECURITY_UNKNOWN:
case G_SUPPLICANT_SECURITY_NONE:
+#if defined TIZEN_EXT
+ key_mgmt = "NONE";
+ add_network_security_none(dict, ssid);
+ add_network_security_ciphers(dict, ssid);
+ break;
+#endif
case G_SUPPLICANT_SECURITY_WEP:
key_mgmt = "NONE";
add_network_security_wep(dict, ssid);
diff --git a/gweb/gresolv.c b/gweb/gresolv.c
index 864d2adb..74467f2e 100644
--- a/gweb/gresolv.c
+++ b/gweb/gresolv.c
@@ -665,7 +665,12 @@ static void parse_response(struct resolv_nameserver *nameserver,
debug(resolv, "response from %s", nameserver->address);
+#if defined TIZEN_EXT
+ if (ns_initparse(buf, len, &msg) == -1)
+ return;
+#else
ns_initparse(buf, len, &msg);
+#endif
list = g_queue_find_custom(resolv->query_queue,
GUINT_TO_POINTER(ns_msg_id(msg)), compare_query_msgid);
@@ -713,7 +718,12 @@ static void parse_response(struct resolv_nameserver *nameserver,
lookup->ipv4_status = status;
for (i = 0; i < count; i++) {
+#if defined TIZEN_EXT
+ if (ns_parserr(&msg, ns_s_an, i, &rr) == -1)
+ continue;
+#else
ns_parserr(&msg, ns_s_an, i, &rr);
+#endif
if (ns_rr_class(rr) != ns_c_in)
continue;
diff --git a/include/network.h b/include/network.h
index 65504935..9d7f5f90 100644
--- a/include/network.h
+++ b/include/network.h
@@ -117,6 +117,26 @@ int connman_network_set_nameservers(struct connman_network *network,
const char *nameservers);
int connman_network_set_domain(struct connman_network *network,
const char *domain);
+#if defined TIZEN_EXT
+/*
+ * Description: Network client requires additional wifi specific info
+ */
+int connman_network_set_bssid(struct connman_network *network,
+ const unsigned char *bssid);
+unsigned char *connman_network_get_bssid(struct connman_network *network);
+
+int connman_network_set_maxrate(struct connman_network *network,
+ unsigned int maxrate);
+unsigned int connman_network_get_maxrate(struct connman_network *network);
+
+int connman_network_set_enc_mode(struct connman_network *network,
+ const char *encryption_mode);
+const char *connman_network_get_enc_mode(struct connman_network *network);
+
+int connman_network_set_proxy(struct connman_network *network,
+ const char *proxies);
+#endif
+
int connman_network_set_name(struct connman_network *network,
const char *name);
int connman_network_set_strength(struct connman_network *network,
diff --git a/include/service.h b/include/service.h
index 5e646a08..8953cb7e 100644
--- a/include/service.h
+++ b/include/service.h
@@ -115,6 +115,27 @@ char **connman_service_get_proxy_servers(struct connman_service *service);
char **connman_service_get_proxy_excludes(struct connman_service *service);
const char *connman_service_get_proxy_url(struct connman_service *service);
const char *connman_service_get_proxy_autoconfig(struct connman_service *service);
+#if defined TIZEN_EXT
+/*
+ * Increase reference count of user-initiated packet data network connection
+ */
+void connman_service_user_pdn_connection_ref(struct connman_service *service);
+
+/*
+ * Decrease reference count of user initiated packet data network connection
+ * and return TRUE if counter is zero.
+ */
+connman_bool_t connman_service_user_pdn_connection_unref_and_test(
+ struct connman_service *service);
+
+/*
+ * Test reference count of user initiated packet data network connection
+ * and return TRUE if counter is zero. No impact to reference count
+ */
+connman_bool_t connman_service_is_no_ref_user_pdn_connection(
+ struct connman_service *service);
+#endif
+
connman_bool_t connman_service_get_favorite(struct connman_service *service);
struct connman_service *connman_service_lookup_from_network(struct connman_network *network);
diff --git a/plugins/wifi.c b/plugins/wifi.c
index 5f078692..c50945b8 100644
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -1367,6 +1367,9 @@ static int network_disconnect(struct connman_network *network)
struct connman_device *device = connman_network_get_device(network);
struct wifi_data *wifi;
int err;
+#if defined TIZEN_EXT
+ struct connman_service *service;
+#endif
DBG("network %p", network);
@@ -1374,6 +1377,22 @@ static int network_disconnect(struct connman_network *network)
if (wifi == NULL || wifi->interface == NULL)
return -ENODEV;
+#if defined TIZEN_EXT
+ if (connman_network_get_associating(network) == TRUE)
+ connman_network_set_error(network,
+ CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
+ else {
+ service = connman_service_lookup_from_network(network);
+
+ if (service != NULL &&
+ (__connman_service_is_connected_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV4) == FALSE &&
+ __connman_service_is_connected_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV6) == FALSE) &&
+ (connman_service_get_favorite(service) == FALSE))
+ __connman_service_set_passphrase(service, NULL);
+ }
+#endif
connman_network_set_associating(network, FALSE);
if (wifi->disconnecting == TRUE)
@@ -1790,6 +1809,15 @@ static void network_added(GSupplicantNetwork *supplicant_network)
connman_network_set_frequency(network,
g_supplicant_network_get_frequency(supplicant_network));
+#if defined TIZEN_EXT
+ connman_network_set_bssid(network,
+ g_supplicant_network_get_bssid(supplicant_network));
+ connman_network_set_maxrate(network,
+ g_supplicant_network_get_maxrate(supplicant_network));
+ connman_network_set_enc_mode(network,
+ g_supplicant_network_get_enc_mode(supplicant_network));
+#endif
+
connman_network_set_available(network, TRUE);
connman_network_set_string(network, "WiFi.Mode", mode);
@@ -1844,6 +1872,11 @@ static void network_changed(GSupplicantNetwork *network, const char *property)
struct wifi_data *wifi;
const char *name, *identifier;
struct connman_network *connman_network;
+#if defined TIZEN_EXT
+ const unsigned char *bssid;
+ unsigned int maxrate;
+ uint16_t frequency;
+#endif
interface = g_supplicant_network_get_interface(network);
wifi = g_supplicant_interface_get_data(interface);
@@ -1864,6 +1897,16 @@ static void network_changed(GSupplicantNetwork *network, const char *property)
calculate_strength(network));
connman_network_update(connman_network);
}
+
+#if defined TIZEN_EXT
+ bssid = g_supplicant_network_get_bssid(network);
+ maxrate = g_supplicant_network_get_maxrate(network);
+ frequency = g_supplicant_network_get_frequency(network);
+
+ connman_network_set_bssid(connman_network, bssid);
+ connman_network_set_maxrate(connman_network, maxrate);
+ connman_network_set_frequency(connman_network, frequency);
+#endif
}
static void debug(const char *str)
diff --git a/src/connman.h b/src/connman.h
index 1e6bfec9..c61a872f 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -675,6 +675,10 @@ void __connman_service_timeserver_changed(struct connman_service *service,
GSList *ts_list);
void __connman_service_set_pac(struct connman_service *service,
const char *pac);
+#if defined TIZEN_EXT
+void __connman_service_set_proxy(struct connman_service *service,
+ const char *proxies);
+#endif
connman_bool_t __connman_service_is_hidden(struct connman_service *service);
connman_bool_t __connman_service_is_split_routing(struct connman_service *service);
int __connman_service_get_index(struct connman_service *service);
diff --git a/src/dhcp.c b/src/dhcp.c
index c5c14a8a..028035cf 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -412,6 +412,9 @@ static int dhcp_request(struct connman_dhcp *dhcp)
GDHCPClientError error;
const char *hostname;
int index;
+#if defined TIZEN_EXT
+ const char *last_address;
+#endif
DBG("dhcp %p", dhcp);
@@ -460,6 +463,14 @@ static int dhcp_request(struct connman_dhcp *dhcp)
service = connman_service_lookup_from_network(dhcp->network);
ipconfig = __connman_service_get_ip4config(service);
+#if defined TIZEN_EXT
+ last_address = __connman_ipconfig_get_dhcp_address(ipconfig);
+
+ if (last_address != NULL && strlen(last_address) > 0)
+ g_dhcp_client_set_address_known(dhcp_client, TRUE);
+
+ return g_dhcp_client_start(dhcp_client, last_address);
+#else
/*
* Clear the addresses at startup so that lease callback will
* take the lease and set ip address properly.
@@ -468,6 +479,7 @@ static int dhcp_request(struct connman_dhcp *dhcp)
return g_dhcp_client_start(dhcp_client,
__connman_ipconfig_get_dhcp_address(ipconfig));
+#endif
}
static int dhcp_release(struct connman_dhcp *dhcp)
diff --git a/src/network.c b/src/network.c
index 6a926cbc..789925a6 100644
--- a/src/network.c
+++ b/src/network.c
@@ -41,6 +41,11 @@
*/
#define RS_REFRESH_TIMEOUT 3
+#if defined TIZEN_EXT
+#define WIFI_ENCYPTION_MODE_LEN_MAX 6
+#define WIFI_BSSID_LEN_MAX 6
+#endif
+
static GSList *network_list = NULL;
static GSList *driver_list = NULL;
@@ -88,6 +93,11 @@ struct connman_network {
connman_bool_t wps;
connman_bool_t use_wps;
char *pin_wps;
+#if defined TIZEN_EXT
+ char encryption_mode[WIFI_ENCYPTION_MODE_LEN_MAX];
+ unsigned char bssid[WIFI_BSSID_LEN_MAX];
+ unsigned int maxrate;
+#endif
} wifi;
};
@@ -1507,6 +1517,9 @@ int __connman_network_connect(struct connman_network *network)
network->connecting = TRUE;
+#if defined TIZEN_EXT
+ if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR)
+#endif
__connman_device_disconnect(network->device);
err = network->driver->connect(network);
@@ -1696,6 +1709,87 @@ int connman_network_set_ipaddress(struct connman_network *network,
return 0;
}
+#if defined TIZEN_EXT
+/*
+ * Description: Network client requires additional wifi specific info
+ */
+int connman_network_set_bssid(struct connman_network *network,
+ const unsigned char *bssid)
+{
+ int i = 0;
+
+ if (bssid == NULL)
+ return -EINVAL;
+
+ DBG("network %p bssid %02x:%02x:%02x:%02x:%02x:%02x", network,
+ bssid[0], bssid[1], bssid[2],
+ bssid[3], bssid[4], bssid[5]);
+
+ for (;i < WIFI_BSSID_LEN_MAX;i++)
+ network->wifi.bssid[i] = bssid[i];
+
+ return 0;
+}
+
+unsigned char *connman_network_get_bssid(struct connman_network *network)
+{
+ return (unsigned char *)network->wifi.bssid;
+}
+
+int connman_network_set_maxrate(struct connman_network *network,
+ unsigned int maxrate)
+{
+ DBG("network %p maxrate %d", network, maxrate);
+
+ network->wifi.maxrate = maxrate;
+
+ return 0;
+}
+
+unsigned int connman_network_get_maxrate(struct connman_network *network)
+{
+ return network->wifi.maxrate;
+}
+
+int connman_network_set_enc_mode(struct connman_network *network,
+ const char *encryption_mode)
+{
+ if (encryption_mode == NULL)
+ return -EINVAL;
+
+ DBG("network %p encryption mode %s", network, encryption_mode);
+
+ g_strlcpy(network->wifi.encryption_mode, encryption_mode,
+ WIFI_ENCYPTION_MODE_LEN_MAX);
+
+ return 0;
+}
+
+const char *connman_network_get_enc_mode(struct connman_network *network)
+{
+ return (const char *)network->wifi.encryption_mode;
+}
+
+int connman_network_set_proxy(struct connman_network *network,
+ const char *proxies)
+{
+ struct connman_service *service;
+
+ DBG("network %p proxies %s", network, proxies);
+
+ service = connman_service_lookup_from_network(network);
+ if (service == NULL)
+ return -EINVAL;
+
+ __connman_service_set_proxy(service, proxies);
+
+ connman_service_set_proxy_method(service,
+ CONNMAN_SERVICE_PROXY_METHOD_MANUAL);
+
+ return 0;
+}
+#endif
+
int connman_network_set_nameservers(struct connman_network *network,
const char *nameservers)
{
diff --git a/src/service.c b/src/service.c
index af8bfcee..12d167f6 100644
--- a/src/service.c
+++ b/src/service.c
@@ -39,6 +39,9 @@
#define CONNECT_TIMEOUT 120
+#if defined TIZEN_EXT
+#define WIFI_BSSID_STR_LEN 18
+#endif
static DBusConnection *connection = NULL;
static GSequence *service_list = NULL;
@@ -124,6 +127,15 @@ struct connman_service {
connman_bool_t hidden_service;
char *config_file;
char *config_entry;
+#if defined TIZEN_EXT
+ /*
+ * Description: TIZEN implements system global connection management.
+ * It's only for PDP (cellular) bearer. Wi-Fi is managed
+ * by ConnMan automatically. Reference count can help to
+ * manage open/close connection requests by each application.
+ */
+ int user_pdn_connection_refcount;
+#endif
};
static connman_bool_t allow_property_changed(struct connman_service *service);
@@ -139,6 +151,40 @@ struct find_data {
struct connman_service *service;
};
+#if defined TIZEN_EXT
+/*
+ * Public APIs to use user_pdn_connection_refcount
+ */
+void connman_service_user_pdn_connection_ref(struct connman_service *service)
+{
+ __sync_fetch_and_add(&service->user_pdn_connection_refcount, 1);
+ DBG("User make a PDP connection with already refcount: %d",
+ service->user_pdn_connection_refcount);
+}
+
+connman_bool_t connman_service_user_pdn_connection_unref_and_test(
+ struct connman_service *service)
+{
+ DBG("User disconnect PDP connection with already refcount: %d",
+ service->user_pdn_connection_refcount);
+
+ if (__sync_sub_and_fetch(&service->user_pdn_connection_refcount, 1)
+ > 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+connman_bool_t connman_service_is_no_ref_user_pdn_connection(
+ struct connman_service *service)
+{
+ __sync_synchronize();
+ if (service->user_pdn_connection_refcount == 0)
+ return TRUE;
+
+ return FALSE;
+}
+#endif
static void compare_path(gpointer value, gpointer user_data)
{
struct connman_service *service = value;
@@ -2178,6 +2224,37 @@ connman_bool_t __connman_service_session_dec(struct connman_service *service)
return TRUE;
}
+#if defined TIZEN_EXT
+static void append_wifi_ext_info(DBusMessageIter *dict,
+ struct connman_network *network)
+{
+ char bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
+ char *bssid_str = bssid_buff;
+ unsigned char *bssid;
+ unsigned int maxrate;
+ uint16_t frequency;
+ const char *enc_mode;
+
+ bssid = connman_network_get_bssid(network);
+ maxrate = connman_network_get_maxrate(network);
+ frequency = connman_network_get_frequency(network);
+ enc_mode = connman_network_get_enc_mode(network);
+
+ snprintf(bssid_str, WIFI_BSSID_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
+ bssid[0], bssid[1], bssid[2],
+ bssid[3], bssid[4], bssid[5]);
+
+ connman_dbus_dict_append_basic(dict, "BSSID",
+ DBUS_TYPE_STRING, &bssid_str);
+ connman_dbus_dict_append_basic(dict, "MaxRate",
+ DBUS_TYPE_UINT32, &maxrate);
+ connman_dbus_dict_append_basic(dict, "Frequency",
+ DBUS_TYPE_UINT16, &frequency);
+ connman_dbus_dict_append_basic(dict, "EncryptionMode",
+ DBUS_TYPE_STRING, &enc_mode);
+}
+#endif
+
static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
struct connman_service *service)
{
@@ -2238,6 +2315,14 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
append_ethernet, service);
break;
case CONNMAN_SERVICE_TYPE_WIFI:
+#if defined TIZEN_EXT
+ if (service->network != NULL)
+ append_wifi_ext_info(dict, service->network);
+
+ connman_dbus_dict_append_dict(dict, "Ethernet",
+ append_ethernet, service);
+ break;
+#endif
case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
connman_dbus_dict_append_dict(dict, "Ethernet",
@@ -2654,6 +2739,22 @@ void __connman_service_set_pac(struct connman_service *service,
proxy_changed(service);
}
+#if defined TIZEN_EXT
+void __connman_service_set_proxy(struct connman_service *service,
+ const char *proxies)
+{
+ char **proxies_array = NULL;
+
+ g_strfreev(service->proxies);
+ service->proxies = NULL;
+
+ if (proxies != NULL)
+ proxies_array = g_strsplit(proxies, " ", 0);
+
+ service->proxies = proxies_array;
+}
+#endif
+
void __connman_service_set_identity(struct connman_service *service,
const char *identity)
{
@@ -3780,6 +3881,10 @@ static DBusMessage *connect_service(DBusConnection *conn,
DBG("service %p", service);
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ connman_service_user_pdn_connection_ref(service);
+#endif
if (service->pending != NULL)
return __connman_error_in_progress(msg);
@@ -3848,6 +3953,16 @@ static DBusMessage *disconnect_service(DBusConnection *conn,
DBG("service %p", service);
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) {
+ if (connman_service_user_pdn_connection_unref_and_test(service) != TRUE)
+ return __connman_error_failed(msg, EISCONN);
+
+ if (is_connected(service) == TRUE &&
+ service == __connman_service_get_default())
+ return __connman_error_failed(msg, EISCONN);
+ }
+#endif
reply_pending(service, ECONNABORTED);
service->ignore = TRUE;
@@ -4394,6 +4509,9 @@ static void service_initialize(struct connman_service *service)
service->provider = NULL;
service->wps = FALSE;
+#if defined TIZEN_EXT
+ service->user_pdn_connection_refcount = 0;
+#endif
}
/**
@@ -5075,18 +5193,38 @@ static int service_update_preferred_order(struct connman_service *default_servic
return -EALREADY;
}
+#if defined TIZEN_EXT
+static connman_bool_t __connman_service_can_drop_cellular(
+ struct connman_service *cellular)
+{
+ if (cellular->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
+ is_connected(cellular) == TRUE)
+ if (connman_service_is_no_ref_user_pdn_connection(cellular)
+ == TRUE)
+ return TRUE;
+ return FALSE;
+}
+#endif
+
static void single_connected_tech(struct connman_service *allowed)
{
GSList *services = NULL;
GSequenceIter *iter;
GSList *list;
+#if defined TIZEN_EXT
+ if (allowed->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ return;
+#endif
iter = g_sequence_get_begin_iter(service_list);
while (g_sequence_iter_is_end(iter) == FALSE) {
struct connman_service *service = g_sequence_get(iter);
if (service != allowed && is_connected(service))
+#if defined TIZEN_EXT
+ if (__connman_service_can_drop_cellular(service) == TRUE)
+#endif
services = g_slist_prepend(services, service);
iter = g_sequence_iter_next(iter);
@@ -5144,7 +5282,16 @@ static int service_indicate_state(struct connman_service *service)
if (new_state == CONNMAN_SERVICE_STATE_IDLE &&
old_state != CONNMAN_SERVICE_STATE_DISCONNECT) {
+#if !defined TIZEN_EXT
+ /*
+ * Description: 'service->pending' should be cleared whenever
+ * connection is finished regardless success or failure.
+ * If the service is disconnected in configuration state by
+ * dhcp failure or by the other part of connman, new state is
+ * 'idle' but old state is 'disconnect'. So it's not cleared.
+ */
reply_pending(service, ECONNABORTED);
+#endif
__connman_service_disconnect(service);
}
@@ -5166,6 +5313,9 @@ static int service_indicate_state(struct connman_service *service)
if (new_state == CONNMAN_SERVICE_STATE_IDLE) {
connman_bool_t reconnect;
+#if defined TIZEN_EXT
+ reply_pending(service, ECONNABORTED);
+#endif
reconnect = get_reconnect_state(service);
if (reconnect == TRUE)
__connman_service_auto_connect();
@@ -5296,7 +5446,13 @@ int __connman_service_indicate_error(struct connman_service *service,
set_error(service, error);
+#if defined TIZEN_EXT
+ if (service->favorite == FALSE &&
+ (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY ||
+ service->error == CONNMAN_SERVICE_ERROR_CONNECT_FAILED))
+#else
if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY)
+#endif
__connman_service_set_passphrase(service, NULL);
__connman_service_ipconfig_indicate_state(service,
@@ -5507,6 +5663,11 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service,
if (ipconfig == NULL)
return -EINVAL;
+#if defined TIZEN_EXT
+ if (new_state == CONNMAN_SERVICE_STATE_FAILURE &&
+ service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ service->user_pdn_connection_refcount = 0;
+#endif
/* Any change? */
if (old_state == new_state)
return -EALREADY;