Kalle Valo <kalle.valo@canonical.com>
Fabien Marotte <fabienx.marotte@linux.intel.com>
Pekka Pessi <pekka.pessi@nokia.com>
-Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
+Tomasz Bursztyka <tomasz.bursztyka@nokia.com>
Cristiano Fernandes <cristiano.fernandes@hp.com>
Joey Lee <jlee@novell.com>
Leena Gunda <leena.gunda@wipro.com>
-Patrik Flykt <patrik.flykt@linux.intel.com>
+Patrik Flykt <patrik.flykt@nokia.com>
David Woodhouse <dwmw2@infradead.org>
-Gustavo Padovan <gustavo@padovan.org>
+Gustavo F. Padovan <padovan@profusion.mobi>
Julien Massot <jmassot@aldebaran-robotics.com>
-Jukka Rissanen <jukka.rissanen@linux.intel.com>
+Jukka Rissanen <jukka.rissanen@nokia.com>
Grant Erickson <marathon96@gmail.com>
Guillaume Lucas <guillaumex.lucas@intel.com>
Henri Bragge <henri.bragge@ixonos.com>
-Alok Barsode <alok.barsode@intel.com>
+Alok Barsode <alok.barsode@nokia.com>
Sébastien Bianti <sebastien.bianti@linux.intel.com>
Yu A Wang <yu.a.wang@intel.com>
Thierry Boureille <thierry.boureille@gmail.com>
Jeff Zheng <jeff.zheng@intel.com>
Philippe Nunes <philippe.nunes@linux.intel.com>
Danny Jeongseok Seo <s.seo@samsung.com>
-Flávio Ceolin <flavio.ceolin@profusion.mobi>
-Arjan van de Ven <arjan@linux.intel.com>
-Daniel Mack <zonque@gmail.com>
-Guillaume Zajac <guillaume.zajac@linux.intel.com>
Manfred Kober <manfred.kober@gmx.de>
-Mario Domenech Goulart <mario.goulart@gmail.com>
-Otavio Salvador <otavio@ossystems.com.br>
-Tim Sander <tim01@iss.tu-darmstadt.de>
-Adrien Bustany <adrien.bustany@nokia.com>
-Henrique Dante de Almeida <hdante@profusion.mobi>
-Lucas De Marchi <lucas.demarchi@profusion.mobi>
-Elena Tebesoi <elena.tebesoi@gmail.com>
-Mikel Astiz <mikel.astiz@bmw-carit.de>
-Paulo Pizarro <paulo.pizarro@gmail.com>
-ver 1.3:
- Fix issue with default configuration values.
- Fix issue with timeserver canonical name entries.
- Fix issue with crash from cellular dummy context.
- Fix issue with incorrect index for private networks.
-
-ver 1.2:
- Fix issue with not handling WiFi security changes.
- Fix issue with not stopping WiFi scanning on shutdown.
- Fix issue with auto-scanning and network discovery.
- Fix issue with D-Bus reply for hidden WiFi networks.
- Fix issue with overlapping memory areas and DNS requests.
- Add support for randomized DNS transaction identifiers.
- Add support for DNS caching over TCP connections.
- Add support for using default IPv6 privacy setting.
- Add support for providing previous passphrase to agent.
- Add support for configuration unprovisioning handling.
- Add support for NetworkInterfaceBlacklist configuration.
- Add support for Bluetooth DUN daemon (dundee).
-
-ver 1.1:
- Fix issue with missing message type and DHCPv4 support.
- Fix issue with potential NULL pointer in DHCPv6 handling.
- Fix issue with potential NULL pointer in VPN handling.
- Fix issue with potential NULL pointer for WiFi SSID.
- Fix issue with missing conversion of raw WiFi PSK input.
- Fix issue with missing stop for WiFi auto-scanning handling.
- Fix issue with uninitialized IPv6 prefix length in oFono plugin.
- Fix issue with domain search list handling according to RFC 6106.
- Fix issue with domain name list notifications.
- Fix issue with nameserver list notifications.
- Fix issue with incorrect fixed IP configuration.
- Fix issue with incorrect cleanup of resolver timers.
- Fix issue with handling of RDNSS lifetime expiration.
- Fix issue with crash on wrong domain length information.
- Add support for favorite service database migration.
- Add support for disabling WISPr functionality.
- Add support for configurable agent timeouts.
-
-ver 1.0:
- Fix issue with missing WiFi disconnecting flag.
- Fix issue with missing GPRS context attached check.
- Fix issue with potential crash and supplicant handling.
- Fix issue with potential crash and VPN provider.
- Fix issue with potential crash and host routes.
-
-ver 0.85:
- Fix issue with duplicate service timeservers.
- Fix issue with failure state when aborting agent request.
- Fix issue with automatic scanning for hidden WiFi networks.
- Fix issue with missing hostname/domainname validity checks.
- Fix issue with missing DHCP packet length checks.
- Add support for browser launching from WISPr login.
-
-ver 0.84:
- Fix issue with handling changed WiFi security of access points.
- Fix issue with state notification of NetworkManager compatibility.
-
-ver 0.83:
- Fix issue with Ethernet not being enabled by default.
- Fix issue with missing host routes for WISPr request.
- Fix issue with missing HTTPS handling for WISPr support.
- Fix issue with agent asking for passphrase for open service.
- Fix issue with endless online check for preferred technology.
- Fix issue with IPv6 RDNSS and DNS server creation.
- Fix issue with WiFi roaming state change handling.
- Fix issue with broken handling of WPS PBC method.
-
-ver 0.82:
- Fix issue with global online state handling.
- Fix issue with timeserver handling in case of VPN.
- Fix issue with automatic WiFi scanning handling.
- Fix issue with WPS PIN length of zero and PBC.
-
-ver 0.81:
- Update default configuration options.
- Add support for WPS PBC advertising handling.
- Add support for wpa_supplicant background scanning.
- Fix issue with showing cellular services without APN.
- Fix issue with missing timeservers changed signal.
-
-ver 0.80:
- Update to support additional D-Bus API changes.
- Add support for preferred technologies switching.
- Add support for default auto connect technologies option.
- Add support for service specific timeserver configuration.
- Add support for extended timeserver fallback functionality.
- Add support for extended nameserver fallback functionality.
- Add support for user supplied routes for providers.
- Add support for checking WiFi passphrase validity.
- Fix issue with WISPr support and proxy handling.
- Fix issue with Ethernet and auto connect handling.
- Fix issue with too early IPv6 auto connection.
- Fix issue with too early 6to4 connection checks.
- Fix issue with oFono interaction on disconnect.
- Fix issue with DNS servers behind point-to-point links.
- Fix issue with pending DNS proxy requests.
- Fix multiple issues with VPN handling.
- Fix multiple issues with default gateway handling.
-
-ver 0.79:
- Update to support changed D-Bus API.
- Add support for WiFi background scanning.
- Add support for showing hidden WiFi networks as services.
- Add support for generic stateless DHCPv6 handling.
- Add support for DHCPv4 client identifier handling.
- Add support for generic IP address pool handling.
- Add support for global DNS cache handling.
- Add support for internal NTP time handling.
- Add support for updated oFono handling.
+ver 0.78.4
+ Apply BMC fix 24943
+
+ver 0.78.3:
+ Update ofono plugin.
+ Apply BMC fixes 24592, 23741, 23740, 24549, 24702, 24651, 24737,
+ 24712, 24942, 24965 and 25026.
+
+ver 0.78.2:
+ Backport ofono with CDMA support
+
+ver 0.78.1:
+ Rebased for connman-stable
ver 0.78:
Fix multiple issues with service connection states.
gdhcp_sources = gdhcp/gdhcp.h gdhcp/common.h gdhcp/common.c gdhcp/client.c \
gdhcp/server.c gdhcp/ipv4ll.h gdhcp/ipv4ll.c
-gweb_sources = gweb/gweb.h gweb/gweb.c gweb/gresolv.h gweb/gresolv.c
-
-if WISPR
-gweb_sources += gweb/giognutls.h gweb/giognutls.c
-else
-gweb_sources += gweb/giognutls.h gweb/gionotls.c
-endif
+gweb_sources = gweb/gweb.h gweb/gweb.c gweb/gresolv.h gweb/gresolv.c \
+ gweb/giognutls.h gweb/giognutls.c
if DATAFILES
sbin_PROGRAMS = src/connmand
-src_connmand_SOURCES = $(gdbus_sources) $(gdhcp_sources) $(gweb_sources) \
+src_connmand_SOURCES = $(gdbus_sources) $(gdhcp_sources) \
+ gweb/gweb.h gweb/gweb.c \
+ gweb/gresolv.h gweb/gresolv.c \
+ gweb/giognutls.h gweb/gionotls.c \
$(builtin_sources) src/connman.ver \
src/main.c src/connman.h src/log.c \
src/error.c src/plugin.c src/task.c \
src/clock.c src/timezone.c \
src/agent.c src/notifier.c src/provider.c \
src/resolver.c src/ipconfig.c src/detect.c src/inet.c \
- src/dhcp.c src/dhcpv6.c src/rtnl.c src/proxy.c \
+ src/dhcp.c src/rtnl.c src/proxy.c \
src/utsname.c src/timeserver.c src/rfkill.c \
src/storage.c src/dbus.c src/config.c \
src/technology.c src/counter.c src/ntp.c \
src/session.c src/tethering.c src/wpad.c src/wispr.c \
- src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c \
- src/ippool.c src/bridge.c src/nat.c
+ src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c
src_connmand_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ \
- @XTABLES_LIBS@ @GNUTLS_LIBS@ -lresolv -ldl
+ @CAPNG_LIBS@ @XTABLES_LIBS@ -lresolv -ldl
src_connmand_LDFLAGS = -Wl,--export-dynamic \
-Wl,--version-script=$(srcdir)/src/connman.ver
build_scriptdir = $(scriptdir)
endif
-AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \
+AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @CAPNG_CFLAGS@ @XTABLES_CFLAGS@ \
@GNUTLS_CFLAGS@ $(builtin_cflags) \
-DCONNMAN_PLUGIN_BUILTIN \
-DSTATEDIR=\""$(statedir)"\" \
INCLUDES = -I$(builddir)/include -I$(builddir)/src -I$(srcdir)/gdbus
EXTRA_DIST = src/genbuiltin src/connman-dbus.conf src/connman-polkit.conf \
- plugins/connman-nmcompat.conf
+ plugins/connman-nmcompat.conf
script_DATA =
client_cm_LDADD = @DBUS_LIBS@
endif
-if WISPR
-noinst_PROGRAMS += tools/wispr
-
-tools_wispr_SOURCES = $(gweb_sources) tools/wispr.c
-tools_wispr_LDADD = @GLIB_LIBS@ @GNUTLS_LIBS@ -lresolv
-endif
-
if TOOLS
-noinst_PROGRAMS += tools/supplicant-test \
+noinst_PROGRAMS += tools/wispr tools/supplicant-test \
tools/dhcp-test tools/dhcp-server-test \
tools/addr-test tools/web-test tools/resolv-test \
tools/dbus-test tools/polkit-test \
tools/iptables-test tools/tap-test tools/wpad-test \
tools/stats-tool tools/private-network-test \
- unit/test-session unit/test-ippool unit/test-nat
+ tools/alg-test unit/test-session
+
+tools_wispr_SOURCES = $(gweb_sources) tools/wispr.c
+tools_wispr_LDADD = @GLIB_LIBS@ @GNUTLS_LIBS@ -lresolv
tools_supplicant_test_SOURCES = $(gdbus_sources) tools/supplicant-test.c \
tools/supplicant-dbus.h tools/supplicant-dbus.c \
tools_private_network_test_LDADD = @GLIB_LIBS@ @DBUS_LIBS@
+tools_alg_test_LDADD = @GLIB_LIBS@
+
unit_test_session_SOURCES = $(gdbus_sources) src/log.c src/dbus.c \
unit/test-session.c unit/utils.c unit/manager-api.c \
unit/session-api.c unit/test-connman.h
unit_test_session_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ -ldl
unit_objects += $(unit_test_session_OBJECTS)
-
-unit_test_ippool_SOURCES = $(gdbus_sources) src/log.c src/dbus.c \
- src/ippool.c unit/test-ippool.c
-unit_test_ippool_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ -ldl
-unit_objects += $(unit_test_ippool_OBJECTS)
-
-unit_test_nat_SOURCES = $(gdbus_sources) src/log.c src/dbus.c \
- src/iptables.c src/nat.c unit/test-nat.c
-unit_test_nat_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ @XTABLES_LIBS@ -ldl
-unit_objects += $(unit_nat_ippool_OBJECTS)
endif
-test_scripts = test/get-state test/list-services \
- test/monitor-services test/test-clock \
+test_scripts = test/get-state test/list-profiles test/list-services \
+ test/connect-service test/monitor-services test/set-address \
test/simple-agent test/show-introspection test/test-compat \
test/test-manager test/test-connman test/monitor-connman \
- test/connect-vpn test/disconnect-vpn \
+ test/connect-vpn test/disconnect-vpn test/monitor-manager \
test/test-counter test/set-ipv4-method test/set-ipv6-method \
+ test/set-nameservers test/set-domains test/find-service \
test/get-services test/get-proxy-autoconfig test/set-proxy \
test/enable-tethering test/disable-tethering test/backtrace \
- test/test-session test/test-supplicant \
+ test/test-session test/provision-service test/test-supplicant \
test/test-new-supplicant test/service-move-before \
test/set-global-timeservers test/get-global-timeservers \
- test/set-nameservers test/set-domains
+ test/test-clock
if TEST
testdir = $(pkglibdir)/test
doc/manager-api.txt doc/agent-api.txt \
doc/service-api.txt doc/technology-api.txt \
doc/counter-api.txt doc/config-format.txt \
- doc/clock-api.txt doc/session-api.txt \
- doc/session-overview.txt doc/backtrace.txt \
doc/advanced-configuration.txt
DISTCHECK_CONFIGURE_FLAGS = --disable-gtk-doc \
--disable-datafiles \
+ --enable-loopback \
+ --enable-ethernet \
+ --enable-wifi \
+ --enable-bluetooth \
+ --enable-ofono \
+ --enable-telephony \
+ --enable-tizen-ext \
+ --enable-pacrunner \
+ --enable-google \
+ --enable-meego \
+ --enable-client \
--enable-hh2serial-gps \
+ --enable-ntpd \
--enable-openconnect \
- --enable-openvpn \
- --enable-vpnc \
- --enable-nmcompat \
- --enable-polkit
+ --enable-tools
DISTCLEANFILES = $(pkgconfig_DATA)
@DBUS_CFLAGS@
if LOOPBACK
+if LOOPBACK_BUILTIN
builtin_modules += loopback
builtin_sources += plugins/loopback.c
+else
+plugin_LTLIBRARIES += plugins/loopback.la
+plugin_objects += $(plugins_loopback_la_OBJECTS)
+plugins_loopback_la_CFLAGS = $(plugin_cflags)
+plugins_loopback_la_LDFLAGS = $(plugin_ldflags)
+endif
endif
if ETHERNET
+if ETHERNET_BUILTIN
builtin_modules += ethernet
builtin_sources += plugins/ethernet.c
+else
+plugin_LTLIBRARIES += plugins/ethernet.la
+plugin_objects += $(plugins_ethernet_la_OBJECTS)
+plugins_ethernet_la_CFLAGS = $(plugin_cflags)
+plugins_ethernet_la_LDFLAGS = $(plugin_ldflags)
+endif
endif
gsupplicant_sources = gsupplicant/gsupplicant.h gsupplicant/dbus.h \
gsupplicant/supplicant.c gsupplicant/dbus.c
if WIFI
+if WIFI_BUILTIN
builtin_modules += wifi
builtin_sources += plugins/wifi.c $(gsupplicant_sources)
+
+else
+plugin_LTLIBRARIES += plugins/wifi.la
+plugin_objects += $(plugins_wifi_la_OBJECTS)
+plugins_wifi_la_SOURCES = plugins/wifi.c $(gsupplicant_sources)
+plugins_wifi_la_CFLAGS = $(plugin_cflags)
+plugins_wifi_la_LDFLAGS = $(plugin_ldflags)
+
+endif
endif
if BLUETOOTH
+if BLUETOOTH_BUILTIN
builtin_modules += bluetooth
builtin_sources += plugins/bluetooth.c
+else
+plugin_LTLIBRARIES += plugins/bluetooth.la
+plugin_objects += $(plugins_bluetooth_la_OBJECTS)
+plugins_bluetooth_la_CFLAGS = $(plugin_cflags)
+plugins_bluetooth_la_LDFLAGS = $(plugin_ldflags)
+endif
endif
if HH2SERIAL_GPS
endif
if OFONO
+if OFONO_BUILTIN
builtin_modules += ofono
builtin_sources += plugins/mcc.h plugins/ofono.c
+else
+plugin_LTLIBRARIES += plugins/ofono.la
+plugin_objects += $(plugins_ofono_la_OBJECTS)
+plugins_ofono_la_SOURCES = plugins/mcc.h plugins/ofono.c
+plugins_ofono_la_CFLAGS = $(plugin_cflags)
+plugins_ofono_la_LDFLAGS = $(plugin_ldflags)
+endif
endif
-if DUNDEE
-builtin_modules += dundee
-builtin_sources += plugins/dundee.c
+if TELEPHONY
+if TELEPHONY_BUILTIN
+builtin_modules += telephony
+builtin_sources += plugins/telephony.c
+else
+plugin_LTLIBRARIES += plugins/telephony.la
+plugin_objects += $(plugins_telephony_la_OBJECTS)
+plugins_telephony_la_CFLAGS = $(plugin_cflags)
+plugins_telephony_la_LDFLAGS = $(plugin_ldflags)
+endif
endif
if OPENCONNECT
builtin_sources += $(builtin_vpn_sources)
if PACRUNNER
+if PACRUNNER_BUILTIN
builtin_modules += pacrunner
builtin_sources += plugins/pacrunner.c
+else
+plugin_LTLIBRARIES += plugins/pacrunner.la
+plugin_objects += $(plugins_pacrunner_la_OBJECTS)
+plugins_pacrunner_la_CFLAGS = $(plugin_cflags)
+plugins_pacrunner_la_LDFLAGS = $(plugin_ldflags)
+endif
+endif
+
+if GOOGLE
+if GOOGLE_BUILTIN
+builtin_modules += google
+builtin_sources += plugins/google.c
+else
+plugin_LTLIBRARIES += plugins/google.la
+plugin_objects += $(plugins_google_la_OBJECTS)
+plugins_google_la_CFLAGS = $(plugin_cflags)
+plugins_google_la_LDFLAGS = $(plugin_ldflags)
+endif
+endif
+
+if MEEGO
+if MEEGO_BUILTIN
+builtin_modules += meego
+builtin_sources += plugins/meego.c
+else
+plugin_LTLIBRARIES += plugins/meego.la
+plugin_objects += $(plugins_meego_la_OBJECTS)
+plugins_meego_la_CFLAGS = $(plugin_cflags)
+plugins_meego_la_LDFLAGS = $(plugin_ldflags)
+endif
endif
if POLKIT
+if POLKIT_BUILTIN
builtin_modules += polkit
builtin_sources += plugins/polkit.c
+else
+plugin_LTLIBRARIES += plugins/polkit.la
+plugin_objects += $(plugins_polkit_la_OBJECTS)
+plugins_polkit_la_CFLAGS = $(plugin_cflags)
+plugins_polkit_la_LDFLAGS = $(plugin_ldflags)
+endif
if DATAFILES
policydir = @POLKIT_DATADIR@
plugins_iospm_la_LDFLAGS = $(plugin_ldflags)
endif
+if FAKE
+plugin_LTLIBRARIES += plugins/fake.la
+plugin_objects += $(plugins_fake_la_OBJECTS)
+plugins_fake_la_CFLAGS = $(plugin_cflags)
+plugins_fake_la_LDFLAGS = $(plugin_ldflags)
+endif
+
if OPENCONNECT
script_PROGRAMS += scripts/openconnect-script
scripts_openvpn_script_LDADD = @DBUS_LIBS@
endif
+if NTPD
+if NTPD_BUILTIN
+builtin_modules += ntpd
+builtin_sources += plugins/ntpd.c
+builtin_cflags += -DNTPD=\"@NTPD@\"
+else
+plugin_LTLIBRARIES += plugins/ntpd.la
+plugin_objects += $(plugins_ntpd_la_OBJECTS)
+plugins_ntpd_la_CFLAGS = $(plugin_cflags) -DNTPD=\"@NTPD@\"
+plugins_ntpd_la_LDFLAGS = $(plugin_ldflags)
+endif
+endif
+
if NMCOMPAT
+if NMCOMPAT_BUILTIN
builtin_modules += nmcompat
builtin_sources += plugins/nmcompat.c
+else
+plugin_LTLIBRARIES += plugins/nmcompat.la
+plugin_objects += $(plugins_nmcompat_la_OBJECTS)
+plugins_nmcompat_la_CFLAGS = $(plugin_cflags)
+plugins_nmcompat_la_LDFLAGS = $(plugin_ldflags)
+endif
endif
if TIST
Connection Manager
******************
-Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
Functionality and features
The following features are built-in into Connection Manager:
- Generic plugin infrastructure
- Device and network abstraction (with basic storage support)
- - IPv4, IPv4-LL (link-local) and DHCP
- - IPv6, DHCPv6 and 6to4 tunnels
- - Advanced routing and DNS configuration
- - Built-in DNS proxy and intelligent caching
- - Built-in WISPr hotspot logins and portal detection
- - Time and timezone configuration (manual and automatic with NTP)
- - Proxy handling (manual and automatic with WPAD)
- - Tethering support (USB, Bluetooth and WiFi AP mode)
- - Detailed statistics handling (home and roaming)
+ - IPv4, routing and DNS configuration
+ - DNS Proxy
Various plugins can be enabled for networking support:
- Ethernet plugin
- - WiFi plugin with WEP40/WEP128 and WPA/WPA2 (personal and enterprise)
- - Bluetooth plugin (using BlueZ)
- - 2G/3G/4G plugin (using oFono)
+ - WiFi plugin with WEP40/WEP128 and WPA/WPA2 (personal only) support
+ - Bluetooth plugin
Also plugins with additional features are available:
- - Loopback interface setup
- - PACrunner proxy handling
- - PolicyKit authorization support
+ - Loopback setup
+ - PolicyKit support
Compilation and installation
- GCC compiler
- GLib library
- D-Bus library
- - IP-Tables library
- - GnuTLS library (optional)
- PolicyKit (optional)
To configure run:
make && make install
-Configuration and options
-=========================
-
-For a working system, certain configuration options need to be enabled:
-
- --disable-ethernet
-
- Disable support for Ethernet network cards
-
- By default Ethernet technology support is built-in and
- enabled. This option can be used to build a small daemon
- for a specific system if Ethernet support is not required.
-
- --disable-wifi
-
- Disable support for WiFi devices
-
- By default WiFi technology support is built-in and
- enabled. This option can be used to build a small daemon
- for a specific system if WiFi support is not required.
-
- It is safe to build a daemon with WiFi support and no
- running wpa_supplicant. The start of wpa_supplicant is
- automatically detected and only a runtime dependency. It
- is not needed to build ConnMan.
-
- --disable-bluetooth
-
- Disable support for Bluetooth devices
+VPN
+===
- By default Bluetooth technology support is built-in and
- enabled. This option can be used to build a small daemon
- for a specific system if Bluetooth support is not required.
+In order to compile pptp and l2tp VPN plugins, you need ppp development
+package.
- It is safe to build a daemon with Bluetooth support and no
- running bluetoothd. The start of bluetoothd is automatically
- detected and only a runtime dependency. It is not needed to
- build ConnMan.
+To run l2tp you will need
+ - xl2tpd, http://www.xelerance.com/services/software/xl2tpd
- --disable-ofono
+To run pptp you will need
+ - pptp client, http://pptpclient.sourceforge.net
- Disable support for cellular 2G/3G/4G devices
+Both l2tp and pptp also need pppd.
- By default oFono technology support is built-in and
- enabled. This option can be used to build a small daemon
- for a specific system where oFono is not used.
- It is safe to build a daemon with oFono support and no
- running ofonod. That start of ofonod is automatically
- detected and only a runtime dependency. It is not needed to
- build ConnMan.
+Configuration and options
+=========================
- --disable-dundee
+For a working system, certain configuration options need to be enabled:
- Disable support for Bluetooth DUN devices
+ --enable-ethernet
- By default Bluetooth DUN technology (dundee) support is
- built-in and enabled. This option can be used to build a
- small daemon for a specific system where dundee is not used.
+ Enable support for Ethernet network cards
- It is safe to build a daemon with dundee support and no
- running dundee. That start of dundee is automatically
- detected and only a runtime dependency. It is not needed to
- build ConnMan.
+ --enable-wifi
- --disable-pacrunner
+ Enable support for WiFi devices (requires wpa_supplicant)
- Disable support for PACrunner proxy handling
- By default PACrunner support is built-in and enabled. This
- option can be used to build a small daemon for a specific
- system where PACrunner is not used.
+ --enable-bluetooth
- It is safe to build a daemon with PACrunner support and no
- pacrunner daemon. It will detect and start a PACrunner
- process if needed at runtime. The presence is not needed
- to build ConnMan.
+ Enable support for Bluetooth devices (requires BlueZ)
- --disable-loopback
+ --enable-loopback
- Disable setup of loopback device
+ Enable setup of loopback device
For distributions with a really minimal init system and no
networking scripts this can take care of setting up the
loopback device and enabling it.
- It is safe to leave this selected even if networking
- scripts are in place. It detects an already configured
- loopback device and leaves it as it is.
-
- --disable-wispr
-
- Disable support for WISPr hotspot logins
-
- For systems with really minimal memory requirements, this
- will disable the support for WISPr hotspot logins. The code
- for WISPr will be still compiled into the daemon, but its
- requirement on GnuTLS for secure connections will be lifted.
-
- The missing GnuTLS support shrinks the memory requirements
- by about 30% and for systems that are more stationary and do
- not log into hotspots this might be a better trade off.
-
- Disabling WISPr support is not disabling the portal detection
- support. A portal will still be detected, but instead of being
- asked for login credentials, the request for a browser session
- will be made through the agent.
+ It is safe to select this option even if networking scripts
+ are in place. It detects an already configured loopback
+ device and leaves it as it is.
--enable-polkit
This allows to check every D-Bus access against a security
policy and so restrict access to certain functionality.
- --enable-nmcompat
-
- Enable support for NetworkManager compatibility interfaces
-
- This allows to expose a minimal set of NetworkManager
- interfaces. It is useful for systems with applications
- written to use NetworkManager to detect online/offline
- status and have not yet been converted to use ConnMan.
-
-
-wpa_supplicant configuration
-============================
-
-In order to get wpa_supplicant and Connection Manager working properly
-together you should edit wpa_supplicant .config file and set:
-
-CONFIG_WPS=y
-CONFIG_AP=y
-CONFIG_CTRL_IFACE_DBUS_NEW=y
-
-and, add:
-
-CONFIG_BGSCAN_SIMPLE=y
-
-This last option will enable the support of background scanning while being
-connected, which is necessary when roaming on wifi.
-
-It is recommended to use wpa_supplicant 0.8.x or 1.x or later.
-
-
-VPN
-===
-
-In order to compile pptp and l2tp VPN plugins, you need ppp development
-package.
-
-To run l2tp you will need
- - xl2tpd, http://www.xelerance.com/services/software/xl2tpd
-
-To run pptp you will need
- - pptp client, http://pptpclient.sourceforge.net
-
-Both l2tp and pptp also need pppd.
-
-
-OpenVPN
-=======
-
-Up to version 2.2 of OpenVPN, pushing additional routes from the
-server will not always work. Some of the symptons are that additional
-routes will not be set by ConnMan if the uplink is a cellular
-network. While the same setup works well for a WiFi or ethernet
-uplink.
-
-
-Information
-===========
-
-Mailing list:
- connman@connman.net
-
-For additional information about the project visit ConnMan web site:
- http://www.connman.net
Priority: High
Complexity: C4
Owner: Daniel Wagner <daniel.wagner@bmw-carit.de>
- Owner: Patrik Flykt <patrik.flykt@linux.intel.com>
+ Owner: Samuel Ortiz <sameo@linux.intel.com>
The session API should provide a connection abstraction in order to
prioritize applications network accesses, prevent or allow network
See http://www.mail-archive.com/connman@connman.net/msg01653.html
+- DNS caching
+
+ Priority: Low
+ Complexity: C4
+
+ A simple initial implementation would see ConnMan's dnsproxy
+ caching the DNS record based on their TTL.
+
+
+- Power management
+
+ Priority: Medium
+ Complexity: C4
+ Owner: Samuel Ortiz <sameo@linux.intel.com>
+
+ Implement a simple device pm hook that ConnMan's core code would
+ use whenever it decides to put devices in power save mode. Although
+ the kernel runtime power management code should take care of that,
+ not all driver (especially WiFi ones) implement runtime PM hooks.
+
+
+- IP ranges allocation and check
+
+ Priority: High
+ Complexity: C2
+
+ For both tethering and private networks, but also to detect invalid
+ static IP configurations, we need to have a core IP range layer
+ that manages all currently used IP blocks.
+
+
- Personal firewall
Priority: Low
security integration.
-- Favorite service migration removal
- Priority: Medium
- Complexity: C1
- When: 12/2012
+WiFi
+====
- Remove service migration code that moves services from default.profile
- to the current directory-based structure.
+- Ad-Hoc support
+ Priority: Medium
+ Complexity: C2
+ Owner: Samuel Ortiz <sameo@linux.intel.com>
+
+
+- Fast Connect
+
+ Priority: Low
+ Complexity: C4
+ Owner: Samuel Ortiz <sameo@linux.intel.com>
-WiFi
-====
- EAP-AKA/SIM
Complexity: C2
-- Previous WPS pin code sending
- Priority: Medium
- Complexity: C2
+Bluetooth
+=========
- Provide previous WPS pin code in PreviousPassphrase field if WPS was used.
+- DUN client
-- Removing wpa_supplicant 0.7.x legacy support
+ Priority: Low
+ Complexity: C4
+ Owner: Mario Tokarz <mario.tokarz@bmw-carit.de>
- Priority: Low
- Complexity: C1
- Owner: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
-
- Removing global country property setter in gsupplicant, and removing
- wifi's technology set_regdom implementation. Removing autoscan fallback.
- (Note: should be done around the end 2012)
-
-Bluetooth
-=========
Cellular
- IPsec
- Priority: Medium
- Complexity: C4
- Owner: Jukka Rissanen <jukka.rissanen@linux.intel.com>
-
-
-Tools
-=====
-
-- Command line tool
-
Priority: Low
Complexity: C4
- Owner: Patrik Flykt <patrik.flykt@linux.intel.com>
-
- For platforms not running python, it could prove useful to provide them
- with a native single binary command line tool.
-User Interface
-==============
-
-- GNOME3 UI
+- Split tunnelling
Priority: Low
- Complexity: C4
- Owner: Alok Barsode <alok.barsode@linux.intel.com>
+ Complexity: C8
+ Dependencies: Core:Private networks
- A GNOME3 shell user interface would make it easier for mainstream distros
- users to use ConnMan.
+ The current VPN support puts the VPN interface at the top of the
+ service list, giving VPNs the default route. When doing split
+ tunneling, the system routes packet to the VPN interface for
+ private IPs, while going through the default interface for the rest
+ of the traffic.
--- /dev/null
+aclocal
+libtoolize
+autoheader
+autoconf
+automake --add-missing
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
AC_PREREQ(2.60)
-AC_INIT(connman, 1.3)
+AC_INIT(connman, 0.78.4)
AM_INIT_AUTOMAKE([foreign subdir-objects color-tests])
AM_CONFIG_HEADER(config.h)
AC_ARG_ENABLE(threads,
AC_HELP_STRING([--enable-threads], [enable threading support]),
- [enable_threads=${enableval}], [enable_threads="no"])
+ [enable_threads=${enableval}], [enable_threads="yes"])
+
+AC_ARG_ENABLE(ethernet,
+ AC_HELP_STRING([--enable-ethernet], [enable Ethernet support]),
+ [enable_ethernet=${enableval}], [enable_ethernet="yes"])
+AM_CONDITIONAL(ETHERNET, test "${enable_ethernet}" != "no")
+AM_CONDITIONAL(ETHERNET_BUILTIN, test "${enable_ethernet}" = "builtin")
+
+AC_ARG_ENABLE(wifi,
+ AC_HELP_STRING([--enable-wifi], [enable WiFi support]),
+ [enable_wifi=${enableval}], [enable_wifi="yes"])
+if (test "${enable_wifi}" != "no"); then
+ AC_PATH_PROG(WPASUPPLICANT, [wpa_supplicant], [],
+ $PATH:/sbin:/usr/sbin)
+fi
+AM_CONDITIONAL(WIFI, test "${enable_wifi}" != "no")
+AM_CONDITIONAL(WIFI_BUILTIN, test "${enable_wifi}" = "builtin")
+
+AC_ARG_ENABLE(bluetooth,
+ AC_HELP_STRING([--enable-bluetooth], [enable Bluetooth support]),
+ [enable_bluetooth=${enableval}], [enable_bluetooth="no"])
+AM_CONDITIONAL(BLUETOOTH, test "${enable_bluetooth}" != "no")
+AM_CONDITIONAL(BLUETOOTH_BUILTIN, test "${enable_bluetooth}" = "builtin")
AC_ARG_ENABLE(hh2serial-gps,
AC_HELP_STRING([--enable-hh2serial-gps], [enable hh2serial GPS support]),
AM_CONDITIONAL(HH2SERIAL_GPS, test "${enable_hh2serial_gps}" != "no")
AM_CONDITIONAL(HH2SERIAL_GPS_BUILTIN, test "${enable_hh2serial_gps}" = "builtin")
+AC_ARG_ENABLE(ofono,
+ AC_HELP_STRING([--enable-ofono], [enable oFono support]),
+ [enable_ofono=${enableval}], [enable_ofono="no"])
+AM_CONDITIONAL(OFONO, test "${enable_ofono}" != "no")
+AM_CONDITIONAL(OFONO_BUILTIN, test "${enable_ofono}" = "builtin")
+
+AC_ARG_ENABLE(telephony,
+ AC_HELP_STRING([--enable-telephony], [enable Telephony support]),
+ [enable_telephony=${enableval}], [enable_telephony="yes"])
+AM_CONDITIONAL(TELEPHONY, test "${enable_telephony}" != "no")
+AM_CONDITIONAL(TELEPHONY_BUILTIN, test "${enable_telephony}" = "builtin")
+
+AC_ARG_ENABLE(tizen-ext, AC_HELP_STRING([--enable-tizen-ext],
+ [enable TIZEN extensions]), [
+ if (test "${enableval}" = "yes"); then
+ CFLAGS="$CFLAGS -DTIZEN_EXT"
+ PKG_CHECK_MODULES(IPTC, libiptc, dummy=yes,
+ AC_MSG_ERROR(libiptc is required for tizen-ext))
+ IPTC_LIBS="$IPTC_LIBS -lip4tc"
+ AC_SUBST(IPTC_CFLAGS)
+ AC_SUBST(IPTC_LIBS)
+ fi
+])
+
AC_ARG_WITH(openconnect, AC_HELP_STRING([--with-openconnect=PROGRAM],
[specify location of openconnect binary]), [path_openconnect=${withval}])
AM_CONDITIONAL(PPTP, test "${enable_pptp}" != "no")
AM_CONDITIONAL(PPTP_BUILTIN, test "${enable_pptp}" = "builtin")
+AC_ARG_ENABLE(loopback,
+ AC_HELP_STRING([--enable-loopback], [enable loopback support]),
+ [enable_loopback=${enableval}], [enable_loopback="yes"])
+if (test "${enable_loopback}" != "no"); then
+ AC_CHECK_HEADERS(sys/inotify.h, dummy=yes,
+ AC_MSG_ERROR(inotify header files are required))
+
+ AC_CHECK_LIB(c, inotify_init, dummy=yes,
+ AC_MSG_ERROR(inotify library support is required))
+fi
+AM_CONDITIONAL(LOOPBACK, test "${enable_loopback}" != "no")
+AM_CONDITIONAL(LOOPBACK_BUILTIN, test "${enable_loopback}" = "builtin")
+
+AC_ARG_ENABLE(pacrunner,
+ AC_HELP_STRING([--enable-pacrunner], [enable PAC runner support]),
+ [enable_pacrunner=${enableval}], [enable_pacrunner="no"])
+
+AM_CONDITIONAL(PACRUNNER, test "${enable_pacrunner}" != "no")
+AM_CONDITIONAL(PACRUNNER_BUILTIN, test "${enable_pacrunner}" = "builtin")
+
+AC_ARG_ENABLE(google,
+ AC_HELP_STRING([--enable-google], [enable Google Public DNS support]),
+ [enable_google=${enableval}], [enable_google="no"])
+AM_CONDITIONAL(GOOGLE, test "${enable_google}" != "no")
+AM_CONDITIONAL(GOOGLE_BUILTIN, test "${enable_google}" = "builtin")
+
+AC_ARG_ENABLE(meego,
+ AC_HELP_STRING([--enable-meego], [enable MeeGo features support]),
+ [enable_meego=${enableval}], [enable_meego="no"])
+AM_CONDITIONAL(MEEGO, test "${enable_meego}" != "no")
+AM_CONDITIONAL(MEEGO_BUILTIN, test "${enable_meego}" = "builtin")
+
AC_CHECK_HEADERS(resolv.h, dummy=yes,
AC_MSG_ERROR(resolver header files are required))
AC_CHECK_LIB(resolv, ns_initparse, dummy=yes, [
[enable Intel OSPM support]), [enable_iospm=${enableval}])
AM_CONDITIONAL(IOSPM, test "${enable_iospm}" = "yes")
+AC_ARG_WITH(ntpd, AC_HELP_STRING([--with-ntpd=PROGRAM],
+ [specify ntpd binary location]), [path_ntpd=${withval}])
+
+AC_ARG_ENABLE(ntpd,
+ AC_HELP_STRING([--enable-ntpd], [enable ntpd support]),
+ [enable_ntpd=${enableval}], [enable_ntpd="no"])
+
+if (test "${enable_ntpd}" != "no"); then
+ if (test -z "${path_ntpd}"); then
+ AC_PATH_PROG(NTPD, [ntpd], [], $PATH:/sbin:/usr/sbin)
+ else
+ NTPD="${path_ntpd}"
+ AC_SUBST(NTPD)
+ fi
+fi
+AM_CONDITIONAL(NTPD, test "${enable_ntpd}" != "no")
+AM_CONDITIONAL(NTPD_BUILTIN, test "${enable_ntpd}" = "builtin")
+
+AC_ARG_ENABLE(nmcompat,
+ AC_HELP_STRING([--enable-nmcompat], [enable nmcompat support]),
+ [enable_nmcompat=${enableval}], [enable_nmcompat="no"])
+AM_CONDITIONAL(NMCOMPAT, test "${enable_nmcompat}" != "no")
+AM_CONDITIONAL(NMCOMPAT_BUILTIN, test "${enable_nmcompat}" = "builtin")
+
AC_ARG_ENABLE(tist,
AC_HELP_STRING([--enable-tist], [enable TI Shared Transport support]),
[enable_tist=${enableval}], [enable_tist="no"])
AC_DEFINE_UNQUOTED([STATS_MAX_FILE_SIZE], (${stats_max_file_size}), [Maximal size of a statistics round robin file])
-PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.28, dummy=yes,
- AC_MSG_ERROR(GLib >= 2.28 is required))
+PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.22, dummy=yes,
+ AC_MSG_ERROR(GLib >= 2.22 is required))
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
fi
-PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.4, dummy=yes,
- AC_MSG_ERROR(D-Bus >= 1.4 is required))
+PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.0, dummy=yes,
+ AC_MSG_ERROR(D-Bus >= 1.0 is required))
+saved_CFLAGS="$CFLAGS"
+saved_LIBS="$LIBS"
+CFLAGS="$CFLAGS $DBUS_CFLAGS"
+LIBS="$LIBS $DBUS_LIBS"
+AC_CHECK_LIB(dbus-1, dbus_watch_get_unix_fd, dummy=yes,
+ AC_DEFINE(NEED_DBUS_WATCH_GET_UNIX_FD, 1,
+ [Define to 1 if you need the dbus_watch_get_unix_fd() function.]))
+AC_CHECK_LIB(dbus-1, dbus_connection_can_send_type, dummy=yes,
+ AC_DEFINE(NEED_DBUS_CONNECTION_CAN_SEND_TYPE, 1,
+ [Define to 1 if you need the dbus_connection_can_send_type() function.]
+))
+CFLAGS="$saved_CFLAGS"
+LIBS="$saved_LIBS"
AC_SUBST(DBUS_CFLAGS)
AC_SUBST(DBUS_LIBS)
AC_SUBST(XTABLES_CFLAGS)
AC_SUBST(XTABLES_LIBS)
-AC_ARG_ENABLE(test, AC_HELP_STRING([--enable-test],
- [enable test/example scripts]), [enable_test=${enableval}])
-AM_CONDITIONAL(TEST, test "${enable_test}" = "yes")
-
-AC_ARG_ENABLE(nmcompat, AC_HELP_STRING([--enable-nmcompat],
- [enable Network Manager support]),
- [enable_nmcompat=${enableval}], [enable_nmcompat="no"])
-AM_CONDITIONAL(NMCOMPAT, test "${enable_nmcompat}" != "no")
-
-AC_ARG_ENABLE(polkit, AC_HELP_STRING([--enable-polkit],
- [enable PolicyKit support]),
+AC_ARG_ENABLE(polkit,
+ AC_HELP_STRING([--enable-polkit], [enable PolicyKit support]),
[enable_polkit=${enableval}], [enable_polkit="no"])
if (test "${enable_polkit}" != "no"); then
POLKIT_DATADIR="`$PKG_CONFIG --variable=actiondir polkit`"
AC_SUBST(POLKIT_DATADIR)
fi
AM_CONDITIONAL(POLKIT, test "${enable_polkit}" != "no")
+AM_CONDITIONAL(POLKIT_BUILTIN, test "${enable_polkit}" = "builtin")
-AC_ARG_ENABLE(loopback, AC_HELP_STRING([--disable-loopback],
- [disable loopback support]),
- [enable_loopback=${enableval}])
-AM_CONDITIONAL(LOOPBACK, test "${enable_loopback}" != "no")
-
-AC_ARG_ENABLE(ethernet, AC_HELP_STRING([--disable-ethernet],
- [disable Ethernet support]),
- [enable_ethernet=${enableval}])
-AM_CONDITIONAL(ETHERNET, test "${enable_ethernet}" != "no")
-
-AC_ARG_ENABLE(wifi, AC_HELP_STRING([--disable-wifi],
- [disable WiFi support]),
- [enable_wifi=${enableval}])
-AM_CONDITIONAL(WIFI, test "${enable_wifi}" != "no")
-
-AC_ARG_ENABLE(bluetooth, AC_HELP_STRING([--disable-bluetooth],
- [disable Bluetooth support]),
- [enable_bluetooth=${enableval}])
-AM_CONDITIONAL(BLUETOOTH, test "${enable_bluetooth}" != "no")
-
-AC_ARG_ENABLE(ofono, AC_HELP_STRING([--disable-ofono],
- [disable oFono support]),
- [enable_ofono=${enableval}])
-AM_CONDITIONAL(OFONO, test "${enable_ofono}" != "no")
-
-AC_ARG_ENABLE(dundee, AC_HELP_STRING([--disable-dundee],
- [disable dundee support (Bluetooth DUN)]),
- [enable_dundee=${enableval}])
-AM_CONDITIONAL(DUNDEE, test "${enable_dundee}" != "no")
-
-AC_ARG_ENABLE(pacrunner, AC_HELP_STRING([--disable-pacrunner],
- [disable PACrunner support]),
- [enable_pacrunner=${enableval}])
-AM_CONDITIONAL(PACRUNNER, test "${enable_pacrunner}" != "no")
+AC_ARG_ENABLE(client, AC_HELP_STRING([--enable-client],
+ [enable command line client]), [enable_client=${enableval}])
+AM_CONDITIONAL(CLIENT, test "${enable_client}" = "yes")
-AC_ARG_ENABLE(wispr, AC_HELP_STRING([--disable-wispr],
- [disable WISPr support]),
- [enable_wispr=${enableval}])
-AM_CONDITIONAL(WISPR, test "${enable_wispr}" != "no")
-
-AC_ARG_ENABLE(tools, AC_HELP_STRING([--disable-tools],
- [disable testing tools]),
- [enable_tools=${enableval}])
-AM_CONDITIONAL(TOOLS, test "${enable_tools}" != "no")
-
-AC_ARG_ENABLE(client, AC_HELP_STRING([--disable-client],
- [disable command line client]),
- [disable_client=${enableval}])
-AM_CONDITIONAL(CLIENT, test "${enable_client}" != "no")
-
-if (test "${enable_wispr}" != "no"); then
+AC_ARG_ENABLE(tools, AC_HELP_STRING([--enable-tools],
+ [enable testing tools]), [enable_tools=${enableval}])
+if (test "${enable_tools}" = "yes"); then
PKG_CHECK_MODULES(GNUTLS, gnutls, dummy=yes,
AC_MSG_ERROR(GnuTLS library is required))
-else
- GNUTLS_CFLAGS=""
- GNUTLS_LIBS=""
-fi
-AC_SUBST(GNUTLS_CFLAGS)
-AC_SUBST(GNUTLS_LIBS)
-
-if (test "${enable_loopback}" != "no"); then
- AC_CHECK_HEADERS(sys/inotify.h, dummy=yes,
- AC_MSG_ERROR(inotify header files are required))
+ AC_SUBST(GNUTLS_CFLAGS)
+ AC_SUBST(GNUTLS_LIBS)
- AC_CHECK_LIB(c, inotify_init, dummy=yes,
- AC_MSG_ERROR(inotify library support is required))
+ AC_CHECK_HEADERS(linux/if_alg.h, dummy=yes,
+ AC_MSG_ERROR(User-space algorithm header files are required))
fi
+AM_CONDITIONAL(TOOLS, test "${enable_tools}" = "yes")
-if (test "${enable_wifi}" != "no"); then
- AC_PATH_PROG(WPASUPPLICANT, [wpa_supplicant], [],
- $PATH:/sbin:/usr/sbin)
+AC_ARG_ENABLE(test, AC_HELP_STRING([--enable-test],
+ [enable test/example scripts]), [enable_test=${enableval}])
+AM_CONDITIONAL(TEST, test "${enable_test}" = "yes")
+
+AC_ARG_ENABLE(fake, AC_HELP_STRING([--enable-fake],
+ [enable fake device support]), [enable_fake=${enableval}])
+AM_CONDITIONAL(FAKE, test "${enable_fake}" = "yes")
+
+AC_ARG_ENABLE(capng, AC_HELP_STRING([--enable-capng],
+ [enable capabilities support]), [enable_capng=${enableval}])
+if (test "${enable_capng}" = "yes"); then
+ PKG_CHECK_MODULES(CAPNG, libcap-ng, dummy=yes,
+ AC_MSG_ERROR(Capabilities library is required))
+ AC_SUBST(CAPNG_CFLAGS)
+ AC_SUBST(CAPNG_LIBS)
+ AC_DEFINE(HAVE_CAPNG, 1, [Define to 1 if you have capabilities library.])
fi
AC_ARG_ENABLE(datafiles, AC_HELP_STRING([--disable-datafiles],
--- /dev/null
+connman (0.78.4-0slp2+90) unstable; urgency=low
+
+ * Ethernet : add technology driver to ethernet plugin
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.78.4-0slp2+90
+
+ -- Jaehyun Kim <jeik01.kim@samsung.com> Tue, 21 Aug 2012 13:51:37 +0900
+
+connman (0.78.4-0slp2+89) unstable; urgency=low
+
+ * Fix 'unable to connect' issue and reply pending bug
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.78.4-0slp2+89
+
+ -- Jaehyun Kim <jeik01.kim@samsung.com> Thu, 16 Aug 2012 22:39:54 +0900
+
+connman (0.78.4-0slp2+88) unstable; urgency=low
+
+ * Fix compile warnings and some build environment
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.78.4-0slp2+88
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Fri, 10 Aug 2012 15:13:37 +0900
+
+connman (0.78.4-0slp2+87) unstable; urgency=low
+
+ * Skip DHCP discovery if server already known
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.78.4-0slp2+87
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Wed, 25 Jul 2012 16:17:12 +0900
+
+connman (0.78.4-0slp2+86) unstable; urgency=low
+
+ * Check the technology type of connected service first and reorder service list
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.78.4-0slp2+86
+
+ -- Jaehyun Kim <jeik01.kim@samsung.com> Fri, 20 Jul 2012 20:26:35 +0900
+
+connman (0.78.4-0slp2+85) unstable; urgency=low
+
+ * Support EAP detail information
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.78.4-0slp2+85
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Fri, 15 Jun 2012 18:06:38 +0900
+
+connman (0.78.4-0slp2+84) unstable; urgency=low
+
+ * Remove a code that disables dbus auto-activation when sends a dbus message to net-config
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.78.4-0slp2+84
+
+ -- Jaehyun Kim <jeik01.kim@samsung.com> Fri, 08 Jun 2012 20:37:12 +0900
+
+connman (0.78.4-0slp2+83) unstable; urgency=low
+
+ * Fix a bss updated, when Wi-Fi security updated from PSK to OPEN
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.78.4-0slp2+83
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Mon, 04 Jun 2012 11:01:53 +0900
+
+connman (0.78.4-0slp2+82) unstable; urgency=low
+
+ * Fix invalid key retries
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.78.4-0slp2+82
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Thu, 24 May 2012 17:03:16 +0900
+
+connman (0.78.4-0slp2+81) unstable; urgency=low
+
+ * Fix wifi_scan
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.78.4-0slp2+81
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Tue, 22 May 2012 17:32:09 +0900
+
+connman (0.78.4-0slp2+80) unstable; urgency=low
+
+ * Wi-Fi enterprise SIM and AKA
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.78.4-0slp2+80
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Sun, 13 May 2012 17:36:37 +0900
+
+connman (0.78.4-0slp2+79) unstable; urgency=low
+
+ * Revise Wi-Fi enterprise to enable PEAP, TLS, TTLS
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.78.4-0slp2+79
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Fri, 11 May 2012 10:28:04 +0900
+
+connman (0.78.4-0slp2+78) unstable; urgency=low
+
+ * Fix telephony technology driver
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.78.4-0slp2+78
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Wed, 09 May 2012 17:56:57 +0900
+
+connman (0.78.4-0slp2+77) unstable; urgency=low
+
+ * Upgrade ConnMan-stable 0.78.4
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.78.4-0slp2+77
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Tue, 17 Apr 2012 20:51:49 +0900
+
+connman (0.77.2-0slp2+76) unstable; urgency=low
+
+ * Update ConnMan init script for Android suplicant
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+76
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Tue, 24 Apr 2012 20:28:32 +0900
+
+connman (0.77.2-0slp2+75) unstable; urgency=low
+
+ * Fix a bug which connman can't update MAC address of Wi-Fi
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+75
+
+ -- root <jeik01.kim@samsung.com> Thu, 12 Apr 2012 18:23:04 +0900
+
+connman (0.77.2-0slp2+74) unstable; urgency=low
+
+ * Fix cellular profile add bugs
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+74
+
+ -- Jaehyun Kim <jeik01.kim@samsung.com> Mon, 09 Apr 2012 17:47:31 +0900
+
+connman (0.77.2-0slp2+73) unstable; urgency=low
+
+ * Fix Wi-Fi tethering state bugs
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+73
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Mon, 02 Apr 2012 14:14:38 +0900
+
+connman (0.77.2-0slp2+72) unstable; urgency=low
+
+ * Fix default network info update
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+72
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Thu, 29 Mar 2012 21:48:36 +0900
+
+connman (0.77.2-0slp2+71) unstable; urgency=low
+
+ * Fix bugs on event handling(flight mode/data allowed/roaming)
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+71
+
+ -- Jaehyun Kim <jeik01.kim@samsung.com> Fri, 23 Mar 2012 19:27:26 +0900
+
+connman (0.77.2-0slp2+70) unstable; urgency=low
+
+ * Enable ConnMan debug log for developers
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+70
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Thu, 22 Mar 2012 20:00:15 +0900
+
+connman (0.77.2-0slp2+69) unstable; urgency=low
+
+ * Revise Wi-Fi device scan
+ * If deivce is connecing, do no make scan
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+69
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Fri, 16 Mar 2012 17:09:01 +0900
+
+connman (0.77.2-0slp2+68) unstable; urgency=low
+
+ * Fix ConnMan __connman_service_connect_default
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+68
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Fri, 16 Mar 2012 16:46:34 +0900
+
+connman (0.77.2-0slp2+67) unstable; urgency=low
+
+ * Revise New Telephony DBus interface name
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+67
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Thu, 15 Mar 2012 13:31:17 +0900
+
+connman (0.77.2-0slp2+66) unstable; urgency=low
+
+ * Rename sonet plug-in to telephony plug-in
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+66
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Fri, 09 Mar 2012 17:37:20 +0900
+
+connman (0.77.2-0slp2+65) unstable; urgency=low
+
+ * Write log routine without syslogd
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+65
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Fri, 09 Mar 2012 16:35:07 +0900
+
+connman (0.77.2-0slp2+64) unstable; urgency=low
+
+ * Revise connection management of Tizen data network to fit New Telepony
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+64
+
+ -- Danny Jeongseok Seo <s.seo@samsung.com> Fri, 09 Mar 2012 11:33:46 +0900
+
+connman (0.77.2-0slp2+63) unstable; urgency=low
+
+ * Change sonet's dbus service name
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+63
+
+ -- Sunkey Lee <yuvjjang.lee@samsung.com> Thu, 09 Feb 2012 10:36:51 +0900
+
+connman (0.77.2-0slp2+62) unstable; urgency=low
+
+ * Add mixed wifi encryption mode to service interface
+ * Lookup a matched service using essid and update it immediately when Manager.ProvisionService is invoked
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+62
+
+ -- Jaehyun Kim <jeik01.kim@samsung.com> Thu, 02 Feb 2012 20:00:10 +0900
+
+connman (0.77.2-0slp2+61) unstable; urgency=low
+
+ * Add a propertiy(wifi encryption mode) to service interface
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+61
+
+ -- Jaehyun Kim <jeik01.kim@samsung.com> Wed, 01 Feb 2012 16:42:26 +0900
+
+connman (0.77.2-0slp2+60) unstable; urgency=low
+
+ * Fix wifi disconnect callback bug
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+60
+
+ -- Sunkey Lee <yuvjjang.lee@samsung.com> Tue, 31 Jan 2012 16:20:46 +0900
+
+connman (0.77.2-0slp2+59) unstable; urgency=low
+
+ * Enable loopback plugin
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+59
+
+ -- Sunkey Lee <yuvjjang.lee@samsung.com> Wed, 25 Jan 2012 14:29:57 +0900
+
+connman (0.77.2-0slp2+58) unstable; urgency=low
+
+ * Modify the way to set dbus access authority
+ * According to security plicy, change to use ID from string
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+58
+
+ -- Sanghoon Cho <sanghoon80.cho@samsung.com> Tue, 17 Jan 2012 17:13:02 +0900
+
+connman (0.77.2-0slp2+57) unstable; urgency=low
+
+ * Fix a disconnect callback crash
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+57
+
+ -- Sunkey Lee <yuvjjang.lee@samsung.com> Thu, 12 Jan 2012 21:50:24 +0900
+
+connman (0.77.2-0slp2+56) unstable; urgency=low
+
+ * Fix a bug
+ * The WPS flag("UseWPS") is not cleared when cancel the wps connection
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+56
+
+ -- Sanghoon Cho <sanghoon80.cho@samsung.com> Thu, 12 Jan 2012 20:36:07 +0900
+
+connman (0.77.2-0slp2+55) unstable; urgency=low
+
+ * Release connman_0.77.2-0slp2+55
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+55
+
+ -- Jaehyun Kim <jeik01.kim@samsung.com> Thu, 12 Jan 2012 11:20:49 +0900
+
+connman (0.77.2-0slp2+54) unstable; urgency=low
+
+ * Release connman_0.77.2-0slp2+54
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+54
+
+ -- Sunkey Lee <yuvjjang.lee@samsung.com> Thu, 22 Dec 2011 17:07:43 +0900
+
+connman (0.77.2-0slp2+53) unstable; urgency=low
+
+ * Release connman_0.77.2-0slp2+53
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+53
+
+ -- DongHoo Park <donghoo.park@samsung.com> Fri, 09 Dec 2011 20:03:37 +0900
+
+connman (0.77.2-0slp2+52) unstable; urgency=low
+
+ * Clear service->pending though connection is stopped before completed
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+52
+
+ -- Misun Kim <ms0123.kim@samsung.com> Wed, 07 Dec 2011 18:52:24 +0900
+
+connman (0.77.2-0slp2+51) unstable; urgency=low
+
+ * Fix a bug which service's state doesn't recover from associating state
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+51
+
+ -- Sunkey Lee <yuvjjang.lee@samsung.com> Wed, 07 Dec 2011 11:01:32 +0900
+
+connman (0.77.2-0slp2+50) unstable; urgency=low
+
+ * Release connman_0.77.2-0slp2+50
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+50
+
+ -- Jeongseok Seo <s.seo@samsung.com> Mon, 05 Dec 2011 23:22:06 +0900
+
+connman (0.77.2-0slp2+49) unstable; urgency=low
+
+ * Release connman_0.77.2-0slp2+49
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+49
+
+ -- Jeongseok Seo <s.seo@samsung.com> Sat, 03 Dec 2011 12:04:44 +0900
+
+connman (0.77.2-0slp2+48) unstable; urgency=low
+
+ * Delete dev package of connman
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+48
+
+ -- Howon Jung <howon.jung@samsung.com> Tue, 29 Nov 2011 14:54:53 +0900
+
+connman (0.77.2-0slp2+47) unstable; urgency=low
+
+ * Create new key-value file when there is no default one
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+47
+
+ -- Jeongseok Seo <s.seo@samsung.com> Mon, 28 Nov 2011 21:34:28 +0900
+
+connman (0.77.2-0slp2+46) unstable; urgency=low
+
+ * Fix the bug which is not able to create modem instance when sonet plugin receives the modem_added dbus-signal
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+46
+
+ -- DongHoo Park <donghoo.park@samsung.com> Thu, 24 Nov 2011 12:57:35 +0900
+
+connman (0.77.2-0slp2+45) unstable; urgency=low
+
+ * Add reference count and scan decision scheme to control Wi-Fi scan for saving power
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+45
+
+ -- Jeongseok Seo <s.seo@samsung.com> Mon, 21 Nov 2011 14:59:28 +0900
+
+connman (0.77.2-0slp2+44) unstable; urgency=low
+
+ * plugin/alwayson.c: Fix crash, that is loosing related service instance when timer is called back
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+44
+
+ -- DongHoo Park <donghoo.park@samsung.com> Tue, 22 Nov 2011 17:12:02 +0900
+
+connman (0.77.2-0slp2+43) unstable; urgency=low
+
+ * src/device.c: Fix the connman crash when the cellular_service_enabled variable is set before creating device instance
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+43
+
+ -- DongHoo Park <donghoo.park@samsung.com> Tue, 22 Nov 2011 13:48:31 +0900
+
+connman (0.77.2-0slp2+42) unstable; urgency=low
+
+ * src/service.c: Patch a valid DBUS reply of synchronous service_disconnect instead of NULL reply
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+42
+
+ -- DongHoo Park <donghoo.park@samsung.com> Mon, 21 Nov 2011 19:57:04 +0900
+
+connman (0.77.2-0slp2+41) unstable; urgency=low
+
+ * plugin/sonet.c: Change the action of IP method type setting
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+41
+
+ -- DongHoo Park <donghoo.park@samsung.com> Fri, 18 Nov 2011 16:38:06 +0900
+
+connman (0.77.2-0slp2+40) unstable; urgency=low
+
+ * Unnecessary sigaction and backtrace of connmand
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+40
+
+ -- Jeongseok Seo <s.seo@samsung.com> Wed, 16 Nov 2011 21:57:43 +0900
+
+connman (0.77.2-0slp2+39) unstable; urgency=low
+
+ * fix the bug which is wrong conditional statement in sonet plug-in
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+39
+
+ -- DongHoo Park <donghoo.park@samsung.com> Wed, 16 Nov 2011 20:49:33 +0900
+
+connman (0.77.2-0slp2+38) unstable; urgency=low
+
+ * not to create ip_config structure when ipv6 address is not available and remove unnecessary patch
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+38
+
+ -- DongHoo Park <donghoo.park@samsung.com> Wed, 16 Nov 2011 14:28:37 +0900
+
+connman (0.77.2-0slp2+37) unstable; urgency=low
+
+ * fix to set default routing table, not to retey in no-link case, dbus crash
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+37
+
+ -- DongHoo Park <donghoo.park@samsung.com> Mon, 14 Nov 2011 18:18:14 +0900
+
+connman (0.77.2-0slp2+36) unstable; urgency=low
+
+ * change connection retry logic
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+36
+
+ -- DongHoo Park <donghoo.park@samsung.com> Fri, 11 Nov 2011 14:25:52 +0900
+
+connman (0.77.2-0slp2+35) unstable; urgency=low
+
+ * connman_dbus_service_property_changed_with_error_cause can get root causes of service state failure
+ without ConnMan agent
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+35
+
+ -- Jeongseok Seo <s.seo@samsung.com> Fri, 04 Nov 2011 18:16:33 +0900
+
+connman (0.77.2-0slp2+34) unstable; urgency=low
+
+ * Fix minor warnings and prevent bugs
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+34
+
+ -- Jeongseok Seo <s.seo@samsung.com> Fri, 04 Nov 2011 16:53:44 +0900
+
+connman (0.77.2-0slp2+33) unstable; urgency=low
+
+ * fix ther return value of timeout function
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+33
+
+ -- DongHoo Park <donghoo.park@samsung.com> Thu, 03 Nov 2011 14:31:40 +0900
+
+connman (0.77.2-0slp2+32) unstable; urgency=low
+
+ * update sonet plug-in
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+32
+
+ -- DongHoo Park <donghoo.park@samsung.com> Thu, 27 Oct 2011 08:26:59 +0900
+
+connman (0.77.2-0slp2+31) unstable; urgency=low
+
+ * __connman_service_lookup_from_index() returns incorrect service pointer
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+31
+
+ -- Misun Kim <ms0123.kim@samsung.com> Mon, 17 Oct 2011 21:08:37 +0900
+
+connman (0.77.2-0slp2+30) unstable; urgency=low
+
+ * don't try auto connection and scan immediately when the service is changed to IDLE state
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+30
+
+ -- Misun Kim <ms0123.kim@samsung.com> Fri, 14 Oct 2011 15:51:23 +0900
+
+connman (0.77.2-0slp2+29) unstable; urgency=low
+
+ * Fix auto_connect failure after remove_service (forgot Wi-Fi profile)
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+29
+
+ -- Jeongseok Seo <s.seo@samsung.com> Wed, 12 Oct 2011 13:05:55 +0900
+
+connman (0.77.2-0slp2+28) unstable; urgency=low
+
+ * Fix auto_connect problem, when device->connections remains it is not triggered
+ * device: clear device->connections and auto_connect checks device state, not device->connections
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+28
+
+ -- Jeongseok Seo <s.seo@samsung.com> Wed, 05 Oct 2011 13:18:56 +0900
+
+connman (0.77.2-0slp2+27) unstable; urgency=low
+
+ * fix network enable signal handler problem
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+27
+
+ -- DongHoo Park <donghoo.park@samsung.com> Tue, 27 Sep 2011 20:17:09 +0900
+
+connman (0.77.2-0slp2+26) unstable; urgency=low
+
+ * ConnMan doesn't care about cellular for auto connecting
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+26
+
+ -- Misun Kim <ms0123.kim@samsung.com> Tue, 27 Sep 2011 11:59:29 +0900
+
+connman (0.77.2-0slp2+25) unstable; urgency=low
+
+ * Remove libnetfilter-queue-dev dependency
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+25
+
+ -- JaeHyun Kim <jeik01.kim@samsung.com> Tue, 27 Sep 2011 10:32:13 +0900
+
+connman (0.77.2-0slp2+24) unstable; urgency=low
+
+ * fix error code num (ISCONN)
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+24
+
+ -- DongHoo Park <donghoo.park@samsung.com> Mon, 26 Sep 2011 20:50:47 +0900
+
+connman (0.77.2-0slp2+23) unstable; urgency=low
+
+ * fix MMS (3g connection) problem
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+23
+
+ -- DongHoo Park <donghoo.park@samsung.com> Mon, 26 Sep 2011 16:07:00 +0900
+
+connman (0.77.2-0slp2+22) unstable; urgency=low
+
+ * Fix pdp activation failure recovery at the very begining
+ * Fix retry timer (unlimited loop)
+ * Fix MMS, WAP auto join problem
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+22
+
+ -- Jeongseok Seo <s.seo@samsung.com> Thu, 22 Sep 2011 21:58:44 +0900
+
+connman (0.77.2-0slp2+21) unstable; urgency=low
+
+ * check connected service type / reorder service list
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+21
+
+ -- Misun Kim <ms0123.kim@samsung.com> Thu, 22 Sep 2011 14:35:03 +0900
+
+connman (0.77.2-0slp2+20) unstable; urgency=low
+
+ * Init script
+ * Arrange SEC_EXT tag
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+20
+
+ -- Jeongseok Seo <s.seo@samsung.com> Wed, 21 Sep 2011 22:35:32 +0900
+
+connman (0.77.2-0slp2+19) unstable; urgency=low
+
+ * Fix RequestScan with specific bearer type
+ * Fix technology enable/disable, fix net.connman.Error.NoCarrier
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+19
+
+ -- Jeongseok Seo <s.seo@samsung.com> Thu, 22 Sep 2011 11:12:09 +0900
+
+connman (0.77.2-0slp2+18) unstable; urgency=low
+
+ * fix default connection problem (unexpected 3g connection)
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+18
+
+ -- DongHoo Park <donghoo.park@samsung.com> Wed, 21 Sep 2011 11:13:37 +0900
+
+connman (0.77.2-0slp2+17) unstable; urgency=low
+
+ * ConnMan upgrade to 0.77.2 commit 162dce08a37b8e09e098ef682bcafd2a7aa155d0
+ * git://github.com/sameo/connman-stable
+ * git://git.kernel.org/?p=network/connman/connman-stable.git
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.77.2-0slp2+17
+
+ -- Jeongseok Seo <s.seo@samsung.com> Mon, 19 Sep 2011 21:00:12 +0900
+
+connman (0.73-0slp2+17) unstable; urgency=low
+
+ * add connection retry timer
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.73-0slp2+17
+
+ -- DongHoo Park <donghoo.park@samsung.com> Fri, 16 Sep 2011 16:15:16 +0900
+
+connman (0.73-0slp2+16) unstable; urgency=low
+
+ * try auto connecting without reference to celluar connection
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.73-0slp2+16
+
+ -- Misun Kim <ms0123.kim@samsung.com> Fri, 16 Sep 2011 15:16:25 +0900
+
+connman (0.73-0slp2+15) unstable; urgency=low
+
+ * Fix serveral ConnMan crashes by Samuel Ortiz
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.73-0slp2+15
+
+ -- Jeongseok Seo <s.seo@samsung.com> Thu, 15 Sep 2011 23:25:36 +0900
+
+connman (0.73-0slp2+14) unstable; urgency=low
+
+ * fix build warnning - pass invalid pointer
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.73-0slp2+14
+
+ -- DongHoo Park <donghoo.park@samsung.com> Wed, 14 Sep 2011 10:59:36 +0900
+
+connman (0.73-0slp2+13) unstable; urgency=low
+
+ * stop scanning in connected state / bug fix - bg scan interval was increased by scan request
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.73-0slp2+13
+
+ -- Misun Kim <ms0123.kim@samsung.com> Wed, 07 Sep 2011 15:38:48 +0900
+
+connman (0.73-0slp2+12) unstable; urgency=low
+
+ * Add scan complete signal
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.73-0slp2+12
+
+ -- Sunkey Lee <yuvjjang.lee@samsung.com> Wed, 31 Aug 2011 15:05:01 +0900
+
+connman (0.73-0slp2+11) unstable; urgency=low
+
+ * add cellular service enabled notifier
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.73-0slp2+11
+
+ -- DongHoo Park <donghoo.park@samsung.com> Tue, 30 Aug 2011 19:19:51 +0900
+
+connman (0.73-0slp2+10) unstable; urgency=low
+
+ * fix to make multiple pdp, add network option changed signal
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.73-0slp2+10
+
+ -- DongHoo Park <donghoo.park@samsung.com> Mon, 29 Aug 2011 17:04:38 +0900
+
+connman (0.73-0slp2+9) unstable; urgency=low
+
+ * add sim init signal and fix duplicate device, network
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.73-0slp2+9
+
+ -- DongHoo Park <donghoo.park@samsung.com> Wed, 24 Aug 2011 23:06:46 +0900
+
+connman (0.73-0slp2+8) unstable; urgency=low
+
+ * add sonet plug-in , always on plug-in, modify device force scan trigger
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.73-0slp2+8
+
+ -- DongHoo Park <donghoo.park@samsung.com> Tue, 23 Aug 2011 10:44:17 +0900
+
+connman (0.73-0slp2+7) unstable; urgency=low
+
+ * Add more APIs to use user-initiated pdp connection management
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.73-0slp2+6
+
+ -- Jeongseok Seo <s.seo@samsung.com> Tue, 23 Aug 2011 09:45:22 +0900
+
+connman (0.73-0slp2+6) unstable; urgency=low
+
+ * System-wide connection management (so-called "one connection")
+ * Git: slp/pkgs/c/connman
+ * Tag: connman_0.73-0slp2+6
+
+ -- Jeongseok Seo <s.seo@samsung.com> Thu, 18 Aug 2011 16:11:37 +0900
+
+connman (0.73-0slp2+5) unstable; urgency=low
+
+ * apply samsung bg scan & auto power on
+
+ -- Misun Kim <ms0123.kim@samsung.com> Fri, 27 Jul 2011 15:54:27 +0900
+
+connman (0.73-0slp2+4) unstable; urgency=low
+
+ * apply always-on feature in modman plug-in
+
+ -- DongHoo Park <donghoo.park@samsung.com> Thu, 21 Jul 2011 20:54:32 +0900
+
+connman (0.73-0slp2+3) unstable; urgency=low
+
+ * enable log, change modman plug-in, add always on plug-in
+
+ -- DongHoo Park <donghoo.park@samsung.com> Thu, 07 Jul 2011 08:06:24 +0900
+
+connman (0.73-0slp2+2) unstable; urgency=low
+
+ * Delete unnecessary codes
+
+ -- Jeongseok Seo <s.seo@samsung.com> Mon, 27 Jun 2011 15:12:48 +0900
+
+connman (0.73-0slp2+1) unstable; urgency=low
+
+ * Version up
+
+ -- DongHoo Park <donghoo.park@samsung.com> Mon, 13 Jun 2011 21:19:57 +0900
+
+connman (0.64-0slp2+4) unstable; urgency=low
+
+ * change local state directory
+
+ -- JaeHyun Kim <jeik01.kim@samsung.com> Wed, 27 Apr 2011 17:19:59 +0900
+
+connman (0.64-0slp2+3) unstable; urgency=low
+
+ * reorder service list
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Wed, 05 Jan 2011 17:15:33 +0900
+
+connman (0.64-0slp2+2) unstable; urgency=low
+
+ * resolve that inet_ntoa gets 100% CPU usage, sometimes
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Mon, 29 Nov 2010 14:02:54 +0900
+
+connman (0.64-0slp2+1) unstable; urgency=low
+
+ * upgrade to connman-0.64
+ * apply samsung patch
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Mon, 29 Nov 2010 08:40:36 +0900
+
+connman (0.63-0slp2+5) unstable; urgency=low
+
+ * enable auto activation
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Wed, 24 Nov 2010 20:12:19 +0900
+
+connman (0.63-0slp2+4) unstable; urgency=low
+
+ * during idle timeout, check active sessions from proc file system
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Mon, 22 Nov 2010 14:12:32 +0900
+
+connman (0.63-0slp2+3) unstable; urgency=low
+
+ * setup hookif when started
+ * move wifi plugin as builtin
+ * set vconfkey for http_proxy
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Tue, 16 Nov 2010 09:18:10 +0900
+
+connman (0.63-0slp2+2) unstable; urgency=low
+
+ * add autonomous on demand data connection
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Mon, 15 Nov 2010 08:56:13 +0900
+
+connman (0.63-0slp2+1) unstable; urgency=low
+
+ * upgrade to connman-0.63
+ * apply samsung patch
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Fri, 05 Nov 2010 17:06:38 +0900
+
+connman (0.62-0slp2+7) unstable; urgency=low
+
+ * enable on-demand connnection
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Wed, 27 Oct 2010 20:42:13 +0900
+
+connman (0.62-0slp2+6) unstable; urgency=low
+
+ * rollback on-demand connection
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Mon, 25 Oct 2010 13:15:57 +0900
+
+connman (0.62-0slp2+5) unstable; urgency=low
+
+ * remove modman state watch
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Thu, 21 Oct 2010 08:52:44 +0900
+
+connman (0.62-0slp2+4) unstable; urgency=low
+
+ * update roaming property properly
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Wed, 20 Oct 2010 20:03:19 +0900
+
+connman (0.62-0slp2+3) unstable; urgency=low
+
+ * enable on-demand connection (only for dns query)
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Tue, 19 Oct 2010 21:09:27 +0900
+
+connman (0.62-0slp2+2) unstable; urgency=low
+
+ * support ethernet/ipv4/proxy property of
+ service interface in pdp connection
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Mon, 18 Oct 2010 20:14:59 +0900
+
+connman (0.62-0slp2+1) unstable; urgency=low
+
+ * add modman plugin
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Fri, 08 Oct 2010 09:00:00 +0900
+
+connman (0.62-0slp2) unstable; urgency=low
+
+ * Upgrade to connman-0.62
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Mon, 04 Oct 2010 08:06:53 +0900
+
+connman (0.61-0slp2) unstable; urgency=low
+
+ * Upgrade to connman-0.61
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Sat, 11 Sep 2010 18:13:33 +0900
+
+connman (0.60-0slp2) unstable; urgency=low
+
+ * Upgrade to connman-0.60
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Thu, 09 Sep 2010 08:08:38 +0900
+
+connman (0.59-0slp2) unstable; urgency=low
+
+ * debianize
+
+ -- Jongmin Lee <jm105.lee@samsung.com> Thu, 02 Sep 2010 12:11:03 +0900
--- /dev/null
+@PREFIX@/include/*
+@PREFIX@/lib/pkgconfig/*
--- /dev/null
+@PREFIX@/sbin/*
+@PREFIX@/lib/connman/plugins/*.so
+@PREFIX@/share/dbus-1/services/*
+@PREFIX@/etc/dbus-1/system.d/*
+@PREFIX@/etc/connman/main.conf
+/var/lib/connman/settings
+/etc/rc.d/init.d/connman
+/etc/rc.d/rc3.d/S61connman
+/etc/rc.d/rc5.d/S61connman
--- /dev/null
+#!/bin/sh
+chmod 600 /var/lib/connman/settings
--- /dev/null
+Source: connman
+Section: net
+Priority: extra
+Maintainer: Danny Jeongseok Seo <s.seo@samsung.com>
+Uploaders: Danny Jeongseok Seo <s.seo@samsung.com>, DongHoo Park <donghoo.park@samsung.com>, Jaehyun Kim <jeik01.kim@samsung.com>, Misun Kim <ms0123.kim@samsung.com>, Sunkey Lee <yuvjjang.lee@samsung.com>, Sanghoon Cho <sanghoon80.cho@samsung.com>
+Build-Depends: debhelper (>= 5), autotools-dev, libglib2.0-dev, libdbus-1-dev, iptables-dev
+Standards-Version: 0.1.0
+
+Package: connman
+Section: net
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Connection Manager
+ The Linux Connection Manager project provides a daemon for managing
+ Internet connections within embedded devices running the Linux
+ operating system. The Connection Manager is designed to be slim and to
+ use as few resources as possible, so it can be easily integrated in
+ other Moblin-based embedded systems. It is fully modular system that
+ can be extended through plug-ins, to support all kinds of wired or
+ wireless technologies. Also, configuration methods like DHCP and
+ domain name resolving are implemented using plug-ins. The plug-in
+ approach allows for easy adaption and modification for various use cases.
+
+Package: connman-dbg
+Section: net
+Architecture: any
+Depends: connman (= ${Source-Version}), ${misc:Depends}
+Description: debug symbols for Connection Manager
--- /dev/null
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+
+DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+
+CFLAGS ?= -Wall -g -O2
+LDFLAGS ?= -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed
+PREFIX ?= /usr
+DATADIR ?= /opt
+
+CONFIGURE_ARGS = \
+ --localstatedir=/var \
+ --enable-tizen-ext
+ $(NULL)
+# --enable-debug \
+# $(NULL)
+
+configure: configure.ac
+ ./autogen.sh
+
+config.status: configure
+ dh_testdir
+ # Add here commands to configure the package.
+ CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" ./configure --prefix=$(PREFIX) $(CONFIGURE_ARGS)
+
+build: build-stamp
+
+build-stamp: config.status
+ dh_testdir
+
+ # Add here commands to compile the package.
+ $(MAKE)
+ #docbook-to-man debian/ncurses.sgml > ncurses.1
+
+ for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
+ cat $$f > $${f%.in}; \
+ sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \
+ sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \
+ done
+
+ touch $@
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp
+
+ # Add here commands to clean up after the build process.
+ -$(MAKE) distclean
+
+ for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
+ rm -f $${f%.in}; \
+ done
+
+ rm -f depcomp
+ rm -f compile
+ rm -f missing
+ rm -f ltmain.sh
+ rm -f install-sh
+ rm -f config.guess
+ rm -f configh.h
+ rm -f config.h.in
+ rm -f config.log
+ rm -f config.sub
+ rm -f config.guess
+ rm -f configure
+ rm -f Makefile.in
+ rm -f aclocal.m4
+ rm -f ../connman_*.deb
+ rm -f ../connman-*.deb
+ rm -f ../connman_*.changes
+ rm -f ../connman_*.dsc
+ rm -f ../connman_*.tar.gz
+
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ # Add here commands to install the package into debian/connman.
+ $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+ mkdir -p $(CURDIR)/debian/tmp/var/lib/connman
+ cp -f $(CURDIR)/resources/var/lib/connman/settings \
+ $(CURDIR)/debian/tmp/var/lib/connman/settings
+ mkdir -p $(CURDIR)/debian/tmp$(PREFIX)/share/dbus-1/services
+ cp -f $(CURDIR)/resources$(PREFIX)/share/dbus-1/services/net.connman.service \
+ $(CURDIR)/debian/tmp$(PREFIX)/share/dbus-1/services/net.connman.service
+ mkdir -p $(CURDIR)/debian/tmp$(PREFIX)/etc/connman
+ cp -f $(CURDIR)/src/main.conf $(CURDIR)/debian/tmp$(PREFIX)/etc/connman/main.conf
+ mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/init.d
+ cp -f $(CURDIR)/resources/etc/rc.d/init.d/connman \
+ $(CURDIR)/debian/tmp/etc/rc.d/init.d/connman
+ mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc3.d
+ ln -s ../init.d/connman $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/S61connman
+ mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc5.d
+ ln -s ../init.d/connman $(CURDIR)/debian/tmp/etc/rc.d/rc5.d/S61connman
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+# dh_installchangelogs
+# dh_installdocs
+# dh_installexamples
+ dh_install --sourcedir=debian/tmp
+# dh_installmenu
+# dh_installdebconf
+# dh_installlogrotate
+# dh_installemacsen
+# dh_installpam
+# dh_installmime
+# dh_python
+# dh_installinit
+# dh_installcron
+# dh_installinfo
+# dh_installman
+ dh_link
+ dh_strip --dbg-package=connman-dbg
+ dh_compress
+ dh_fixperms
+# dh_perl
+ dh_makeshlibs
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install
Possible Errors: net.connman.Agent.Error.Retry
- void RequestBrowser(object service, string url)
-
- This method gets called when it is required
- to ask the user to open a website to procceed
- with login handling.
-
- This can happen if connected to a hotspot portal
- page without WISPr support.
-
- Possible Errors: net.connman.Agent.Error.Canceled
-
dict RequestInput(object service, dict fields)
This method gets called when trying to connect to
The dictionary arguments contains field names with
their input parameters.
- In case of WISPr credentials requests and if the user
- prefers to login through the browser by himself, agent
- will have to return a LaunchBrowser error (see below).
-
Possible Errors: net.connman.Agent.Error.Canceled
- net.connman.Agent.Error.LaunchBrowser
void Cancel()
key, a PSK passphrase or a passphrase for EAP
authentication methods.
- string PreviousPassphrase
-
- The previous passphrase successfully saved, i.e.
- which lead to a successfull connection. This field is
- provided as an informational argument when connecting
- with it does not work anymore, for instance when it
- has been changed on the AP. Such argument appears when
- a RequestInput is raised after a retry.
-
string WPS
This field requests the use of WPS to get associated.
string Requirement
Contains the requirement option. Valid values are
- "mandatory", "optional", "alternate" or
- "informational".
+ "mandatory", "optional" or "alternate".
The "alternate" value specifies that this field can be
returned as an alternative to another one. An example
All "mandatory" fields must be returned, while the
"optional" can be returned if available.
- Nothing needs to be returned for "informational", as it
- is here only to provide an information so a value is
- attached to it.
-
array{string} Alternates
Contains the list of alternate field names this
field can be represented by.
- string Value
-
- Contains data as a string, relatively to an
- "informational" argument.
-
Examples Requesting a passphrase for WPA2 network
RequestInput("/service1",
- { "Passphrase" : { "Type" : "psk",
+ { "Passphrase" : { "Type" : "psk",
"Requirement" : "mandatory"
}
}
==> { "Passphrase" : "secret123" }
- Requesting a passphrase after an error on the previous one:
-
- RequestInput("/service1",
- { "Passphrase" : { "Type" : "psk",
- "Requirement" : "mandatory"
- },
- "PreviousPassphrase" :
- { "Type" : "psk",
- "Requirement : "informational",
- "Value" : "secret123"
- }
- }
-
Requesting name for hidden network
RequestInput("/service2",
"Requirement" : "mandatory",
"Alternates" : [ "SSID" ]
},
- "SSID" : { "Type" : "ssid",
- "Requirement" : "alternate"
- }
+ "SSID" : { "Type" : "ssid",
+ "Requirement" : "alternate"
+ }
}
==> { "Name" : "My hidden network" }
"Alternates" : [ "WPS" ]
},
"WPS" : { "Type" : "wpspin",
- "Requirement" : "alternate"
+ "Requirement" : "alternate"
}
}
{ "Identity" : { "Type" : "string",
"Requirement" : "mandatory"
},
- "Passphrase" : { "Type" : "passphrase",
+ "Passphrase" : { "Type" : "passphrase",
"Requirement" : "mandatory"
}
}
{ "Identity" : { "Type" : "string",
"Requirement" : "mandatory"
},
- "Passphrase" : { "Type" : "response",
+ "Passphrase" : { "Type" : "response",
"Requirement" : "mandatory"
}
}
Requesting username and password for a WISPr-enabled hotspot:
RequestInput("/service5",
- { "Username" : { "Type" : "string",
- "Requirement" : "mandatory"
- },
- "Password" : { "Type" : "passphrase",
- "Requirement" : "mandatory"
- }
- }
-
- ==> { "Username" : "foo", "Password": "secret" }
+ { "Username" : { "Type" : "string",
+ "Requirement" : "mandatory"
+ },
+ "Password" : { "Type" : "passphrase",
+ "Requirement" : "mandatory"
+ }
+ }
+
+ ==> { "Username" : "foo", "Password": "secret" }
Interface net.connman.Clock
Object path /
-Methods dict GetProperties() [experimental]
+Methods dict GetProperties()
Returns all system clock properties. See the
properties section for available properties.
Possible Errors: [service].Error.InvalidArguments
- void SetProperty(string name, variant value) [experimental]
+ void SetProperty(string name, variant value)
Changes the value of the specified property. Only
properties that are listed as read-write are
Possible Errors: [service].Error.InvalidArguments
[service].Error.InvalidProperty
-Signals PropertyChanged(string name, variant value) [experimental]
+Signals PropertyChanged(string name, variant value)
This signal indicates a changed value of the given
property.
-Properties uint64 Time [readonly or readwrite] [experimental]
+Properties uint64 Time [readonly or readwrite]
Current system time in seconds since epoch.
time should be using gettimeofday() and related
system calls.
- string TimeUpdates [readwrite] [experimental]
+ string TimeUpdates [readwrite]
Possible values are "manual" and "auto" to indicate
time update policy.
many sources as possible to determine the correct
and updated time.
- string Timezone [readonly or readwrite] [experimental]
+ string Timezone [readonly or readwrite]
Current system timezone string. Allowed values
are from the standard timezone data (tzdata)
When the timezone gets changed a PropertyChanged
signal will be send out.
- string TimezoneUpdates [readwrite] [experimental]
+ string TimezoneUpdates [readwrite]
Possible values are "manual" and "auto" to indicate
timezone update policy.
many sources as possible to determine the correct
timezone.
- array{string} Timeservers [readwrite] [experimental]
+ array{string} Timeservers [readwrite]
List of global default NTP servers. The list should
be sorted in order of preference.
Those configuration files are text files with a simple format and we typically
have one file per provisioned network.
-If the config file is removed, then Connman tries to remove the
-provisioned service. If individual service entry inside config is removed,
-then the corresponding provisioned service is removed. If service
-entry is changed, then corresponding service is removed and then
-immediately re-provisioned.
-
Global entry [global]
=====================
=========================
Each provisioned service must start with the [service_*] tag. Replace * with
-an identifier unique to the config file.
+your service identifier.
+The service identifier can be anything and will be used internally by connman
+to store the different services into an hash table.
Allowed fields:
- Type: Service type. We currently only support wifi.
-- Name: A string representation of an 802.11 SSID. If the SSID field is
- present, the Name field is ignored.
-- SSID: A hexadecimal representation of an 802.11 SSID. If the SSID field is
- omitted, the Name field is used instead.
+- SSID: An hexadecimal or a string representation of a 802.11 SSID.
- EAP: EAP type. We currently only support tls, ttls or peap.
- CACertFile: File path to CA certificate file (PEM/DER).
- ClientCertFile: File path to client certificate file (PEM/DER).
- PrivateKeyFile: File path to client private key file (PEM/DER/PFX).
- PrivateKeyPassphrase: Password/passphrase for private key file.
- PrivateKeyPassphraseType: We only support the fsid passphrase type for now.
- This is for private keys generated by using their own filesystem UUID as the
- passphrase. The PrivateKeyPassphrase field is ignored when this field is set
- to fsid.
+This is for private keys generated by using their own filesystem UUID as the
+passphrase. The PrivateKeyPassphrase field is ignored when this field is set
+to fsid.
- Identity: Identity string for EAP.
- Phase2: Phase2 (inner authentication with TLS tunnel) authentication method.
- Prefix the value with "EAP-" to indicate the usage of an EAP-based inner
- authentication method (should only be used with EAP = TTLS).
+Prefix the value with "EAP-" to indicate the usage of an EAP-based inner
+authentication method (should only be used with EAP = TTLS).
- Passphrase: RSN/WPA/WPA2 Passphrase
Possible Errors: [service].Error.InvalidArguments
[service].Error.InvalidProperty
- array{object,dict} GetTechnologies()
+ string GetState()
- Returns a list of tuples with technology object
- path and dictionary of technology properties.
+ Return global connection state of a system. The
+ same value is return via the State property.
+
+ Possible Errors: [service].Error.InvalidArguments
+
+ void RequestScan(string type)
+
+ Request to trigger a scan for the specified
+ technology. The empty string "" triggers scanning
+ on all technologies.
+
+ Possible Errors: [service].Error.InvalidArguments
+
+ void EnableTechnology(string type)
+
+ Enable specified type of technologies.
+
+ Possible Errors: [service].Error.InvalidArguments
+
+ void DisableTechnology(string type)
+
+ Disable specified type of technologies.
Possible Errors: [service].Error.InvalidArguments
Possible Errors: [service].Error.InvalidArguments
+ object LookupService(string pattern)
+
+ Lookup a service matching the specific pattern.
+
+ Examples are interface names like "eth0", "wlan0"
+ etc. or service names like "hotspot" etc.
+
+ In case of multiple services match the the pattern
+ an error is returned.
+
+ Possible Errors: [service].Error.InvalidArguments
+ [service].Error.NotUnique
+ [service].Error.NotFound
+
+ object ConnectService(dict network)
+
+ Connect to a network specified by the given
+ properties.
+
+ For connecting to a hidden WiFi network for example
+ it is required that Type = "wifi" and the SSID
+ properties are provided.
+
+ When successful this method will return object
+ path of the service object.
+
+ This method can also be used to connect to an
+ already existing service. It works exactly the
+ same as executing the Connect method from the
+ service interface.
+
+ This method call will only return in case of an
+ error or when the service is fully connected. So
+ setting a longer D-Bus timeout might be a really
+ good idea.
+
+ When 'SessionMode' property is enabled, this method
+ call is disallowed.
+
+ Possible Errors: [service].Error.InvalidArguments
+
+ void ProvisionService(string configuration)
+
+ Provide a configuration for services.
+
+ Service configuration is provided as a single string
+ that follows the same format as configuration files,
+ see config-format.txt. An exception to this format
+ is that only one service can be provisioned per call.
+
+ Possible Errors: [service].Error.InvalidArguments
+
object ConnectProvider(dict provider)
Connect to a VPN specified by the given provider
Possible Errors: [service].Error.InvalidArguments
- void RegisterCounter(object path, uint32 accuracy, uint32 period) [experimental]
+ void RegisterCounter(object path, uint32 accuracy, uint32 period)
Register a new counter for user notifications.
Possible Errors: [service].Error.InvalidArguments
- void UnregisterCounter(object path) [experimental]
+ void UnregisterCounter(object path)
Unregister an existing counter.
Possible Errors: [service].Error.InvalidArguments
- object CreateSession(dict settings, object notifier) [experimental]
+ object CreateSession(dict settings, object notifier)
Create a new session for the application. Every
application can create multiple session with
Every application should at least create one session
to inform about its requirements and it purpose.
- void DestroySession(object session) [experimental]
+ void DestroySession(object session)
Remove the previously created session.
Possible Errors: [service].Error.InvalidArguments
-Signals TechnologyAdded(object path, dict properties)
-
- Signal that is sent when a new technology is added.
-
- It contains the object path of the technology and
- also its properties.
+Signals PropertyChanged(string name, variant value)
- TechnologyRemoved(object path)
-
- Signal that is sent when a technology has been removed.
+ This signal indicates a changed value of the given
+ property.
- The object path is no longer accessible after this
- signal and only emitted for reference.
+ StateChanged(string state)
- ServicesChanged(array{object, dict}, array{object})
+ This signal is similar to the PropertyChanged signal
+ for the State property.
- Signals a list of services that have been changed
- via the first array. And a list of service that
- have been removed via the second array.
+ It exists for application state only care about the
+ current state and so can avoid to be woken up when
+ other details changes.
- The list of added services is sorted. The dictionary
- with the properties might be empty in case none of
- the properties have changed. Or only contains the
- properties that have changed.
+Signals ScanCompleted(boolean success)
- For newly added services the whole set of properties
- will be present.
+ This signal indicates that RequestScan was finished completely and
+ networks were updated.
- The list of removed services can be empty.
+Properties string State [readonly]
- This signal will only be triggered when the sort
- order of the service list or the number of services
- changes. It will not be emitted if only a property
- of the service object changes. For that it is
- required to watch the PropertyChanged signal of
- the service object.
+ The global connection state of a system. Possible
+ values are "online" if at least one connection exists
+ and "offline" if no device is connected.
- PropertyChanged(string name, variant value)
+ In certain situations the state might change to
+ the value "connected". This can only be seen if
+ previously no connection was present.
- This signal indicates a changed value of the given
- property.
+ array{string} AvailableTechnologies [readonly]
-Properties string State [readonly]
+ The list of available technologies. The strings
+ are the same as the ones from the service types.
- The global connection state of a system. Possible
- values are "offline", "idle", "ready" and "online".
+ array{string} EnabledTechnologies [readonly]
- If the device is in offline mode, the value "offline"
- indicates this special global state. It can also be
- retrieved via the OfflineMode property, but is kept
- here for consistency and to differentiate from "idle".
+ The list of enabled technologies. The strings
+ are the same as the ones from the service types.
- However when OfflineMode property is true, the State
- property can still be "idle", "ready" or "online"
- since it is possible by the end user to re-enable
- individual technologies like WiFi and Bluetooth while
- in offline mode.
+ array{string} ConnectedTechnologies [readonly]
- The states "idle", "ready" and "online" match to
- states from the services. If no service is in
- either "ready" or "online" state it will indicate
- the "idle" state.
+ The list of connected technologies. The strings
+ are the same as the ones from the service type.
- If at least one service is in "ready" state and no
- service is in "online" state, then it will indicate
- the "ready" state.
+ string DefaultTechnology [readonly]
- When at least one service is in "online" state,
- this property will indicate "online" as well.
+ The current connected technology which holds the
+ default route.
boolean OfflineMode [readwrite]
the limited usage of WiFi or Bluetooth devices might
be allowed in some situations.
- boolean SessionMode [readwrite] [experminental]
+ object ActiveProfile [readwrite]
+
+ Object path of the current active profile.
+
+ array{object} Technologies [readonly]
+
+ List of technology object paths.
+
+ array{object} Services [readonly]
+
+ List of service object paths. The list is sorted
+ internally to have the service with the default
+ route always first and then the favorite services
+ followed by scan results.
+
+ This list represents the available services for the
+ current selected profile. If the profile gets changed
+ then this list will be updated.
+
+ The same list is available via the profile object
+ itself. It is just provided here for convenience of
+ applications only dealing with the current active
+ profile.
+
+ boolean SessionMode [readwrite]
This disables the auto connect feature. It should be
enabled when the Session API is used. When SessionMode
Interface net.connman.Service
Object path [variable prefix]/{service0,service1,...}
-Methods dict GetProperties() [deprecated]
+Methods dict GetProperties()
Returns properties for the service object. See
the properties section for available properties.
- Usage of this method is highly discouraged. Use
- the Manager.GetServices() method instead.
-
Possible Errors: [service].Error.InvalidArguments
void SetProperty(string name, variant value)
Possible Errors: [service].Error.InvalidArguments
- void ResetCounters() [experimental]
+ void ResetCounters()
Reset the counter statistics.
The service name (for example "Wireless" etc.)
This name can be used for directly displaying it in
- the application. It has pure informational purpose
- and no attempt should be made to translate it.
+ the application. It has pure informational purpose.
- For Ethernet devices and hidden WiFi networks this
- property is not present.
+ For Ethernet devices and hidden WiFi networks it is
+ not guaranteed that this property is present.
string Type [readonly]
advanced properties or showing the correct icon
to the user.
- Together with a missing Name property, this can
- be used to identify hidden WiFi networks.
-
array{string} Security [readonly]
If the service type is WiFi, then this property is
or key management settings.
Possible values are "none", "wep", "psk", "ieee8021x"
- and also "wps".
+ and also "wps". Alternate values for "psk" can also
+ be "wpa" and "rsn".
+
+ This property might be only present for WiFi
+ services.
+
+ boolean LoginRequired [readonly]
+
+ This property indicates that an additional login
+ step, like web based authentication, is needed
+ before the connection establishment can proceed.
+
+ string Passphrase [readwrite]
+
+ If the service type is WiFi, then this property
+ can be used to store a passphrase.
+
+ No PropertyChanged signals will be sent for this
+ property. The PassphraseRequired property should
+ be monitored instead.
+
+ This property might also not always be included
+ since it is protected by a different security policy.
+
+ boolean PassphraseRequired [readonly]
+
+ If the service type is WiFi, then this property
+ indicates if a passphrase is required.
+
+ If a passphrase has been set already or if no
+ passphrase is needed, then this property will
+ be set to false.
+
+ 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.
array{string} Nameservers.Configuration [readwrite]
The list of manually configured domain name
- servers. Some cellular networks don't provide
- correct name servers and this allows for an
- override.
+ servers. Some 3G networks don't provide correct
+ name servers and this allows for an override.
This array is sorted by priority and the first
entry in the list represents the nameserver with
the service. However there might be small window
where name resolution might fail.
- array{string} Timeservers [readonly]
-
- The list of currently active timeservers for this
- service. If the server is not in READY or ONLINE
- state than this list will be empty.
-
- array{string} Timeservers.Configuration [readwrite]
-
- The list of manually configured time servers.
-
- The first entry in the list represents the
- timeserver with the highest priority.
-
- When using manual configuration this setting
- is useful to override all the other timeserver
- settings. This is service specific, hence only
- the values for the default service are used.
-
- Changes to this property will result in restart
- of NTP query.
-
array{string} Domains [readonly]
- The list of currently used search domains taken
- from Domains.Configurations if set, otherwise a
- domain name if provided by DHCP or VPNs.
+ The list of currently used search domains.
array{string} Domains.Configuration [readwrite]
string Host [readonly]
- VPN host IP.
+ VPN host IP.
string Domain [readonly]
- VPN Domain.
+ VPN Domain.
string Name [readonly]
- VPN provider Name.
+ VPN provider Name.
string Type [readonly]
- VPN provider type.
+ VPN provider type.
dict Ethernet [readonly]
This indicates the current bearer that is used
for this session. Or an empty string if no bearer
- if available.
-
- string ConnectionType [readwrite]
-
- This is used to indicate which connection is requested
- from the session. The state of the session will be
- updated accordingly. Values can be nothing, 'local' or
- 'internet'.
- 'local' means the session requests to be connected,
- but does not require specifically to be online.
- Therefore State property will be set to 'connected' if
- underlying service gets ready and/or online.
- 'online' means the session requests to be connected,
- and online. State property will never get 'connected'
- but instead will switch to 'online' if underlying
- service gets online.
- No value means the session requests any kind of
- connection and the state will be updated on all steps,
- 'connected' and 'online'. This is the default value.
-
- boolean State [readonly]
-
- This indicates if the connection is disconnected,
- connected or online. It is updated according to the
- selected ConnectionType. The session will not be
- in a useful shape (i.e.: providing a network connection
- to the owner) until its State gets updated to connected
- and/or online.
-
- This maps to the useful port of the service state.
- And it is only valid for the selected bearer
- configuration. Otherwise it will be reported as
- disconnected even if connected services are present.
-
- In addition the State settings notification might
- not happen right away. Notifications of this state
+ is available.
+
+ boolean Online [readonly]
+
+ This indicates if the connection is online or
+ offline.
+
+ This maps to the online service state. And it is
+ only valid for the selected bearer configuration.
+ Otherwise it will be reported as offline even if
+ the global state would be online.
+
+ In addition the Online settings notification might
+ not happen right away. Notifications of online state
can be delayed based on the speed of the bearer. It
- is done to avoid congestion on bearers like cellular
- etc.
+ is done to avoid congestion on bearers like 3G etc.
boolean Priority [readwrite]
dict IPv4 [readonly]
- Current IPv4 configuration.
+ Current IPv4 configuration. This settings is only
+ valid when online is true as well. Otherwise an
+ empty dictionary is reported.
dict IPv6 [readonly]
- Current IPv6 configuration.
+ Current IPv6 configuration. This setting is only
+ valid when online is true as well. Otherwise an
+ empty dictionary is reported.
boolean AvoidHandover [readwrite]
Interface net.connman.Technology
Object path [variable prefix]/{technology0,technology1,...}
-Methods dict GetProperties() [deprecated]
+Methods dict GetProperties()
Returns properties for the technology object. See
the properties section for available properties.
- Usage of this method is highly discouraged. Use
- the Manager.GetTechnologies() method instead.
-
- Possible Errors: [service].Error.InvalidArguments
-
- void SetProperty(string name, variant value)
-
- Changes the value of the specified property. Only
- properties that are listed as read-write are
- changeable. On success a PropertyChanged signal
- will be emitted.
-
Possible Errors: [service].Error.InvalidArguments
- [service].Error.InvalidProperty
-
- void Scan()
-
- Trigger a scan for this specific technology. The
- method call will return when a scan has been
- finished and results are available. So setting
- a longer D-Bus timeout might be a really good
- idea.
-
- Results will be signaled via the ServicesChanged
- signal from the manager interface.
Signals PropertyChanged(string name, variant value)
This signal indicates a changed value of the given
property.
-Properties boolean Powered [readwrite]
-
- Boolean representing the power state of the
- technology. False means that the technology is
- off (and is available RF-Killed) while True means
- that the technology is enabled.
-
- boolean Connected [readonly]
-
- Boolean representing if a technolgy is connected.
+Properties string State [readonly]
- This is just a convience property for allowing the
- UI to easily show if this technolgy has an active
- connection or not.
+ The technology state information.
- If this property is True it means that at least one
- service of this technology is in ready state.
+ Valid states are "offline", "enabled" and "connected".
string Name [readonly]
string TetheringIdentifier [readwrite]
- The tethering broadcasted identifier.
+ The tethering broadcasted identifier.
- This property is only valid for the WiFi technology,
- and is then mapped to the WiFi AP SSID clients will
- have to join in order to gain internet connectivity.
+ This property is only valid for the WiFi technology,
+ and is then mapped to the WiFi AP SSID clients will
+ have to join in order to gain internet connectivity.
string TetheringPassphrase [readwrite]
- The tethering connection passphrase.
+ The tethering connection passphrase.
- This property is only valid for the WiFi technology,
- and is then mapped to the WPA pre-shared key clients
- will have to use in order to establish a connection.
+ This property is only valid for the WiFi technology,
+ and is then mapped to the WPA pre-shared key clients
+ will have to use in order to establish a connection.
+++ /dev/null
-{
- <syslog error>
- Memcheck:Cond
- obj:/lib/libc-*.so
- ...
- fun:localtime_r
- fun:__vsyslog_chk
- fun:__syslog_chk
- fun:__connman_log_init
- ...
-}
-{
- <iconv open>
- Memcheck:Addr4
- obj:/lib/libc-*.so
- obj:/lib/libglib-2.0.so*
- fun:g_iconv_open
- ...
- fun:g_convert
- fun:g_locale_to_utf8
- fun:g_strerror
- fun:g_key_file_load_from_file
- ...
-}
-{
- <ioctl ADDRT/DELRT>
- Memcheck:Param
- ioctl(SIOCADDRT/DELRT)
- obj:/lib/ld-*.so
- ...
-}
-{
- <g_main_loop>
- Memcheck:Leak
- fun:memalign
- ...
- fun:g_slice_alloc
- ...
- fun:g_main_loop_new
- ...
-}
-{
- <g_option_context_parse>
- Memcheck:Leak
- ...
- fun:g_slice_alloc
- ...
- fun:g_option_context_parse
- ...
-}
-{
- <g_key_file_load_from_data>
- Memcheck:Leak
- ...
- fun:g_slice_alloc
- ...
- fun:g_key_file_load_from_data
- ...
-}
-{
- <g_key_file_new 1>
- Memcheck:Leak
- ...
- fun:g_slice_alloc
- ...
- fun:g_key_file_new
- ...
-}
-{
- <g_key_file_new 2>
- Memcheck:Leak
- fun:*alloc
- ...
- fun:g_key_file_new
- fun:main
-}
-{
- <connman plugin cleanup>
- Memcheck:Leak
- ...
- fun:__connman_plugin_cleanup
- ...
-}
-{
- <cmd line option parsing>
- Memcheck:Leak
- fun:malloc
- fun:g_malloc
- fun:g_strdup
- fun:g_set_prgname
- fun:g_option_context_parse
- fun:main
-}
-{
- <dbus system bus setup 1>
- Memcheck:Leak
- ...
- fun:dbus_malloc*
- ...
- fun:g_dbus_setup_bus
- fun:main
-}
-{
- <dbus system bus setup 2>
- Memcheck:Leak
- ...
- fun:g_malloc*
- ...
- fun:dbus_connection_set_watch_functions
- fun:setup_bus
- ...
-}
-{
- <key file get charset>
- Memcheck:Leak
- ...
- fun:g_*alloc*
- ...
- fun:g_strerror
- fun:g_key_file_load_from_file
- fun:main
-}
-{
- <dbus disconnect func set>
- Memcheck:Leak
- ...
- fun:filter_data_get
- fun:g_dbus_add_signal_watch
- fun:g_dbus_set_disconnect_function
- fun:main
-}
-{
- <plugin dlopen>
- Memcheck:Leak
- ...
- fun:dlopen
- fun:__connman_plugin_init
- fun:main
-}
-{
- <dbus system bus setup 3>
- Memcheck:Leak
- ...
- fun:dbus_malloc0
- ...
- fun:dbus_parse_address
- ...
- fun:g_dbus_setup_bus
- fun:main
-}
-{
- <libdbus internals 1>
- Memcheck:Leak
- fun:*malloc
- ...
- obj:/lib/libdbus-1.so.3.5.3
-}
-{
- <dbus system bus setup 4>
- Memcheck:Leak
- fun:*alloc
- ...
- fun:dbus_*alloc*
- ...
- fun:g_dbus_setup_bus
- fun:main
-}
-{
- <dbus system bus setup 5>
- Memcheck:Leak
- fun:calloc
- fun:g_malloc0
- ...
- fun:g_dbus_set_disconnect_function
- fun:main
-}
-{
- <dbus bus remove match>
- Memcheck:Leak
- fun:malloc
- fun:g_malloc
- fun:g_source_set_callback
- fun:g_timeout_add_full
- fun:g_timeout_add
- ...
- fun:dbus_pending_call_block
- fun:dbus_connection_send_with_reply_and_block
- ...
- fun:dbus_bus_remove_match
-}
-{
- <g_main_loop_run/new>
- Memcheck:Leak
- fun:*alloc
- ...
- fun:g_main_loop_*
- fun:main
-}
-{
- <g_main_context_dispatch>
- Memcheck:Leak
- fun:*alloc
- ...
- fun:g_main_context_dispatch
-}
-{
- <libdbus internals 2>
- Memcheck:Leak
- fun:realloc
- fun:dbus_realloc
- ...
- fun:dbus_message_set_reply_serial
- fun:dbus_message_new_error
- ...
-}
-{
- <libdbus internals 3>
- Memcheck:Leak
- fun:realloc
- fun:dbus_realloc
- ...
- fun:dbus_message_new_signal
- ...
-}
-{
- <dbus_bus_register>
- Memcheck:Leak
- fun:malloc
- fun:realloc
- fun:dbus_realloc
- ...
- fun:dbus_pending_call_block
- fun:dbus_connection_send_with_reply_and_block
- fun:dbus_bus_register
-}
typedef struct {
const char *name;
const char *signature;
-} GDBusArgInfo;
-
-typedef struct {
- const char *name;
+ const char *reply;
GDBusMethodFunction function;
GDBusMethodFlags flags;
unsigned int privilege;
- const GDBusArgInfo *in_args;
- const GDBusArgInfo *out_args;
} GDBusMethodTable;
typedef struct {
const char *name;
+ const char *signature;
GDBusSignalFlags flags;
- const GDBusArgInfo *args;
} GDBusSignalTable;
typedef struct {
GDBusSecurityFunction function;
} GDBusSecurityTable;
-#define GDBUS_ARGS(args...) (const GDBusArgInfo[]) { args, { } }
-
-#define GDBUS_METHOD(_name, _in_args, _out_args, _function) \
- .name = _name, \
- .in_args = _in_args, \
- .out_args = _out_args, \
- .function = _function
-
-#define GDBUS_ASYNC_METHOD(_name, _in_args, _out_args, _function) \
- .name = _name, \
- .in_args = _in_args, \
- .out_args = _out_args, \
- .function = _function, \
- .flags = G_DBUS_METHOD_FLAG_ASYNC
-
-#define GDBUS_DEPRECATED_METHOD(_name, _in_args, _out_args, _function) \
- .name = _name, \
- .in_args = _in_args, \
- .out_args = _out_args, \
- .function = _function, \
- .flags = G_DBUS_METHOD_FLAG_DEPRECATED
-
-#define GDBUS_DEPRECATED_ASYNC_METHOD(_name, _in_args, _out_args, _function) \
- .name = _name, \
- .in_args = _in_args, \
- .out_args = _out_args, \
- .function = _function, \
- .flags = G_DBUS_METHOD_FLAG_ASYNC | G_DBUS_METHOD_FLAG_DEPRECATED
-
-#define GDBUS_NOREPLY_METHOD(_name, _in_args, _out_args, _function) \
- .name = _name, \
- .in_args = _in_args, \
- .out_args = _out_args, \
- .function = _function, \
- .flags = G_DBUS_METHOD_FLAG_NOREPLY
-
-#define GDBUS_SIGNAL(_name, _args) \
- .name = _name, \
- .args = _args
-
-#define GDBUS_DEPRECATED_SIGNAL(_name, _args) \
- .name = _name, \
- .args = _args, \
- .flags = G_DBUS_SIGNAL_FLAG_DEPRECATED
-
gboolean g_dbus_register_interface(DBusConnection *connection,
const char *path, const char *name,
const GDBusMethodTable *methods,
#include <glib.h>
#include <dbus/dbus.h>
+#ifdef NEED_DBUS_WATCH_GET_UNIX_FD
+#define dbus_watch_get_unix_fd dbus_watch_get_fd
+#endif
+
#include "gdbus.h"
#define DISPATCH_TIMEOUT 0
void *iface_user_data;
};
-static void print_arguments(GString *gstr, const GDBusArgInfo *args,
+static void print_arguments(GString *gstr, const char *sig,
const char *direction)
{
- for (; args && args->name; args++) {
- g_string_append_printf(gstr,
- "\t\t\t<arg name=\"%s\" type=\"%s\"",
- args->name, args->signature);
+ int i;
+
+ for (i = 0; sig[i]; i++) {
+ char type[32];
+ int struct_level, dict_level;
+ unsigned int len;
+ gboolean complete;
+
+ complete = FALSE;
+ struct_level = dict_level = 0;
+ memset(type, 0, sizeof(type));
+
+ /* Gather enough data to have a single complete type */
+ for (len = 0; len < (sizeof(type) - 1) && sig[i]; len++, i++) {
+ switch (sig[i]){
+ case '(':
+ struct_level++;
+ break;
+ case ')':
+ struct_level--;
+ if (struct_level <= 0 && dict_level <= 0)
+ complete = TRUE;
+ break;
+ case '{':
+ dict_level++;
+ break;
+ case '}':
+ dict_level--;
+ if (struct_level <= 0 && dict_level <= 0)
+ complete = TRUE;
+ break;
+ case 'a':
+ break;
+ default:
+ if (struct_level <= 0 && dict_level <= 0)
+ complete = TRUE;
+ break;
+ }
+
+ type[len] = sig[i];
+
+ if (complete)
+ break;
+ }
+
if (direction)
g_string_append_printf(gstr,
- " direction=\"%s\"/>\n", direction);
+ "\t\t\t<arg type=\"%s\" direction=\"%s\"/>\n",
+ type, direction);
else
- g_string_append_printf(gstr, "/>\n");
-
+ g_string_append_printf(gstr,
+ "\t\t\t<arg type=\"%s\"/>\n",
+ type);
}
}
const GDBusSignalTable *signal;
for (method = iface->methods; method && method->name; method++) {
- gboolean deprecated = method->flags &
- G_DBUS_METHOD_FLAG_DEPRECATED;
- gboolean noreply = method->flags &
- G_DBUS_METHOD_FLAG_NOREPLY;
-
- if (!deprecated && !noreply &&
- !(method->in_args && method->in_args->name) &&
- !(method->out_args && method->out_args->name))
+ if (!strlen(method->signature) && !strlen(method->reply))
g_string_append_printf(gstr, "\t\t<method name=\"%s\"/>\n",
method->name);
else {
g_string_append_printf(gstr, "\t\t<method name=\"%s\">\n",
method->name);
- print_arguments(gstr, method->in_args, "in");
- print_arguments(gstr, method->out_args, "out");
-
- if (deprecated)
- g_string_append_printf(gstr, "\t\t\t<annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n");
-
- if (noreply)
- g_string_append_printf(gstr, "\t\t\t<annotation name=\"org.freedesktop.DBus.Method.NoReply\" value=\"true\"/>\n");
-
+ print_arguments(gstr, method->signature, "in");
+ print_arguments(gstr, method->reply, "out");
g_string_append_printf(gstr, "\t\t</method>\n");
}
}
for (signal = iface->signals; signal && signal->name; signal++) {
- gboolean deprecated = signal->flags &
- G_DBUS_SIGNAL_FLAG_DEPRECATED;
-
- if (!deprecated && !(signal->args && signal->args->name))
+ if (!strlen(signal->signature))
g_string_append_printf(gstr, "\t\t<signal name=\"%s\"/>\n",
signal->name);
else {
g_string_append_printf(gstr, "\t\t<signal name=\"%s\">\n",
signal->name);
- print_arguments(gstr, signal->args, NULL);
-
- if (deprecated)
- g_string_append_printf(gstr, "\t\t\t<annotation name=\"org.freedesktop.DBus.Deprecated\" value=\"true\"/>\n");
-
+ print_arguments(gstr, signal->signature, NULL);
g_string_append_printf(gstr, "\t\t</signal>\n");
}
}
struct generic_data *data = user_data;
DBusMessage *reply;
+ if (!dbus_message_has_signature(message, DBUS_TYPE_INVALID_AS_STRING)) {
+ error("Unexpected signature to introspect call");
+ return NULL;
+ }
+
if (data->introspect == NULL)
generate_introspection_xml(connection, data,
dbus_message_get_path(message));
return NULL;
}
-static gboolean g_dbus_args_have_signature(const GDBusArgInfo *args,
- DBusMessage *message)
-{
- const char *sig = dbus_message_get_signature(message);
- const char *p = NULL;
-
- for (; args && args->signature && *sig; args++) {
- p = args->signature;
-
- for (; *sig && *p; sig++, p++) {
- if (*p != *sig)
- return FALSE;
- }
- }
-
- if (*sig || (p && *p) || (args && args->signature))
- return FALSE;
-
- return TRUE;
-}
-
static DBusHandlerResult generic_message(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
method->name) == FALSE)
continue;
- if (g_dbus_args_have_signature(method->in_args,
- message) == FALSE)
+ if (dbus_message_has_signature(message,
+ method->signature) == FALSE)
continue;
if (check_privilege(connection, message, method,
g_free(parent_path);
}
-static const GDBusMethodTable introspect_methods[] = {
- { GDBUS_METHOD("Introspect", NULL,
- GDBUS_ARGS({ "xml", "s" }), introspect) },
+static GDBusMethodTable introspect_methods[] = {
+ { "Introspect", "", "s", introspect },
{ }
};
static gboolean check_signal(DBusConnection *conn, const char *path,
const char *interface, const char *name,
- const GDBusArgInfo **args)
+ const char **args)
{
struct generic_data *data = NULL;
struct interface_data *iface;
for (signal = iface->signals; signal && signal->name; signal++) {
if (!strcmp(signal->name, name)) {
- *args = signal->args;
- return TRUE;
+ *args = signal->signature;
+ break;
}
}
- error("No signal named %s on interface %s", name, interface);
- return FALSE;
+ if (*args == NULL) {
+ error("No signal named %s on interface %s", name, interface);
+ return FALSE;
+ }
+
+ return TRUE;
}
static dbus_bool_t emit_signal_valist(DBusConnection *conn,
{
DBusMessage *signal;
dbus_bool_t ret;
- const GDBusArgInfo *args;
+ const char *signature, *args;
if (!check_signal(conn, path, interface, name, &args))
return FALSE;
if (!ret)
goto fail;
- if (g_dbus_args_have_signature(args, signal) == FALSE) {
+ signature = dbus_message_get_signature(signal);
+ if (strcmp(args, signature) != 0) {
error("%s.%s: expected signature'%s' but got '%s'",
interface, name, args, signature);
ret = FALSE;
connection = dbus_connection_ref(data->connection);
listeners = g_slist_remove(listeners, data);
+ filter_data_free(data);
/* Remove filter if there are no listeners left for the connection */
- if (filter_data_find(connection, NULL, NULL, NULL, NULL, NULL,
- NULL) == NULL)
+ data = filter_data_find(connection, NULL, NULL, NULL, NULL, NULL,
+ NULL);
+ if (data == NULL)
dbus_connection_remove_filter(connection, message_filter,
NULL);
- filter_data_free(data);
dbus_connection_unref(connection);
return TRUE;
remove_match(data);
listeners = g_slist_remove(listeners, data);
+ filter_data_free(data);
- /* Remove filter if there are no listeners left for the connection */
- if (filter_data_find(connection, NULL, NULL, NULL, NULL, NULL,
- NULL) == NULL)
+ /* Remove filter if there no listener left for the connection */
+ data = filter_data_find(connection, NULL, NULL, NULL, NULL, NULL,
+ NULL);
+ if (data == NULL)
dbus_connection_remove_filter(connection, message_filter,
NULL);
- filter_data_free(data);
-
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
if (data == NULL)
return 0;
- cb = filter_data_add_callback(data, connect, disconnect, NULL, destroy,
+ cb = filter_data_add_callback(data, connect, disconnect, NULL, NULL,
user_data);
if (cb == NULL)
return 0;
*
* DHCP client library with GLib integration
*
- * Copyright (C) 2009-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
IPV4LL_ANNOUNCE,
IPV4LL_MONITOR,
IPV4LL_DEFEND,
- INFORMATION_REQ,
- SOLICITATION,
- REQUEST,
- RENEW,
- REBIND,
- RELEASE,
} ClientState;
struct _GDHCPClient {
uint32_t server_ip;
uint32_t requested_ip;
char *assigned_ip;
- time_t start;
uint32_t lease_seconds;
ListenMode listen_mode;
int listener_sockfd;
gpointer address_conflict_data;
GDHCPDebugFunc debug_func;
gpointer debug_data;
- GDHCPClientEventFunc information_req_cb;
- gpointer information_req_data;
- GDHCPClientEventFunc solicitation_cb;
- gpointer solicitation_data;
- GDHCPClientEventFunc advertise_cb;
- gpointer advertise_data;
- GDHCPClientEventFunc request_cb;
- gpointer request_data;
- GDHCPClientEventFunc renew_cb;
- gpointer renew_data;
- GDHCPClientEventFunc rebind_cb;
- gpointer rebind_data;
- GDHCPClientEventFunc release_cb;
- gpointer release_data;
char *last_address;
- unsigned char *duid;
- int duid_len;
- unsigned char *server_duid;
- int server_duid_len;
- uint16_t status_code;
- uint32_t iaid;
- uint32_t T1, T2;
- struct in6_addr ia_na;
- struct in6_addr ia_ta;
- time_t last_renew;
- time_t last_rebind;
- time_t expire;
+#if defined TIZEN_EXT
+ gboolean init_reboot;
+#endif
};
static inline void debug(GDHCPClient *client, const char *format, ...)
}
/* Initialize the packet with the proper defaults */
-static void init_packet(GDHCPClient *dhcp_client, gpointer pkt, char type)
+static void init_packet(GDHCPClient *dhcp_client,
+ struct dhcp_packet *packet, char type)
{
- if (dhcp_client->type == G_DHCP_IPV6)
- dhcpv6_init_header(pkt, type);
- else {
- struct dhcp_packet *packet = pkt;
+ dhcp_init_header(packet, type);
- dhcp_init_header(packet, type);
- memcpy(packet->chaddr, dhcp_client->mac_address, 6);
- }
+ memcpy(packet->chaddr, dhcp_client->mac_address, 6);
}
static void add_request_options(GDHCPClient *dhcp_client,
}
}
-struct hash_params {
- unsigned char *buf;
- int max_buf;
- unsigned char **ptr_buf;
-};
-
-static void add_dhcpv6_binary_option(gpointer key, gpointer value,
- gpointer user_data)
-{
- uint8_t *option = value;
- uint16_t len;
- struct hash_params *params = user_data;
-
- /* option[0][1] contains option code */
- len = option[2] << 8 | option[3];
-
- if ((*params->ptr_buf + len + 2 + 2) > (params->buf + params->max_buf))
- return;
-
- memcpy(*params->ptr_buf, option, len + 2 + 2);
- (*params->ptr_buf) += len + 2 + 2;
-}
-
-static void add_dhcpv6_send_options(GDHCPClient *dhcp_client,
- unsigned char *buf, int max_buf,
- unsigned char **ptr_buf)
-{
- struct hash_params params = {
- .buf = buf,
- .max_buf = max_buf,
- .ptr_buf = ptr_buf
- };
-
- if (dhcp_client->type == G_DHCP_IPV4)
- return;
-
- g_hash_table_foreach(dhcp_client->send_value_hash,
- add_dhcpv6_binary_option, ¶ms);
-
- *ptr_buf = *params.ptr_buf;
-}
-
-static void copy_option(uint8_t *buf, uint16_t code, uint16_t len,
- uint8_t *msg)
-{
- buf[0] = code >> 8;
- buf[1] = code & 0xff;
- buf[2] = len >> 8;
- buf[3] = len & 0xff;
- if (len > 0 && msg != NULL)
- memcpy(&buf[4], msg, len);
-}
-
-static void add_dhcpv6_request_options(GDHCPClient *dhcp_client,
- struct dhcpv6_packet *packet,
- unsigned char *buf, int max_buf,
- unsigned char **ptr_buf)
-{
- GList *list;
- uint16_t code;
- int len;
-
- if (dhcp_client->type == G_DHCP_IPV4)
- return;
-
- for (list = dhcp_client->request_list; list; list = list->next) {
- code = (uint16_t) GPOINTER_TO_INT(list->data);
-
- switch (code) {
- case G_DHCPV6_CLIENTID:
- if (dhcp_client->duid == NULL)
- return;
-
- len = 2 + 2 + dhcp_client->duid_len;
- if ((*ptr_buf + len) > (buf + max_buf)) {
- debug(dhcp_client, "Too long dhcpv6 message "
- "when writing client id option");
- return;
- }
-
- copy_option(*ptr_buf, G_DHCPV6_CLIENTID,
- dhcp_client->duid_len, dhcp_client->duid);
- (*ptr_buf) += len;
- break;
-
- case G_DHCPV6_SERVERID:
- if (dhcp_client->server_duid == NULL)
- return;
-
- len = 2 + 2 + dhcp_client->server_duid_len;
- if ((*ptr_buf + len) > (buf + max_buf)) {
- debug(dhcp_client, "Too long dhcpv6 message "
- "when writing server id option");
- return;
- }
-
- copy_option(*ptr_buf, G_DHCPV6_SERVERID,
- dhcp_client->server_duid_len,
- dhcp_client->server_duid);
- (*ptr_buf) += len;
- break;
-
- case G_DHCPV6_RAPID_COMMIT:
- len = 2 + 2;
- if ((*ptr_buf + len) > (buf + max_buf)) {
- debug(dhcp_client, "Too long dhcpv6 message "
- "when writing rapid commit option");
- return;
- }
-
- copy_option(*ptr_buf, G_DHCPV6_RAPID_COMMIT, 0, 0);
- (*ptr_buf) += len;
- break;
-
- case G_DHCPV6_ORO:
- break;
-
- case G_DHCPV6_DNS_SERVERS:
- break;
-
- case G_DHCPV6_SNTP_SERVERS:
- break;
-
- default:
- break;
- }
- }
-}
-
static void add_binary_option(gpointer key, gpointer value, gpointer user_data)
{
uint8_t *option = value;
add_binary_option, packet);
}
-/*
- * Return an RFC 951- and 2131-complaint BOOTP 'secs' value that
- * represents the number of seconds elapsed from the start of
- * attempting DHCP to satisfy some DHCP servers that allow for an
- * "authoritative" reply before responding.
- */
-static uint16_t dhcp_attempt_secs(GDHCPClient *dhcp_client)
-{
- return htons(MIN(time(NULL) - dhcp_client->start, UINT16_MAX));
-}
-
static int send_discover(GDHCPClient *dhcp_client, uint32_t requested)
{
struct dhcp_packet packet;
init_packet(dhcp_client, &packet, DHCPDISCOVER);
packet.xid = dhcp_client->xid;
- packet.secs = dhcp_attempt_secs(dhcp_client);
if (requested)
dhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested);
init_packet(dhcp_client, &packet, DHCPREQUEST);
packet.xid = dhcp_client->xid;
- packet.secs = dhcp_attempt_secs(dhcp_client);
dhcp_add_simple_option(&packet, DHCP_REQUESTED_IP,
dhcp_client->requested_ip);
+#if defined TIZEN_EXT
+ if (dhcp_client->init_reboot != TRUE)
+#endif
dhcp_add_simple_option(&packet, DHCP_SERVER_ID, dhcp_client->server_ip);
add_request_options(dhcp_client, &packet);
close(sk);
}
-int g_dhcpv6_create_duid(GDHCPDuidType duid_type, int index, int type,
- unsigned char **duid, int *duid_len)
-{
- time_t duid_time;
-
- switch (duid_type) {
- case G_DHCPV6_DUID_LLT:
- *duid_len = 2 + 2 + 4 + ETH_ALEN;
- *duid = g_try_malloc(*duid_len);
- if (*duid == NULL)
- return -ENOMEM;
-
- (*duid)[0] = 0;
- (*duid)[1] = 1;
- get_interface_mac_address(index, &(*duid)[2 + 2 + 4]);
- (*duid)[2] = 0;
- (*duid)[3] = type;
- duid_time = time(NULL) - DUID_TIME_EPOCH;
- (*duid)[4] = duid_time >> 24;
- (*duid)[5] = duid_time >> 16;
- (*duid)[6] = duid_time >> 8;
- (*duid)[7] = duid_time & 0xff;
- break;
- case G_DHCPV6_DUID_EN:
- return -EINVAL;
- case G_DHCPV6_DUID_LL:
- *duid_len = 2 + 2 + ETH_ALEN;
- *duid = g_try_malloc(*duid_len);
- if (*duid == NULL)
- return -ENOMEM;
-
- (*duid)[0] = 0;
- (*duid)[1] = 3;
- get_interface_mac_address(index, &(*duid)[2 + 2]);
- (*duid)[2] = 0;
- (*duid)[3] = type;
- break;
- }
-
- return 0;
-}
-
-int g_dhcpv6_client_set_duid(GDHCPClient *dhcp_client, unsigned char *duid,
- int duid_len)
-{
- if (dhcp_client == NULL || dhcp_client->type == G_DHCP_IPV4)
- return -EINVAL;
-
- g_free(dhcp_client->duid);
-
- dhcp_client->duid = duid;
- dhcp_client->duid_len = duid_len;
-
- return 0;
-}
-
-uint32_t g_dhcpv6_client_get_iaid(GDHCPClient *dhcp_client)
-{
- if (dhcp_client == NULL || dhcp_client->type == G_DHCP_IPV4)
- return 0;
-
- return dhcp_client->iaid;
-}
-
-void g_dhcpv6_client_create_iaid(GDHCPClient *dhcp_client, int index,
- unsigned char *iaid)
-{
- uint8_t buf[6];
-
- get_interface_mac_address(index, buf);
-
- memcpy(iaid, &buf[2], 4);
- dhcp_client->iaid = iaid[0] << 24 |
- iaid[1] << 16 | iaid[2] << 8 | iaid[3];
-}
-
-int g_dhcpv6_client_get_timeouts(GDHCPClient *dhcp_client,
- uint32_t *T1, uint32_t *T2,
- time_t *last_renew, time_t *last_rebind,
- time_t *expire)
-{
- if (dhcp_client == NULL || dhcp_client->type == G_DHCP_IPV4)
- return -EINVAL;
-
- if (T1 != NULL)
- *T1 = dhcp_client->T1;
-
- if (T2 != NULL)
- *T2 = dhcp_client->T2;
-
- if (last_renew != NULL)
- *last_renew = dhcp_client->last_renew;
-
- if (last_rebind != NULL)
- *last_rebind = dhcp_client->last_rebind;
-
- if (expire != NULL)
- *expire = dhcp_client->expire;
-
- return 0;
-}
-
-static uint8_t *create_iaaddr(GDHCPClient *dhcp_client, uint8_t *buf,
- uint16_t len)
-{
- buf[0] = 0;
- buf[1] = G_DHCPV6_IAADDR;
- buf[2] = 0;
- buf[3] = len;
- memcpy(&buf[4], &dhcp_client->ia_na, 16);
- memset(&buf[20], 0, 4); /* preferred */
- memset(&buf[24], 0, 4); /* valid */
- return buf;
-}
-
-static void put_iaid(GDHCPClient *dhcp_client, int index, uint8_t *buf)
-{
- uint32_t iaid;
-
- iaid = g_dhcpv6_client_get_iaid(dhcp_client);
- if (iaid == 0) {
- g_dhcpv6_client_create_iaid(dhcp_client, index, buf);
- return;
- }
-
- buf[0] = iaid >> 24;
- buf[1] = iaid >> 16;
- buf[2] = iaid >> 8;
- buf[3] = iaid;
-}
-
-int g_dhcpv6_client_set_ia(GDHCPClient *dhcp_client, int index,
- int code, uint32_t *T1, uint32_t *T2,
- gboolean add_iaaddr)
-{
- if (code == G_DHCPV6_IA_TA) {
- uint8_t ia_options[4];
-
- put_iaid(dhcp_client, index, ia_options);
-
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_IA_TA);
- g_dhcpv6_client_set_send(dhcp_client, G_DHCPV6_IA_TA,
- ia_options, sizeof(ia_options));
-
- } else if (code == G_DHCPV6_IA_NA) {
-
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_IA_NA);
-
- if (add_iaaddr == TRUE) {
-#define IAADDR_LEN (16+4+4)
- uint8_t ia_options[4+4+4+2+2+IAADDR_LEN];
-
- put_iaid(dhcp_client, index, ia_options);
-
- if (T1 != NULL) {
- ia_options[4] = *T1 >> 24;
- ia_options[5] = *T1 >> 16;
- ia_options[6] = *T1 >> 8;
- ia_options[7] = *T1;
- } else
- memset(&ia_options[4], 0x00, 4);
-
- if (T2 != NULL) {
- ia_options[8] = *T2 >> 24;
- ia_options[9] = *T2 >> 16;
- ia_options[10] = *T2 >> 8;
- ia_options[11] = *T2;
- } else
- memset(&ia_options[8], 0x00, 4);
-
- create_iaaddr(dhcp_client, &ia_options[12],
- IAADDR_LEN);
-
- g_dhcpv6_client_set_send(dhcp_client, G_DHCPV6_IA_NA,
- ia_options, sizeof(ia_options));
- } else {
- uint8_t ia_options[4+4+4];
-
- put_iaid(dhcp_client, index, ia_options);
-
- memset(&ia_options[4], 0x00, 4); /* T1 (4 bytes) */
- memset(&ia_options[8], 0x00, 4); /* T2 (4 bytes) */
-
- g_dhcpv6_client_set_send(dhcp_client, G_DHCPV6_IA_NA,
- ia_options, sizeof(ia_options));
- }
-
- } else
- return -EINVAL;
-
- return 0;
-}
-
-int g_dhcpv6_client_set_oro(GDHCPClient *dhcp_client, int args, ...)
-{
- va_list va;
- int i, j, len = sizeof(uint16_t) * args;
- uint8_t *values;
-
- values = g_try_malloc(len);
- if (values == NULL)
- return -ENOMEM;
-
- va_start(va, args);
- for (i = 0, j = 0; i < args; i++) {
- uint16_t value = va_arg(va, int);
- values[j++] = value >> 8;
- values[j++] = value & 0xff;
- }
- va_end(va);
-
- g_dhcpv6_client_set_send(dhcp_client, G_DHCPV6_ORO, values, len);
-
- return 0;
-}
-
-static int send_dhcpv6_msg(GDHCPClient *dhcp_client, int type, char *msg)
-{
- struct dhcpv6_packet *packet;
- uint8_t buf[MAX_DHCPV6_PKT_SIZE];
- unsigned char *ptr;
- int ret, max_buf;
-
- memset(buf, 0, sizeof(buf));
- packet = (struct dhcpv6_packet *)&buf[0];
- ptr = buf + sizeof(struct dhcpv6_packet);
-
- debug(dhcp_client, "sending DHCPv6 %s message", msg);
-
- init_packet(dhcp_client, packet, type);
-
- dhcp_client->xid = packet->transaction_id[0] << 16 |
- packet->transaction_id[1] << 8 |
- packet->transaction_id[2];
-
- max_buf = MAX_DHCPV6_PKT_SIZE - sizeof(struct dhcpv6_packet);
-
- add_dhcpv6_request_options(dhcp_client, packet, buf, max_buf, &ptr);
-
- add_dhcpv6_send_options(dhcp_client, buf, max_buf, &ptr);
-
- ret = dhcpv6_send_packet(dhcp_client->ifindex, packet, ptr - buf);
-
- debug(dhcp_client, "sent %d pkt %p len %d", ret, packet, ptr - buf);
- return ret;
-}
-
-static int send_solicitation(GDHCPClient *dhcp_client)
-{
- return send_dhcpv6_msg(dhcp_client, DHCPV6_SOLICIT, "solicit");
-}
-
-static int send_dhcpv6_request(GDHCPClient *dhcp_client)
-{
- return send_dhcpv6_msg(dhcp_client, DHCPV6_REQUEST, "request");
-}
-
-static int send_dhcpv6_renew(GDHCPClient *dhcp_client)
-{
- return send_dhcpv6_msg(dhcp_client, DHCPV6_RENEW, "renew");
-}
-
-static int send_dhcpv6_rebind(GDHCPClient *dhcp_client)
-{
- return send_dhcpv6_msg(dhcp_client, DHCPV6_REBIND, "rebind");
-}
-
-static int send_dhcpv6_release(GDHCPClient *dhcp_client)
-{
- return send_dhcpv6_msg(dhcp_client, DHCPV6_RELEASE, "release");
-}
-
-static int send_information_req(GDHCPClient *dhcp_client)
-{
- return send_dhcpv6_msg(dhcp_client, DHCPV6_INFORMATION_REQ,
- "information-req");
-}
-
static void remove_value(gpointer data, gpointer user_data)
{
char *value = data;
g_direct_equal, NULL, g_free);
dhcp_client->request_list = NULL;
dhcp_client->require_list = NULL;
- dhcp_client->duid = NULL;
- dhcp_client->duid_len = 0;
- dhcp_client->last_renew = dhcp_client->last_rebind = time(NULL);
- dhcp_client->expire = 0;
*error = G_DHCP_CLIENT_ERROR_NONE;
int target_conflict;
memset(&arp, 0, sizeof(arp));
+ bytes = 0;
bytes = read(dhcp_client->listener_sockfd, &arp, sizeof(arp));
if (bytes < 0)
return bytes;
return 0;
}
-static gboolean check_package_owner(GDHCPClient *dhcp_client, gpointer pkt)
+static gboolean check_package_owner(GDHCPClient *dhcp_client,
+ struct dhcp_packet *packet)
{
- if (dhcp_client->type == G_DHCP_IPV6) {
- struct dhcpv6_packet *packet6 = pkt;
- uint32_t xid;
-
- if (packet6 == NULL)
- return FALSE;
-
- xid = packet6->transaction_id[0] << 16 |
- packet6->transaction_id[1] << 8 |
- packet6->transaction_id[2];
-
- if (xid != dhcp_client->xid)
- return FALSE;
- } else {
- struct dhcp_packet *packet = pkt;
-
- if (packet->xid != dhcp_client->xid)
- return FALSE;
+ if (packet->xid != dhcp_client->xid)
+ return FALSE;
- if (packet->hlen != 6)
- return FALSE;
+ if (packet->hlen != 6)
+ return FALSE;
- if (memcmp(packet->chaddr, dhcp_client->mac_address, 6))
- return FALSE;
- }
+ if (memcmp(packet->chaddr, dhcp_client->mac_address, 6))
+ return FALSE;
return TRUE;
}
GIOChannel *listener_channel;
int listener_sockfd;
- if (dhcp_client->listen_mode == listen_mode)
- return 0;
-
debug(dhcp_client, "switch listening mode (%d ==> %d)",
dhcp_client->listen_mode, listen_mode);
+ if (dhcp_client->listen_mode == listen_mode)
+ return 0;
+
if (dhcp_client->listen_mode != L_NONE) {
- if (dhcp_client->listener_watch > 0)
- g_source_remove(dhcp_client->listener_watch);
+ g_source_remove(dhcp_client->listener_watch);
dhcp_client->listener_channel = NULL;
dhcp_client->listen_mode = L_NONE;
dhcp_client->listener_sockfd = -1;
if (listen_mode == L2)
listener_sockfd = dhcp_l2_socket(dhcp_client->ifindex);
- else if (listen_mode == L3) {
- if (dhcp_client->type == G_DHCP_IPV6)
- listener_sockfd = dhcp_l3_socket(DHCPV6_CLIENT_PORT,
- dhcp_client->interface,
- AF_INET6);
- else
- listener_sockfd = dhcp_l3_socket(CLIENT_PORT,
- dhcp_client->interface,
- AF_INET);
- } else if (listen_mode == L_ARP)
+ else if (listen_mode == L3)
+ listener_sockfd = dhcp_l3_socket(CLIENT_PORT,
+ dhcp_client->interface);
+ else if (listen_mode == L_ARP)
listener_sockfd = ipv4ll_arp_socket(dhcp_client->ifindex);
else
return -EIO;
return list;
}
-static inline uint32_t get_uint32(unsigned char *value)
-{
- return value[0] << 24 | value[1] << 16 |
- value[2] << 8 | value[3];
-}
-
-static inline uint16_t get_uint16(unsigned char *value)
-{
- return value[0] << 8 | value[1];
-}
-
-static GList *get_addresses(GDHCPClient *dhcp_client,
- int code, int len,
- unsigned char *value,
- uint16_t *status)
-{
- GList *list = NULL;
- struct in6_addr addr;
- uint32_t iaid, T1 = 0, T2 = 0, preferred = 0, valid = 0;
- uint16_t option_len, option_code, st = 0, max_len;
- int addr_count = 0, i, pos;
- uint8_t *option;
- char *str;
-
- if (value == NULL || len < 4)
- return NULL;
-
- iaid = get_uint32(&value[0]);
- if (dhcp_client->iaid != iaid)
- return NULL;
-
- if (code == G_DHCPV6_IA_NA) {
- T1 = get_uint32(&value[4]);
- T2 = get_uint32(&value[8]);
-
- if (T1 > T2)
- /* RFC 3315, 22.4 */
- return NULL;
-
- pos = 12;
- } else
- pos = 4;
-
- if (len <= pos)
- return NULL;
-
- max_len = len - pos;
-
- /* We have more sub-options in this packet. */
- do {
- option = dhcpv6_get_sub_option(&value[pos], max_len,
- &option_code, &option_len);
-
- debug(dhcp_client, "pos %d option %p code %d len %d",
- pos, option, option_code, option_len);
-
- if (option == NULL)
- break;
-
- if (pos >= max_len)
- break;
-
- switch (option_code) {
- case G_DHCPV6_IAADDR:
- i = 0;
- memcpy(&addr, &option[0], sizeof(addr));
- i += sizeof(addr);
- preferred = get_uint32(&option[i]);
- i += 4;
- valid = get_uint32(&option[i]);
-
- addr_count++;
- break;
-
- case G_DHCPV6_STATUS_CODE:
- st = get_uint16(&option[0]);
- debug(dhcp_client, "error code %d", st);
- if (option_len > 2) {
- str = g_strndup((gchar *)&option[2],
- option_len - 2);
- debug(dhcp_client, "error text: %s", str);
- g_free(str);
- }
-
- *status = st;
- break;
- }
-
- pos += 2 + 2 + option_len;
-
- } while (option != NULL);
-
- if (addr_count > 0 && st == 0) {
- /* We only support one address atm */
- char str[INET6_ADDRSTRLEN + 1];
-
- if (preferred > valid)
- /* RFC 3315, 22.6 */
- return NULL;
-
- dhcp_client->T1 = T1;
- dhcp_client->T2 = T2;
-
- inet_ntop(AF_INET6, &addr, str, INET6_ADDRSTRLEN);
- debug(dhcp_client, "count %d addr %s T1 %u T2 %u",
- addr_count, str, T1, T2);
-
- list = g_list_append(list, g_strdup(str));
-
- if (code == G_DHCPV6_IA_NA)
- memcpy(&dhcp_client->ia_na, &addr,
- sizeof(struct in6_addr));
- else
- memcpy(&dhcp_client->ia_ta, &addr,
- sizeof(struct in6_addr));
-
- g_dhcpv6_client_set_expire(dhcp_client, valid);
- }
-
- return list;
-}
-
-static GList *get_dhcpv6_option_value_list(GDHCPClient *dhcp_client,
- int code, int len,
- unsigned char *value,
- uint16_t *status)
-{
- GList *list = NULL;
- char *str;
- int i;
-
- if (value == NULL)
- return NULL;
-
- switch (code) {
- case G_DHCPV6_DNS_SERVERS: /* RFC 3646, chapter 3 */
- case G_DHCPV6_SNTP_SERVERS: /* RFC 4075, chapter 4 */
- if (len % 16) {
- debug(dhcp_client,
- "%s server list length (%d) is invalid",
- code == G_DHCPV6_DNS_SERVERS ? "DNS" : "SNTP",
- len);
- return NULL;
- }
- for (i = 0; i < len; i += 16) {
-
- str = g_try_malloc0(INET6_ADDRSTRLEN+1);
- if (str == NULL)
- return list;
-
- if (inet_ntop(AF_INET6, &value[i], str,
- INET6_ADDRSTRLEN) == NULL)
- g_free(str);
- else
- list = g_list_append(list, str);
- }
- break;
-
- case G_DHCPV6_IA_NA: /* RFC 3315, chapter 22.4 */
- case G_DHCPV6_IA_TA: /* RFC 3315, chapter 22.5 */
- list = get_addresses(dhcp_client, code, len, value, status);
- break;
-
- default:
- break;
- }
-
- return list;
-}
-
-static void get_dhcpv6_request(GDHCPClient *dhcp_client,
- struct dhcpv6_packet *packet,
- uint16_t pkt_len, uint16_t *status)
-{
- GList *list, *value_list;
- uint8_t *option;
- uint16_t code;
- uint16_t option_len;
-
- for (list = dhcp_client->request_list; list; list = list->next) {
- code = (uint16_t) GPOINTER_TO_INT(list->data);
-
- option = dhcpv6_get_option(packet, pkt_len, code, &option_len,
- NULL);
- if (option == NULL) {
- g_hash_table_remove(dhcp_client->code_value_hash,
- GINT_TO_POINTER((int) code));
- continue;
- }
-
- value_list = get_dhcpv6_option_value_list(dhcp_client, code,
- option_len, option, status);
-
- debug(dhcp_client, "code %d %p len %d list %p", code, option,
- option_len, value_list);
-
- if (value_list == NULL)
- g_hash_table_remove(dhcp_client->code_value_hash,
- GINT_TO_POINTER((int) code));
- else
- g_hash_table_insert(dhcp_client->code_value_hash,
- GINT_TO_POINTER((int) code), value_list);
- }
-}
-
static void get_request(GDHCPClient *dhcp_client, struct dhcp_packet *packet)
{
GDHCPOptionType type;
{
GDHCPClient *dhcp_client = user_data;
struct dhcp_packet packet;
- struct dhcpv6_packet *packet6 = NULL;
- uint8_t *message_type = NULL, *client_id = NULL, *option_u8,
- *server_id = NULL;
- uint16_t option_len = 0, status = 0;
- gpointer pkt;
- unsigned char buf[MAX_DHCPV6_PKT_SIZE];
- uint16_t pkt_len = 0;
- int count;
+ uint8_t *message_type, *option_u8;
int re;
if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
if (dhcp_client->listen_mode == L_NONE)
return FALSE;
- pkt = &packet;
-
if (dhcp_client->listen_mode == L2)
- re = dhcp_recv_l2_packet(&packet,
- dhcp_client->listener_sockfd);
- else if (dhcp_client->listen_mode == L3) {
- if (dhcp_client->type == G_DHCP_IPV6) {
- re = dhcpv6_recv_l3_packet(&packet6, buf, sizeof(buf),
- dhcp_client->listener_sockfd);
- pkt_len = re;
- pkt = packet6;
- } else
- re = dhcp_recv_l3_packet(&packet,
- dhcp_client->listener_sockfd);
- } else if (dhcp_client->listen_mode == L_ARP) {
- ipv4ll_recv_arp_packet(dhcp_client);
+ re = dhcp_recv_l2_packet(&packet, dhcp_client->listener_sockfd);
+ else if (dhcp_client->listen_mode == L3)
+ re = dhcp_recv_l3_packet(&packet, dhcp_client->listener_sockfd);
+ else if (dhcp_client->listen_mode == L_ARP) {
+ re = ipv4ll_recv_arp_packet(dhcp_client);
return TRUE;
}
else
if (re < 0)
return TRUE;
- if (check_package_owner(dhcp_client, pkt) == FALSE)
+ if (check_package_owner(dhcp_client, &packet) == FALSE)
return TRUE;
- if (dhcp_client->type == G_DHCP_IPV6) {
- if (packet6 == NULL)
- return TRUE;
-
- count = 0;
- client_id = dhcpv6_get_option(packet6, pkt_len,
- G_DHCPV6_CLIENTID, &option_len, &count);
-
- if (client_id == NULL || count == 0 || option_len == 0 ||
- memcmp(dhcp_client->duid, client_id,
- dhcp_client->duid_len) != 0) {
- debug(dhcp_client,
- "client duid error, discarding msg %p/%d/%d",
- client_id, option_len, count);
- return TRUE;
- }
-
- option_u8 = dhcpv6_get_option(packet6, pkt_len,
- G_DHCPV6_STATUS_CODE, &option_len, NULL);
- if (option_u8 != 0 && option_len > 0) {
- status = option_u8[0]<<8 | option_u8[1];
- if (status != 0) {
- debug(dhcp_client, "error code %d", status);
- if (option_len > 2) {
- gchar *txt = g_strndup(
- (gchar *)&option_u8[2],
- option_len - 2);
- debug(dhcp_client, "error text: %s",
- txt);
- g_free(txt);
- }
- }
- dhcp_client->status_code = status;
- } else
- dhcp_client->status_code = 0;
-
- } else {
- message_type = dhcp_get_option(&packet, DHCP_MESSAGE_TYPE);
- if (message_type == NULL)
- return TRUE;
- }
-
- if (message_type == NULL && client_id == NULL)
- /* No message type / client id option, ignore package */
+ message_type = dhcp_get_option(&packet, DHCP_MESSAGE_TYPE);
+ if (message_type == NULL)
+ /* No message type option, ignore package */
return TRUE;
debug(dhcp_client, "received DHCP packet (current state %d)",
dhcp_client->timeout = 0;
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);
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,
}
break;
- case SOLICITATION:
- if (dhcp_client->type != G_DHCP_IPV6)
- return TRUE;
-
- if (packet6->message != DHCPV6_REPLY &&
- packet6->message != DHCPV6_ADVERTISE)
- return TRUE;
-
- count = 0;
- server_id = dhcpv6_get_option(packet6, pkt_len,
- G_DHCPV6_SERVERID, &option_len, &count);
- if (server_id == NULL || count != 1 || option_len == 0) {
- /* RFC 3315, 15.10 */
- debug(dhcp_client,
- "server duid error, discarding msg %p/%d/%d",
- server_id, option_len, count);
- return TRUE;
- }
- dhcp_client->server_duid = g_try_malloc(option_len);
- if (dhcp_client->server_duid == NULL)
- return TRUE;
- memcpy(dhcp_client->server_duid, server_id, option_len);
- dhcp_client->server_duid_len = option_len;
-
- if (packet6->message == DHCPV6_REPLY) {
- uint8_t *rapid_commit;
- count = 0;
- option_len = 0;
- rapid_commit = dhcpv6_get_option(packet6, pkt_len,
- G_DHCPV6_RAPID_COMMIT,
- &option_len, &count);
- if (rapid_commit == NULL || option_len == 0 ||
- count != 1)
- /* RFC 3315, 17.1.4 */
- return TRUE;
- }
-
- switch_listening_mode(dhcp_client, L_NONE);
-
- if (dhcp_client->status_code == 0)
- get_dhcpv6_request(dhcp_client, packet6, pkt_len,
- &dhcp_client->status_code);
-
- if (packet6->message == DHCPV6_ADVERTISE) {
- if (dhcp_client->advertise_cb != NULL)
- dhcp_client->advertise_cb(dhcp_client,
- dhcp_client->advertise_data);
- return TRUE;
- }
-
- if (dhcp_client->solicitation_cb != NULL) {
- /*
- * The dhcp_client might not be valid after the
- * callback call so just return immediately.
- */
- dhcp_client->solicitation_cb(dhcp_client,
- dhcp_client->solicitation_data);
- return TRUE;
- }
- break;
- case INFORMATION_REQ:
- case REQUEST:
- case RENEW:
- case REBIND:
- case RELEASE:
- if (dhcp_client->type != G_DHCP_IPV6)
- return TRUE;
-
- if (packet6->message != DHCPV6_REPLY)
- return TRUE;
-
- count = 0;
- option_len = 0;
- server_id = dhcpv6_get_option(packet6, pkt_len,
- G_DHCPV6_SERVERID, &option_len, &count);
- if (server_id == NULL || count != 1 || option_len == 0 ||
- (dhcp_client->server_duid_len > 0 &&
- memcmp(dhcp_client->server_duid, server_id,
- dhcp_client->server_duid_len) != 0)) {
- /* RFC 3315, 15.10 */
- debug(dhcp_client,
- "server duid error, discarding msg %p/%d/%d",
- server_id, option_len, count);
- return TRUE;
- }
-
- switch_listening_mode(dhcp_client, L_NONE);
-
- dhcp_client->status_code = 0;
- get_dhcpv6_request(dhcp_client, packet6, pkt_len,
- &dhcp_client->status_code);
-
- if (dhcp_client->information_req_cb != NULL) {
- /*
- * The dhcp_client might not be valid after the
- * callback call so just return immediately.
- */
- dhcp_client->information_req_cb(dhcp_client,
- dhcp_client->information_req_data);
- return TRUE;
- }
- if (dhcp_client->request_cb != NULL) {
- dhcp_client->request_cb(dhcp_client,
- dhcp_client->request_data);
- return TRUE;
- }
- if (dhcp_client->renew_cb != NULL) {
- dhcp_client->renew_cb(dhcp_client,
- dhcp_client->renew_data);
- return TRUE;
- }
- if (dhcp_client->rebind_cb != NULL) {
- dhcp_client->rebind_cb(dhcp_client,
- dhcp_client->rebind_data);
- return TRUE;
- }
- if (dhcp_client->release_cb != NULL) {
- dhcp_client->release_cb(dhcp_client,
- dhcp_client->release_data);
- return TRUE;
- }
- break;
default:
break;
}
int re;
uint32_t addr;
- if (dhcp_client->type == G_DHCP_IPV6) {
- if (dhcp_client->information_req_cb) {
- dhcp_client->state = INFORMATION_REQ;
- re = switch_listening_mode(dhcp_client, L3);
- if (re != 0) {
- switch_listening_mode(dhcp_client, L_NONE);
- dhcp_client->state = 0;
- return re;
- }
- send_information_req(dhcp_client);
-
- } else if (dhcp_client->solicitation_cb) {
- dhcp_client->state = SOLICITATION;
- re = switch_listening_mode(dhcp_client, L3);
- if (re != 0) {
- switch_listening_mode(dhcp_client, L_NONE);
- dhcp_client->state = 0;
- return re;
- }
- send_solicitation(dhcp_client);
-
- } else if (dhcp_client->request_cb) {
- dhcp_client->state = REQUEST;
- re = switch_listening_mode(dhcp_client, L3);
- if (re != 0) {
- switch_listening_mode(dhcp_client, L_NONE);
- dhcp_client->state = 0;
- return re;
- }
- send_dhcpv6_request(dhcp_client);
-
- } else if (dhcp_client->renew_cb) {
- dhcp_client->state = RENEW;
- re = switch_listening_mode(dhcp_client, L3);
- if (re != 0) {
- switch_listening_mode(dhcp_client, L_NONE);
- dhcp_client->state = 0;
- return re;
- }
- send_dhcpv6_renew(dhcp_client);
-
- } else if (dhcp_client->rebind_cb) {
- dhcp_client->state = REBIND;
- re = switch_listening_mode(dhcp_client, L3);
- if (re != 0) {
- switch_listening_mode(dhcp_client, L_NONE);
- dhcp_client->state = 0;
- return re;
- }
- send_dhcpv6_rebind(dhcp_client);
-
- } else if (dhcp_client->release_cb) {
- dhcp_client->state = RENEW;
- re = switch_listening_mode(dhcp_client, L3);
- if (re != 0) {
- switch_listening_mode(dhcp_client, L_NONE);
- dhcp_client->state = 0;
- return re;
- }
- send_dhcpv6_release(dhcp_client);
- }
-
- return 0;
- }
-
if (dhcp_client->retry_times == DISCOVER_RETRIES) {
ipv4ll_start(dhcp_client);
return 0;
return re;
dhcp_client->xid = rand();
- dhcp_client->start = time(NULL);
}
if (last_address == NULL) {
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,
dhcp_client->lease_available_data = data;
return;
case G_DHCP_CLIENT_EVENT_IPV4LL_AVAILABLE:
- if (dhcp_client->type == G_DHCP_IPV6)
- return;
dhcp_client->ipv4ll_available_cb = func;
dhcp_client->ipv4ll_available_data = data;
return;
dhcp_client->lease_lost_data = data;
return;
case G_DHCP_CLIENT_EVENT_IPV4LL_LOST:
- if (dhcp_client->type == G_DHCP_IPV6)
- return;
dhcp_client->ipv4ll_lost_cb = func;
dhcp_client->ipv4ll_lost_data = data;
return;
dhcp_client->address_conflict_cb = func;
dhcp_client->address_conflict_data = data;
return;
- case G_DHCP_CLIENT_EVENT_INFORMATION_REQ:
- if (dhcp_client->type == G_DHCP_IPV4)
- return;
- dhcp_client->information_req_cb = func;
- dhcp_client->information_req_data = data;
- return;
- case G_DHCP_CLIENT_EVENT_SOLICITATION:
- if (dhcp_client->type == G_DHCP_IPV4)
- return;
- dhcp_client->solicitation_cb = func;
- dhcp_client->solicitation_data = data;
- return;
- case G_DHCP_CLIENT_EVENT_ADVERTISE:
- if (dhcp_client->type == G_DHCP_IPV4)
- return;
- dhcp_client->advertise_cb = func;
- dhcp_client->advertise_data = data;
- return;
- case G_DHCP_CLIENT_EVENT_REQUEST:
- if (dhcp_client->type == G_DHCP_IPV4)
- return;
- dhcp_client->request_cb = func;
- dhcp_client->request_data = data;
- return;
- case G_DHCP_CLIENT_EVENT_RENEW:
- if (dhcp_client->type == G_DHCP_IPV4)
- return;
- dhcp_client->renew_cb = func;
- dhcp_client->renew_data = data;
- return;
- case G_DHCP_CLIENT_EVENT_REBIND:
- if (dhcp_client->type == G_DHCP_IPV4)
- return;
- dhcp_client->rebind_cb = func;
- dhcp_client->rebind_data = data;
- return;
- case G_DHCP_CLIENT_EVENT_RELEASE:
- if (dhcp_client->type == G_DHCP_IPV4)
- return;
- dhcp_client->release_cb = func;
- dhcp_client->release_data = data;
- return;
}
}
{
GList *option = NULL;
- if (dhcp_client->type == G_DHCP_IPV6)
- return NULL;
-
switch (dhcp_client->state) {
case IPV4LL_DEFEND:
case IPV4LL_MONITOR:
case RELEASED:
case IPV4LL_PROBE:
case IPV4LL_ANNOUNCE:
- case INFORMATION_REQ:
- case SOLICITATION:
- case REQUEST:
- case RENEW:
- case REBIND:
- case RELEASE:
break;
}
return NULL;
}
GDHCPClientError g_dhcp_client_set_request(GDHCPClient *dhcp_client,
- unsigned int option_code)
+ unsigned char option_code)
{
if (g_list_find(dhcp_client->request_list,
GINT_TO_POINTER((int) option_code)) == NULL)
return G_DHCP_CLIENT_ERROR_NONE;
}
-void g_dhcp_client_clear_requests(GDHCPClient *dhcp_client)
-{
- g_list_free(dhcp_client->request_list);
- dhcp_client->request_list = NULL;
-}
-
-void g_dhcp_client_clear_values(GDHCPClient *dhcp_client)
-{
- g_hash_table_remove_all(dhcp_client->send_value_hash);
-}
-
-static uint8_t *alloc_dhcp_option(int code, const uint8_t *data, unsigned size)
+static uint8_t *alloc_dhcp_option(int code, const char *str, int extra)
{
uint8_t *storage;
+ int len = strnlen(str, 255);
- storage = g_try_malloc(size + OPT_DATA);
- if (storage == NULL)
- return NULL;
-
+ storage = malloc(len + extra + OPT_DATA);
storage[OPT_CODE] = code;
- storage[OPT_LEN] = size;
- memcpy(&storage[OPT_DATA], data, size);
+ storage[OPT_LEN] = len + extra;
+ memcpy(storage + extra + OPT_DATA, str, len);
return storage;
}
-static uint8_t *alloc_dhcp_data_option(int code, const uint8_t *data, unsigned size)
-{
- return alloc_dhcp_option(code, data, MIN(size, 255));
-}
-
-static uint8_t *alloc_dhcp_string_option(int code, const char *str)
-{
- return alloc_dhcp_data_option(code, (const uint8_t *)str, strlen(str));
-}
-
-GDHCPClientError g_dhcp_client_set_id(GDHCPClient *dhcp_client)
-{
- const unsigned maclen = 6;
- const unsigned idlen = maclen + 1;
- const uint8_t option_code = G_DHCP_CLIENT_ID;
- uint8_t idbuf[idlen];
- uint8_t *data_option;
-
- idbuf[0] = ARPHRD_ETHER;
-
- memcpy(&idbuf[1], dhcp_client->mac_address, maclen);
-
- data_option = alloc_dhcp_data_option(option_code, idbuf, idlen);
- if (data_option == NULL)
- return G_DHCP_CLIENT_ERROR_NOMEM;
-
- g_hash_table_insert(dhcp_client->send_value_hash,
- GINT_TO_POINTER((int) option_code), data_option);
-
- return G_DHCP_CLIENT_ERROR_NONE;
-}
-
/* Now only support send hostname */
GDHCPClientError g_dhcp_client_set_send(GDHCPClient *dhcp_client,
unsigned char option_code, const char *option_value)
uint8_t *binary_option;
if (option_code == G_DHCP_HOST_NAME && option_value != NULL) {
- binary_option = alloc_dhcp_string_option(option_code,
- option_value);
- if (binary_option == NULL)
- return G_DHCP_CLIENT_ERROR_NOMEM;
+ binary_option = alloc_dhcp_option(option_code,
+ option_value, 0);
g_hash_table_insert(dhcp_client->send_value_hash,
GINT_TO_POINTER((int) option_code), binary_option);
return G_DHCP_CLIENT_ERROR_NONE;
}
-static uint8_t *alloc_dhcpv6_option(uint16_t code, uint8_t *option,
- uint16_t len)
-{
- uint8_t *storage;
-
- storage = g_malloc(2 + 2 + len);
- if (storage == NULL)
- return NULL;
-
- storage[0] = code >> 8;
- storage[1] = code & 0xff;
- storage[2] = len >> 8;
- storage[3] = len & 0xff;
- memcpy(storage + 2 + 2, option, len);
-
- return storage;
-}
-
-void g_dhcpv6_client_set_send(GDHCPClient *dhcp_client,
- uint16_t option_code,
- uint8_t *option_value,
- uint16_t option_len)
-{
- if (option_value != NULL) {
- uint8_t *binary_option;
-
- debug(dhcp_client, "setting option %d to %p len %d",
- option_code, option_value, option_len);
-
- binary_option = alloc_dhcpv6_option(option_code, option_value,
- option_len);
- if (binary_option != NULL)
- g_hash_table_insert(dhcp_client->send_value_hash,
- GINT_TO_POINTER((int) option_code),
- binary_option);
- }
-}
-
-void g_dhcpv6_client_reset_renew(GDHCPClient *dhcp_client)
-{
- if (dhcp_client == NULL || dhcp_client->type == G_DHCP_IPV4)
- return;
-
- dhcp_client->last_renew = time(NULL);
-}
-
-void g_dhcpv6_client_reset_rebind(GDHCPClient *dhcp_client)
-{
- if (dhcp_client == NULL || dhcp_client->type == G_DHCP_IPV4)
- return;
-
- dhcp_client->last_rebind = time(NULL);
-}
-
-void g_dhcpv6_client_set_expire(GDHCPClient *dhcp_client, uint32_t timeout)
-{
- if (dhcp_client == NULL || dhcp_client->type == G_DHCP_IPV4)
- return;
-
- dhcp_client->expire = time(NULL) + timeout;
-}
-
-uint16_t g_dhcpv6_client_get_status(GDHCPClient *dhcp_client)
-{
- if (dhcp_client == NULL || dhcp_client->type == G_DHCP_IPV4)
- return 0;
-
- return dhcp_client->status_code;
-}
-
GDHCPClient *g_dhcp_client_ref(GDHCPClient *dhcp_client)
{
if (dhcp_client == NULL)
g_free(dhcp_client->interface);
g_free(dhcp_client->assigned_ip);
g_free(dhcp_client->last_address);
- g_free(dhcp_client->duid);
- g_free(dhcp_client->server_duid);
g_list_free(dhcp_client->request_list);
g_list_free(dhcp_client->require_list);
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
/*
* DHCP library with GLib integration
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#endif
#include <stdio.h>
-#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
-#include <arpa/inet.h>
#include "gdhcp.h"
#include "common.h"
return i;
}
-uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len,
- int code, uint16_t *option_len, int *option_count)
-{
- int rem, count = 0;
- uint8_t *optionptr, *found = NULL;
- uint16_t opt_code, opt_len, len;
-
- optionptr = packet->options;
- rem = pkt_len - 1 - 3;
-
- if (rem <= 0)
- goto bad_packet;
-
- while (1) {
- opt_code = optionptr[0] << 8 | optionptr[1];
- opt_len = len = optionptr[2] << 8 | optionptr[3];
- len += 2 + 2; /* skip code and len */
-
- if (len < 4)
- goto bad_packet;
-
- rem -= len;
- if (rem < 0)
- break;
-
- if (opt_code == code) {
- if (option_len != NULL)
- *option_len = opt_len;
- if (rem == 0)
- found = NULL;
- else
- found = optionptr + 2 + 2;
- count++;
- }
-
- if (rem == 0)
- break;
-
- optionptr += len;
- }
-
- if (option_count != NULL)
- *option_count = count;
-
- return found;
-
-bad_packet:
- if (option_len != NULL)
- *option_len = 0;
- if (option_count != NULL)
- *option_count = 0;
- return NULL;
-}
-
-uint8_t *dhcpv6_get_sub_option(unsigned char *option, uint16_t max_len,
- uint16_t *option_code, uint16_t *option_len)
-{
- int rem;
- uint16_t code, len;
-
- rem = max_len - 2 - 2;
-
- if (rem <= 0)
- /* Bad option */
- return NULL;
-
- code = option[0] << 8 | option[1];
- len = option[2] << 8 | option[3];
-
- rem -= len;
- if (rem < 0)
- return NULL;
-
- *option_code = code;
- *option_len = len;
-
- return &option[4];
-}
-
/*
* Add an option (supplied in binary form) to the options.
* Option format: [code][len][data1][data2]..[dataLEN]
optionptr[end + len] = DHCP_END;
}
-/*
- * Add an option (supplied in binary form) to the options.
- * Option format: [code][len][data1][data2]..[dataLEN]
- */
-void dhcpv6_add_binary_option(struct dhcpv6_packet *packet, uint16_t max_len,
- uint16_t *pkt_len, uint8_t *addopt)
-{
- unsigned len;
- uint8_t *optionptr = packet->options;
-
- len = 2 + 2 + (addopt[2] << 8 | addopt[3]);
-
- /* end position + (option code/length + addopt length) */
- if (*pkt_len + len >= max_len)
- /* option did not fit into the packet */
- return;
-
- memcpy(optionptr + *pkt_len, addopt, len);
- *pkt_len += len;
-}
-
void dhcp_add_simple_option(struct dhcp_packet *packet, uint8_t code,
uint32_t data)
{
data <<= 8 * (4 - len);
#endif
- dhcp_put_unaligned(data, (uint32_t *)(option + OPT_DATA));
+ dhcp_put_unaligned(data, (uint32_t *) &option[OPT_DATA]);
dhcp_add_binary_option(packet, option);
return;
dhcp_add_simple_option(packet, DHCP_MESSAGE_TYPE, type);
}
-void dhcpv6_init_header(struct dhcpv6_packet *packet, uint8_t type)
-{
- int id;
-
- memset(packet, 0, sizeof(*packet));
-
- packet->message = type;
-
- id = random();
-
- packet->transaction_id[0] = (id >> 16) & 0xff;
- packet->transaction_id[1] = (id >> 8) & 0xff;
- packet->transaction_id[2] = id & 0xff;
-}
-
static gboolean check_vendor(uint8_t *option_vendor, const char *vendor)
{
uint8_t vendor_length = sizeof(vendor) - 1;
return n;
}
-int dhcpv6_recv_l3_packet(struct dhcpv6_packet **packet, unsigned char *buf,
- int buf_len, int fd)
-{
- int n;
-
- n = read(fd, buf, buf_len);
- if (n < 0)
- return -errno;
-
- *packet = (struct dhcpv6_packet *)buf;
-
- return n;
-}
-
/* TODO: Use glib checksum */
uint16_t dhcp_checksum(void *addr, int count)
{
return ~sum;
}
-#define IN6ADDR_ALL_DHCP_RELAY_AGENTS_AND_SERVERS_MC_INIT \
- { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0x1,0,0x2 } } } /* ff02::1:2 */
-static const struct in6_addr in6addr_all_dhcp_relay_agents_and_servers_mc =
- IN6ADDR_ALL_DHCP_RELAY_AGENTS_AND_SERVERS_MC_INIT;
-
-/* from netinet/in.h */
-struct in6_pktinfo {
- struct in6_addr ipi6_addr; /* src/dst IPv6 address */
- unsigned int ipi6_ifindex; /* send/recv interface index */
-};
-
-int dhcpv6_send_packet(int index, struct dhcpv6_packet *dhcp_pkt, int len)
-{
- struct msghdr m;
- struct iovec v;
- struct in6_pktinfo *pktinfo;
- struct cmsghdr *cmsg;
- int fd, ret;
- struct sockaddr_in6 dst;
- void *control_buf;
- size_t control_buf_len;
-
- fd = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
- if (fd < 0)
- return -errno;
-
- memset(&dst, 0, sizeof(dst));
- dst.sin6_family = AF_INET6;
- dst.sin6_port = htons(DHCPV6_SERVER_PORT);
-
- dst.sin6_addr = in6addr_all_dhcp_relay_agents_and_servers_mc;
-
- control_buf_len = CMSG_SPACE(sizeof(struct in6_pktinfo));
- control_buf = g_try_malloc0(control_buf_len);
- if (control_buf == NULL) {
- close(fd);
- return -ENOMEM;
- }
-
- memset(&m, 0, sizeof(m));
- memset(&v, 0, sizeof(v));
-
- m.msg_name = &dst;
- m.msg_namelen = sizeof(dst);
-
- v.iov_base = (char *)dhcp_pkt;
- v.iov_len = len;
- m.msg_iov = &v;
- m.msg_iovlen = 1;
-
- m.msg_control = control_buf;
- m.msg_controllen = control_buf_len;
- cmsg = CMSG_FIRSTHDR(&m);
- cmsg->cmsg_level = IPPROTO_IPV6;
- cmsg->cmsg_type = IPV6_PKTINFO;
- cmsg->cmsg_len = CMSG_LEN(sizeof(*pktinfo));
-
- pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
- memset(pktinfo, 0, sizeof(*pktinfo));
- pktinfo->ipi6_ifindex = index;
- m.msg_controllen = cmsg->cmsg_len;
-
- ret = sendmsg(fd, &m, 0);
- if (ret < 0)
- perror("DHCPv6 msg send failed");
-
- g_free(control_buf);
- close(fd);
-
- return ret;
-}
-
int dhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
uint32_t source_ip, int source_port, uint32_t dest_ip,
int dest_port, const uint8_t *dest_arp, int ifindex)
return n;
}
-int dhcp_l3_socket(int port, const char *interface, int family)
+int dhcp_l3_socket(int port, const char *interface)
{
- int fd, opt = 1, len;
- struct sockaddr_in addr4;
- struct sockaddr_in6 addr6;
- struct sockaddr *addr;
+ int fd, opt = 1;
+ struct sockaddr_in addr;
- fd = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
- if (fd < 0)
- return -errno;
+ fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
return -1;
}
- if (family == AF_INET) {
- memset(&addr4, 0, sizeof(addr4));
- addr4.sin_family = family;
- addr4.sin_port = htons(port);
- addr = (struct sockaddr *)&addr4;
- len = sizeof(addr4);
- } else if (family == AF_INET6) {
- memset(&addr6, 0, sizeof(addr6));
- addr6.sin6_family = family;
- addr6.sin6_port = htons(port);
- addr = (struct sockaddr *)&addr6;
- len = sizeof(addr6);
- } else {
- close(fd);
- return -EINVAL;
- }
-
- if (bind(fd, addr, len) != 0) {
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
close(fd);
return -1;
}
*
* DHCP client library with GLib integration
*
- * Copyright (C) 2009-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#define CLIENT_PORT 68
#define SERVER_PORT 67
-#define DHCPV6_CLIENT_PORT 546
-#define DHCPV6_SERVER_PORT 547
-#define MAX_DHCPV6_PKT_SIZE 1500
-
#define EXTEND_FOR_BUGGY_SERVERS 80
static const uint8_t MAC_BCAST_ADDR[ETH_ALEN] __attribute__((aligned(2))) = {
struct dhcp_packet data;
} __attribute__((packed));
-/* See RFC 3315 */
-struct dhcpv6_packet {
- uint8_t message;
- uint8_t transaction_id[3];
- uint8_t options[];
-} __attribute__((packed));
-
-
/* See RFC 2132 */
#define DHCP_PADDING 0x00
#define DHCP_SUBNET 0x01
#define DHCP_MINTYPE DHCPDISCOVER
#define DHCP_MAXTYPE DHCPINFORM
-/* Message types for DHCPv6, RFC 3315 sec 5.3 */
-#define DHCPV6_SOLICIT 1
-#define DHCPV6_ADVERTISE 2
-#define DHCPV6_REQUEST 3
-#define DHCPV6_CONFIRM 4
-#define DHCPV6_RENEW 5
-#define DHCPV6_REBIND 6
-#define DHCPV6_REPLY 7
-#define DHCPV6_RELEASE 8
-#define DHCPV6_DECLINE 9
-#define DHCPV6_RECONFIGURE 10
-#define DHCPV6_INFORMATION_REQ 11
-
-/*
- * DUID time starts 2000-01-01.
- */
-#define DUID_TIME_EPOCH 946684800
-
typedef enum {
OPTION_UNKNOWN,
OPTION_IP,
};
uint8_t *dhcp_get_option(struct dhcp_packet *packet, int code);
-uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len,
- int code, uint16_t *option_len, int *option_count);
-uint8_t *dhcpv6_get_sub_option(unsigned char *option, uint16_t max_len,
- uint16_t *code, uint16_t *option_len);
int dhcp_end_option(uint8_t *optionptr);
void dhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt);
-void dhcpv6_add_binary_option(struct dhcpv6_packet *packet, uint16_t max_len,
- uint16_t *pkt_len, uint8_t *addopt);
void dhcp_add_simple_option(struct dhcp_packet *packet,
uint8_t code, uint32_t data);
GDHCPOptionType dhcp_get_code_type(uint8_t code);
-GDHCPOptionType dhcpv6_get_code_type(uint16_t code);
uint16_t dhcp_checksum(void *addr, int count);
void dhcp_init_header(struct dhcp_packet *packet, char type);
-void dhcpv6_init_header(struct dhcpv6_packet *packet, uint8_t type);
int dhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
uint32_t source_ip, int source_port,
uint32_t dest_ip, int dest_port,
const uint8_t *dest_arp, int ifindex);
-int dhcpv6_send_packet(int index, struct dhcpv6_packet *dhcp_pkt, int len);
int dhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
uint32_t source_ip, int source_port,
uint32_t dest_ip, int dest_port);
-int dhcp_l3_socket(int port, const char *interface, int family);
+int dhcp_l3_socket(int port, const char *interface);
int dhcp_recv_l3_packet(struct dhcp_packet *packet, int fd);
-int dhcpv6_recv_l3_packet(struct dhcpv6_packet **packet, unsigned char *buf,
- int buf_len, int fd);
-int dhcp_l3_socket_send(int index, int port, int family);
-
char *get_interface_name(int index);
gboolean interface_is_up(int index);
*
* DHCP library with GLib integration
*
- * Copyright (C) 2009-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#ifndef __G_DHCP_H
#define __G_DHCP_H
-#include <stdint.h>
-
#include <glib.h>
#ifdef __cplusplus
G_DHCP_CLIENT_EVENT_LEASE_LOST,
G_DHCP_CLIENT_EVENT_IPV4LL_LOST,
G_DHCP_CLIENT_EVENT_ADDRESS_CONFLICT,
- G_DHCP_CLIENT_EVENT_INFORMATION_REQ,
- G_DHCP_CLIENT_EVENT_SOLICITATION,
- G_DHCP_CLIENT_EVENT_ADVERTISE,
- G_DHCP_CLIENT_EVENT_REQUEST,
- G_DHCP_CLIENT_EVENT_RENEW,
- G_DHCP_CLIENT_EVENT_REBIND,
- G_DHCP_CLIENT_EVENT_RELEASE,
} GDHCPClientEvent;
typedef enum {
#define G_DHCP_DOMAIN_NAME 0x0f
#define G_DHCP_HOST_NAME 0x0c
#define G_DHCP_NTP_SERVER 0x2a
-#define G_DHCP_CLIENT_ID 0x3d
-
-#define G_DHCPV6_CLIENTID 1
-#define G_DHCPV6_SERVERID 2
-#define G_DHCPV6_IA_NA 3
-#define G_DHCPV6_IA_TA 4
-#define G_DHCPV6_IAADDR 5
-#define G_DHCPV6_ORO 6
-#define G_DHCPV6_STATUS_CODE 13
-#define G_DHCPV6_RAPID_COMMIT 14
-#define G_DHCPV6_DNS_SERVERS 23
-#define G_DHCPV6_SNTP_SERVERS 31
-
-#define G_DHCPV6_ERROR_SUCCESS 0
-#define G_DHCPV6_ERROR_FAILURE 1
-#define G_DHCPV6_ERROR_NO_ADDR 2
-#define G_DHCPV6_ERROR_BINDING 3
-#define G_DHCPV6_ERROR_LINK 4
-#define G_DHCPV6_ERROR_MCAST 5
-
-typedef enum {
- G_DHCPV6_DUID_LLT = 1,
- G_DHCPV6_DUID_EN = 2,
- G_DHCPV6_DUID_LL = 3,
-} GDHCPDuidType;
typedef void (*GDHCPClientEventFunc) (GDHCPClient *client, gpointer user_data);
gpointer user_data);
GDHCPClientError g_dhcp_client_set_request(GDHCPClient *client,
- unsigned int option_code);
-void g_dhcp_client_clear_requests(GDHCPClient *dhcp_client);
-void g_dhcp_client_clear_values(GDHCPClient *dhcp_client);
-GDHCPClientError g_dhcp_client_set_id(GDHCPClient *client);
+ unsigned char option_code);
GDHCPClientError g_dhcp_client_set_send(GDHCPClient *client,
unsigned char option_code,
const char *option_value);
void g_dhcp_client_set_debug(GDHCPClient *client,
GDHCPDebugFunc func, gpointer user_data);
-int g_dhcpv6_create_duid(GDHCPDuidType duid_type, int index, int type,
- unsigned char **duid, int *duid_len);
-int g_dhcpv6_client_set_duid(GDHCPClient *dhcp_client, unsigned char *duid,
- int duid_len);
-void g_dhcpv6_client_set_send(GDHCPClient *dhcp_client, uint16_t option_code,
- uint8_t *option_value, uint16_t option_len);
-uint16_t g_dhcpv6_client_get_status(GDHCPClient *dhcp_client);
-int g_dhcpv6_client_set_oro(GDHCPClient *dhcp_client, int args, ...);
-void g_dhcpv6_client_create_iaid(GDHCPClient *dhcp_client, int index,
- unsigned char *iaid);
-int g_dhcpv6_client_get_timeouts(GDHCPClient *dhcp_client,
- uint32_t *T1, uint32_t *T2,
- time_t *last_renew, time_t *last_rebind,
- time_t *expire);
-uint32_t g_dhcpv6_client_get_iaid(GDHCPClient *dhcp_client);
-int g_dhcpv6_client_set_ia(GDHCPClient *dhcp_client, int index,
- int code, uint32_t *T1, uint32_t *T2, gboolean add_iaaddr);
-void g_dhcpv6_client_reset_renew(GDHCPClient *dhcp_client);
-void g_dhcpv6_client_reset_rebind(GDHCPClient *dhcp_client);
-void g_dhcpv6_client_set_expire(GDHCPClient *dhcp_client, uint32_t timeout);
+#if defined TIZEN_EXT
+void g_dhcp_client_set_address_known(GDHCPClient *client, gboolean known);
+#endif
/* DHCP Server */
typedef enum {
*
* DHCP Server library with GLib integration
*
- * Copyright (C) 2009-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
return 0;
listener_sockfd = dhcp_l3_socket(SERVER_PORT,
- dhcp_server->interface, AF_INET);
+ dhcp_server->interface);
if (listener_sockfd < 0)
return -EIO;
*
* WPA supplicant library with GLib integration
*
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* WPA supplicant library with GLib integration
*
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* WPA supplicant library with GLib integration
*
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#define G_SUPPLICANT_PAIRWISE_TKIP (1 << 1)
#define G_SUPPLICANT_PAIRWISE_CCMP (1 << 2)
-#define G_SUPPLICANT_WPS_CONFIGURED (1 << 0)
-#define G_SUPPLICANT_WPS_PBC (1 << 1)
-#define G_SUPPLICANT_WPS_PIN (1 << 2)
-#define G_SUPPLICANT_WPS_REGISTRAR (1 << 3)
+#define G_SUPPLICANT_MAX_FAST_SCAN 4
typedef enum {
G_SUPPLICANT_MODE_UNKNOWN,
const char *phase2_auth;
dbus_bool_t use_wps;
const char *pin_wps;
- const char *bgscan;
};
typedef struct _GSupplicantSSID GSupplicantSSID;
-/*
- * Max number of SSIDs that can be scanned.
- * In wpa_s 0.7x the limit is 4.
- * In wps_s 0.8 or later it is 16.
- * The value is only used if wpa_supplicant does not return any max limit
- * for number of scannable SSIDs.
- */
-#define WPAS_MAX_SCAN_SSIDS 4
-
-struct scan_ssid {
- unsigned char ssid[32];
- uint8_t ssid_len;
-};
-
struct _GSupplicantScanParams {
- GSList *ssids;
+ struct scan_ssid {
+ unsigned char ssid[32];
+ uint8_t ssid_len;
+ } ssids[G_SUPPLICANT_MAX_FAST_SCAN];
uint8_t num_ssids;
- uint16_t *freqs;
+ uint16_t freqs[G_SUPPLICANT_MAX_FAST_SCAN];
};
typedef struct _GSupplicantScanParams GSupplicantScanParams;
/* global API */
-typedef void (*GSupplicantCountryCallback) (int result,
- const char *alpha2,
- void *user_data);
+typedef void (*GSupplicantCountryCallback) (void *user_data);
int g_supplicant_set_country(const char *alpha2,
GSupplicantCountryCallback callback,
GSupplicantInterfaceCallback callback,
void *user_data);
-int g_supplicant_interface_autoscan(GSupplicantInterface *interface,
- const char *autoscan_data,
- GSupplicantInterfaceCallback callback,
- void *user_data);
-
int g_supplicant_interface_connect(GSupplicantInterface *interface,
GSupplicantSSID *ssid,
GSupplicantInterfaceCallback callback,
int g_supplicant_interface_enable_selected_network(GSupplicantInterface *interface,
dbus_bool_t enable);
-int g_supplicant_interface_set_country(GSupplicantInterface *interface,
- GSupplicantCountryCallback callback,
- const char *alpha2,
- void *user_data);
/* Network API */
struct _GSupplicantNetwork;
dbus_int16_t g_supplicant_network_get_signal(GSupplicantNetwork *network);
dbus_uint16_t g_supplicant_network_get_frequency(GSupplicantNetwork *network);
dbus_bool_t g_supplicant_network_get_wps(GSupplicantNetwork *network);
-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);
int g_supplicant_register(const GSupplicantCallbacks *callbacks);
void g_supplicant_unregister(const GSupplicantCallbacks *callbacks);
-static inline
-void g_supplicant_free_scan_params(GSupplicantScanParams *scan_params)
-{
- g_slist_free_full(scan_params->ssids, g_free);
- g_free(scan_params->freqs);
- g_free(scan_params);
-}
-
#ifdef __cplusplus
}
#endif
*
* WPA supplicant library with GLib integration
*
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
dbus_int16_t signal;
GSupplicantMode mode;
GSupplicantSecurity security;
- dbus_bool_t rsn_selected;
- unsigned int wpa_keymgmt;
- unsigned int wpa_pairwise;
- unsigned int wpa_group;
- unsigned int rsn_keymgmt;
- unsigned int rsn_pairwise;
- unsigned int rsn_group;
unsigned int keymgmt;
+ unsigned int pairwise;
+ unsigned int group;
dbus_bool_t privacy;
dbus_bool_t psk;
dbus_bool_t ieee8021x;
- unsigned int wps_capabilities;
};
struct _GSupplicantNetwork {
GSupplicantMode mode;
GSupplicantSecurity security;
dbus_bool_t wps;
- unsigned int wps_capabilities;
GHashTable *bss_table;
GHashTable *config_table;
};
g_hash_table_destroy(interface->net_mapping);
g_hash_table_destroy(interface->network_table);
- if (interface->scan_callback != NULL) {
- SUPPLICANT_DBG("call interface %p callback %p scanning %d",
- interface, interface->scan_callback,
- interface->scanning);
-
- interface->scan_callback(-EIO, interface, interface->scan_data);
- interface->scan_callback = NULL;
- interface->scan_data = NULL;
-
- if (interface->scanning == TRUE) {
- interface->scanning = FALSE;
- callback_scan_finished(interface);
- }
- }
-
callback_interface_removed(interface);
g_free(interface->wps_cred.key);
if (interface == NULL)
return 0;
- if (interface->max_scan_ssids == 0)
- return WPAS_MAX_SCAN_SSIDS;
-
return interface->max_scan_ssids;
}
return network->wps;
}
-dbus_bool_t g_supplicant_network_is_wps_active(GSupplicantNetwork *network)
+#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)
- return FALSE;
-
- if (network->wps_capabilities & G_SUPPLICANT_WPS_CONFIGURED)
- return TRUE;
+ if (network == NULL || network->best_bss == NULL)
+ return NULL;
- return FALSE;
+ return (const unsigned char *)network->best_bss->bssid;
}
-dbus_bool_t g_supplicant_network_is_wps_pbc(GSupplicantNetwork *network)
+unsigned int g_supplicant_network_get_maxrate(GSupplicantNetwork *network)
{
- if (network == NULL)
- return FALSE;
-
- if (network->wps_capabilities & G_SUPPLICANT_WPS_PBC)
- return TRUE;
+ if (network == NULL || network->best_bss == NULL)
+ return 0;
- return FALSE;
+ return network->best_bss->maxrate;
}
-dbus_bool_t g_supplicant_network_is_wps_advertizing(GSupplicantNetwork *network)
+const char *g_supplicant_network_get_enc_mode(GSupplicantNetwork *network)
{
- if (network == NULL)
- return FALSE;
+ if (network == NULL || network->best_bss == NULL)
+ return NULL;
- if (network->wps_capabilities & G_SUPPLICANT_WPS_REGISTRAR)
- return TRUE;
+ if ((network->best_bss->pairwise & G_SUPPLICANT_PAIRWISE_CCMP) &&
+ (network->best_bss->pairwise & G_SUPPLICANT_PAIRWISE_TKIP))
+ return "mixed";
+ else if (network->best_bss->pairwise & G_SUPPLICANT_PAIRWISE_CCMP)
+ return "aes";
+ else if (network->best_bss->pairwise & G_SUPPLICANT_PAIRWISE_TKIP)
+ return "tkip";
+ else if (network->best_bss->security == G_SUPPLICANT_SECURITY_WEP)
+ return "wep";
- return FALSE;
+ return "none";
}
+#endif
static void merge_network(GSupplicantNetwork *network)
{
static char *create_name(unsigned char *ssid, int ssid_len)
{
- GString *string;
- const gchar *remainder, *invalid;
- int valid_bytes, remaining_bytes;
+ char *name;
+ int i;
if (ssid_len < 1 || ssid[0] == '\0')
- return g_strdup("");
-
- string = NULL;
- remainder = (const gchar *)ssid;
- remaining_bytes = ssid_len;
-
- while (remaining_bytes != 0) {
- if (g_utf8_validate(remainder, remaining_bytes,
- &invalid) == TRUE) {
- break;
- }
-
- valid_bytes = invalid - remainder;
-
- if (string == NULL)
- string = g_string_sized_new(remaining_bytes);
-
- g_string_append_len(string, remainder, valid_bytes);
+ name = NULL;
+ else
+ name = g_try_malloc0(ssid_len + 1);
- /* append U+FFFD REPLACEMENT CHARACTER */
- g_string_append(string, "\357\277\275");
+ if (name == NULL)
+ return g_strdup("");
- remaining_bytes -= valid_bytes + 1;
- remainder = invalid + 1;
+ for (i = 0; i < ssid_len; i++) {
+ if (g_ascii_isprint(ssid[i]))
+ name[i] = ssid[i];
+ else
+ name[i] = ' ';
}
- if (string == NULL)
- return g_strndup((const gchar *)ssid, ssid_len + 1);
-
- g_string_append(string, remainder);
-
- return g_string_free(string, FALSE);
+ return name;
}
static char *create_group(struct g_supplicant_bss *bss)
return g_string_free(str, FALSE);
}
-static void add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
+static void add_bss_to_network(struct g_supplicant_bss *bss)
{
GSupplicantInterface *interface = bss->interface;
GSupplicantNetwork *network;
char *group;
group = create_group(bss);
- SUPPLICANT_DBG("New group created: %s", group);
-
if (group == NULL)
return;
network = g_hash_table_lookup(interface->network_table, group);
if (network != NULL) {
g_free(group);
- SUPPLICANT_DBG("Network %s already exist", network->name);
-
goto done;
}
network->frequency = bss->frequency;
network->best_bss = bss;
- SUPPLICANT_DBG("New network %s created", network->name);
+ network->wps = FALSE;
+ if ((bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPS) != 0)
+ network->wps = TRUE;
network->bss_table = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, remove_bss);
callback_network_added(network);
done:
- /* We update network's WPS properties if only bss provides WPS. */
- if ((bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPS) != 0) {
- network->wps = TRUE;
- network->wps_capabilities |= bss->wps_capabilities;
- }
-
if (bss->signal > network->signal) {
network->signal = bss->signal;
network->best_bss = bss;
static void bss_keymgmt(DBusMessageIter *iter, void *user_data)
{
- unsigned int *keymgmt = user_data;
+ struct g_supplicant_bss *bss = user_data;
const char *str = NULL;
int i;
for (i = 0; keymgmt_map[i].str != NULL; i++)
if (strcmp(str, keymgmt_map[i].str) == 0) {
- SUPPLICANT_DBG("Keymgmt: %s", str);
- *keymgmt |= keymgmt_map[i].val;
+ bss->keymgmt |= keymgmt_map[i].val;
break;
}
}
static void bss_group(DBusMessageIter *iter, void *user_data)
{
- unsigned int *group = user_data;
+ struct g_supplicant_bss *bss = user_data;
const char *str = NULL;
int i;
for (i = 0; group_map[i].str != NULL; i++)
if (strcmp(str, group_map[i].str) == 0) {
- SUPPLICANT_DBG("Group: %s", str);
- *group |= group_map[i].val;
+ bss->group |= group_map[i].val;
break;
}
}
static void bss_pairwise(DBusMessageIter *iter, void *user_data)
{
- unsigned int *pairwise = user_data;
+ struct g_supplicant_bss *bss = user_data;
const char *str = NULL;
int i;
for (i = 0; pairwise_map[i].str != NULL; i++)
if (strcmp(str, pairwise_map[i].str) == 0) {
- SUPPLICANT_DBG("Pairwise: %s", str);
- *pairwise |= pairwise_map[i].val;
+ bss->pairwise |= pairwise_map[i].val;
break;
}
}
static void bss_wpa(const char *key, DBusMessageIter *iter,
void *user_data)
{
- struct g_supplicant_bss *bss = user_data;
- unsigned int value = 0;
-
- SUPPLICANT_DBG("Key: %s", key);
-
- if (g_strcmp0(key, "KeyMgmt") == 0) {
- supplicant_dbus_array_foreach(iter, bss_keymgmt, &value);
-
- if (bss->rsn_selected == TRUE)
- bss->rsn_keymgmt = value;
- else
- bss->wpa_keymgmt = value;
- } else if (g_strcmp0(key, "Group") == 0) {
- supplicant_dbus_array_foreach(iter, bss_group, &value);
-
- if (bss->rsn_selected == TRUE)
- bss->rsn_group = value;
- else
- bss->wpa_group = value;
- } else if (g_strcmp0(key, "Pairwise") == 0) {
- supplicant_dbus_array_foreach(iter, bss_pairwise, &value);
-
- if (bss->rsn_selected == TRUE)
- bss->rsn_pairwise = value;
- else
- bss->wpa_pairwise = value;
- }
+ if (g_strcmp0(key, "KeyMgmt") == 0)
+ supplicant_dbus_array_foreach(iter, bss_keymgmt, user_data);
+ else if (g_strcmp0(key, "Group") == 0)
+ supplicant_dbus_array_foreach(iter, bss_group, user_data);
+ else if (g_strcmp0(key, "Pairwise") == 0)
+ supplicant_dbus_array_foreach(iter, bss_pairwise, user_data);
}
static unsigned int get_tlv(unsigned char *ie, unsigned int ie_size,
const unsigned char WPS_OUI[] = { 0x00, 0x50, 0xf2, 0x04 };
unsigned char *ie, *ie_end;
DBusMessageIter array;
- unsigned int value;
int ie_len;
#define WMM_WPA1_WPS_INFO 221
#define WPS_INFO_MIN_LEN 6
#define WPS_VERSION_TLV 0x104A
#define WPS_STATE_TLV 0x1044
-#define WPS_METHODS_TLV 0x1012
-#define WPS_REGISTRAR_TLV 0x1041
#define WPS_VERSION 0x10
-#define WPS_PBC 0x04
-#define WPS_PIN 0x00
-#define WPS_CONFIGURED 0x02
dbus_message_iter_recurse(iter, &array);
dbus_message_iter_get_fixed_array(&array, &ie, &ie_len);
if (ie == NULL || ie_len < 2)
return;
- bss->wps_capabilities = 0;
- bss->keymgmt = 0;
-
for (ie_end = ie + ie_len; ie < ie_end && ie + ie[1] + 1 <= ie_end;
ie += ie[1] + 2) {
SUPPLICANT_DBG("IE: match WPS_OUI");
- value = get_tlv(&ie[6], ie[1], WPS_STATE_TLV);
- if (get_tlv(&ie[6], ie[1], WPS_VERSION_TLV) == WPS_VERSION &&
- value != 0) {
+ if (get_tlv(&ie[6], ie[1],
+ WPS_VERSION_TLV) == WPS_VERSION &&
+ get_tlv(&ie[6], ie[1],
+ WPS_STATE_TLV) != 0)
bss->keymgmt |= G_SUPPLICANT_KEYMGMT_WPS;
-
- if (value == WPS_CONFIGURED)
- bss->wps_capabilities |=
- G_SUPPLICANT_WPS_CONFIGURED;
- }
-
- value = get_tlv(&ie[6], ie[1], WPS_METHODS_TLV);
- if (value != 0) {
- if (GUINT16_FROM_BE(value) == WPS_PBC)
- bss->wps_capabilities |= G_SUPPLICANT_WPS_PBC;
- if (GUINT16_FROM_BE(value) == WPS_PIN)
- bss->wps_capabilities |= G_SUPPLICANT_WPS_PIN;
- } else
- bss->wps_capabilities |=
- G_SUPPLICANT_WPS_PBC | G_SUPPLICANT_WPS_PIN;
-
- /* If the AP sends this it means it's advertizing
- * as a registrar and the WPS process is launched
- * on its side */
- if (get_tlv(&ie[6], ie[1], WPS_REGISTRAR_TLV) != 0)
- bss->wps_capabilities |= G_SUPPLICANT_WPS_REGISTRAR;
-
- SUPPLICANT_DBG("WPS Methods 0x%x", bss->wps_capabilities);
}
}
static void bss_compute_security(struct g_supplicant_bss *bss)
{
- /*
- * Combining RSN and WPA keymgmt
- * We combine it since parsing IEs might have set something for WPS. */
- bss->keymgmt |= bss->rsn_keymgmt | bss->wpa_keymgmt;
-
- bss->ieee8021x = FALSE;
- bss->psk = FALSE;
-
- if (bss->keymgmt &
- (G_SUPPLICANT_KEYMGMT_WPA_EAP |
- G_SUPPLICANT_KEYMGMT_WPA_FT_EAP |
- G_SUPPLICANT_KEYMGMT_WPA_EAP_256))
- bss->ieee8021x = TRUE;
-
- if (bss->keymgmt &
- (G_SUPPLICANT_KEYMGMT_WPA_PSK |
- G_SUPPLICANT_KEYMGMT_WPA_FT_PSK |
- G_SUPPLICANT_KEYMGMT_WPA_PSK_256))
- bss->psk = TRUE;
-
if (bss->ieee8021x == TRUE)
bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
else if (bss->psk == TRUE)
bss->security = G_SUPPLICANT_SECURITY_NONE;
}
-
static void bss_property(const char *key, DBusMessageIter *iter,
void *user_data)
{
if (key == NULL)
return;
+ if (g_strcmp0(key, "WPA") == 0) {
+
+ /* WPA/RSN property can be updated:
+ * - When WPS signal arrived at first with signal_bss_changed,
+ * WPA/RSN related properties should be cleared.
+ * - Consecutive WPA and RSN signals can be update properties
+ * correctly.
+ * - When bss added, it's not affect anything. */
+
+ bss->keymgmt = 0;
+ bss->group = 0;
+ bss->pairwise = 0;
+ bss->ieee8021x = FALSE;
+ bss->psk = FALSE;
+ }
+
if (g_strcmp0(key, "BSSID") == 0) {
DBusMessageIter array;
unsigned char *addr;
dbus_message_iter_get_basic(iter, &privacy);
bss->privacy = privacy;
- } else if (g_strcmp0(key, "RSN") == 0) {
- bss->rsn_selected = TRUE;
-
+ } else if ((g_strcmp0(key, "RSN") == 0) ||
+ (g_strcmp0(key, "WPA") == 0)) {
supplicant_dbus_property_foreach(iter, bss_wpa, bss);
- } else if (g_strcmp0(key, "WPA") == 0) {
- bss->rsn_selected = FALSE;
- supplicant_dbus_property_foreach(iter, bss_wpa, bss);
+ if (bss->keymgmt &
+ (G_SUPPLICANT_KEYMGMT_WPA_EAP |
+ G_SUPPLICANT_KEYMGMT_WPA_FT_EAP |
+ G_SUPPLICANT_KEYMGMT_WPA_EAP_256))
+ bss->ieee8021x = TRUE;
+
+ if (bss->keymgmt &
+ (G_SUPPLICANT_KEYMGMT_WPA_PSK |
+ G_SUPPLICANT_KEYMGMT_WPA_FT_PSK |
+ G_SUPPLICANT_KEYMGMT_WPA_PSK_256))
+ bss->psk = TRUE;
} else if (g_strcmp0(key, "IEs") == 0)
bss_process_ies(iter, bss);
else
supplicant_dbus_property_foreach(iter, bss_property, bss);
bss_compute_security(bss);
- add_or_replace_bss_to_network(bss);
+ add_bss_to_network(bss);
}
static void interface_bss_added_without_keys(DBusMessageIter *iter,
bss_property, bss);
bss_compute_security(bss);
- add_or_replace_bss_to_network(bss);
+ add_bss_to_network(bss);
}
static void update_signal(gpointer key, gpointer value,
{
GSupplicantInterface *interface;
GSupplicantNetwork *network;
- GSupplicantSecurity old_security;
struct g_supplicant_bss *bss;
SUPPLICANT_DBG("");
supplicant_dbus_property_foreach(iter, bss_property, bss);
- old_security = network->security;
bss_compute_security(bss);
- if (old_security != bss->security) {
+ if (bss->security != network->security) {
struct g_supplicant_bss *new_bss;
SUPPLICANT_DBG("New network security for %s", bss->ssid);
g_hash_table_remove(interface->network_table, network->group);
- add_or_replace_bss_to_network(new_bss);
+ add_bss_to_network(new_bss);
return;
}
struct supplicant_regdom {
GSupplicantCountryCallback callback;
- const char *alpha2;
const void *user_data;
};
DBusMessageIter *iter, void *user_data)
{
struct supplicant_regdom *regdom = user_data;
- int result = 0;
+ char *alpha2;
SUPPLICANT_DBG("Country setting result");
if (user_data == NULL)
return;
- if (error != NULL) {
+ if (error == NULL) {
+ alpha2 = (char *)regdom->user_data;
+ } else {
SUPPLICANT_DBG("Country setting failure %s", error);
- result = -EINVAL;
+ alpha2 = NULL;
}
if (regdom->callback)
- regdom->callback(result, regdom->alpha2,
- (void *) regdom->user_data);
+ regdom->callback(alpha2);
g_free(regdom);
}
static void country_params(DBusMessageIter *iter, void *user_data)
{
struct supplicant_regdom *regdom = user_data;
+ const char *country;
+
+ country = regdom->user_data;
- dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
- ®dom->alpha2);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &country);
}
int g_supplicant_set_country(const char *alpha2,
return -ENOMEM;
regdom->callback = callback;
- regdom->alpha2 = alpha2;
regdom->user_data = user_data;
return supplicant_dbus_property_set(SUPPLICANT_PATH, SUPPLICANT_INTERFACE,
regdom);
}
-int g_supplicant_interface_set_country(GSupplicantInterface *interface,
- GSupplicantCountryCallback callback,
- const char *alpha2,
- void *user_data)
-{
- struct supplicant_regdom *regdom;
-
- regdom = dbus_malloc0(sizeof(*regdom));
- if (regdom == NULL)
- return -ENOMEM;
-
- regdom->callback = callback;
- regdom->alpha2 = alpha2;
- regdom->user_data = user_data;
-
- return supplicant_dbus_property_set(interface->path,
- SUPPLICANT_INTERFACE ".Interface",
- "Country", DBUS_TYPE_STRING_AS_STRING,
- country_params, country_result,
- regdom);
-}
-
struct interface_data {
GSupplicantInterface *interface;
GSupplicantInterfaceCallback callback;
void *user_data;
};
-struct interface_autoscan_data {
- GSupplicantInterface *interface;
- GSupplicantInterfaceCallback callback;
- const char *autoscan_params;
- void *user_data;
-};
-
static void interface_create_property(const char *key, DBusMessageIter *iter,
void *user_data)
{
SUPPLICANT_DBG("");
if (error != NULL) {
- g_warning("error %s", error);
+ g_critical("error %s", error);
err = -EIO;
goto done;
}
if (error != NULL) {
SUPPLICANT_DBG("Interface not created yet");
+ err = -EIO;
goto create;
}
}
if (data != NULL && data->scan_params != NULL)
- g_supplicant_free_scan_params(data->scan_params);
+ g_free(data->scan_params);
dbus_free(data);
}
unsigned int freq;
int i;
- for (i = 0; i < scan_data->num_ssids; i++) {
+ for (i = 0; i < G_SUPPLICANT_MAX_FAST_SCAN; i++) {
freq = scan_data->freqs[i];
if (!freq)
break;
static void append_ssids(DBusMessageIter *iter, void *user_data)
{
GSupplicantScanParams *scan_data = user_data;
- GSList *list;
-
- for (list = scan_data->ssids; list; list = list->next) {
- struct scan_ssid *scan_ssid = list->data;
+ int i;
- append_ssid(iter, scan_ssid->ssid, scan_ssid->ssid_len);
- }
+ for (i = 0; i < scan_data->num_ssids; i++)
+ append_ssid(iter, scan_data->ssids[i].ssid,
+ scan_data->ssids[i].ssid_len);
}
static void supplicant_add_scan_frequency(DBusMessageIter *dict,
DBusMessageIter entry, value, array;
const char *key = "Channels";
- if (scan_params->freqs && scan_params->freqs[0] != 0) {
+ if (scan_params->freqs[0] != 0) {
dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
NULL, &entry);
return ret;
}
-static void interface_autoscan_result(const char *error,
- DBusMessageIter *iter, void *user_data)
-{
- struct interface_autoscan_data *data = user_data;
- int err = 0;
-
- if (error != NULL) {
- SUPPLICANT_DBG("error %s", error);
- err = -EIO;
- }
-
- if (data != NULL && data->callback != NULL)
- data->callback(err, data->interface, data->user_data);
-
- dbus_free(data);
-}
-
-static void interface_autoscan_params(DBusMessageIter *iter, void *user_data)
-{
- struct interface_autoscan_data *data = user_data;
-
- dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
- &data->autoscan_params);
-}
-
-int g_supplicant_interface_autoscan(GSupplicantInterface *interface,
- const char *autoscan_data,
- GSupplicantInterfaceCallback callback,
- void *user_data)
-{
- struct interface_autoscan_data *data;
- int ret;
-
- data = dbus_malloc0(sizeof(*data));
- if (data == NULL)
- return -ENOMEM;
-
- data->interface = interface;
- data->callback = callback;
- data->autoscan_params = autoscan_data;
- data->user_data = user_data;
-
- ret = supplicant_dbus_method_call(interface->path,
- SUPPLICANT_INTERFACE ".Interface", "AutoScan",
- interface_autoscan_params,
- interface_autoscan_result, data);
- if (ret < 0)
- dbus_free(data);
-
- return ret;
-}
-
static int parse_supplicant_error(DBusMessageIter *iter)
{
int err = -ECANCELED;
char *key;
- /* If the given passphrase is malformed wpa_s returns
- * "invalid message format" but this error should be interpreted as
- * invalid-key.
- */
while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
dbus_message_iter_get_basic(iter, &key);
- if (strncmp(key, "psk", 3) == 0 ||
- strncmp(key, "wep_key", 7) == 0 ||
- strcmp(key, "invalid message format") == 0) {
+ if (strncmp(key, "psk", 4) == 0 ||
+ strncmp(key, "wep_key", 7) == 0) {
err = -ENOKEY;
break;
}
return TRUE;
}
-static unsigned char hexchar2bin(char c)
-{
- if ((c >= '0') && (c <= '9'))
- return c - '0';
- else if ((c >= 'A') && (c <= 'F'))
- return c - 'A' + 10;
- else if ((c >= 'a') && (c <= 'f'))
- return c - 'a' + 10;
- else
- return c;
-}
-
-static void hexstring2bin(const char *string, unsigned char *data, size_t data_len)
-{
- size_t i;
-
- for (i = 0; i < data_len; i++)
- data[i] = (hexchar2bin(string[i * 2 + 0]) << 4 |
- hexchar2bin(string[i * 2 + 1]) << 0);
-}
-
static void add_network_security_psk(DBusMessageIter *dict,
GSupplicantSSID *ssid)
{
if (ssid->passphrase && strlen(ssid->passphrase) > 0) {
- const char *key = "psk";
-
- if (is_psk_raw_key(ssid->passphrase) == TRUE) {
- unsigned char data[32];
- unsigned char *datap = data;
-
- /* The above pointer alias is required by D-Bus because
- * with D-Bus and GCC, non-heap-allocated arrays cannot
- * be passed directly by their base pointer. */
-
- hexstring2bin(ssid->passphrase, datap, sizeof(data));
- supplicant_dbus_dict_append_fixed_array(dict,
- key, DBUS_TYPE_BYTE,
- &datap, sizeof(data));
- } else
- supplicant_dbus_dict_append_basic(dict,
- key, DBUS_TYPE_STRING,
+ if (is_psk_raw_key(ssid->passphrase) == TRUE)
+ supplicant_dbus_property_append_fixed_array(dict,
+ "psk", DBUS_TYPE_BYTE,
+ &ssid->passphrase, 64);
+ else
+ supplicant_dbus_dict_append_basic(dict, "psk",
+ DBUS_TYPE_STRING,
&ssid->passphrase);
}
}
{
char *eap_value;
+#if defined TIZEN_EXT
+ if (ssid->eap == NULL)
+#else
if (ssid->eap == NULL || ssid->identity == NULL)
+#endif
return;
if (g_strcmp0(ssid->eap, "tls") == 0) {
add_network_security_tls(dict, ssid);
} else if (g_strcmp0(ssid->eap, "peap") == 0 ||
g_strcmp0(ssid->eap, "ttls") == 0) {
+#if defined TIZEN_EXT
+ if (ssid->identity == NULL)
+ return;
+#endif
add_network_security_peap(dict, ssid);
+#if defined TIZEN_EXT
+ } else if (g_strcmp0(ssid->eap, "sim") == 0 ||
+ g_strcmp0(ssid->eap, "aka") == 0) {
+#endif
} else
return;
supplicant_dbus_dict_append_basic(dict, "eap",
DBUS_TYPE_STRING,
&eap_value);
+#if defined TIZEN_EXT
+ if (ssid->identity != NULL)
+ supplicant_dbus_dict_append_basic(dict, "identity",
+ DBUS_TYPE_STRING,
+ &ssid->identity);
+#else
supplicant_dbus_dict_append_basic(dict, "identity",
DBUS_TYPE_STRING,
&ssid->identity);
+#endif
g_free(eap_value);
}
supplicant_dbus_dict_append_basic(&dict, "frequency",
DBUS_TYPE_UINT32, &ssid->freq);
- if (ssid->bgscan != NULL)
- supplicant_dbus_dict_append_basic(&dict, "bgscan",
- DBUS_TYPE_STRING, &ssid->bgscan);
-
add_network_mode(&dict, ssid);
add_network_security(&dict, ssid);
SUPPLICANT_DBG("");
+#if defined TIZEN_EXT
+ if (error != NULL && data->callback != NULL) {
+ data->callback(-EIO, data->interface, data->user_data);
+ data->user_data = NULL;
+ }
+#else
if (error != NULL && data->callback != NULL)
data->callback(-EIO, data->interface, data->user_data);
+#endif
/* If we are disconnecting from previous WPS successful
* association. i.e.: it did not went through AddNetwork,
* and interface->network_path was never set. */
- if (data->interface->network_path == NULL) {
- dbus_free(data);
+ if (data->interface->network_path == NULL)
return;
- }
network_remove(data);
}
callback_system_killed();
if (interface_table != NULL) {
- g_hash_table_foreach(interface_table,
+ g_hash_table_foreach(interface_table,
unregister_remove_interface, NULL);
g_hash_table_destroy(interface_table);
interface_table = NULL;
*
* Web service library with GLib integration
*
- * Copyright (C) 2009-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
GIOChannel channel;
gint fd;
gnutls_certificate_credentials_t cred;
- gnutls_session_t session;
+ gnutls_session session;
gboolean established;
gboolean again;
};
return result;
}
-gboolean g_io_channel_supports_tls(void)
-{
- return TRUE;
-}
-
GIOChannel *g_io_channel_gnutls_new(int fd)
{
GIOGnuTLSChannel *gnutls_channel;
*
* Web service library with GLib integration
*
- * Copyright (C) 2009-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <glib.h>
-gboolean g_io_channel_supports_tls(void);
-
GIOChannel *g_io_channel_gnutls_new(int fd);
*
* Web service library with GLib integration
*
- * Copyright (C) 2009-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include "giognutls.h"
-gboolean g_io_channel_supports_tls(void)
-{
- return FALSE;
-}
-
GIOChannel *g_io_channel_gnutls_new(int fd)
{
return NULL;
*
* Resolver library with GLib integration
*
- * Copyright (C) 2009-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
const void *data)
{
int n = lookup->nr_results++;
- lookup->results = g_try_realloc(lookup->results,
+ lookup->results = g_realloc(lookup->results,
sizeof(struct sort_result) * (n + 1));
- if (lookup->results == NULL)
- return;
memset(&lookup->results[n], 0, sizeof(struct sort_result));
*
* Resolver library with GLib integration
*
- * Copyright (C) 2009-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Web service library with GLib integration
*
- * Copyright (C) 2009-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <stdio.h>
#include <errno.h>
-#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sys/socket.h>
-#include <sys/sendfile.h>
-#include <sys/stat.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if.h>
-#include <netinet/tcp.h>
-#include <ifaddrs.h>
#include "giognutls.h"
#include "gresolv.h"
GWebResult result;
GWebResultFunc result_func;
- GWebRouteFunc route_func;
GWebInputFunc input_func;
- int fd;
- gsize length;
- gsize offset;
gpointer user_data;
};
static void free_session(struct web_session *session)
{
- GWeb *web;
+ GWeb *web = session->web;
if (session == NULL)
return;
g_free(session->request);
- web = session->web;
if (session->resolv_action > 0)
g_resolv_cancel_lookup(web->resolv, session->resolv_action);
g_free(web);
}
-gboolean g_web_supports_tls(void)
-{
- return g_io_channel_supports_tls();
-}
-
void g_web_set_debug(GWeb *web, GWebDebugFunc func, gpointer user_data)
{
if (web == NULL)
result == TRUE ? "continue" : "stop");
}
-static inline void call_route_func(struct web_session *session)
-{
- if (session->route_func != NULL)
- session->route_func(session->address, session->addr->ai_family,
- session->web->index, session->user_data);
-}
-
static gboolean process_send_buffer(struct web_session *session)
{
- GString *buf;
+ GString *buf = session->send_buffer;
gsize count, bytes_written;
GIOStatus status;
- if (session == NULL)
- return FALSE;
-
- buf = session->send_buffer;
count = buf->len;
if (count == 0) {
if (session->request_started == TRUE &&
- session->more_data == FALSE &&
- session->fd == -1)
+ session->more_data == FALSE)
session->body_done = TRUE;
return FALSE;
return TRUE;
}
-static gboolean process_send_file(struct web_session *session)
-{
- int sk;
- off_t offset;
- ssize_t bytes_sent;
-
- if (session->fd == -1)
- return FALSE;
-
- if (session->request_started == FALSE || session->more_data == TRUE)
- return FALSE;
-
- sk = g_io_channel_unix_get_fd(session->transport_channel);
- if (sk < 0)
- return FALSE;
-
- offset = session->offset;
-
- bytes_sent = sendfile(sk, session->fd, &offset, session->length);
-
- debug(session->web, "errno: %d, bytes to send %zu / bytes sent %zu",
- errno, session->length, bytes_sent);
-
- if (bytes_sent < 0 && errno != EAGAIN)
- return FALSE;
-
- session->offset = offset;
- session->length -= bytes_sent;
-
- if (session->length == 0) {
- session->body_done = TRUE;
- return FALSE;
- }
-
- return TRUE;
-}
-
static void process_next_chunk(struct web_session *session)
{
GString *buf = session->send_buffer;
session->content_type);
if (session->input_func == NULL) {
session->more_data = FALSE;
- length = session->length;
+ length = 0;
} else
session->more_data = session->input_func(&body, &length,
session->user_data);
g_string_append_printf(buf, "%zx\r\n", length);
g_string_append_len(buf, (char *) body, length);
g_string_append(buf, "\r\n");
- } else if (session->fd == -1)
+ } else
g_string_append_len(buf, (char *) body, length);
}
}
if (process_send_buffer(session) == TRUE)
return TRUE;
- if (process_send_file(session) == TRUE)
- return TRUE;
-
if (session->request_started == FALSE) {
session->request_started = TRUE;
start_request(session);
return TRUE;
}
-static int bind_to_address(int sk, const char *interface, int family)
-{
- struct ifaddrs *ifaddr_list, *ifaddr;
- int size, err = -1;
-
- if (getifaddrs(&ifaddr_list) < 0)
- return err;
-
- for (ifaddr = ifaddr_list; ifaddr != NULL; ifaddr = ifaddr->ifa_next) {
- if (g_strcmp0(ifaddr->ifa_name, interface) != 0)
- continue;
-
- if (ifaddr->ifa_addr == NULL ||
- ifaddr->ifa_addr->sa_family != family)
- continue;
-
- switch (family) {
- case AF_INET:
- size = sizeof(struct sockaddr_in);
- break;
- case AF_INET6:
- size = sizeof(struct sockaddr_in6);
- break;
- default:
- continue;
- }
-
- err = bind(sk, (struct sockaddr *) ifaddr->ifa_addr, size);
- break;
- }
-
- freeifaddrs(ifaddr_list);
- return err;
-}
-
-static inline int bind_socket(int sk, int index, int family)
-{
- char interface[IF_NAMESIZE];
- int err;
-
- if (if_indextoname(index, interface) == NULL)
- return -1;
-
- err = setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
- interface, IF_NAMESIZE);
- if (err < 0)
- err = bind_to_address(sk, interface, family);
-
- return err;
-}
-
static int connect_session_transport(struct web_session *session)
{
GIOFlags flags;
return -EIO;
if (session->web->index > 0) {
- if (bind_socket(sk, session->web->index,
- session->addr->ai_family) < 0) {
- debug(session->web, "bind() %s", strerror(errno));
- close(sk);
- return -EIO;
+ char interface[IF_NAMESIZE];
+
+ memset(interface, 0, IF_NAMESIZE);
+
+ if (if_indextoname(session->web->index, interface) != NULL) {
+ if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
+ interface, IF_NAMESIZE) < 0) {
+ close(sk);
+ return -EIO;
+ }
+
+ debug(session->web, "Use interface %s", interface);
}
}
}
if (session->transport_channel == NULL) {
- debug(session->web, "channel missing");
close(sk);
return -ENOMEM;
}
if (connect(sk, session->addr->ai_addr,
session->addr->ai_addrlen) < 0) {
if (errno != EINPROGRESS) {
- debug(session->web, "connect() %s", strerror(errno));
close(sk);
return -EIO;
}
}
session->address = g_strdup(results[0]);
- call_route_func(session);
if (create_transport(session) < 0) {
call_result_func(session, 409);
static guint do_request(GWeb *web, const char *url,
const char *type, GWebInputFunc input,
- int fd, gsize length, GWebResultFunc func,
- GWebRouteFunc route, gpointer user_data)
+ GWebResultFunc func, gpointer user_data)
{
struct web_session *session;
session->web = web;
session->result_func = func;
- session->route_func = route;
session->input_func = input;
- session->fd = fd;
- session->length = length;
- session->offset = 0;
session->user_data = user_data;
session->receive_buffer = g_try_malloc(DEFAULT_BUFFER_SIZE);
return web->next_query_id++;
}
-guint g_web_request_get(GWeb *web, const char *url, GWebResultFunc func,
- GWebRouteFunc route, gpointer user_data)
+guint g_web_request_get(GWeb *web, const char *url,
+ GWebResultFunc func, gpointer user_data)
{
- return do_request(web, url, NULL, NULL, -1, 0, func, route, user_data);
+ return do_request(web, url, NULL, NULL, func, user_data);
}
guint g_web_request_post(GWeb *web, const char *url,
const char *type, GWebInputFunc input,
GWebResultFunc func, gpointer user_data)
{
- return do_request(web, url, type, input, -1, 0, func, NULL, user_data);
-}
-
-guint g_web_request_post_file(GWeb *web, const char *url,
- const char *type, const char *file,
- GWebResultFunc func, gpointer user_data)
-{
- struct stat st;
- int fd;
- guint ret;
-
- if (stat(file, &st) < 0)
- return 0;
-
- fd = open(file, O_RDONLY);
- if (fd < 0)
- return 0;
-
- ret = do_request(web, url, type, NULL, fd, st.st_size, func, NULL,
- user_data);
- if (ret == 0)
- close(fd);
-
- return ret;
+ return do_request(web, url, type, input, func, user_data);
}
gboolean g_web_cancel_request(GWeb *web, guint id)
*
* Web service library with GLib integration
*
- * Copyright (C) 2009-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
typedef gboolean (*GWebResultFunc)(GWebResult *result, gpointer user_data);
-typedef gboolean (*GWebRouteFunc)(const char *addr, int ai_family,
- int if_index, gpointer user_data);
-
typedef gboolean (*GWebInputFunc)(const guint8 **data, gsize *length,
gpointer user_data);
void g_web_set_debug(GWeb *web, GWebDebugFunc func, gpointer user_data);
-gboolean g_web_supports_tls(void);
-
gboolean g_web_set_proxy(GWeb *web, const char *proxy);
gboolean g_web_set_address_family(GWeb *web, int family);
gboolean g_web_get_close_connection(GWeb *web);
guint g_web_request_get(GWeb *web, const char *url,
- GWebResultFunc func, GWebRouteFunc route,
- gpointer user_data);
+ GWebResultFunc func, gpointer user_data);
guint g_web_request_post(GWeb *web, const char *url,
const char *type, GWebInputFunc input,
GWebResultFunc func, gpointer user_data);
-guint g_web_request_post_file(GWeb *web, const char *url,
- const char *type, const char *file,
- GWebResultFunc func, gpointer user_data);
gboolean g_web_cancel_request(GWeb *web, guint id);
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
dbus_bool_t connman_dbus_property_changed_basic(const char *path,
const char *interface, const char *key,
int type, void *val);
+#if defined TIZEN_EXT
+dbus_bool_t connman_dbus_service_property_changed_with_error_cause(const char *path,
+ const char *interface, const char *key1, int type1, void *val1,
+ const char *key2, int type2, void *val2);
+#endif
dbus_bool_t connman_dbus_property_changed_dict(const char *path,
const char *interface, const char *key,
connman_dbus_append_cb_t function, void *user_data);
const char *path, const char *key, int type,
connman_dbus_append_cb_t function,
void *user_data);
+#if defined TIZEN_EXT
+/*
+ * August 22nd, 2011. TIZEN
+ *
+ * This part is added to send a DBus signal which means scan is completed
+ * because scan UX of a Wi-Fi setting application has an active scan procedure
+ * and it needs scan complete signal whether success or not
+ */
+dbus_bool_t connman_dbus_scan_completed_basic(const char *path,
+ const char *interface,int type, void *val);
+#endif
static inline void connman_dbus_dict_open(DBusMessageIter *iter,
DBusMessageIter *dict)
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
struct connman_device *connman_device_create(const char *node,
enum connman_device_type type);
-
-#define connman_device_ref(device) \
- connman_device_ref_debug(device, __FILE__, __LINE__, __func__)
-
-#define connman_device_unref(device) \
- connman_device_unref_debug(device, __FILE__, __LINE__, __func__)
-
-struct connman_device *
-connman_device_ref_debug(struct connman_device *device,
- const char *file, int line, const char *caller);
-void connman_device_unref_debug(struct connman_device *device,
- const char *file, int line, const char *caller);
+struct connman_device *connman_device_ref(struct connman_device *device);
+void connman_device_unref(struct connman_device *device);
enum connman_device_type connman_device_get_type(struct connman_device *device);
void connman_device_set_index(struct connman_device *device, int index);
int connman_device_set_powered(struct connman_device *device,
connman_bool_t powered);
+#if defined TIZEN_EXT
+/*
+ * Description: It checks significant and effective Wi-Fi profiles which can make an auto-connection.
+ * It saves power consumption not to scan if there is no valid profile to make an auto-connection.
+ */
+void connman_device_significant_wifi_profile_ref(struct connman_device *device);
+connman_bool_t connman_device_significant_wifi_profile_unref_and_test(struct connman_device *device);
+
+connman_bool_t connman_device_load_significant_wifi_profile_refcount_from_storage(struct connman_device *device);
+connman_bool_t connman_device_save_significant_wifi_profile_refcount_to_storage(struct connman_device *device);
+#endif
+
int connman_device_set_scanning(struct connman_device *device,
connman_bool_t scanning);
connman_bool_t connman_device_get_scanning(struct connman_device *device);
struct connman_network *network);
void connman_device_remove_all_networks(struct connman_device *device);
+void connman_device_schedule_scan(struct connman_device *device);
+
int connman_device_register(struct connman_device *device);
void connman_device_unregister(struct connman_device *device);
void *connman_device_get_data(struct connman_device *device);
void connman_device_set_data(struct connman_device *device, void *data);
-int connman_device_set_regdom(struct connman_device *device,
- const char *alpha2);
-void connman_device_regdom_notify(struct connman_device *device,
- int result, const char *alpha2);
-
struct connman_device_driver {
const char *name;
enum connman_device_type type;
int (*disable) (struct connman_device *device);
int (*scan) (struct connman_device *device);
int (*scan_fast) (struct connman_device *device);
- int (*scan_hidden)(struct connman_device *device,
- const char *ssid, unsigned int ssid_len,
- const char *identity, const char* passphrase,
- void *user_data);
- int (*set_regdom) (struct connman_device *device,
- const char *alpha2);
};
int connman_device_driver_register(struct connman_device_driver *driver);
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
int connman_inet_set_mtu(int index, int mtu);
int connman_inet_setup_tunnel(char *tunnel, int mtu);
int connman_inet_create_tunnel(char **iface);
-int connman_inet_get_dest_addr(int index, char **dest);
-int connman_inet_ipv6_get_dest_addr(int index, char **dest);
-int connman_inet_check_ipaddress(const char *host);
-connman_bool_t connman_inet_check_hostname(const char *ptr, size_t len);
#ifdef __cplusplus
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* @short_description: Functions for IP configuration handling
*/
-struct connman_ipaddress;
+struct connman_ipaddress {
+ int family;
+ unsigned char prefixlen;
+ char *local;
+ char *peer;
+ char *broadcast;
+ char *gateway;
+};
struct connman_ipaddress *connman_ipaddress_alloc(int family);
void connman_ipaddress_free(struct connman_ipaddress *ipaddress);
struct connman_ipconfig;
+struct connman_ipconfig_ops {
+ void (*up) (struct connman_ipconfig *ipconfig);
+ void (*down) (struct connman_ipconfig *ipconfig);
+ void (*lower_up) (struct connman_ipconfig *ipconfig);
+ void (*lower_down) (struct connman_ipconfig *ipconfig);
+ void (*ip_bound) (struct connman_ipconfig *ipconfig);
+ void (*ip_release) (struct connman_ipconfig *ipconfig);
+};
+
+struct connman_ipconfig *connman_ipconfig_create(int index,
+ enum connman_ipconfig_type type);
+struct connman_ipconfig *connman_ipconfig_ref(struct connman_ipconfig *ipconfig);
+void connman_ipconfig_unref(struct connman_ipconfig *ipconfig);
+
+void *connman_ipconfig_get_data(struct connman_ipconfig *ipconfig);
+void connman_ipconfig_set_data(struct connman_ipconfig *ipconfig, void *data);
+
+int connman_ipconfig_get_index(struct connman_ipconfig *ipconfig);
+const char *connman_ipconfig_get_ifname(struct connman_ipconfig *ipconfig);
+
+void connman_ipconfig_set_ops(struct connman_ipconfig *ipconfig,
+ const struct connman_ipconfig_ops *ops);
+int connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
+ enum connman_ipconfig_method method);
+void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig);
+void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig);
+
#ifdef __cplusplus
}
#endif
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
struct connman_debug_desc {
const char *name;
const char *file;
+#if defined TIZEN_EXT
+#define CONNMAN_DEBUG_FLAG_DEFAULT (1)
+#else
#define CONNMAN_DEBUG_FLAG_DEFAULT (0)
+#endif
#define CONNMAN_DEBUG_FLAG_PRINT (1 << 0)
#define CONNMAN_DEBUG_FLAG_ALIAS (1 << 1)
unsigned int flags;
-
/*
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
struct connman_network *connman_network_create(const char *identifier,
enum connman_network_type type);
-
-#define connman_network_ref(network) \
- connman_network_ref_debug(network, __FILE__, __LINE__, __func__)
-
-#define connman_network_unref(network) \
- connman_network_unref_debug(network, __FILE__, __LINE__, __func__)
-
-struct connman_network *
-connman_network_ref_debug(struct connman_network *network,
- const char *file, int line, const char *caller);
-void connman_network_unref_debug(struct connman_network *network,
- const char *file, int line, const char *caller);
+struct connman_network *connman_network_ref(struct connman_network *network);
+void connman_network_unref(struct connman_network *network);
enum connman_network_type connman_network_get_type(struct connman_network *network);
const char *connman_network_get_identifier(struct connman_network *network);
connman_bool_t connman_network_get_associating(struct connman_network *network);
-void connman_network_clear_hidden(void *user_data);
-int connman_network_connect_hidden(struct connman_network *network,
- char *identity, char* passphrase, void *user_data);
-
void connman_network_set_ipv4_method(struct connman_network *network,
enum connman_ipconfig_method method);
void connman_network_set_ipv6_method(struct connman_network *network,
const char *nameservers);
int connman_network_set_domain(struct connman_network *network,
const char *domain);
+#if defined TIZEN_EXT
+/*
+ * Description: Telephony plug-in requires manual PROXY setting function
+ */
+int connman_network_set_proxy(struct connman_network *network,
+ const char *proxies);
+/*
+ * 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);
+
+const char *connman_network_get_ifname(struct connman_network *network);
+#endif
+
int connman_network_set_name(struct connman_network *network,
const char *name);
int connman_network_set_strength(struct connman_network *network,
connman_uint8_t strength);
connman_uint8_t connman_network_get_strength(struct connman_network *network);
+int connman_network_set_roaming(struct connman_network *network,
+ connman_bool_t roaming);
int connman_network_set_frequency(struct connman_network *network,
connman_uint16_t frequency);
connman_uint16_t connman_network_get_frequency(struct connman_network *network);
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
struct connman_provider;
struct connman_ipaddress;
-#define connman_provider_ref(provider) \
- connman_provider_ref_debug(provider, __FILE__, __LINE__, __func__)
-
-#define connman_provider_unref(provider) \
- connman_provider_unref_debug(provider, __FILE__, __LINE__, __func__)
-
-struct connman_provider *
-connman_provider_ref_debug(struct connman_provider *provider,
- const char *file, int line, const char *caller);
-void connman_provider_unref_debug(struct connman_provider *provider,
- const char *file, int line, const char *caller);
+struct connman_provider *connman_provider_ref(struct connman_provider *provider);
+void connman_provider_unref(struct connman_provider *provider);
int connman_provider_set_string(struct connman_provider *provider,
const char *key, const char *value);
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
const char *server);
int connman_resolver_remove_all(const char *interface);
+int connman_resolver_append_public_server(const char *server);
+int connman_resolver_remove_public_server(const char *server);
+
void connman_resolver_flush(void);
#ifdef __cplusplus
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
struct connman_service;
struct connman_service *connman_service_create(void);
-
-#define connman_service_ref(service) \
- connman_service_ref_debug(service, __FILE__, __LINE__, __func__)
-
-#define connman_service_unref(service) \
- connman_service_unref_debug(service, __FILE__, __LINE__, __func__)
-
-struct connman_service *
-connman_service_ref_debug(struct connman_service *service,
- const char *file, int line, const char *caller);
-void connman_service_unref_debug(struct connman_service *service,
- const char *file, int line, const char *caller);
+struct connman_service *connman_service_ref(struct connman_service *service);
+void connman_service_unref(struct connman_service *service);
enum connman_service_type connman_service_get_type(struct connman_service *service);
char *connman_service_get_interface(struct connman_service *service);
const char *connman_service_get_domainname(struct connman_service *service);
char **connman_service_get_nameservers(struct connman_service *service);
-char **connman_service_get_timeservers_config(struct connman_service *service);
-char **connman_service_get_timeservers(struct connman_service *service);
void connman_service_set_proxy_method(struct connman_service *service, enum connman_service_proxy_method method);
enum connman_service_proxy_method connman_service_get_proxy_method(struct connman_service *service);
char **connman_service_get_proxy_servers(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
+/*
+ * 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.
+ */
+
+/*
+ * Increase reference count of user-initiated packet data network connection
+ */
+void connman_service_user_initiated_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_initiated_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_initiated_pdn_connection(struct connman_service *service);
+#endif
+
#ifdef __cplusplus
}
#endif
*
* Connection Manager
*
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#ifndef __CONNMAN_SETTING_H
#define __CONNMAN_SETTING_H
-#include <connman/types.h>
-
#ifdef __cplusplus
extern "C" {
#endif
connman_bool_t connman_setting_get_bool(const char *key);
-char **connman_setting_get_string_list(const char *key);
-unsigned int *connman_setting_get_uint_list(const char *key);
-
-unsigned int connman_timeout_input_request(void);
-unsigned int connman_timeout_browser_launch(void);
#ifdef __cplusplus
}
*
* Connection Manager
*
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
extern "C" {
#endif
-int __connman_timeserver_system_set(char **server);
+#define CONNMAN_TIMESERVER_PRIORITY_LOW -100
+#define CONNMAN_TIMESERVER_PRIORITY_DEFAULT 0
+#define CONNMAN_TIMESERVER_PRIORITY_HIGH 100
+
+/**
+ * SECTION:timeserver
+ * @title: timeserver premitives
+ * @short_description: Functions for handling time servers (including NTP)
+ */
+
+int connman_timeserver_append(const char *server);
+int connman_timeserver_remove(const char *server);
+void connman_timeserver_sync(void);
+
+struct connman_timeserver_driver {
+ const char *name;
+ int priority;
+ int (*append) (const char *server);
+ int (*remove) (const char *server);
+ void (*sync) (void);
+};
+
+int connman_timeserver_driver_register(struct connman_timeserver_driver *driver);
+void connman_timeserver_driver_unregister(struct connman_timeserver_driver *driver);
#ifdef __cplusplus
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
--- /dev/null
+#sbs-git:pkgs/c/connman connman 0.78.4
+
+Name: connman
+Summary: Connection Manager
+Version: 0.78.4_90
+Release: 1
+Group: System/Network
+License: GNU General Public License version 2
+URL: http://connman.net
+Source0: %{name}-%{version}.tar.gz
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(dbus-1)
+BuildRequires: pkgconfig(xtables)
+BuildRequires: pkgconfig(libiptc)
+
+%description
+Connection Manager provides a daemon for managing Internet connections
+within embedded devices running the Linux operating system.
+
+%prep
+%setup -q
+
+
+%build
+
+./autogen.sh
+
+./configure --prefix=/usr \
+ --localstatedir=/var \
+ --enable-tizen-ext
+
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+mkdir -p %{buildroot}/var/lib/connman
+cp resources/var/lib/connman/settings %{buildroot}/var/lib/connman/settings
+mkdir -p %{buildroot}/usr/share/dbus-1/services
+cp resources/usr/share/dbus-1/services/net.connman.service %{buildroot}/usr/share/dbus-1/services/net.connman.service
+mkdir -p %{buildroot}/usr/etc/connman
+cp src/main.conf %{buildroot}/usr/etc/connman/main.conf
+mkdir -p %{buildroot}/etc/rc.d/init.d
+cp resources/etc/rc.d/init.d/connman %{buildroot}/etc/rc.d/init.d/connman
+mkdir -p %{buildroot}/etc/rc.d/rc3.d
+ln -s ../init.d/connman %{buildroot}/etc/rc.d/rc3.d/S61connman
+mkdir -p %{buildroot}/etc/rc.d/rc5.d
+ln -s ../init.d/connman %{buildroot}/etc/rc.d/rc5.d/S61connman
+
+rm -rf %{buildroot}/usr/include/
+rm -rf %{buildroot}/usr/lib/pkgconfig/
+rm %{buildroot}/etc/dbus-1/system.d/*.conf
+
+mkdir -p %{buildroot}/usr/etc/dbus-1/system.d/
+cp src/connman.conf %{buildroot}/usr/etc/dbus-1/system.d/
+
+
+%post
+#Resource
+chmod 600 /var/lib/connman/settings
+
+
+%files
+%defattr(-,root,root,-)
+#%doc AUTHORS COPYING INSTALL ChangeLog NEWS README
+%{_sbindir}/*
+%{_var}/lib/connman/settings
+%{_libdir}/connman/plugins/*.so
+%{_datadir}/dbus-1/services/*
+%{_prefix}/etc/dbus-1/system.d/*
+%{_prefix}/etc/connman/main.conf
+%{_sysconfdir}/rc.d/init.d/connman
+%{_sysconfdir}/rc.d/rc3.d/S61connman
+%{_sysconfdir}/rc.d/rc5.d/S61connman
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
connman_network_set_group(network, ident);
- g_hash_table_replace(bluetooth_networks, g_strdup(path), network);
+ g_hash_table_insert(bluetooth_networks, g_strdup(path), network);
done:
dbus_message_unref(reply);
static int bluetooth_probe(struct connman_device *device)
{
- GHashTableIter iter;
- gpointer key, value;
-
DBG("device %p", device);
- if (bluetooth_devices == NULL)
- return -ENOTSUP;
-
- g_hash_table_iter_init(&iter, bluetooth_devices);
-
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- struct connman_device *device_pan = value;
-
- if (device == device_pan)
- return 0;
- }
-
- return -ENOTSUP;
+ return 0;
}
static void bluetooth_remove(struct connman_device *device)
watch = g_dbus_add_service_watch(connection, BLUEZ_SERVICE,
bluetooth_connect, bluetooth_disconnect, NULL, NULL);
- added_watch = g_dbus_add_signal_watch(connection, BLUEZ_SERVICE, NULL,
+ added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
BLUEZ_MANAGER_INTERFACE,
ADAPTER_ADDED, adapter_added,
NULL, NULL);
- removed_watch = g_dbus_add_signal_watch(connection, BLUEZ_SERVICE, NULL,
+ removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
BLUEZ_MANAGER_INTERFACE,
ADAPTER_REMOVED, adapter_removed,
NULL, NULL);
- adapter_watch = g_dbus_add_signal_watch(connection, BLUEZ_SERVICE,
- NULL, BLUEZ_ADAPTER_INTERFACE,
+ adapter_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ BLUEZ_ADAPTER_INTERFACE,
PROPERTY_CHANGED, adapter_changed,
NULL, NULL);
- device_removed_watch = g_dbus_add_signal_watch(connection,
- BLUEZ_SERVICE, NULL,
+ device_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
BLUEZ_ADAPTER_INTERFACE,
DEVICE_REMOVED, device_removed,
NULL, NULL);
- device_watch = g_dbus_add_signal_watch(connection, BLUEZ_SERVICE, NULL,
+ device_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
BLUEZ_DEVICE_INTERFACE,
PROPERTY_CHANGED, device_changed,
NULL, NULL);
- network_watch = g_dbus_add_signal_watch(connection, BLUEZ_SERVICE,
- NULL, BLUEZ_NETWORK_INTERFACE,
+ network_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ BLUEZ_NETWORK_INTERFACE,
PROPERTY_CHANGED, network_changed,
NULL, NULL);
+++ /dev/null
-/*
- *
- * Connection Manager
- *
- * Copyright (C) 2012 BMW Car IT GmbH. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <errno.h>
-
-#include <gdbus.h>
-
-#define CONNMAN_API_SUBJECT_TO_CHANGE
-#include <connman/plugin.h>
-#include <connman/device.h>
-#include <connman/network.h>
-#include <connman/inet.h>
-#include <connman/dbus.h>
-
-#define DUNDEE_SERVICE "org.ofono.dundee"
-#define DUNDEE_MANAGER_INTERFACE DUNDEE_SERVICE ".Manager"
-#define DUNDEE_DEVICE_INTERFACE DUNDEE_SERVICE ".Device"
-
-#define DEVICE_ADDED "DeviceAdded"
-#define DEVICE_REMOVED "DeviceRemoved"
-#define PROPERTY_CHANGED "PropertyChanged"
-
-#define GET_PROPERTIES "GetProperties"
-#define SET_PROPERTY "SetProperty"
-#define GET_DEVICES "GetDevices"
-
-#define TIMEOUT 40000
-
-static DBusConnection *connection;
-
-static GHashTable *dundee_devices = NULL;
-
-struct dundee_data {
- char *path;
- char *name;
-
- struct connman_device *device;
- struct connman_network *network;
-
- connman_bool_t active;
-
- int index;
-
- /* IPv4 Settings */
- enum connman_ipconfig_method method;
- struct connman_ipaddress *address;
- char *nameservers;
-
- DBusPendingCall *call;
-};
-
-static char *get_ident(const char *path)
-{
- char *pos;
-
- if (*path != '/')
- return NULL;
-
- pos = strrchr(path, '/');
- if (pos == NULL)
- return NULL;
-
- return pos + 1;
-}
-
-static void create_device(struct dundee_data *info)
-{
- struct connman_device *device;
- char *ident;
-
- DBG("%s", info->path);
-
- ident = g_strdup(get_ident(info->path));
- device = connman_device_create(ident, CONNMAN_DEVICE_TYPE_BLUETOOTH);
- if (device == NULL)
- goto out;
-
- DBG("device %p", device);
-
- connman_device_set_ident(device, ident);
-
- connman_device_set_string(device, "Path", info->path);
-
- connman_device_set_data(device, info);
-
- if (connman_device_register(device) < 0) {
- connman_error("Failed to register DUN device");
- connman_device_unref(device);
- goto out;
- }
-
- info->device = device;
-
-out:
- g_free(ident);
-}
-
-static void destroy_device(struct dundee_data *info)
-{
- connman_device_set_powered(info->device, FALSE);
-
- if (info->call != NULL)
- dbus_pending_call_cancel(info->call);
-
- if (info->network != NULL) {
- connman_device_remove_network(info->device, info->network);
- connman_network_unref(info->network);
- info->network = NULL;
- }
-
- connman_device_unregister(info->device);
- connman_device_unref(info->device);
-
- info->device = NULL;
-}
-
-static void device_destroy(gpointer data)
-{
- struct dundee_data *info = data;
-
- if (info->device != NULL)
- destroy_device(info);
-
- g_free(info->path);
- g_free(info->name);
-
- g_free(info);
-}
-
-static void create_network(struct dundee_data *info)
-{
- struct connman_network *network;
- const char *group;
-
- DBG("%s", info->path);
-
- network = connman_network_create(info->path,
- CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN);
- if (network == NULL)
- return;
-
- DBG("network %p", network);
-
- connman_network_set_data(network, info);
-
- connman_network_set_string(network, "Path",
- info->path);
-
- connman_network_set_name(network, info->name);
-
- group = get_ident(info->path);
- connman_network_set_group(network, group);
-
- connman_network_set_available(network, TRUE);
-
- if (connman_device_add_network(info->device, network) < 0) {
- connman_network_unref(network);
- return;
- }
-
- info->network = network;
-}
-
-static void set_connected(struct dundee_data *info)
-{
- DBG("%s", info->path);
-
- connman_inet_ifup(info->index);
-
- connman_network_set_index(info->network, info->index);
- connman_network_set_ipv4_method(info->network,
- CONNMAN_IPCONFIG_METHOD_FIXED);
- connman_network_set_ipaddress(info->network, info->address);
- connman_network_set_nameservers(info->network, info->nameservers);
-
- connman_network_set_connected(info->network, TRUE);
-}
-
-static void set_disconnected(struct dundee_data *info)
-{
- DBG("%s", info->path);
-
- connman_network_set_connected(info->network, FALSE);
- connman_inet_ifdown(info->index);
-}
-
-static void set_property_reply(DBusPendingCall *call, void *user_data)
-{
- struct dundee_data *info = user_data;
- DBusMessage *reply;
- DBusError error;
-
- DBG("%s", info->path);
-
- info->call = NULL;
-
- dbus_error_init(&error);
-
- reply = dbus_pending_call_steal_reply(call);
-
- if (dbus_set_error_from_message(&error, reply)) {
- connman_error("Failed to change property: %s %s %s",
- info->path, error.name, error.message);
- dbus_error_free(&error);
-
- connman_network_set_error(info->network,
- CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
- }
-
- dbus_message_unref(reply);
-
- dbus_pending_call_unref(call);
-}
-
-static int set_property(struct dundee_data *info,
- const char *property, int type, void *value)
-{
- DBusMessage *message;
- DBusMessageIter iter;
-
- DBG("%s %s", info->path, property);
-
- message = dbus_message_new_method_call(DUNDEE_SERVICE, info->path,
- DUNDEE_DEVICE_INTERFACE, SET_PROPERTY);
- if (message == NULL)
- return -ENOMEM;
-
- dbus_message_iter_init_append(message, &iter);
- connman_dbus_property_append_basic(&iter, property, type, value);
-
- if (dbus_connection_send_with_reply(connection, message,
- &info->call, TIMEOUT) == FALSE) {
- connman_error("Failed to change property: %s %s",
- info->path, property);
- dbus_message_unref(message);
- return -EINVAL;
- }
-
- if (info->call == NULL) {
- connman_error("D-Bus connection not available");
- dbus_message_unref(message);
- return -EINVAL;
- }
-
- dbus_pending_call_set_notify(info->call, set_property_reply,
- info, NULL);
-
- dbus_message_unref(message);
-
- return -EINPROGRESS;
-}
-
-static int device_set_active(struct dundee_data *info)
-{
- dbus_bool_t active = TRUE;
-
- DBG("%s", info->path);
-
- return set_property(info, "Active", DBUS_TYPE_BOOLEAN,
- &active);
-}
-
-static int device_set_inactive(struct dundee_data *info)
-{
- dbus_bool_t active = FALSE;
- int err;
-
- DBG("%s", info->path);
-
- err = set_property(info, "Active", DBUS_TYPE_BOOLEAN,
- &active);
- if (err == -EINPROGRESS)
- return 0;
-
- return err;
-}
-
-static int network_probe(struct connman_network *network)
-{
- DBG("network %p", network);
-
- return 0;
-}
-
-static void network_remove(struct connman_network *network)
-{
- DBG("network %p", network);
-}
-
-static int network_connect(struct connman_network *network)
-{
- struct dundee_data *info = connman_network_get_data(network);
-
- DBG("network %p", network);
-
- return device_set_active(info);
-}
-
-static int network_disconnect(struct connman_network *network)
-{
- struct dundee_data *info = connman_network_get_data(network);
-
- DBG("network %p", network);
-
- return device_set_inactive(info);
-}
-
-static struct connman_network_driver network_driver = {
- .name = "network",
- .type = CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN,
- .probe = network_probe,
- .remove = network_remove,
- .connect = network_connect,
- .disconnect = network_disconnect,
-};
-
-static int dundee_probe(struct connman_device *device)
-{
- GHashTableIter iter;
- gpointer key, value;
-
- DBG("device %p", device);
-
- if (dundee_devices == NULL)
- return -ENOTSUP;
-
- g_hash_table_iter_init(&iter, dundee_devices);
-
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- struct dundee_data *info = value;
-
- if (device == info->device)
- return 0;
- }
-
- return -ENOTSUP;
-}
-
-static void dundee_remove(struct connman_device *device)
-{
- DBG("device %p", device);
-}
-
-static int dundee_enable(struct connman_device *device)
-{
- DBG("device %p", device);
-
- return 0;
-}
-
-static int dundee_disable(struct connman_device *device)
-{
- DBG("device %p", device);
-
- return 0;
-}
-
-static struct connman_device_driver dundee_driver = {
- .name = "dundee",
- .type = CONNMAN_DEVICE_TYPE_BLUETOOTH,
- .probe = dundee_probe,
- .remove = dundee_remove,
- .enable = dundee_enable,
- .disable = dundee_disable,
-};
-
-static char *extract_nameservers(DBusMessageIter *array)
-{
- DBusMessageIter entry;
- char *nameservers = NULL;
- char *tmp;
-
- dbus_message_iter_recurse(array, &entry);
-
- while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
- const char *nameserver;
-
- dbus_message_iter_get_basic(&entry, &nameserver);
-
- if (nameservers == NULL) {
- nameservers = g_strdup(nameserver);
- } else {
- tmp = nameservers;
- nameservers = g_strdup_printf("%s %s", tmp, nameserver);
- g_free(tmp);
- }
-
- dbus_message_iter_next(&entry);
- }
-
- return nameservers;
-}
-
-static void extract_settings(DBusMessageIter *array,
- struct dundee_data *info)
-{
- DBusMessageIter dict;
- char *address = NULL, *gateway = NULL;
- char *nameservers = NULL;
- const char *interface = NULL;
- int index = -1;
-
- if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
- return;
-
- dbus_message_iter_recurse(array, &dict);
-
- while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
- DBusMessageIter entry, value;
- const char *key, *val;
-
- dbus_message_iter_recurse(&dict, &entry);
- dbus_message_iter_get_basic(&entry, &key);
-
- dbus_message_iter_next(&entry);
- dbus_message_iter_recurse(&entry, &value);
-
- if (g_str_equal(key, "Interface") == TRUE) {
- dbus_message_iter_get_basic(&value, &interface);
-
- DBG("Interface %s", interface);
-
- index = connman_inet_ifindex(interface);
-
- DBG("index %d", index);
-
- if (index < 0)
- break;
- } else if (g_str_equal(key, "Address") == TRUE) {
- dbus_message_iter_get_basic(&value, &val);
-
- address = g_strdup(val);
-
- DBG("Address %s", address);
- } else if (g_str_equal(key, "DomainNameServers") == TRUE) {
- nameservers = extract_nameservers(&value);
-
- DBG("Nameservers %s", nameservers);
- } else if (g_str_equal(key, "Gateway") == TRUE) {
- dbus_message_iter_get_basic(&value, &val);
-
- gateway = g_strdup(val);
-
- DBG("Gateway %s", gateway);
- }
-
- dbus_message_iter_next(&dict);
- }
-
- if (index < 0)
- goto out;
-
- info->address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV4);
- if (info->address == NULL)
- goto out;
-
- info->index = index;
- connman_ipaddress_set_ipv4(info->address, address, NULL, gateway);
-
- info->nameservers = nameservers;
-
-out:
- if (info->nameservers != nameservers)
- g_free(nameservers);
-
- g_free(address);
- g_free(gateway);
-}
-
-static gboolean device_changed(DBusConnection *connection,
- DBusMessage *message,
- void *user_data)
-{
- const char *path = dbus_message_get_path(message);
- struct dundee_data *info = NULL;
- DBusMessageIter iter, value;
- const char *key;
- const char *signature = DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING;
-
- if (dbus_message_has_signature(message, signature) == FALSE) {
- connman_error("dundee signature does not match");
- return TRUE;
- }
-
- info = g_hash_table_lookup(dundee_devices, path);
- if (info == NULL)
- return TRUE;
-
- if (dbus_message_iter_init(message, &iter) == FALSE)
- return TRUE;
-
- dbus_message_iter_get_basic(&iter, &key);
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_recurse(&iter, &value);
-
- /*
- * Dundee guarantees the ordering of Settings and
- * Active. Settings will always be send before Active = True.
- * That means we don't have to order here.
- */
- if (g_str_equal(key, "Active") == TRUE) {
- dbus_message_iter_get_basic(&value, &info->active);
-
- DBG("%s Active %d", info->path, info->active);
-
- if (info->active == TRUE)
- set_connected(info);
- else
- set_disconnected(info);
- } else if (g_str_equal(key, "Settings") == TRUE) {
- DBG("%s Settings", info->path);
-
- extract_settings(&value, info);
- } else if (g_str_equal(key, "Name") == TRUE) {
- char *name;
-
- dbus_message_iter_get_basic(&value, &name);
-
- g_free(info->name);
- info->name = g_strdup(name);
-
- DBG("%s Name %s", info->path, info->name);
-
- connman_network_set_name(info->network, info->name);
- connman_network_update(info->network);
- }
-
- return TRUE;
-}
-
-static void add_device(const char *path, DBusMessageIter *properties)
-{
- struct dundee_data *info;
-
- info = g_hash_table_lookup(dundee_devices, path);
- if (info != NULL)
- return;
-
- info = g_try_new0(struct dundee_data, 1);
- if (info == NULL)
- return;
-
- info->path = g_strdup(path);
-
- while (dbus_message_iter_get_arg_type(properties) ==
- DBUS_TYPE_DICT_ENTRY) {
- DBusMessageIter entry, value;
- const char *key;
-
- dbus_message_iter_recurse(properties, &entry);
- dbus_message_iter_get_basic(&entry, &key);
-
- dbus_message_iter_next(&entry);
- dbus_message_iter_recurse(&entry, &value);
-
- if (g_str_equal(key, "Active") == TRUE) {
- dbus_message_iter_get_basic(&value, &info->active);
-
- DBG("%s Active %d", info->path, info->active);
- } else if (g_str_equal(key, "Settings") == TRUE) {
- DBG("%s Settings", info->path);
-
- extract_settings(&value, info);
- } else if (g_str_equal(key, "Name") == TRUE) {
- char *name;
-
- dbus_message_iter_get_basic(&value, &name);
-
- info->name = g_strdup(name);
-
- DBG("%s Name %s", info->path, info->name);
- }
-
- dbus_message_iter_next(properties);
- }
-
- g_hash_table_insert(dundee_devices, g_strdup(path), info);
-
- create_device(info);
- create_network(info);
-
- if (info->active == TRUE)
- set_connected(info);
-}
-
-static gboolean device_added(DBusConnection *connection, DBusMessage *message,
- void *user_data)
-{
- DBusMessageIter iter, properties;
- const char *path;
- const char *signature = DBUS_TYPE_OBJECT_PATH_AS_STRING
- DBUS_TYPE_ARRAY_AS_STRING
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
-
- if (dbus_message_has_signature(message, signature) == FALSE) {
- connman_error("dundee signature does not match");
- return TRUE;
- }
-
- DBG("");
-
- if (dbus_message_iter_init(message, &iter) == FALSE)
- return TRUE;
-
- dbus_message_iter_get_basic(&iter, &path);
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_recurse(&iter, &properties);
-
- add_device(path, &properties);
-
- return TRUE;
-}
-
-static void remove_device(DBusConnection *connection, const char *path)
-{
- DBG("path %s", path);
-
- g_hash_table_remove(dundee_devices, path);
-}
-
-static gboolean device_removed(DBusConnection *connection, DBusMessage *message,
- void *user_data)
-{
- const char *path;
- const char *signature = DBUS_TYPE_OBJECT_PATH_AS_STRING;
-
- if (dbus_message_has_signature(message, signature) == FALSE) {
- connman_error("dundee signature does not match");
- return TRUE;
- }
-
- dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID);
- remove_device(connection, path);
- return TRUE;
-}
-
-static void manager_get_devices_reply(DBusPendingCall *call, void *user_data)
-{
- DBusMessage *reply;
- DBusError error;
- DBusMessageIter array, dict;
- const char *signature = DBUS_TYPE_ARRAY_AS_STRING
- DBUS_STRUCT_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_OBJECT_PATH_AS_STRING
- DBUS_TYPE_ARRAY_AS_STRING
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING
- DBUS_STRUCT_END_CHAR_AS_STRING;
-
- DBG("");
-
- reply = dbus_pending_call_steal_reply(call);
-
- if (dbus_message_has_signature(reply, signature) == FALSE) {
- connman_error("dundee signature does not match");
- goto done;
- }
-
- dbus_error_init(&error);
-
- if (dbus_set_error_from_message(&error, reply) == TRUE) {
- connman_error("%s", error.message);
- dbus_error_free(&error);
- goto done;
- }
-
- if (dbus_message_iter_init(reply, &array) == FALSE)
- goto done;
-
- dbus_message_iter_recurse(&array, &dict);
-
- while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_STRUCT) {
- DBusMessageIter value, properties;
- const char *path;
-
- dbus_message_iter_recurse(&dict, &value);
- dbus_message_iter_get_basic(&value, &path);
-
- dbus_message_iter_next(&value);
- dbus_message_iter_recurse(&value, &properties);
-
- add_device(path, &properties);
-
- dbus_message_iter_next(&dict);
- }
-
-done:
- dbus_message_unref(reply);
-
- dbus_pending_call_unref(call);
-}
-
-static int manager_get_devices(void)
-{
- DBusMessage *message;
- DBusPendingCall *call;
-
- DBG("");
-
- message = dbus_message_new_method_call(DUNDEE_SERVICE, "/",
- DUNDEE_MANAGER_INTERFACE, GET_DEVICES);
- if (message == NULL)
- return -ENOMEM;
-
- if (dbus_connection_send_with_reply(connection, message,
- &call, TIMEOUT) == FALSE) {
- connman_error("Failed to call GetDevices()");
- dbus_message_unref(message);
- return -EINVAL;
- }
-
- if (call == NULL) {
- connman_error("D-Bus connection not available");
- dbus_message_unref(message);
- return -EINVAL;
- }
-
- dbus_pending_call_set_notify(call, manager_get_devices_reply,
- NULL, NULL);
-
- dbus_message_unref(message);
-
- return -EINPROGRESS;
-}
-
-static void dundee_connect(DBusConnection *connection, void *user_data)
-{
- DBG("connection %p", connection);
-
- dundee_devices = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, device_destroy);
-
- manager_get_devices();
-}
-
-static void dundee_disconnect(DBusConnection *connection, void *user_data)
-{
- DBG("connection %p", connection);
-
- g_hash_table_destroy(dundee_devices);
- dundee_devices = NULL;
-}
-
-static guint watch;
-static guint added_watch;
-static guint removed_watch;
-static guint device_watch;
-
-static int dundee_init(void)
-{
- int err;
-
- connection = connman_dbus_get_connection();
- if (connection == NULL)
- return -EIO;
-
- watch = g_dbus_add_service_watch(connection, DUNDEE_SERVICE,
- dundee_connect, dundee_disconnect, NULL, NULL);
-
- added_watch = g_dbus_add_signal_watch(connection, DUNDEE_SERVICE, NULL,
- DUNDEE_MANAGER_INTERFACE,
- DEVICE_ADDED, device_added,
- NULL, NULL);
-
- removed_watch = g_dbus_add_signal_watch(connection, DUNDEE_SERVICE,
- NULL, DUNDEE_MANAGER_INTERFACE,
- DEVICE_REMOVED, device_removed,
- NULL, NULL);
-
- device_watch = g_dbus_add_signal_watch(connection, DUNDEE_SERVICE,
- NULL, DUNDEE_DEVICE_INTERFACE,
- PROPERTY_CHANGED,
- device_changed,
- NULL, NULL);
-
-
- if (watch == 0 || added_watch == 0 || removed_watch == 0 ||
- device_watch == 0) {
- err = -EIO;
- goto remove;
- }
-
- err = connman_network_driver_register(&network_driver);
- if (err < 0)
- goto remove;
-
- err = connman_device_driver_register(&dundee_driver);
- if (err < 0) {
- connman_network_driver_unregister(&network_driver);
- goto remove;
- }
-
- return 0;
-
-remove:
- g_dbus_remove_watch(connection, watch);
- g_dbus_remove_watch(connection, added_watch);
- g_dbus_remove_watch(connection, removed_watch);
- g_dbus_remove_watch(connection, device_watch);
-
- dbus_connection_unref(connection);
-
- return err;
-}
-
-static void dundee_exit(void)
-{
- g_dbus_remove_watch(connection, watch);
- g_dbus_remove_watch(connection, added_watch);
- g_dbus_remove_watch(connection, removed_watch);
- g_dbus_remove_watch(connection, device_watch);
-
- connman_device_driver_unregister(&dundee_driver);
- connman_network_driver_unregister(&network_driver);
-
- dbus_connection_unref(connection);
-}
-
-CONNMAN_PLUGIN_DEFINE(dundee, "Dundee plugin", VERSION,
- CONNMAN_PLUGIN_PRIORITY_DEFAULT, dundee_init, dundee_exit)
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
{
DBG("network %p", network);
- connman_network_set_connected(network, TRUE);
-
return 0;
}
{
DBG("network %p", network);
- connman_network_set_connected(network, FALSE);
-
return 0;
}
.disconnect = cable_disconnect,
};
+#if defined TIZEN_EXT
+static void set_proxy(struct connman_network *network)
+{
+ const char http_proxy[] = "http_proxy";
+ char *proxy = NULL;
+
+ proxy = getenv(http_proxy);
+ DBG("Get system proxy: %s", proxy);
+
+ if(proxy != NULL && strlen(proxy) > 8)
+ connman_network_set_proxy(network, proxy);
+}
+#endif
+
static void add_network(struct connman_device *device,
struct ethernet_data *ethernet)
{
connman_network_set_group(network, "cable");
+ connman_network_set_connected(network, TRUE);
+
+#if defined TIZEN_EXT
+ set_proxy(network);
+#endif
+
ethernet->network = network;
}
.set_tethering = tech_set_tethering,
};
+#if defined TIZEN_EXT
static int eth_probe(struct connman_technology *technology)
{
return 0;
.probe = eth_probe,
.remove = eth_remove,
};
+#endif
static int ethernet_init(void)
{
int err;
+#if defined TIZEN_EXT
err = connman_technology_driver_register(ð_driver);
if (err < 0)
return err;
+#endif
err = connman_network_driver_register(&cable_driver);
if (err < 0)
static void ethernet_exit(void)
{
+#if defined TIZEN_EXT
connman_technology_driver_unregister(ð_driver);
+#endif
connman_technology_driver_unregister(&tech_driver);
--- /dev/null
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#define CONNMAN_API_SUBJECT_TO_CHANGE
+#include <connman/plugin.h>
+#include <connman/device.h>
+#include <connman/log.h>
+
+static void create_network(struct connman_device *device, const char *name)
+{
+ struct connman_network *network;
+
+ network = connman_network_create(name, CONNMAN_NETWORK_TYPE_VENDOR);
+ if (network == NULL)
+ return;
+
+ connman_network_register(network);
+
+ connman_device_add_network(device, network);
+ connman_network_unref(network);
+}
+
+static int device_probe(struct connman_device *device)
+{
+ DBG("");
+
+ return 0;
+}
+
+static void device_remove(struct connman_device *device)
+{
+ DBG("");
+}
+
+static int device_enable(struct connman_device *device)
+{
+ DBG("");
+
+ create_network(device, "network_one");
+ create_network(device, "network_two");
+
+ return 0;
+}
+
+static int device_disable(struct connman_device *device)
+{
+ DBG("");
+
+ return 0;
+}
+
+static struct connman_device_driver device_driver = {
+ .name = "fake",
+ .type = CONNMAN_DEVICE_TYPE_VENDOR,
+ .probe = device_probe,
+ .remove = device_remove,
+ .enable = device_enable,
+ .disable = device_disable,
+};
+
+static void create_device(const char *name)
+{
+ struct connman_device *device;
+
+ device = connman_device_create(name, CONNMAN_DEVICE_TYPE_VENDOR);
+ if (device == NULL)
+ return;
+
+ connman_device_register(device);
+ connman_device_unref(device);
+}
+
+static int fake_init(void)
+{
+ create_device("fake");
+
+ return connman_device_driver_register(&device_driver);
+}
+
+static void fake_exit(void)
+{
+ connman_device_driver_unregister(&device_driver);
+}
+
+CONNMAN_PLUGIN_DEFINE(fake, "Tesing plugin", VERSION,
+ CONNMAN_PLUGIN_PRIORITY_DEFAULT, fake_init, fake_exit)
--- /dev/null
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define CONNMAN_API_SUBJECT_TO_CHANGE
+#include <connman/plugin.h>
+#include <connman/resolver.h>
+
+#define GOOGLE_DNS1 "8.8.8.8"
+#define GOOGLE_DNS2 "8.8.4.4"
+
+static int google_init(void)
+{
+ connman_resolver_append_public_server(GOOGLE_DNS1);
+ connman_resolver_append_public_server(GOOGLE_DNS2);
+
+ return 0;
+}
+
+static void google_exit(void)
+{
+ connman_resolver_remove_public_server(GOOGLE_DNS2);
+ connman_resolver_remove_public_server(GOOGLE_DNS1);
+}
+
+CONNMAN_PLUGIN_DEFINE(google, "Google Public DNS plugin", VERSION,
+ CONNMAN_PLUGIN_PRIORITY_LOW, google_init, google_exit)
*
* hh2serial GPS
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* Connection Manager
*
* Copyright (C) 2010 BMW Car IT GmbH. All rights reserved.
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <connman/plugin.h>
#include <connman/utsname.h>
#include <connman/log.h>
-#include <connman/inet.h>
static in_addr_t loopback_address;
static in_addr_t loopback_netmask;
static int loopback_set_hostname(const char *hostname)
{
- const char *ptr;
- int err, len;
+ int err;
if (g_strcmp0(hostname, "<hostname>") == 0)
return 0;
- len = strlen(hostname);
-
- if (connman_inet_check_hostname(hostname, len) == FALSE)
- return -EINVAL;
-
- if ((ptr = strstr(hostname, ".")) != NULL)
- len = ptr - hostname;
-
- if (sethostname(hostname, len) < 0) {
+ if (sethostname(hostname, strlen(hostname)) < 0) {
err = -errno;
connman_error("Failed to set hostname to %s", hostname);
return err;
static int loopback_set_domainname(const char *domainname)
{
- int err, len;
-
- len = strlen(domainname);
-
- if (connman_inet_check_hostname(domainname, len) == FALSE)
- return -EINVAL;
+ int err;
- if (setdomainname(domainname, len) < 0) {
+ if (setdomainname(domainname, strlen(domainname)) < 0) {
err = -errno;
connman_error("Failed to set domainname to %s", domainname);
return err;
--- /dev/null
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define CONNMAN_API_SUBJECT_TO_CHANGE
+#include <connman/timeserver.h>
+#include <connman/plugin.h>
+
+#define MEEGO_NTP_SERVER "ntp.meego.com"
+
+static int meego_init(void)
+{
+ return connman_timeserver_append(MEEGO_NTP_SERVER);
+}
+
+static void meego_exit(void)
+{
+ connman_timeserver_remove(MEEGO_NTP_SERVER);
+}
+
+CONNMAN_PLUGIN_DEFINE(meego, "MeeGo features plugin", VERSION,
+ CONNMAN_PLUGIN_PRIORITY_LOW, meego_init, meego_exit)
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
NM_STATE_CONNECTED_GLOBAL = 70
};
+#define NM_STATE_CONNECTED NM_STATE_CONNECTED_GLOBAL
+
#define NM_SERVICE "org.freedesktop.NetworkManager"
#define NM_PATH "/org/freedesktop/NetworkManager"
#define NM_INTERFACE NM_SERVICE
#define DBUS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
static DBusConnection *connection = NULL;
-static struct connman_service *current_service = NULL;
-static dbus_uint32_t nm_state = NM_STATE_UNKNOWN;
+static dbus_uint32_t state = NM_STATE_UNKNOWN;
static void state_changed(dbus_uint32_t state)
{
DBusMessage *signal;
- DBG("state %d", state);
-
signal = dbus_message_new_signal(NM_PATH, NM_INTERFACE,
"StateChanged");
if (signal == NULL)
return;
dbus_message_append_args(signal, DBUS_TYPE_UINT32, &state,
- DBUS_TYPE_INVALID);
+ DBUS_TYPE_INVALID);
g_dbus_send_message(connection, signal);
}
DBusMessageIter iter, dict, dict_entry, dict_val;
DBusMessage *signal;
- DBG("state %d", state);
-
signal = dbus_message_new_signal(NM_PATH, NM_INTERFACE,
"PropertiesChanged");
if (signal == NULL)
static void default_changed(struct connman_service *service)
{
- DBG("service %p", service);
-
- if (service == NULL)
- nm_state = NM_STATE_DISCONNECTED;
+ if (service != NULL)
+ state = NM_STATE_CONNECTED;
else
- nm_state = NM_STATE_CONNECTED_LOCAL;
-
- state_changed(nm_state);
- properties_changed(nm_state);
+ state = NM_STATE_DISCONNECTED;
- current_service = service;
-}
+ DBG("%p %d", service, state);
-static void service_state_changed(struct connman_service *service,
- enum connman_service_state state)
-{
- DBG("service %p state %d", service, state);
-
- if (current_service == NULL || current_service != service)
- return;
-
- switch (state) {
- case CONNMAN_SERVICE_STATE_UNKNOWN:
- nm_state = NM_STATE_UNKNOWN;
- break;
- case CONNMAN_SERVICE_STATE_FAILURE:
- case CONNMAN_SERVICE_STATE_IDLE:
- nm_state = NM_STATE_DISCONNECTED;
- break;
- case CONNMAN_SERVICE_STATE_ASSOCIATION:
- case CONNMAN_SERVICE_STATE_CONFIGURATION:
- nm_state = NM_STATE_CONNECTING;
- break;
- case CONNMAN_SERVICE_STATE_READY:
- nm_state = NM_STATE_CONNECTED_LOCAL;
- break;
- case CONNMAN_SERVICE_STATE_ONLINE:
- nm_state = NM_STATE_CONNECTED_GLOBAL;
- break;
- case CONNMAN_SERVICE_STATE_DISCONNECT:
- nm_state = NM_STATE_DISCONNECTING;
- break;
- }
+ state_changed(state);
- state_changed(nm_state);
- properties_changed(nm_state);
-}
-
-static void offline_mode(connman_bool_t enabled)
-{
- DBG("enabled %d", enabled);
-
- if (enabled == TRUE)
- nm_state = NM_STATE_ASLEEP;
- else
- nm_state = NM_STATE_DISCONNECTED;
-
- state_changed(nm_state);
- properties_changed(nm_state);
-
- current_service = NULL;
+ properties_changed(state);
}
static struct connman_notifier notifier = {
- .name = "nmcompat",
- .priority = CONNMAN_NOTIFIER_PRIORITY_DEFAULT,
- .default_changed = default_changed,
- .service_state_changed = service_state_changed,
- .offline_mode = offline_mode,
+ .name = "nmcompat",
+ .priority = CONNMAN_NOTIFIER_PRIORITY_DEFAULT,
+ .default_changed= default_changed,
};
static DBusMessage *property_get(DBusConnection *conn,
{
const char *interface, *key;
- dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &interface,
- DBUS_TYPE_STRING, &key, DBUS_TYPE_INVALID);
+ DBG("conn %p", conn);
- DBG("interface %s property %s", interface, key);
+ dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_STRING, &interface,
+ DBUS_TYPE_STRING, &key,
+ DBUS_TYPE_INVALID);
- if (g_str_equal(interface, NM_INTERFACE) == FALSE)
- return dbus_message_new_error(msg, DBUS_ERROR_FAILED,
- "Unsupported interface");
+ DBG("interface %s property %s", interface, key);
- if (g_str_equal(key, "State") == TRUE) {
+ if (g_strcmp0(key, "State") == 0) {
DBusMessage *reply;
DBusMessageIter iter, value;
- DBG("state %d", nm_state);
-
reply = dbus_message_new_method_return(msg);
if (reply == NULL)
return NULL;
dbus_message_iter_init_append(reply, &iter);
dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
- DBUS_TYPE_UINT32_AS_STRING, &value);
- dbus_message_iter_append_basic(&value,
- DBUS_TYPE_UINT32, &nm_state);
+ DBUS_TYPE_UINT32_AS_STRING,
+ &value);
+ dbus_message_iter_append_basic(&value, DBUS_TYPE_UINT32,
+ &state);
dbus_message_iter_close_container(&iter, &value);
return reply;
"Unsupported property");
}
-static const GDBusMethodTable methods[] = {
- { GDBUS_METHOD("Get",
- GDBUS_ARGS({ "interface", "s" }, { "key", "s" }),
- GDBUS_ARGS({ "property", "v" }), property_get) },
+static GDBusMethodTable methods[] = {
+ { "Get", "ss", "v", property_get },
{ },
};
-static const GDBusSignalTable signals[] = {
- { GDBUS_SIGNAL("PropertiesChanged",
- GDBUS_ARGS({ "properties", "a{sv}" })) },
- { GDBUS_SIGNAL("StateChanged",
- GDBUS_ARGS({ "state", "u" })) },
+static GDBusSignalTable signals[] = {
+ { "PropertiesChanged", "a{sv}" },
+ { "StateChanged", "u" },
{ },
};
return -1;
if (g_dbus_request_name(connection, NM_SERVICE, NULL) == FALSE) {
- connman_error("nmcompat: failed to register service");
+ connman_error("nmcompat: failed register service\n");
return -1;
}
--- /dev/null
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arpa/inet.h>
+
+#include <gdbus.h>
+
+#define CONNMAN_API_SUBJECT_TO_CHANGE
+#include <connman/types.h>
+#include <connman/plugin.h>
+#include <connman/task.h>
+#include <connman/timeserver.h>
+#include <connman/log.h>
+
+/*
+ * The peers list are the peers currently added to a running ntpd,
+ * while pending_peers are the one appended but not used by ntpd yet.
+ */
+static GList *peers = NULL;
+static GList *pending_peers = NULL;
+
+#define NTPD_PORT 123
+
+struct ntpd_peer {
+ char *server;
+ int refcount;
+};
+
+struct ntpdate_task {
+ struct connman_task *task;
+ gint conf_fd;
+ char *conf_path;
+};
+
+static struct ntpd_peer *find_peer(GList *peer_list, const char* server)
+{
+ GList *list;
+ struct ntpd_peer *peer;
+
+ for (list = peer_list; list; list = list->next) {
+ peer = list->data;
+
+ if (g_str_equal(peer->server, server))
+ return peer;
+ }
+
+ return NULL;
+}
+
+static void remove_peer(GList *peer_list, struct ntpd_peer *peer)
+{
+ if (__sync_fetch_and_sub(&peer->refcount, 1) != 1)
+ return;
+
+ g_free(peer->server);
+ g_free(peer);
+ peer_list = g_list_remove(peer_list, peer);
+}
+
+static connman_bool_t ntpd_running(void)
+{
+ int sock;
+ connman_bool_t ret;
+ struct sockaddr_in server_addr;
+
+ if ((sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0)) == -1)
+ return FALSE;
+
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_port = htons(NTPD_PORT);
+ server_addr.sin_addr.s_addr = INADDR_ANY;
+ memset(&(server_addr.sin_zero), 0, 8);
+
+ if (bind(sock, (struct sockaddr *)&server_addr,
+ sizeof(struct sockaddr)) == -1) {
+ if (errno == EADDRINUSE)
+ ret = TRUE;
+ else
+ ret = FALSE;
+ } else
+ ret = FALSE;
+
+ close(sock);
+
+ return ret;
+}
+
+static void ntpdate_died(struct connman_task *task,
+ int exit_code, void *user_data)
+{
+ struct ntpdate_task *ntpdate = user_data;
+
+ DBG("");
+
+ unlink(ntpdate->conf_path);
+ g_free(ntpdate->conf_path);
+ connman_task_destroy(ntpdate->task);
+}
+
+static void ntpdate_add_peer(struct ntpdate_task *ntpdate, char *peer)
+{
+ FILE *conf_file;
+
+ DBG("%s", peer);
+
+ conf_file = fdopen(ntpdate->conf_fd, "a+");
+ if (conf_file == NULL) {
+ connman_error("fdopen failed");
+ return;
+ }
+
+ fprintf(conf_file, "server %s iburst\n", peer);
+
+ fclose(conf_file);
+}
+
+static int ntpdate(void)
+{
+ int err;
+ GError *g_err;
+ GList *list;
+ struct ntpd_peer *peer;
+ struct ntpdate_task *ntpdate;
+
+ DBG("");
+
+ ntpdate = g_try_new0(struct ntpdate_task, 1);
+ if (ntpdate == NULL)
+ return -ENOMEM;
+
+ /* ntpdate is deprecated, we use ntpd -q instead */
+ ntpdate->task = connman_task_create(NTPD);
+ if (ntpdate->task == NULL) {
+ err = -ENOMEM;
+ goto error_task;
+ }
+
+ connman_task_add_argument(ntpdate->task, "-g", NULL);
+ connman_task_add_argument(ntpdate->task, "-q", NULL);
+
+ /* The servers are added through a temp configuration file */
+ ntpdate->conf_fd = g_file_open_tmp("connman.ntp.conf_XXXXXX",
+ &ntpdate->conf_path, &g_err);
+ if (ntpdate->conf_fd == -1) {
+ err = g_err->code;
+ g_free(g_err);
+ goto error_open;
+ }
+
+ connman_task_add_argument(ntpdate->task, "-c", ntpdate->conf_path);
+
+ DBG("conf path %s", ntpdate->conf_path);
+
+ for (list = pending_peers; list; list = list->next) {
+ peer = list->data;
+
+ ntpdate_add_peer(ntpdate, peer->server);
+ }
+
+ for (list = peers; list; list = list->next) {
+ peer = list->data;
+
+ ntpdate_add_peer(ntpdate, peer->server);
+ }
+
+ close(ntpdate->conf_fd);
+
+ return connman_task_run(ntpdate->task, ntpdate_died, ntpdate,
+ NULL, NULL, NULL);
+error_open:
+ connman_task_destroy(ntpdate->task);
+
+error_task:
+ g_free(ntpdate);
+
+ return err;
+}
+
+static int ntpd_add_peer(char *peer)
+{
+ DBG("%s", peer);
+
+ return 0;
+}
+
+static void ntpd_sync(void)
+{
+ int err;
+ GList *list;
+
+ DBG("");
+
+ if (g_list_length(pending_peers) == 0 &&
+ g_list_length(peers) == 0)
+ return;
+
+ if (!ntpd_running()) {
+ ntpdate();
+ return;
+ }
+
+ /* TODO Grab ntp keys path */
+
+ list = g_list_first(pending_peers);
+ while(list) {
+ struct ntpd_peer *peer = list->data;
+
+ err = ntpd_add_peer(peer->server);
+ if (err)
+ continue;
+
+ peers = g_list_prepend(peers, peer);
+
+ list = g_list_next(list);
+
+ pending_peers = g_list_remove(pending_peers, peer);
+ };
+}
+
+static int ntpd_append(const char *server)
+{
+ struct ntpd_peer *peer;
+
+ DBG("");
+
+ if (server == NULL)
+ return 0;
+
+ if ((peer = find_peer(pending_peers, server)) ||
+ (peer = find_peer(peers, server))) {
+ __sync_fetch_and_add(&peer->refcount, 1);
+ return 0;
+ }
+
+ peer = g_try_new0(struct ntpd_peer, 1);
+ if (peer == NULL)
+ return -ENOMEM;
+
+ peer->server = g_strdup(server);
+ if (peer->server == NULL) {
+ g_free(peer);
+ return -ENOMEM;
+ }
+
+ peer->refcount = 1;
+
+ pending_peers = g_list_prepend(pending_peers, peer);
+
+ return 0;
+}
+
+static int ntpd_remove(const char *server)
+{
+ struct ntpd_peer *peer;
+
+ DBG("");
+
+ if (server == NULL)
+ return 0;
+
+ peer = find_peer(peers, server);
+ if (peer == NULL)
+ goto remove;
+
+ remove_peer(peers, peer);
+
+remove:
+ /* TODO: send ntpd remove command */
+
+ peer = find_peer(pending_peers, server);
+ if (peer == NULL)
+ return 0;
+
+ remove_peer(pending_peers, peer);
+
+ return 0;
+}
+
+static struct connman_timeserver_driver ntpd_driver = {
+ .name = "ntpd",
+ .priority = CONNMAN_TIMESERVER_PRIORITY_DEFAULT,
+ .append = ntpd_append,
+ .remove = ntpd_remove,
+ .sync = ntpd_sync,
+};
+
+static int ntpd_init(void)
+{
+ return connman_timeserver_driver_register(&ntpd_driver);
+}
+
+static void ntpd_exit(void)
+{
+ connman_timeserver_driver_unregister(&ntpd_driver);
+}
+
+CONNMAN_PLUGIN_DEFINE(ntpd, "ntpd plugin", VERSION,
+ CONNMAN_PLUGIN_PRIORITY_DEFAULT, ntpd_init, ntpd_exit)
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
* Copyright (C) 2011 BWM Car IT GmbH. All rights reserved.
*
#include "mcc.h"
+#define uninitialized_var(x) x = x
+
#define OFONO_SERVICE "org.ofono"
#define OFONO_MANAGER_INTERFACE OFONO_SERVICE ".Manager"
* powered -> SubscriberIdentity or Online = True -> gprs, context ->
* attached -> netreg -> ready
*
- * Depending on the modem type, this plugin will behave differently.
- *
- * GSM working flow:
- *
- * When a new modem appears, the plugin always powers it up. This
- * allows the plugin to create a connman_device. The core will call
- * modem_enable() if the technology is enabled. modem_enable() will
- * then set the modem online. If the technology is disabled then
- * modem_disable() will just set the modem offline. The modem is
- * always kept powered all the time.
- *
- * After setting the modem online the plugin waits for the
- * ConnectionManager and ConnectionContext to appear. When the context
- * signals that it is attached and the NetworkRegistration interface
- * appears, a new Service will be created and registered at the core.
- *
- * When asked to connect to the network (network_connect()) the plugin
- * will set the Active property on the context. If this operation is
- * successful the modem is connected to the network. oFono will inform
- * the plugin about IP configuration through the updating the context's
- * properties.
+ * Enabling and disabling modems are steered through the rfkill
+ * interface. That means when ConnMan toggles the rfkill bit oFono
+ * will add or remove the modems.
*
- * CDMA working flow:
- *
- * When a new modem appears, the plugin always powers it up. This
- * allows the plugin to create connman_device either using IMSI either
- * using modem Serial if the modem got a SIM interface or not.
- *
- * As for GSM, the core will call modem_enable() if the technology
- * is enabled. modem_enable() will then set the modem online.
- * If the technology is disabled then modem_disable() will just set the
- * modem offline. The modem is always kept powered all the time.
- *
- * After setting the modem online the plugin waits for CdmaConnectionManager
- * interface to appear. Then, once CdmaNetworkRegistration appears, a new
- * Service will be created and registered at the core.
- *
- * When asked to connect to the network (network_connect()) the plugin
- * will power up the CdmaConnectionManager interface.
- * If the operation is successful the modem is connected to the network.
- * oFono will inform the plugin about IP configuration through the
- * updating CdmaConnectionManager settings properties.
+ * ConnMan will always power up (set Powered and Online) the
+ * modems. No need to power them down because this will be done
+ * through the rfkill inteface.
*/
static DBusConnection *connection;
/* ConnectionContext Interface */
connman_bool_t active;
connman_bool_t set_active;
- connman_bool_t valid_apn; /* APN is 'valid' if length > 0 */
/* SimManager Interface */
char *imsi;
DBG("%s", modem->path);
- if (modem->context->index < 0 ||
- modem->context->ipv4_address == NULL) {
- connman_error("Invalid index and/or address");
- return;
- }
-
connman_network_set_index(modem->network, modem->context->index);
switch (modem->context->ipv4_method) {
{
DBusMessageIter dict;
char *address = NULL, *gateway = NULL;
- unsigned char prefix_length = 0;
+ unsigned char prefix_length;
char *nameservers = NULL;
const char *interface = NULL;
int index = -1;
static void create_device(struct modem_data *modem)
{
struct connman_device *device;
- char *ident = NULL;
+ char *uninitialized_var(ident);
DBG("%s", modem->path);
static int add_cm_context(struct modem_data *modem, const char *context_path,
DBusMessageIter *dict)
{
- const char *context_type = NULL;
+ const char *context_type;
struct network_context *context = NULL;
connman_bool_t active = FALSE;
dbus_message_iter_get_basic(&value, &active);
DBG("%s Active %d", modem->path, active);
- } else if (g_str_equal(key, "AccessPointName") == TRUE) {
- const char *apn;
-
- dbus_message_iter_get_basic(&value, &apn);
- if (apn != NULL && strlen(apn) > 0)
- modem->valid_apn = TRUE;
- else
- modem->valid_apn = FALSE;
-
- DBG("%s AccessPointName '%s'", modem->path, apn);
}
+
dbus_message_iter_next(dict);
}
g_hash_table_replace(context_hash, g_strdup(context_path), modem);
- if (modem->valid_apn == TRUE && modem->attached == TRUE &&
- has_interface(modem->interfaces,
- OFONO_API_NETREG) == TRUE) {
- add_network(modem);
- }
-
return 0;
}
network_context_free(modem->context);
modem->context = NULL;
-
- modem->valid_apn = FALSE;
-
- if (modem->network != NULL)
- remove_network(modem);
}
static gboolean context_changed(DBusConnection *connection,
set_connected(modem);
else
set_disconnected(modem);
- } else if (g_str_equal(key, "AccessPointName") == TRUE) {
- const char *apn;
-
- dbus_message_iter_get_basic(&value, &apn);
-
- DBG("%s AccessPointName %s", modem->path, apn);
-
- if (apn != NULL && strlen(apn) > 0) {
- modem->valid_apn = TRUE;
-
- if (modem->network != NULL)
- return TRUE;
-
- if (modem->attached == FALSE)
- return TRUE;
-
- if (has_interface(modem->interfaces,
- OFONO_API_NETREG) == FALSE) {
- return TRUE;
- }
-
- add_network(modem);
-
- if (modem->active == TRUE)
- set_connected(modem);
- } else {
- modem->valid_apn = FALSE;
-
- if (modem->network == NULL)
- return TRUE;
-
- remove_network(modem);
- }
}
return TRUE;
return;
}
- if (modem->valid_apn == TRUE)
- add_network(modem);
+ add_network(modem);
if (modem->active == TRUE)
set_connected(modem);
}
static struct connman_network_driver network_driver = {
- .name = "cellular",
+ .name = "network",
.type = CONNMAN_NETWORK_TYPE_CELLULAR,
.probe = network_probe,
.remove = network_remove,
OFONO_SERVICE, ofono_connect,
ofono_disconnect, NULL, NULL);
- modem_added_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE,
- NULL, OFONO_MANAGER_INTERFACE,
+ modem_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ OFONO_MANAGER_INTERFACE,
MODEM_ADDED,
modem_added,
NULL, NULL);
- modem_removed_watch = g_dbus_add_signal_watch(connection,
- OFONO_SERVICE, NULL,
+ modem_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
OFONO_MANAGER_INTERFACE,
MODEM_REMOVED,
modem_removed,
NULL, NULL);
- modem_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE, NULL,
+ modem_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
OFONO_MODEM_INTERFACE,
PROPERTY_CHANGED,
modem_changed,
NULL, NULL);
- cm_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE, NULL,
+ cm_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
OFONO_CM_INTERFACE,
PROPERTY_CHANGED,
cm_changed,
NULL, NULL);
- sim_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE, NULL,
+ sim_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
OFONO_SIM_INTERFACE,
PROPERTY_CHANGED,
sim_changed,
NULL, NULL);
- context_added_watch = g_dbus_add_signal_watch(connection,
- OFONO_SERVICE, NULL,
+ context_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
OFONO_CM_INTERFACE,
CONTEXT_ADDED,
cm_context_added,
NULL, NULL);
- context_removed_watch = g_dbus_add_signal_watch(connection,
- OFONO_SERVICE, NULL,
+ context_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
OFONO_CM_INTERFACE,
CONTEXT_REMOVED,
cm_context_removed,
NULL, NULL);
- context_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE,
- NULL, OFONO_CONTEXT_INTERFACE,
+ context_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ OFONO_CONTEXT_INTERFACE,
PROPERTY_CHANGED,
context_changed,
NULL, NULL);
- netreg_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE, NULL,
+ netreg_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
OFONO_NETREG_INTERFACE,
PROPERTY_CHANGED,
netreg_changed,
NULL, NULL);
- cdma_cm_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE,
- NULL, OFONO_CDMA_CM_INTERFACE,
+ cdma_cm_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ OFONO_CDMA_CM_INTERFACE,
PROPERTY_CHANGED,
cdma_cm_changed,
NULL, NULL);
- cdma_netreg_watch = g_dbus_add_signal_watch(connection, OFONO_SERVICE,
- NULL, OFONO_CDMA_NETREG_INTERFACE,
+ cdma_netreg_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+ OFONO_CDMA_NETREG_INTERFACE,
PROPERTY_CHANGED,
cdma_netreg_changed,
NULL, NULL);
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
struct {
const char *cm_opt;
const char *ov_opt;
- char has_value;
} ov_options[] = {
- { "Host", "--remote", 1 },
- { "OpenVPN.CACert", "--ca", 1 },
- { "OpenVPN.Cert", "--cert", 1 },
- { "OpenVPN.Key", "--key", 1 },
- { "OpenVPN.MTU", "--mtu", 1 },
- { "OpenVPN.Proto", "--proto", 1 },
- { "OpenVPN.Port", "--port", 1 },
- { "OpenVPN.AuthUserPass", "--auth-user-pass", 1 },
- { "OpenVPN.TLSRemote", "--tls-remote", 1 },
- { "OpenVPN.Cipher", "--cipher", 1 },
- { "OpenVPN.Auth", "--auth", 1 },
- { "OpenVPN.CompLZO", "--comp-lzo", 0 },
- { "OpenVPN.RemoteCertTls", "--remote-cert-tls", 1 },
+ { "Host", "--remote" },
+ { "OpenVPN.CACert", "--ca" },
+ { "OpenVPN.Cert", "--cert" },
+ { "OpenVPN.Key", "--key" },
+ { "OpenVPN.MTU", "--mtu" },
+ { "OpenVPN.Proto", "--proto" },
+ { "OpenVPN.Port", "--port" },
+ { "OpenVPN.AuthUserPass", "--auth-user-pass" },
+ { "OpenVPN.TLSRemote", "--tls-remote" },
+ { "OpenVPN.Cipher", "--cipher" },
+ { "OpenVPN.Auth", "--auth" },
+ { "OpenVPN.CompLZO", "--comp-lzo" },
+ { "OpenVPN.RemoteCertTls", "--remote-cert-tls" },
};
static void ov_append_dns_entries(const char *key, const char *value,
continue;
if (connman_task_add_argument(task,
- ov_options[i].ov_opt,
- ov_options[i].has_value ? option : NULL) < 0) {
+ ov_options[i].ov_opt, option) < 0) {
return -EIO;
}
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
switch(connman_service_get_proxy_method(default_service)) {
case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
- connman_dbus_dict_close(&iter, &dict);
goto done;
case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
method= "direct";
method = "manual";
str_list = connman_service_get_proxy_servers(default_service);
- if (str_list == NULL) {
- connman_dbus_dict_close(&iter, &dict);
+ if (str_list == NULL)
goto done;
- }
connman_dbus_dict_append_array(&dict, "Servers",
DBUS_TYPE_STRING, append_string_list,
if (str == NULL) {
str = connman_service_get_proxy_autoconfig(
default_service);
- if (str == NULL) {
- connman_dbus_dict_close(&iter, &dict);
+ if (str == NULL)
goto done;
- }
}
connman_dbus_dict_append_basic(&dict, "URL",
connman_dbus_dict_append_array(&dict, "Nameservers",
DBUS_TYPE_STRING, append_string_list,
str_list);
- g_strfreev(str_list);
connman_dbus_dict_close(&iter, &dict);
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* Connection Manager
*
* Copyright (C) 2010 BMW Car IT GmbH. All rights reserved.
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
--- /dev/null
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include <gdbus.h>
+#include <string.h>
+
+#define CONNMAN_API_SUBJECT_TO_CHANGE
+#include <connman/plugin.h>
+#include <connman/device.h>
+#include <connman/network.h>
+#include <connman/ipconfig.h>
+#include <connman/dbus.h>
+#include <connman/inet.h>
+#include <connman/technology.h>
+#include <connman/log.h>
+
+#define PS_DBUS_SERVICE "com.tcore.ps"
+
+#define PS_MASTER_INTERFACE PS_DBUS_SERVICE ".master"
+#define PS_MODEM_INTERFACE PS_DBUS_SERVICE ".modem"
+#define PS_SERVICE_INTERFACE PS_DBUS_SERVICE ".service"
+#define PS_CONTEXT_INTERFACE PS_DBUS_SERVICE ".context"
+
+//methods
+#define GET_MODEMS "GetModems"
+#define GET_SERVICES "GetServices"
+#define GET_CONTEXTS "GetContexts"
+#define ACTIVATE_CONTEXT "Activate"
+#define DEACTIVATE_CONTEXT "Deactivate"
+#define GET_PROPERTIES "GetProperties"
+#define SET_PROPERTY "SetProperties"
+
+//signals
+#define MODEM_ADDED "ModemAdded"
+#define MODEM_REMOVED "ModemRemoved"
+#define SERVICE_ADDED "ServiceAdded"
+#define SERVICE_REMOVED "ServiceRemoved"
+#define CONTEXT_ADDED "ContextAdded"
+#define CONTEXT_REMOVED "ContextRemoved"
+#define PROPERTY_CHANGED "PropertyChanged"
+
+#define TIMEOUT 40000
+
+#define STRING2BOOL(a) ((g_str_equal(a, "TRUE")) ? (TRUE):(FALSE))
+
+static DBusConnection *connection;
+static GHashTable *modem_hash;
+static GHashTable *service_hash;
+static GHashTable *network_hash;
+
+struct telephony_service {
+ char* path;
+
+ gpointer p_modem;
+ char *act;
+ gboolean roaming; //global roaming state
+ gboolean ps_attached; //packet service is available
+};
+
+struct telephony_modem {
+ char* path;
+
+ char *operator;
+ gboolean powered;
+ gboolean sim_init;
+ gboolean flight_mode;
+ gboolean data_allowed;
+ gboolean roaming_allowed;
+
+ struct connman_device *device;
+ struct telephony_service *s_service;
+};
+
+struct telephony_network {
+ char *path;
+ struct connman_network *network;
+
+ enum connman_ipconfig_method ipv4_method;
+ struct connman_ipaddress ipv4_address;
+
+ enum connman_ipconfig_method ipv6_method;
+ struct connman_ipaddress ipv6_address;
+};
+
+// function prototype
+static void telephony_connect(DBusConnection *connection, void *user_data);
+static void telephony_disconnect(DBusConnection *connection, void *user_data);
+static void __remove_modem(gpointer data);
+static void __remove_service(gpointer data);
+static void __remove_network(gpointer data);
+
+static int __modem_probe(struct connman_device *device);
+static void __modem_remove(struct connman_device *device);
+static int __modem_enable(struct connman_device *device);
+static int __modem_disable(struct connman_device *device);
+
+static int __network_probe(struct connman_network *network);
+static void __network_remove(struct connman_network *network);
+static int __network_connect(struct connman_network *network);
+static int __network_disconnect(struct connman_network *network);
+
+
+// dbus request and reply
+static int __dbus_request(const char *path, const char *interface, const char *method,
+ DBusPendingCallNotifyFunction notify, void *user_data,
+ DBusFreeFunction free_function, int type, ...);
+
+static int __request_get_modems(void);
+static void __response_get_modems(DBusPendingCall *call, void *user_data);
+static int __request_get_services(const char* path);
+static void __response_get_services(DBusPendingCall *call, void *user_data);
+static int __request_get_contexts(struct telephony_modem* modem);
+static void __response_get_contexts(DBusPendingCall *call, void *user_data);
+static int __request_network_activate(struct connman_network *network);
+static void __response_network_activate(DBusPendingCall *call, void *user_data);
+static int __request_network_deactivate(struct connman_network *network);
+
+// telephony internal function
+static void __add_modem(const char *path, DBusMessageIter *prop);
+static void __add_service(struct telephony_modem* modem, const char *service_path, DBusMessageIter *prop);
+static void __add_connman_device(const char* modem_path, const char* operator);
+static void __remove_connman_device(struct telephony_modem *modem);
+static void __remove_connman_networks(struct connman_device *device);
+static void __set_device_powered(struct telephony_modem *modem, gboolean powered);
+static int __check_device_powered(const char *path, gboolean online);
+static gboolean __check_network_available(struct connman_network *network);
+static void __create_service(struct connman_network *network);
+static int __add_context(struct connman_device *device, const char *path, DBusMessageIter *prop);
+static gboolean __set_network_ipconfig(struct telephony_network *network, DBusMessageIter *dict);
+static void __set_network_connected(struct telephony_network *network, gboolean connected);
+static char *__get_ident(const char *path);
+
+// signal handler
+static gboolean __changed_modem(DBusConnection *connection, DBusMessage *message, void *user_data);
+static gboolean __added_modem(DBusConnection *connection, DBusMessage *message, void *user_data);
+static gboolean __removed_modem(DBusConnection *connection, DBusMessage *message, void *user_data);
+static gboolean __changed_service(DBusConnection *connection, DBusMessage *message, void *user_data);
+static gboolean __added_service(DBusConnection *connection, DBusMessage *message, void *user_data);
+static gboolean __removed_service(DBusConnection *connection, DBusMessage *message, void *user_data);
+static gboolean __changed_context(DBusConnection *connection, DBusMessage *message, void *user_data);
+static gboolean __added_context(DBusConnection *connection, DBusMessage *message, void *user_data);
+static gboolean __removed_context(DBusConnection *connection, DBusMessage *message, void *user_data);
+
+// device driver
+static struct connman_device_driver modem_driver = {
+ .name = "device",
+ .type = CONNMAN_DEVICE_TYPE_CELLULAR,
+ .probe = __modem_probe,
+ .remove = __modem_remove,
+ .enable = __modem_enable,
+ .disable = __modem_disable,
+};
+
+// network driver
+static struct connman_network_driver network_driver = {
+ .name = "network",
+ .type = CONNMAN_NETWORK_TYPE_CELLULAR,
+ .probe = __network_probe,
+ .remove = __network_remove,
+ .connect = __network_connect,
+ .disconnect = __network_disconnect,
+};
+
+static int tech_probe(struct connman_technology *technology)
+{
+ return 0;
+}
+
+static void tech_remove(struct connman_technology *technology)
+{
+}
+
+static struct connman_technology_driver tech_driver = {
+ .name = "cellular",
+ .type = CONNMAN_SERVICE_TYPE_CELLULAR,
+ .probe = tech_probe,
+ .remove = tech_remove,
+};
+
+// local function
+static void telephony_connect(DBusConnection *connection, void *user_data)
+{
+ DBG("connection %p", connection);
+ modem_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, __remove_modem);
+ service_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, __remove_service);
+ network_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, __remove_network);
+ __request_get_modems();
+ return;
+}
+
+static void telephony_disconnect(DBusConnection *connection, void *user_data)
+{
+ DBG("connection %p", connection);
+
+ if (modem_hash != NULL) {
+ g_hash_table_destroy(modem_hash);
+ modem_hash = NULL;
+ }
+
+ if (network_hash != NULL) {
+ g_hash_table_destroy(network_hash);
+ network_hash = NULL;
+ }
+
+ return;
+}
+
+static void __remove_modem(gpointer data)
+{
+ struct telephony_modem *modem = data;
+
+ __remove_connman_device(modem);
+
+ g_free(modem->path);
+ g_free(modem->operator);
+ g_free(modem);
+}
+
+static void __remove_service(gpointer data)
+{
+ struct telephony_service *service = data;
+
+ g_free(service->path);
+ g_free(service->act);
+ g_free(service);
+}
+
+static void __remove_network(gpointer data)
+{
+ struct telephony_network *info = data;
+ struct connman_device *device;
+
+ device = connman_network_get_device(info->network);
+ if (device != NULL)
+ connman_device_remove_network(device, info->network);
+
+ connman_network_unref(info->network);
+
+ g_free(info->path);
+ g_free(info);
+}
+
+static int __modem_probe(struct connman_device *device)
+{
+ DBG("device %p", device);
+ return 0;
+}
+
+static void __modem_remove(struct connman_device *device)
+{
+ DBG("device %p", device);
+}
+
+static int __modem_enable(struct connman_device *device)
+{
+ const char *path = connman_device_get_string(device, "Path");
+ DBG("device %p, path, %s", device, path);
+
+ return __check_device_powered(path, TRUE);
+}
+
+static int __modem_disable(struct connman_device *device)
+{
+ const char *path = connman_device_get_string(device, "Path");
+ DBG("device %p, path, %s", device, path);
+
+ return __check_device_powered(path, FALSE);
+}
+
+static int __network_probe(struct connman_network *network)
+{
+ DBG("network_prove network(%p)", network);
+ return 0;
+}
+
+static int __network_connect(struct connman_network *network)
+{
+ struct connman_device *device;
+ struct telephony_modem *modem;
+
+ DBG("network %p", network);
+
+ device = connman_network_get_device(network);
+ if (device == NULL)
+ return -ENODEV;
+
+ modem = connman_device_get_data(device);
+ if (modem == NULL)
+ return -ENODEV;
+
+ if (modem->powered == FALSE)
+ return -ENOLINK;
+
+/* if (modem->online == FALSE)
+ return -ENOLINK;
+
+ if (modem->roaming_allowed == FALSE && modem->roaming == TRUE)
+ return -ENOLINK;*/
+
+ return __request_network_activate(network);
+}
+
+static int __network_disconnect(struct connman_network *network)
+{
+ DBG("network %p", network);
+
+ if (connman_network_get_index(network) < 0)
+ return -ENOTCONN;
+
+ connman_network_set_associating(network, FALSE);
+
+ return __request_network_deactivate(network);
+}
+
+static void __network_remove(struct connman_network *network)
+{
+ char const *path = connman_network_get_string(network, "Path");
+ DBG("network %p path %s", network, path);
+
+ g_hash_table_remove(network_hash, path);
+ return;
+}
+
+static int __dbus_request(const char *path, const char *interface, const char *method,
+ DBusPendingCallNotifyFunction notify, void *user_data,
+ DBusFreeFunction free_function, int type, ...)
+{
+ DBG("telephony request");
+
+ DBusMessage *message;
+ DBusPendingCall *call;
+ dbus_bool_t ok;
+ va_list va;
+
+ DBG("path %s %s.%s", path, interface, method);
+
+ if (path == NULL)
+ return -EINVAL;
+
+ message = dbus_message_new_method_call(PS_DBUS_SERVICE, path, interface, method);
+ if (message == NULL)
+ return -ENOMEM;
+
+ dbus_message_set_auto_start(message, FALSE);
+
+ va_start(va, type);
+ ok = dbus_message_append_args_valist(message, type, va);
+ va_end(va);
+
+ if (!ok)
+ return -ENOMEM;
+
+ if (dbus_connection_send_with_reply(connection, message, &call, TIMEOUT) == FALSE) {
+ connman_error("Failed to call %s.%s", interface, method);
+ dbus_message_unref(message);
+ return -EINVAL;
+ }
+
+ if (call == NULL) {
+ connman_error("D-Bus connection not available");
+ dbus_message_unref(message);
+ return -EINVAL;
+ }
+
+ dbus_pending_call_set_notify(call, notify, user_data, free_function);
+
+ dbus_message_unref(message);
+
+ return -EINPROGRESS;
+}
+
+static int __request_get_modems(void)
+{
+ DBG("request get modem");
+ //call connect master
+ return __dbus_request("/", PS_MASTER_INTERFACE, GET_MODEMS,
+ __response_get_modems, NULL, NULL, DBUS_TYPE_INVALID);
+}
+
+static void __response_get_modems(DBusPendingCall *call, void *user_data)
+{
+ DBusMessage *reply;
+ DBusError error;
+ DBusMessageIter args, dict;
+
+ DBG("");
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, reply)) {
+ connman_error("GetModems() %s %s",error.name, error.message);
+ dbus_error_free(&error);
+ goto done;
+ }
+
+ DBG("message signature (%s)", dbus_message_get_signature(reply));
+
+ if (dbus_message_iter_init(reply, &args) == FALSE)
+ goto done;
+
+ dbus_message_iter_recurse(&args, &dict);
+
+ //DBG("message type (%d) dic(%d)", dbus_message_iter_get_arg_type(&dict), DBUS_TYPE_DICT_ENTRY);
+
+ while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry, property;
+ const char *modem_path;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ dbus_message_iter_get_basic(&entry, &modem_path);
+ DBG("modem path (%s)", modem_path);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &property);
+
+ __add_modem(modem_path, &property);
+
+ dbus_message_iter_next(&dict);
+ }
+
+done:
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
+ return;
+}
+
+static int __request_get_services(const char* path)
+{
+ DBG("request get service");
+ return __dbus_request(path,PS_MODEM_INTERFACE,GET_SERVICES,
+ __response_get_services, g_strdup(path), g_free, DBUS_TYPE_INVALID);
+}
+
+static void __response_get_services(DBusPendingCall *call, void *user_data)
+{
+ DBusMessage *reply;
+ DBusError error;
+ DBusMessageIter args, dict;
+
+ const char *path = user_data;
+ struct telephony_modem *modem;
+
+ modem = g_hash_table_lookup(modem_hash, path);
+ if (modem == NULL)
+ return;
+ if (modem->device == NULL)
+ return;
+
+ DBG("");
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, reply)) {
+ connman_error("GetServices() %s %s",error.name, error.message);
+ dbus_error_free(&error);
+ goto done;
+ }
+
+ DBG("message signature (%s)", dbus_message_get_signature(reply));
+
+ if (dbus_message_iter_init(reply, &args) == FALSE)
+ goto done;
+
+ dbus_message_iter_recurse(&args, &dict);
+
+ //DBG("message type (%d) dic(%d)", dbus_message_iter_get_arg_type(&dict), DBUS_TYPE_DICT_ENTRY);
+
+ while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry, property;
+ const char *service_path;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ dbus_message_iter_get_basic(&entry, &service_path);
+ DBG("service path (%s)", service_path);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &property);
+
+ __add_service(modem, service_path,&property);
+
+ dbus_message_iter_next(&dict);
+ }
+
+done:
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
+ return;
+}
+
+static int __request_get_contexts(struct telephony_modem* modem)
+{
+ DBG("request get contexts");
+ return __dbus_request(modem->s_service->path,PS_SERVICE_INTERFACE,GET_CONTEXTS,
+ __response_get_contexts, g_strdup(modem->path), g_free, DBUS_TYPE_INVALID);
+}
+
+static void __response_get_contexts(DBusPendingCall *call, void *user_data)
+{
+ DBusError error;
+ DBusMessage *reply;
+ DBusMessageIter args, dict;
+
+ const char *path = user_data;
+ struct telephony_modem *modem;
+
+ DBG("");
+
+ modem = g_hash_table_lookup(modem_hash, path);
+ if (modem == NULL)
+ return;
+ if (modem->s_service == NULL)
+ return;
+ if (modem->device == NULL)
+ return;
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, reply)) {
+ connman_error("GetContexts() %s %s",error.name, error.message);
+ dbus_error_free(&error);
+ goto done;
+ }
+
+ DBG("message signature (%s)", dbus_message_get_signature(reply));
+
+ if (dbus_message_iter_init(reply, &args) == FALSE)
+ goto done;
+
+ dbus_message_iter_recurse(&args, &dict);
+
+ while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry, property;
+ const char *context_path;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ dbus_message_iter_get_basic(&entry, &context_path);
+ DBG("context path (%s)", context_path);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &property);
+
+ __add_context(modem->device, context_path, &property);
+
+ dbus_message_iter_next(&dict);
+ }
+
+done:
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
+ return;
+}
+
+static int __request_network_activate(struct connman_network *network)
+{
+ DBG("request network activate");
+
+ const char *path = connman_network_get_string(network, "Path");
+ DBG("network %p, path %s", network, path);
+
+ return __dbus_request(path,PS_CONTEXT_INTERFACE,ACTIVATE_CONTEXT,
+ __response_network_activate, g_strdup(path), NULL, DBUS_TYPE_INVALID);
+}
+
+static void __response_network_activate(DBusPendingCall *call, void *user_data)
+{
+ DBG("network activation response");
+
+ DBusError error;
+ DBusMessage *reply;
+
+ struct telephony_network *info;
+ const char* path = user_data;
+
+ info = g_hash_table_lookup(network_hash, path);
+ reply = dbus_pending_call_steal_reply(call);
+
+ if (info == NULL)
+ goto done;
+
+ if (!__check_network_available(info->network)) {
+ g_hash_table_remove(network_hash, path);
+ goto done;
+ }
+
+ dbus_error_init(&error);
+ if (dbus_set_error_from_message(&error, reply)) {
+ connman_error("connection activate() %s %s",error.name, error.message);
+
+ if (connman_network_get_index(info->network) < 0)
+ connman_network_set_error(info->network, CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
+
+ dbus_error_free(&error);
+ goto done;
+ }
+
+done:
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
+ return;
+}
+
+static int __request_network_deactivate(struct connman_network *network)
+{
+ DBG("request network deactivate");
+
+ const char *path = connman_network_get_string(network, "Path");
+ DBG("network %p, path %s", network, path);
+
+ return __dbus_request(path,PS_CONTEXT_INTERFACE,DEACTIVATE_CONTEXT,
+ NULL, NULL, NULL, DBUS_TYPE_INVALID);
+}
+
+static void __add_modem(const char *path, DBusMessageIter *prop)
+{
+ struct telephony_modem *modem;
+
+ modem = g_hash_table_lookup(modem_hash, path);
+ if (modem != NULL)
+ return;
+
+ modem = (struct telephony_modem *)malloc( sizeof(struct telephony_modem));
+ memset(modem, 0, sizeof(struct telephony_modem));
+
+ modem->path = g_strdup(path);
+ modem->device = NULL;
+ modem->s_service = NULL;
+
+ g_hash_table_insert(modem_hash, g_strdup(path), modem);
+
+ while (dbus_message_iter_get_arg_type(prop) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char *key, *tmp;
+
+ dbus_message_iter_recurse(prop, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &tmp);
+
+ DBG("key (%s) value(%s)", key, tmp);
+
+ if (g_str_equal(key, "powered") == TRUE) {
+ modem->powered = STRING2BOOL(tmp);
+ } else if (g_str_equal(key, "operator") == TRUE) {
+ modem->operator = g_strdup(tmp);
+ } else if (g_str_equal(key, "sim_init") == TRUE) {
+ modem->sim_init = STRING2BOOL(tmp);
+ } else if (g_str_equal(key, "flight_mode") == TRUE) {
+ modem->flight_mode = STRING2BOOL(tmp);
+ } else if (g_str_equal(key, "roaming_allowed") == TRUE) {
+ modem->roaming_allowed = STRING2BOOL(tmp);
+ } else if (g_str_equal(key, "data_allowed") == TRUE) {
+ modem->data_allowed = STRING2BOOL(tmp);
+ }
+ dbus_message_iter_next(prop);
+ }
+
+ __add_connman_device(path, modem->operator);
+ __set_device_powered(modem, modem->powered);
+
+ if (modem->powered != TRUE) {
+ DBG("modem is not powered");
+ return;
+ }
+
+ __request_get_services(modem->path);
+
+ return;
+}
+
+static void __add_service(struct telephony_modem* modem, const char *service_path, DBusMessageIter *prop)
+{
+ struct telephony_service *service;
+
+ if (modem->s_service != NULL)
+ return;
+
+ service = (struct telephony_service *)malloc( sizeof(struct telephony_service));
+ memset(service, 0, sizeof(struct telephony_service));
+
+ service->path = g_strdup(service_path);
+ service->p_modem = modem;
+ g_hash_table_insert(service_hash, g_strdup(service_path), service);
+
+ while (dbus_message_iter_get_arg_type(prop) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char *key, *tmp;
+
+ dbus_message_iter_recurse(prop, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &tmp);
+
+ DBG("key (%s) value(%s)", key, tmp);
+
+ if (g_str_equal(key, "roaming") == TRUE) {
+ service->roaming = STRING2BOOL(tmp);
+ } else if (g_str_equal(key, "act") == TRUE) {
+ service->act = g_strdup(tmp);
+ } else if (g_str_equal(key, "ps_attached") == TRUE) {
+ service->ps_attached = STRING2BOOL(tmp);
+ }
+
+ dbus_message_iter_next(prop);
+ }
+
+ modem->s_service = service;
+ __request_get_contexts(modem);
+
+ return;
+}
+
+static void __add_connman_device(const char* modem_path, const char* operator)
+{
+ struct telephony_modem *modem;
+ struct connman_device *device;
+
+ DBG("path %s operator %s", modem_path, operator);
+
+ if (modem_path == NULL)
+ return;
+
+ if (operator == NULL)
+ return;
+
+ modem = g_hash_table_lookup(modem_hash, modem_path);
+ if (modem == NULL)
+ return;
+
+ if (modem->device) {
+ if (!g_strcmp0(operator, connman_device_get_ident(modem->device)))
+ return;
+
+ __remove_connman_device(modem);
+ }
+
+ if (strlen(operator) == 0)
+ return;
+
+ device = connman_device_create(operator, CONNMAN_DEVICE_TYPE_CELLULAR);
+ if (device == NULL)
+ return;
+
+ connman_device_set_ident(device, operator);
+ connman_device_set_string(device, "Path", modem_path);
+ connman_device_set_data(device, modem);
+
+ if (connman_device_register(device) < 0) {
+ connman_error("Failed to register cellular device");
+ connman_device_unref(device);
+ return;
+ }
+
+ modem->device = device;
+
+ return;
+}
+
+static void __remove_connman_device(struct telephony_modem *modem)
+{
+ DBG("modem %p path %s device %p", modem, modem->path, modem->device);
+
+ if (modem->device == NULL)
+ return;
+
+ __remove_connman_networks(modem->device);
+
+ connman_device_unregister(modem->device);
+ connman_device_unref(modem->device);
+
+ modem->device = NULL;
+
+ return;
+}
+
+static void __remove_connman_networks(struct connman_device *device)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+ GSList *info_list = NULL;
+ GSList *list;
+
+ if (network_hash == NULL)
+ return;
+
+ g_hash_table_iter_init(&iter, network_hash);
+
+ while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ struct telephony_network *info = value;
+
+ if (connman_network_get_device(info->network) != device)
+ continue;
+
+ info_list = g_slist_append(info_list, info);
+ }
+
+ for (list = info_list; list != NULL; list = list->next) {
+ struct telephony_network *info = list->data;
+ connman_device_remove_network(device, info->network);
+ }
+
+ g_slist_free(info_list);
+}
+
+static void __set_device_powered(struct telephony_modem *modem, gboolean powered)
+{
+ DBG("set modem(%s) powered(%d)", modem->path, powered);
+
+ if (modem->device) {
+ connman_device_set_powered(modem->device, powered);
+ }
+
+ return;
+}
+
+static int __check_device_powered(const char *path, gboolean powered)
+{
+ struct telephony_modem *modem = g_hash_table_lookup(modem_hash, path);
+
+ if (modem == NULL)
+ return -ENODEV;
+
+ DBG("check modem (%s) powered (%d)", modem->path, modem->powered);
+
+ if (modem->powered == powered)
+ return -EALREADY;
+
+ return 0;
+}
+
+static gboolean __check_network_available(struct connman_network *network)
+{
+ if (network == NULL || connman_network_get_device(network) == NULL) {
+ DBG("Modem or network was removed");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int __add_context(struct connman_device *device, const char *path, DBusMessageIter *prop)
+{
+ char *ident;
+ gboolean active = FALSE;
+
+ struct telephony_modem *modem = connman_device_get_data(device);
+ struct connman_network *network;
+ struct telephony_network *info;
+
+ DBG("modem %p device %p path %s", modem, device, path);
+
+ ident = __get_ident(path);
+
+ network = connman_device_get_network(device, ident);
+ if (network != NULL)
+ return -EALREADY;
+
+ info = g_hash_table_lookup(network_hash, path);
+ if (info != NULL) {
+ DBG("path %p already exists with device %p", path, connman_network_get_device(info->network));
+
+ if (connman_network_get_device(info->network))
+ return -EALREADY;
+
+ g_hash_table_remove(network_hash, path);
+ }
+
+ network = connman_network_create(ident, CONNMAN_NETWORK_TYPE_CELLULAR);
+ if (network == NULL)
+ return -ENOMEM;
+
+ info = (struct telephony_network *)malloc( sizeof(struct telephony_network));
+ memset(info, 0, sizeof(struct telephony_network));
+
+ if (info == NULL) {
+ connman_network_unref(network);
+ return -ENOMEM;
+ }
+
+ info->path = g_strdup(path);
+
+ connman_ipaddress_clear(&info->ipv4_address);
+ connman_ipaddress_clear(&info->ipv6_address);
+ info->network = network;
+
+ connman_network_set_string(network, "Path", path);
+ connman_network_set_name(network, path);
+
+ __create_service(network);
+
+ g_hash_table_insert(network_hash, g_strdup(path), info);
+
+ connman_network_set_available(network, TRUE);
+ connman_network_set_index(network, -1);
+ connman_network_set_roaming(network, modem->s_service->roaming);
+
+ if (connman_device_add_network(device, network) != 0) {
+ g_hash_table_remove(network_hash, path);
+ return -EIO;
+ }
+
+ active = __set_network_ipconfig(info, prop);
+
+ if (active && (connman_network_get_connecting(network) || connman_network_get_associating(network)))
+ __set_network_connected(info, active);
+
+ return 0;
+}
+
+static void __create_service(struct connman_network *network)
+{
+ const char *path;
+ char *group;
+
+ DBG("");
+
+ path = connman_network_get_string(network, "Path");
+
+ group = __get_ident(path);
+
+ connman_network_set_group(network, group);
+}
+
+static gboolean __set_network_ipconfig(struct telephony_network *network, DBusMessageIter *dict)
+{
+ DBG("set network info");
+
+ gboolean active = FALSE;
+ char *dev_name=NULL, *proxy_addr=NULL;
+ char *ipv4_addr=NULL, *ipv4_gw=NULL, *ipv4_netmask=NULL, *ipv4_dns1=NULL, *ipv4_dns2=NULL;
+ char *ipv6_addr=NULL, *ipv6_gw=NULL, *ipv6_netmask=NULL, *ipv6_dns1=NULL, *ipv6_dns2=NULL;
+ int index;
+
+ while (dbus_message_iter_get_arg_type(dict) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char* key, *tmp;
+
+ dbus_message_iter_recurse(dict, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+
+ DBG("key (%s)", key);
+
+ if (g_str_equal(key, "dev_name") == TRUE) {
+ dbus_message_iter_get_basic(&entry, &dev_name);
+ DBG("dev_name (%s)", dev_name);
+ } else if(g_str_equal(key, "proxy") == TRUE) {
+ dbus_message_iter_get_basic(&entry, &proxy_addr);
+ } else if (g_str_equal(key, "ipv4_address") == TRUE) {
+ dbus_message_iter_get_basic(&entry, &ipv4_addr);
+ DBG("ipv4 address (%s)", ipv4_addr);
+ } else if (g_str_equal(key, "ipv4_gateway") == TRUE) {
+ dbus_message_iter_get_basic(&entry, &ipv4_gw);
+ } else if (g_str_equal(key, "ipv4_netmask") == TRUE) {
+ dbus_message_iter_get_basic(&entry, &ipv4_netmask);
+ } else if (g_str_equal(key, "ipv4_dns1") == TRUE) {
+ dbus_message_iter_get_basic(&entry, &ipv4_dns1);
+ } else if (g_str_equal(key, "ipv4_dns2") == TRUE) {
+ dbus_message_iter_get_basic(&entry, &ipv4_dns2);
+ } else if (g_str_equal(key, "ipv6_address") == TRUE) {
+ dbus_message_iter_get_basic(&entry, &ipv6_addr);
+ DBG("ipv6 address (%s)", ipv6_addr);
+ } else if (g_str_equal(key, "ipv6_gateway") == TRUE) {
+ dbus_message_iter_get_basic(&entry, &ipv6_gw);
+ } else if (g_str_equal(key, "ipv6_netmask") == TRUE) {
+ dbus_message_iter_get_basic(&entry, &ipv6_netmask);
+ } else if (g_str_equal(key, "ipv6_dns1") == TRUE) {
+ dbus_message_iter_get_basic(&entry, &ipv6_dns1);
+ } else if (g_str_equal(key, "ipv6_dns2") == TRUE) {
+ dbus_message_iter_get_basic(&entry, &ipv6_dns2);
+ } else if (g_str_equal(key, "active") == TRUE) {
+ dbus_message_iter_get_basic(&entry, &tmp);
+ DBG("active (%s)", tmp);
+ active = STRING2BOOL(tmp);
+ }
+
+ dbus_message_iter_next(dict);
+ }
+
+ // interface index set
+ if (g_str_equal(dev_name ,"")) {
+ const char *ifname = NULL;
+ ifname = connman_network_get_ifname(network->network);
+ index = connman_inet_ifindex(ifname);
+ } else
+ index = connman_inet_ifindex(dev_name);
+
+ DBG("interface %s, index %d", dev_name, index);
+ connman_network_set_index(network->network, index);
+
+ // proxy set
+ DBG("proxy (%s) is set", proxy_addr);
+ connman_network_set_proxy(network->network, proxy_addr);
+
+ // ipv4 set
+ if (g_str_equal(ipv4_addr, "0.0.0.0")) {
+ network->ipv4_method = CONNMAN_IPCONFIG_METHOD_OFF;
+ } else {
+ network->ipv4_method = CONNMAN_IPCONFIG_METHOD_FIXED;
+ connman_ipaddress_set_ipv4(&network->ipv4_address, ipv4_addr, ipv4_netmask, ipv4_gw);
+ gchar *nameservers = g_strdup_printf("%s %s", ipv4_dns1, ipv4_dns2);
+ connman_network_set_nameservers(network->network, nameservers);
+ }
+
+ // ipv6 set
+ if (g_str_equal(ipv6_addr, "::")) {
+ network->ipv6_method = CONNMAN_IPCONFIG_METHOD_OFF;
+ } else {
+ network->ipv6_method = CONNMAN_IPCONFIG_METHOD_FIXED;
+ unsigned char prefix_length = 64;
+ connman_ipaddress_set_ipv6(&network->ipv6_address, ipv6_addr, prefix_length, ipv6_gw);
+ gchar *nameservers = g_strdup_printf("%s %s", ipv6_dns1, ipv6_dns2);
+ connman_network_set_nameservers(network->network, nameservers);
+ }
+
+ if(active)
+ connman_network_set_associating(network->network, TRUE);
+
+ return active;
+}
+
+static void __set_network_connected(struct telephony_network *network, gboolean connected)
+{
+ gboolean setip = FALSE;
+
+ DBG("network %p connected %d", network, connected);
+
+ switch (network->ipv4_method) {
+ case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+ case CONNMAN_IPCONFIG_METHOD_OFF:
+ case CONNMAN_IPCONFIG_METHOD_MANUAL:
+ case CONNMAN_IPCONFIG_METHOD_AUTO:
+ setip = TRUE;
+ break;
+
+ case CONNMAN_IPCONFIG_METHOD_FIXED:
+ connman_network_set_ipv4_method(network->network,network->ipv4_method);
+ connman_network_set_ipaddress(network->network, &network->ipv4_address);
+ setip = TRUE;
+ break;
+
+ case CONNMAN_IPCONFIG_METHOD_DHCP:
+ connman_network_set_ipv4_method(network->network, network->ipv4_method);
+ setip = TRUE;
+ break;
+ }
+
+ switch (network->ipv6_method) {
+ case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+ case CONNMAN_IPCONFIG_METHOD_OFF:
+ case CONNMAN_IPCONFIG_METHOD_MANUAL:
+ case CONNMAN_IPCONFIG_METHOD_DHCP:
+ case CONNMAN_IPCONFIG_METHOD_AUTO:
+ DBG("ipv6 not supported");
+ break;;
+
+ case CONNMAN_IPCONFIG_METHOD_FIXED:
+ connman_network_set_ipv6_method(network->network, network->ipv6_method);
+ connman_network_set_ipaddress(network->network, &network->ipv6_address);
+ setip = TRUE;
+ break;
+ }
+
+ if (setip == TRUE)
+ connman_network_set_connected(network->network, connected);
+
+ return;
+}
+
+static char *__get_ident(const char *path)
+{
+ char *pos;
+
+ if (*path != '/')
+ return NULL;
+
+ pos = strrchr(path, '/');
+ if (pos == NULL)
+ return NULL;
+
+ return pos + 1;
+}
+
+static gboolean __changed_modem(DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ DBG("modem changed signal");
+
+ DBusMessageIter args, dict;
+ const char *path = dbus_message_get_path(message);
+ struct telephony_modem *modem;
+
+ DBG("modem path %s", path);
+
+ modem = g_hash_table_lookup(modem_hash, path);
+ if (modem == NULL) {
+ DBG("modem object does not exists");
+ return TRUE;
+ }
+
+ DBG("message signature (%s)", dbus_message_get_signature(message));
+
+ if (dbus_message_iter_init(message, &args) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_recurse(&args, &dict);
+
+ while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char* key, *tmp;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &tmp);
+
+ DBG("key(%s), value(%s)", key, tmp);
+
+ if (g_str_equal(key, "powered") == TRUE) {
+ modem->powered = STRING2BOOL(tmp);
+ } else if (g_str_equal(key, "operator") == TRUE) {
+ modem->operator = g_strdup(tmp);
+ } else if (g_str_equal(key, "sim_init") == TRUE) {
+ modem->sim_init = STRING2BOOL(tmp);
+ } else if (g_str_equal(key, "flight_mode") == TRUE) {
+ modem->flight_mode = STRING2BOOL(tmp);
+ } else if (g_str_equal(key, "roaming_allowed") == TRUE) {
+ modem->roaming_allowed = STRING2BOOL(tmp);
+ } else if (g_str_equal(key, "data_allowed") == TRUE) {
+ modem->data_allowed = STRING2BOOL(tmp);
+ }
+
+ dbus_message_iter_next(&dict);
+ }
+
+ if (modem->device == NULL)
+ __add_connman_device(path, modem->operator);
+
+ __set_device_powered(modem, modem->powered);
+
+ if (modem->powered != TRUE) {
+ DBG("modem is not powered");
+ return TRUE;
+ }
+
+ if(!modem->s_service){
+ __request_get_services(modem->path);
+ return TRUE;
+ }
+
+ if(modem->flight_mode || !modem->data_allowed){
+ DBG("modem(%s) flight mode(%d) data allowed(%d)", modem->path, modem->flight_mode, modem->data_allowed);
+ return TRUE;
+ }
+
+ return TRUE;
+}
+
+static gboolean __added_modem(DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ DBG("modem added signal");
+
+ const char *modem_path = NULL;
+ DBusMessageIter args, dict, tmp;
+
+ DBG("message signature (%s)", dbus_message_get_signature(message));
+ if (dbus_message_iter_init(message, &args) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_recurse(&args, &dict);
+ memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
+
+ while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char *key, *value;
+
+ dbus_message_iter_recurse(&tmp, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &value);
+
+ DBG("key (%s) value(%s)", key, value);
+
+ if (g_str_equal(key, "path") == TRUE) {
+ modem_path = g_strdup(value);
+ }
+
+ dbus_message_iter_next(&tmp);
+ }
+
+ if (modem_path != NULL) {
+ __add_modem(modem_path, &dict);
+ }
+
+ return TRUE;
+}
+
+static gboolean __removed_modem(DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ DBG("modem removed signal");
+
+ DBusMessageIter iter;
+ const char *modem_path;
+
+ if (dbus_message_iter_init(message, &iter) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_get_basic(&iter, &modem_path);
+ g_hash_table_remove(modem_hash, modem_path);
+
+ return TRUE;
+}
+
+static gboolean __changed_service(DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ DBG("service changed signal");
+
+ DBusMessageIter args, dict;
+ const char *service_path = dbus_message_get_path(message);
+ struct telephony_modem *modem;
+ struct telephony_service *s_service;
+ gboolean roaming_option = TRUE;
+
+ DBG("service path %s", service_path);
+
+ s_service = g_hash_table_lookup(service_hash, service_path);
+ if (s_service == NULL) {
+ DBG("service object does not exists");
+ return TRUE;
+ }
+
+ modem = s_service->p_modem;
+ if (modem == NULL) {
+ DBG("modem object does not exists");
+ return TRUE;
+ }
+
+ DBG("message signature (%s)", dbus_message_get_signature(message));
+
+ if (dbus_message_iter_init(message, &args) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_recurse(&args, &dict);
+
+ while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char* key, *tmp;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &tmp);
+
+ DBG("key(%s), value(%s)", key, tmp);
+
+ if (g_str_equal(key, "roaming") == TRUE) {
+ s_service->roaming = STRING2BOOL(tmp);
+ } else if (g_str_equal(key, "act") == TRUE) {
+ s_service->act = g_strdup(tmp);
+ } else if (g_str_equal(key, "ps_attached") == TRUE) {
+ s_service->ps_attached = STRING2BOOL(tmp);
+ }
+
+ dbus_message_iter_next(&dict);
+ }
+
+ roaming_option &= (!s_service->roaming && !modem->roaming_allowed) || modem->roaming_allowed;
+
+ return TRUE;
+}
+
+
+static gboolean __added_service(DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ DBG("service added signal");
+
+ const char *path = dbus_message_get_path(message);
+ const char *service_path = NULL;
+ DBusMessageIter args, dict, tmp;
+ struct telephony_modem *modem;
+
+ modem = g_hash_table_lookup(modem_hash, path);
+ if (modem == NULL || modem->device == NULL)
+ return TRUE;
+
+ DBG("message signature (%s)", dbus_message_get_signature(message));
+ if (dbus_message_iter_init(message, &args) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_recurse(&args, &dict);
+ memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
+
+ while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char *key, *value;
+
+ dbus_message_iter_recurse(&tmp, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &value);
+
+ DBG("key (%s) value(%s)", key, value);
+
+ if (g_str_equal(key, "path") == TRUE) {
+ service_path = g_strdup(value);
+ }
+
+ dbus_message_iter_next(&tmp);
+ }
+
+ if (service_path != NULL) {
+ __add_service(modem, service_path, &dict);
+ }
+
+ return TRUE;
+}
+
+static gboolean __removed_service(DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ DBG("service removed signal");
+
+ DBusMessageIter iter;
+ const char *service_path;
+
+ if (dbus_message_iter_init(message, &iter) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_get_basic(&iter, &service_path);
+ g_hash_table_remove(service_hash, service_path);
+
+ return TRUE;
+}
+
+static gboolean __changed_context(DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ DBG("network changed signal");
+
+ gboolean active = FALSE;
+ const char *path = dbus_message_get_path(message);
+ struct telephony_network *info;
+ DBusMessageIter args, dict;
+
+ DBG("path %s", path);
+ info = g_hash_table_lookup(network_hash, path);
+ if (info == NULL)
+ return TRUE;
+
+ if (!__check_network_available(info->network)) {
+ g_hash_table_remove(network_hash, path);
+ return TRUE;
+ }
+
+ if (dbus_message_iter_init(message, &args) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_recurse(&args, &dict);
+
+ active = __set_network_ipconfig(info, &dict);
+
+ if (active == FALSE)
+ __set_network_connected(info, active);
+ else if ( (connman_network_get_connecting(info->network) ||
+ connman_network_get_associating(info->network)) )
+ __set_network_connected(info, active);
+
+ return TRUE;
+}
+
+static gboolean __added_context(DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ DBG("network added signal");
+
+ DBusMessageIter args, dict, tmp;
+ const char *path = dbus_message_get_path(message);
+ const char *network_path = NULL;
+ struct telephony_service *service = NULL;
+ struct telephony_modem *modem = NULL;
+
+ service = g_hash_table_lookup(service_hash, path);
+ if (service == NULL || service->p_modem == NULL)
+ return TRUE;
+
+ modem = service->p_modem;
+ if(modem == NULL || modem->device == NULL)
+ return TRUE;
+
+ DBG("message signature (%s)", dbus_message_get_signature(message));
+ if (dbus_message_iter_init(message, &args) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_recurse(&args, &dict);
+ memcpy(&tmp, &dict, sizeof(struct DBusMessageIter));
+
+ while (dbus_message_iter_get_arg_type(&tmp) != DBUS_TYPE_INVALID) {
+ DBusMessageIter entry;
+ const char *key, *value;
+
+ dbus_message_iter_recurse(&tmp, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &value);
+
+ DBG("key (%s) value(%s)", key, value);
+
+ if (g_str_equal(key, "path") == TRUE) {
+ network_path = g_strdup(value);
+ }
+
+ dbus_message_iter_next(&tmp);
+ }
+
+ if (network_path != NULL) {
+ __add_context(modem->device, network_path, &dict);
+ }
+
+ return TRUE;
+}
+
+static gboolean __removed_context(DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ DBG("network removed signal");
+
+ DBusMessageIter iter;
+ const char *path = dbus_message_get_path(message);
+ const char *network_path = NULL;
+ struct telephony_service *service = NULL;
+
+ service = g_hash_table_lookup(service_hash, path);
+ if (service == NULL || service->p_modem == NULL)
+ return TRUE;
+
+ if (dbus_message_iter_init(message, &iter) == FALSE) {
+ DBG("error to read message");
+ return TRUE;
+ }
+
+ dbus_message_iter_get_basic(&iter, &network_path);
+ g_hash_table_remove(network_hash, network_path);
+
+ return TRUE;
+}
+
+// telephony initialization
+static guint watch;
+static guint modem_watch;
+static guint modem_added_watch;
+static guint modem_removed_watch;
+static guint service_watch;
+static guint service_added_watch;
+static guint service_removed_watch;
+static guint context_watch;
+static guint context_added_watch;
+static guint context_removed_watch;
+
+static int telephony_init(void)
+{
+ DBG("telephony plugin");
+ int err;
+
+ connection = connman_dbus_get_connection();
+ if (connection == NULL)
+ return -EIO;
+
+ // telephony watch
+ watch = g_dbus_add_service_watch(connection, PS_DBUS_SERVICE, telephony_connect, telephony_disconnect, NULL, NULL);
+
+ modem_watch = g_dbus_add_signal_watch(connection, NULL, NULL, PS_MODEM_INTERFACE,
+ PROPERTY_CHANGED, __changed_modem, NULL, NULL);
+
+ modem_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL, PS_MASTER_INTERFACE,
+ MODEM_ADDED, __added_modem, NULL, NULL);
+
+ modem_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL, PS_MASTER_INTERFACE,
+ MODEM_REMOVED, __removed_modem, NULL, NULL);
+
+ service_watch = g_dbus_add_signal_watch(connection, NULL, NULL, PS_SERVICE_INTERFACE,
+ PROPERTY_CHANGED, __changed_service, NULL, NULL);
+
+ service_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL, PS_MODEM_INTERFACE,
+ SERVICE_ADDED, __added_service, NULL, NULL);
+
+ service_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL, PS_MODEM_INTERFACE,
+ SERVICE_REMOVED, __removed_service, NULL, NULL);
+
+ context_watch = g_dbus_add_signal_watch(connection, NULL, NULL, PS_CONTEXT_INTERFACE,
+ PROPERTY_CHANGED, __changed_context, NULL, NULL);
+
+ context_added_watch = g_dbus_add_signal_watch(connection, NULL, NULL, PS_SERVICE_INTERFACE,
+ CONTEXT_ADDED, __added_context, NULL, NULL);
+
+ context_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL, PS_SERVICE_INTERFACE,
+ CONTEXT_REMOVED, __removed_context, NULL, NULL);
+
+ if (watch == 0 || modem_watch == 0 || modem_added_watch == 0 || modem_removed_watch == 0
+ || service_watch == 0 || service_added_watch == 0 || service_removed_watch == 0
+ || context_watch == 0 || context_added_watch == 0 || context_removed_watch == 0) {
+ err = -EIO;
+ goto remove;
+ }
+
+ err = connman_network_driver_register(&network_driver);
+ if (err < 0)
+ goto remove;
+
+ err = connman_device_driver_register(&modem_driver);
+ if (err < 0) {
+ connman_network_driver_unregister(&network_driver);
+ goto remove;
+ }
+
+ err = connman_technology_driver_register(&tech_driver);
+ if (err < 0) {
+ connman_device_driver_unregister(&modem_driver);
+ connman_network_driver_unregister(&network_driver);
+ goto remove;
+ }
+
+ return 0;
+
+remove:
+ g_dbus_remove_watch(connection, watch);
+ g_dbus_remove_watch(connection, modem_watch);
+ g_dbus_remove_watch(connection, modem_added_watch);
+ g_dbus_remove_watch(connection, modem_removed_watch);
+ g_dbus_remove_watch(connection, service_watch);
+ g_dbus_remove_watch(connection, service_added_watch);
+ g_dbus_remove_watch(connection, service_removed_watch);
+ g_dbus_remove_watch(connection, context_watch);
+ g_dbus_remove_watch(connection, context_added_watch);
+ g_dbus_remove_watch(connection, context_removed_watch);
+
+ dbus_connection_unref(connection);
+ return err;
+}
+
+static void telephony_exit(void)
+{
+ g_dbus_remove_watch(connection, watch);
+ g_dbus_remove_watch(connection, modem_watch);
+ g_dbus_remove_watch(connection, modem_added_watch);
+ g_dbus_remove_watch(connection, modem_removed_watch);
+ g_dbus_remove_watch(connection, service_watch);
+ g_dbus_remove_watch(connection, service_added_watch);
+ g_dbus_remove_watch(connection, service_removed_watch);
+ g_dbus_remove_watch(connection, context_watch);
+ g_dbus_remove_watch(connection, context_added_watch);
+ g_dbus_remove_watch(connection, context_removed_watch);
+
+ telephony_disconnect(connection, NULL);
+
+ connman_device_driver_unregister(&modem_driver);
+ connman_network_driver_unregister(&network_driver);
+
+ dbus_connection_unref(connection);
+}
+
+CONNMAN_PLUGIN_DEFINE(telephony, "Samsung Telephony Framework plug-in", VERSION,
+ CONNMAN_PLUGIN_PRIORITY_DEFAULT, telephony_init, telephony_exit)
*
* Connection Manager
*
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <dbus/dbus.h>
+#include <glib/ghash.h>
#include <glib/gprintf.h>
#include <connman/provider.h>
stop_vpn(provider);
connman_provider_set_data(provider, NULL);
-
- if (data->watch != 0) {
- connman_provider_unref(provider);
- connman_rtnl_remove_watch(data->watch);
- data->watch = 0;
- }
+ connman_rtnl_remove_watch(data->watch);
vpn_exit:
if (state != VPN_STATE_READY && state != VPN_STATE_DISCONNECT) {
CONNMAN_PROVIDER_STATE_IDLE);
connman_provider_set_index(provider, -1);
+ connman_provider_unref(data->provider);
- if (data != NULL) {
- connman_provider_unref(data->provider);
- g_free(data->if_name);
- g_free(data);
- }
+ g_free(data->if_name);
+ g_free(data);
connman_task_destroy(task);
}
case VPN_STATE_CONNECT:
case VPN_STATE_READY:
index = connman_provider_get_index(provider);
- connman_provider_ref(provider);
data->watch = connman_rtnl_add_newlink_watch(index,
vpn_newlink, provider);
connman_inet_ifup(index);
vpn_driver_data = g_hash_table_lookup(driver_hash, name);
- if (vpn_driver_data == NULL || vpn_driver_data->vpn_driver == NULL) {
- ret = -EINVAL;
- goto exist_err;
- }
+ if (vpn_driver_data != NULL && vpn_driver_data->vpn_driver != NULL &&
+ vpn_driver_data->vpn_driver->flags != VPN_FLAG_NO_TUN) {
- if (vpn_driver_data->vpn_driver->flags != VPN_FLAG_NO_TUN) {
ret = vpn_create_tun(provider);
if (ret < 0)
goto exist_err;
if (vpn_driver_data->vpn_driver->disconnect)
vpn_driver_data->vpn_driver->disconnect();
- if (data->watch != 0) {
- connman_provider_unref(provider);
+ if (data->watch != 0)
connman_rtnl_remove_watch(data->watch);
- data->watch = 0;
- }
+ data->watch = 0;
data->state = VPN_STATE_DISCONNECT;
connman_task_stop(data->task);
if (data == NULL)
return 0;
- if (data->watch != 0) {
- connman_provider_unref(provider);
+ if (data->watch != 0)
connman_rtnl_remove_watch(data->watch);
- data->watch = 0;
- }
-
+ data->watch = 0;
connman_task_stop(data->task);
g_usleep(G_USEC_PER_SEC);
data->provider_driver.remove = vpn_remove;
data->provider_driver.save = vpn_save;
- if (driver_hash == NULL)
+ if (driver_hash == NULL) {
driver_hash = g_hash_table_new_full(g_str_hash,
g_str_equal,
NULL, g_free);
-
- if (driver_hash == NULL) {
- connman_error("driver_hash not initialized for %s", name);
- g_free(data);
- return -ENOMEM;
}
- g_hash_table_replace(driver_hash, (char *)name, data);
+ g_hash_table_insert(driver_hash, (char *)name, data);
connman_provider_driver_register(&data->provider_driver);
const char *vpnc_opt;
const char *vpnc_default;
int type;
- connman_bool_t cm_save;
} vpnc_options[] = {
- { "Host", "IPSec gateway", NULL, OPT_STRING, TRUE },
- { "VPNC.IPSec.ID", "IPSec ID", NULL, OPT_STRING, TRUE },
- { "VPNC.IPSec.Secret", "IPSec secret", NULL, OPT_STRING, FALSE },
- { "VPNC.Xauth.Username", "Xauth username", NULL, OPT_STRING, FALSE },
- { "VPNC.Xauth.Password", "Xauth password", NULL, OPT_STRING, FALSE },
- { "VPNC.IKE.Authmode", "IKE Authmode", NULL, OPT_STRING, TRUE },
- { "VPNC.IKE.DHGroup", "IKE DH Group", NULL, OPT_STRING, TRUE },
- { "VPNC.PFS", "Perfect Forward Secrecy", NULL, OPT_STRING, TRUE },
- { "VPNC.Domain", "Domain", NULL, OPT_STRING, TRUE },
- { "VPNC.Vendor", "Vendor", NULL, OPT_STRING, TRUE },
- { "VPNC.LocalPort", "Local Port", "0", OPT_STRING, TRUE, },
- { "VPNC.CiscoPort","Cisco UDP Encapsulation Port", "0", OPT_STRING,
- TRUE },
- { "VPNC.AppVersion", "Application Version", NULL, OPT_STRING, TRUE },
- { "VPNC.NATTMode", "NAT Traversal Mode", "cisco-udp", OPT_STRING,
- TRUE },
- { "VPNC.DPDTimeout", "DPD idle timeout (our side)", NULL, OPT_STRING,
- TRUE },
- { "VPNC.SingleDES", "Enable Single DES", NULL, OPT_BOOLEAN, TRUE },
- { "VPNC.NoEncryption", "Enable no encryption", NULL, OPT_BOOLEAN,
- TRUE },
+ { "Host", "IPSec gateway", NULL, OPT_STRING },
+ { "VPNC.IPSec.ID", "IPSec ID", NULL, OPT_STRING },
+ { "VPNC.IPSec.Secret", "IPSec secret", NULL, OPT_STRING },
+ { "VPNC.Xauth.Username", "Xauth username", NULL, OPT_STRING },
+ { "VPNC.Xauth.Password", "Xauth password", NULL, OPT_STRING },
+ { "VPNC.IKE.Authmode", "IKE Authmode", NULL, OPT_STRING },
+ { "VPNC.IKE.DHGroup", "IKE DH Group", NULL, OPT_STRING },
+ { "VPNC.PFS", "Perfect Forward Secrecy", NULL, OPT_STRING },
+ { "VPNC.Domain", "Domain", NULL, OPT_STRING },
+ { "VPNC.Vendor", "Vendor", NULL, OPT_STRING },
+ { "VPNC.LocalPort", "Local Port", "0", OPT_STRING },
+ { "VPNC.CiscoPort","Cisco UDP Encapsulation Port", "0", OPT_STRING },
+ { "VPNC.AppVersion", "Application Version", NULL, OPT_STRING },
+ { "VPNC.NATTMode", "NAT Traversal Mode", "cisco-udp", OPT_STRING },
+ { "VPNC.DPDTimeout", "DPD idle timeout (our side)", NULL, OPT_STRING },
+ { "VPNC.SingleDES", "Enable Single DES", NULL, OPT_BOOLEAN },
+ { "VPNC.NoEncryption", "Enable no encryption", NULL, OPT_BOOLEAN },
};
static int vc_notify(DBusMessage *msg, struct connman_provider *provider)
static int vc_save(struct connman_provider *provider, GKeyFile *keyfile)
{
- const char *option;
+ char *option;
int i;
for (i = 0; i < (int)ARRAY_SIZE(vpnc_options); i++) {
if (strncmp(vpnc_options[i].cm_opt, "VPNC.", 5) == 0) {
-
- if (vpnc_options[i].cm_save == FALSE)
- continue;
-
option = connman_provider_get_string(provider,
vpnc_options[i].cm_opt);
if (option == NULL)
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <connman/log.h>
#include <connman/option.h>
#include <connman/storage.h>
-#include <include/setting.h>
#include <gsupplicant/gsupplicant.h>
#define CLEANUP_TIMEOUT 8 /* in seconds */
#define INACTIVE_TIMEOUT 12 /* in seconds */
+#if defined TIZEN_EXT
+/*
+ * Jan, 9th 2012. TIZEN
+ * Remove reconnect procedure after getting disassoc event
+ */
+#define MAXIMUM_RETRIES 1
+#else
#define MAXIMUM_RETRIES 4
+#endif
-#define BGSCAN_DEFAULT "simple:30:-45:300"
-#define AUTOSCAN_DEFAULT "exponential:3:300"
-
-static struct connman_technology *wifi_technology = NULL;
-
-struct hidden_params {
- char ssid[32];
- unsigned int ssid_len;
- char *identity;
- char *passphrase;
- gpointer user_data;
-};
-
-/**
- * Used for autoscan "emulation".
- * Should be removed when wpa_s autoscan support will be by default.
- */
-struct autoscan_params {
- int base;
- int limit;
- int interval;
- unsigned int timeout;
-};
+struct connman_technology *wifi_technology = NULL;
struct wifi_data {
char *identifier;
unsigned flags;
unsigned int watch;
int retries;
- struct hidden_params *hidden;
- /**
- * autoscan "emulation".
- */
- struct autoscan_params *autoscan;
};
-static GList *iface_list = NULL;
+#if defined TIZEN_EXT
+struct callback_data {
+ struct wifi_data *wifi_inf_data;
+ void *data;
+};
+#endif
-static void start_autoscan(struct connman_device *device);
+static GList *iface_list = NULL;
static void handle_tethering(struct wifi_data *wifi)
{
struct connman_device *device = user_data;
struct wifi_data *wifi = connman_device_get_data(device);
- if (wifi == NULL)
- return;
-
DBG("index %d flags %d change %d", wifi->index, flags, change);
if (!change)
wifi->networks = NULL;
}
-static void reset_autoscan(struct connman_device *device)
-{
- struct wifi_data *wifi = connman_device_get_data(device);
- struct autoscan_params *autoscan;
-
- DBG("");
-
- if (wifi == NULL || wifi->autoscan == NULL)
- return;
-
- autoscan = wifi->autoscan;
-
- if (autoscan->timeout == 0 && autoscan->interval == 0)
- return;
-
- g_source_remove(autoscan->timeout);
-
- autoscan->timeout = 0;
- autoscan->interval = 0;
-
- connman_device_unref(device);
-}
-
-static void stop_autoscan(struct connman_device *device)
-{
- reset_autoscan(device);
-
- connman_device_set_scanning(device, FALSE);
-}
-
static void wifi_remove(struct connman_device *device)
{
struct wifi_data *wifi = connman_device_get_data(device);
remove_networks(device, wifi);
- connman_device_set_powered(device, FALSE);
connman_device_set_data(device, NULL);
connman_device_unref(wifi->device);
connman_rtnl_remove_watch(wifi->watch);
g_supplicant_interface_set_data(wifi->interface, NULL);
- g_free(wifi->autoscan);
- g_free(wifi->identifier);
- g_free(wifi);
-}
-
-static int add_scan_param(gchar *hex_ssid, int freq,
- GSupplicantScanParams *scan_data,
- int driver_max_scan_ssids)
-{
- unsigned int i;
- struct scan_ssid *scan_ssid;
-
- if (driver_max_scan_ssids > scan_data->num_ssids && hex_ssid != NULL) {
- gchar *ssid;
- unsigned int j = 0, hex;
- size_t hex_ssid_len = strlen(hex_ssid);
-
- ssid = g_try_malloc0(hex_ssid_len / 2);
- if (ssid == NULL)
- return -ENOMEM;
-
- for (i = 0; i < hex_ssid_len; i += 2) {
- sscanf(hex_ssid + i, "%02x", &hex);
- ssid[j++] = hex;
- }
-
- scan_ssid = g_try_new(struct scan_ssid, 1);
- if (scan_ssid == NULL) {
- g_free(ssid);
- return -ENOMEM;
- }
-
- memcpy(scan_ssid->ssid, ssid, j);
- scan_ssid->ssid_len = j;
- scan_data->ssids = g_slist_prepend(scan_data->ssids,
- scan_ssid);
-
- scan_data->num_ssids++;
-
- g_free(ssid);
- } else
- return -EINVAL;
-
- scan_data->ssids = g_slist_reverse(scan_data->ssids);
-
- if (scan_data->freqs == NULL) {
- scan_data->freqs = g_try_malloc0(sizeof(uint16_t) *
- scan_data->num_ssids);
- if (scan_data->freqs == NULL) {
- g_slist_free_full(scan_data->ssids, g_free);
- return -ENOMEM;
- }
- } else {
- scan_data->freqs = g_try_realloc(scan_data->freqs,
- sizeof(uint16_t) * scan_data->num_ssids);
- if (scan_data->freqs == NULL) {
- g_slist_free_full(scan_data->ssids, g_free);
- return -ENOMEM;
- }
- scan_data->freqs[scan_data->num_ssids - 1] = 0;
- }
-
- /* Don't add duplicate entries */
- for (i = 0; i < scan_data->num_ssids; i++) {
- if (scan_data->freqs[i] == 0) {
- scan_data->freqs[i] = freq;
- break;
- } else if (scan_data->freqs[i] == freq)
- break;
- }
-
- return 0;
-}
-
-static int get_hidden_connections(int max_ssids,
- GSupplicantScanParams *scan_data)
-{
- GKeyFile *keyfile;
- gchar **services;
- char *ssid;
- gchar *str;
- int i, freq;
- gboolean value;
- int num_ssids = 0, add_param_failed = 0;
-
- services = connman_storage_get_services();
- for (i = 0; services && services[i]; i++) {
- if (strncmp(services[i], "wifi_", 5) != 0)
- continue;
-
- keyfile = connman_storage_load_service(services[i]);
-
- value = g_key_file_get_boolean(keyfile,
- services[i], "Hidden", NULL);
- if (value == FALSE) {
- g_key_file_free(keyfile);
- continue;
- }
-
- value = g_key_file_get_boolean(keyfile,
- services[i], "Favorite", NULL);
- if (value == FALSE) {
- g_key_file_free(keyfile);
- continue;
- }
-
- value = g_key_file_get_boolean(keyfile,
- services[i], "AutoConnect", NULL);
- if (value == FALSE) {
- g_key_file_free(keyfile);
- continue;
- }
-
- ssid = g_key_file_get_string(keyfile,
- services[i], "SSID", NULL);
-
- freq = g_key_file_get_integer(keyfile, services[i],
- "Frequency", NULL);
-
- if (add_scan_param(ssid, freq, scan_data, max_ssids) < 0) {
- str = g_key_file_get_string(keyfile,
- services[i], "Name", NULL);
- DBG("Cannot scan %s (%s)", ssid, str);
- g_free(str);
- add_param_failed++;
- }
-
- num_ssids++;
-
- g_key_file_free(keyfile);
- }
-
- if (add_param_failed > 0)
- connman_warn("Unable to scan %d out of %d SSIDs (max is %d)",
- add_param_failed, num_ssids, max_ssids);
-
- g_strfreev(services);
-
- return num_ssids > max_ssids ? max_ssids : num_ssids;
-}
-
-static int throw_wifi_scan(struct connman_device *device,
- GSupplicantInterfaceCallback callback)
-{
- struct wifi_data *wifi = connman_device_get_data(device);
- int ret;
-
- if (wifi == NULL)
- return -ENODEV;
-
- DBG("device %p %p", device, wifi->interface);
-
- if (wifi->tethering == TRUE)
- return 0;
-
- if (connman_device_get_scanning(device) == TRUE)
- return -EALREADY;
-
- connman_device_ref(device);
-
- ret = g_supplicant_interface_scan(wifi->interface, NULL,
- callback, device);
- if (ret == 0)
- connman_device_set_scanning(device, TRUE);
- else
- connman_device_unref(device);
-
- return ret;
-}
-
-static void hidden_free(struct hidden_params *hidden)
-{
- if (hidden == NULL)
- return;
-
- g_free(hidden->identity);
- g_free(hidden->passphrase);
- g_free(hidden);
-}
-
-static void scan_callback(int result, GSupplicantInterface *interface,
- void *user_data)
-{
- struct connman_device *device = user_data;
- struct wifi_data *wifi = connman_device_get_data(device);
-
- DBG("result %d wifi %p", result, wifi);
-
- if (wifi != NULL && wifi->hidden != NULL) {
- connman_network_clear_hidden(wifi->hidden->user_data);
- hidden_free(wifi->hidden);
- wifi->hidden = NULL;
- }
-
- if (result < 0)
- connman_device_reset_scanning(device);
-
- connman_device_set_scanning(device, FALSE);
- start_autoscan(device);
- connman_device_unref(device);
-}
-
-static void scan_callback_hidden(int result,
- GSupplicantInterface *interface, void *user_data)
-{
- struct connman_device *device = user_data;
- struct wifi_data *wifi = connman_device_get_data(device);
- int driver_max_ssids;
-
- DBG("result %d wifi %p", result, wifi);
-
- if (wifi == NULL)
- goto out;
-
- /*
- * Scan hidden networks so that we can autoconnect to them.
- */
- driver_max_ssids = g_supplicant_interface_get_max_scan_ssids(
- wifi->interface);
- DBG("max ssids %d", driver_max_ssids);
-
- if (driver_max_ssids > 0) {
- GSupplicantScanParams *scan_params;
- int ret;
-
- scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
- if (scan_params == NULL)
- goto out;
-
- if (get_hidden_connections(driver_max_ssids,
- scan_params) > 0) {
- ret = g_supplicant_interface_scan(wifi->interface,
- scan_params,
- scan_callback,
- device);
- if (ret == 0)
- return;
- }
-
- g_supplicant_free_scan_params(scan_params);
- }
-
-out:
- scan_callback(result, interface, user_data);
-}
-
-static gboolean autoscan_timeout(gpointer data)
-{
- struct connman_device *device = data;
- struct wifi_data *wifi = connman_device_get_data(device);
- struct autoscan_params *autoscan;
- int interval;
-
- if (wifi == NULL)
- return FALSE;
-
- autoscan = wifi->autoscan;
-
- if (autoscan->interval <= 0) {
- interval = autoscan->base;
- goto set_interval;
- } else
- interval = autoscan->interval * autoscan->base;
-
- if (autoscan->interval >= autoscan->limit)
- interval = autoscan->limit;
-
- throw_wifi_scan(wifi->device, scan_callback_hidden);
-
-set_interval:
- DBG("interval %d", interval);
-
- autoscan->interval = interval;
-
- autoscan->timeout = g_timeout_add_seconds(interval,
- autoscan_timeout, device);
-
- return FALSE;
-}
-
-static void start_autoscan(struct connman_device *device)
-{
- struct wifi_data *wifi = connman_device_get_data(device);
- struct autoscan_params *autoscan;
-
- DBG("");
-
- if (wifi == NULL)
- return;
-
- autoscan = wifi->autoscan;
- if (autoscan == NULL)
- return;
-
- if (autoscan->timeout > 0 || autoscan->interval > 0)
- return;
-
- connman_device_ref(device);
-
- autoscan_timeout(device);
-}
-
-static struct autoscan_params *parse_autoscan_params(const char *params)
-{
- struct autoscan_params *autoscan;
- char **list_params;
- int limit;
- int base;
-
- DBG("Emulating autoscan");
-
- list_params = g_strsplit(params, ":", 0);
- if (list_params == 0)
- return NULL;
-
- if (g_strv_length(list_params) < 3) {
- g_strfreev(list_params);
- return NULL;
- }
-
- base = atoi(list_params[1]);
- limit = atoi(list_params[2]);
-
- g_strfreev(list_params);
-
- autoscan = g_try_malloc0(sizeof(struct autoscan_params));
- if (autoscan == NULL) {
- DBG("Could not allocate memory for autoscan");
- return NULL;
- }
-
- DBG("base %d - limit %d", base, limit);
- autoscan->base = base;
- autoscan->limit = limit;
-
- return autoscan;
-}
-
-static void setup_autoscan(struct wifi_data *wifi)
-{
- if (wifi->autoscan == NULL)
- wifi->autoscan = parse_autoscan_params(AUTOSCAN_DEFAULT);
-
- start_autoscan(wifi->device);
-}
-
-static void interface_autoscan_callback(int result,
- GSupplicantInterface *interface,
- void *user_data)
-{
- struct wifi_data *wifi = user_data;
-
- if (result < 0) {
- DBG("Could not enable Autoscan, falling back...");
- setup_autoscan(wifi);
- }
+ g_free(wifi->identifier);
+ g_free(wifi);
}
static void interface_create_callback(int result,
if (result < 0 || wifi == NULL)
return;
+#if defined TIZEN_EXT
+ if (g_list_find(iface_list, wifi) == NULL) {
+ return;
+ }
+#endif
wifi->interface = interface;
g_supplicant_interface_set_data(interface, wifi);
}
connman_device_set_powered(wifi->device, TRUE);
+}
+
+static void interface_remove_callback(int result,
+ GSupplicantInterface *interface,
+ void *user_data)
+{
+ struct wifi_data *wifi;
+
+ wifi = g_supplicant_interface_get_data(interface);
+
+ DBG("result %d wifi %p", result, wifi);
- if (connman_setting_get_bool("BackgroundScanning") == FALSE)
+ if (result < 0 || wifi == NULL)
return;
- /* Setting up automatic scanning */
- if (g_supplicant_interface_autoscan(interface, AUTOSCAN_DEFAULT,
- interface_autoscan_callback, wifi) < 0) {
- DBG("Could not enable Autoscan, falling back...");
- setup_autoscan(wifi);
- }
+ wifi->interface = NULL;
}
+
static int wifi_enable(struct connman_device *device)
{
struct wifi_data *wifi = connman_device_get_data(device);
DBG("device %p %p", device, wifi);
- if (wifi == NULL)
- return -ENODEV;
-
ret = g_supplicant_interface_create(interface, driver, NULL,
interface_create_callback,
wifi);
struct wifi_data *wifi = connman_device_get_data(device);
int ret;
- DBG("device %p wifi %p", device, wifi);
-
- if (wifi == NULL)
- return -ENODEV;
+ DBG("device %p", device);
wifi->connected = FALSE;
wifi->disconnecting = FALSE;
if (wifi->pending_network != NULL)
wifi->pending_network = NULL;
- stop_autoscan(device);
+ remove_networks(device, wifi);
/* In case of a user scan, device is still referenced */
if (connman_device_get_scanning(device) == TRUE) {
connman_device_unref(wifi->device);
}
- remove_networks(device, wifi);
-
- ret = g_supplicant_interface_remove(wifi->interface, NULL, NULL);
+ ret = g_supplicant_interface_remove(wifi->interface,
+ interface_remove_callback,
+ NULL);
if (ret < 0)
return ret;
return -EINPROGRESS;
}
+static void scan_callback(int result, GSupplicantInterface *interface,
+ void *user_data)
+{
+ struct connman_device *device = user_data;
+
+ DBG("result %d", result);
+
+ if (result < 0)
+ connman_device_reset_scanning(device);
+ else
+ connman_device_set_scanning(device, FALSE);
+ connman_device_unref(device);
+}
+
+static int add_scan_param(gchar *hex_ssid, int freq,
+ GSupplicantScanParams *scan_data,
+ int driver_max_scan_ssids)
+{
+ unsigned int i;
+
+ if (driver_max_scan_ssids > scan_data->num_ssids && hex_ssid != NULL) {
+ gchar *ssid;
+ unsigned int j = 0, hex;
+ size_t hex_ssid_len = strlen(hex_ssid);
+
+ ssid = g_try_malloc0(hex_ssid_len / 2);
+ if (ssid == NULL)
+ return -ENOMEM;
+
+ for (i = 0; i < hex_ssid_len; i += 2) {
+ sscanf(hex_ssid + i, "%02x", &hex);
+ ssid[j++] = hex;
+ }
+
+ memcpy(scan_data->ssids[scan_data->num_ssids].ssid, ssid, j);
+ scan_data->ssids[scan_data->num_ssids].ssid_len = j;
+ scan_data->num_ssids++;
+
+ g_free(ssid);
+ }
+
+ /* Don't add duplicate entries */
+ for (i = 0; i < G_SUPPLICANT_MAX_FAST_SCAN; i++) {
+ if (scan_data->freqs[i] == 0) {
+ scan_data->freqs[i] = freq;
+ break;
+ } else if (scan_data->freqs[i] == freq)
+ break;
+ }
+
+ return 0;
+}
+
struct last_connected {
GTimeVal modified;
gchar *ssid;
g_strfreev(services);
- num_ssids = num_ssids > max_ssids ? max_ssids : num_ssids;
+ num_ssids = num_ssids > G_SUPPLICANT_MAX_FAST_SCAN ?
+ G_SUPPLICANT_MAX_FAST_SCAN : num_ssids;
iter = g_sequence_get_begin_iter(latest_list);
static int wifi_scan(struct connman_device *device)
{
- reset_autoscan(device);
-
- return throw_wifi_scan(device, scan_callback_hidden);
-}
-
-static int wifi_scan_fast(struct connman_device *device)
-{
struct wifi_data *wifi = connman_device_get_data(device);
- GSupplicantScanParams *scan_params = NULL;
int ret;
- int driver_max_ssids = 0;
-
- if (wifi == NULL)
- return -ENODEV;
DBG("device %p %p", device, wifi->interface);
if (connman_device_get_scanning(device) == TRUE)
return -EALREADY;
- driver_max_ssids = g_supplicant_interface_get_max_scan_ssids(
- wifi->interface);
- DBG("max ssids %d", driver_max_ssids);
- if (driver_max_ssids == 0)
- return wifi_scan(device);
-
- scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
- if (scan_params == NULL)
- return -ENOMEM;
-
- ret = get_latest_connections(driver_max_ssids, scan_params);
- if (ret <= 0) {
- g_supplicant_free_scan_params(scan_params);
- return wifi_scan(device);
- }
-
connman_device_ref(device);
- reset_autoscan(device);
-
- ret = g_supplicant_interface_scan(wifi->interface, scan_params,
- scan_callback, device);
+ ret = g_supplicant_interface_scan(wifi->interface, NULL,
+ scan_callback, device);
if (ret == 0)
connman_device_set_scanning(device, TRUE);
- else {
- g_supplicant_free_scan_params(scan_params);
+ else
connman_device_unref(device);
- }
return ret;
}
-/*
- * This func is only used when connecting to this specific AP first time.
- * It is not used when system autoconnects to hidden AP.
- */
-static int wifi_scan_hidden(struct connman_device *device,
- const char *ssid, unsigned int ssid_len,
- const char *identity, const char* passphrase,
- gpointer user_data)
+static int wifi_scan_fast(struct connman_device *device)
{
struct wifi_data *wifi = connman_device_get_data(device);
GSupplicantScanParams *scan_params = NULL;
- struct scan_ssid *scan_ssid;
- struct hidden_params *hidden;
int ret;
+ int driver_max_ssids = 0;
- if (wifi == NULL)
- return -ENODEV;
-
- DBG("hidden SSID %s", ssid);
-
- if (wifi->tethering == TRUE || wifi->hidden != NULL)
- return -EBUSY;
+ DBG("device %p %p", device, wifi->interface);
- if (ssid == NULL || ssid_len == 0 || ssid_len > 32)
- return -EINVAL;
+ if (wifi->tethering == TRUE)
+ return 0;
if (connman_device_get_scanning(device) == TRUE)
return -EALREADY;
+ driver_max_ssids = g_supplicant_interface_get_max_scan_ssids(
+ wifi->interface);
+ DBG("max ssids %d", driver_max_ssids);
+ if (driver_max_ssids == 0)
+ return wifi_scan(device);
+
scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
if (scan_params == NULL)
return -ENOMEM;
- scan_ssid = g_try_new(struct scan_ssid, 1);
- if (scan_ssid == NULL) {
- g_free(scan_params);
- return -ENOMEM;
- }
-
- memcpy(scan_ssid->ssid, ssid, ssid_len);
- scan_ssid->ssid_len = ssid_len;
- scan_params->ssids = g_slist_prepend(scan_params->ssids, scan_ssid);
-
- scan_params->num_ssids = 1;
-
- hidden = g_try_new0(struct hidden_params, 1);
- if (hidden == NULL) {
+ ret = get_latest_connections(driver_max_ssids, scan_params);
+ if (ret <= 0) {
g_free(scan_params);
- return -ENOMEM;
+ return wifi_scan(device);
}
- memcpy(hidden->ssid, ssid, ssid_len);
- hidden->ssid_len = ssid_len;
- hidden->identity = g_strdup(identity);
- hidden->passphrase = g_strdup(passphrase);
- hidden->user_data = user_data;
- wifi->hidden = hidden;
connman_device_ref(device);
-
- reset_autoscan(device);
-
ret = g_supplicant_interface_scan(wifi->interface, scan_params,
- scan_callback, device);
+ scan_callback, device);
if (ret == 0)
connman_device_set_scanning(device, TRUE);
else {
+ g_free(scan_params);
connman_device_unref(device);
- g_supplicant_free_scan_params(scan_params);
- hidden_free(wifi->hidden);
- wifi->hidden = NULL;
}
return ret;
}
-static void wifi_regdom_callback(int result,
- const char *alpha2,
- void *user_data)
-{
- struct connman_device *device = user_data;
-
- connman_device_regdom_notify(device, result, alpha2);
-
- connman_device_unref(device);
-}
-
-static int wifi_set_regdom(struct connman_device *device, const char *alpha2)
-{
- struct wifi_data *wifi = connman_device_get_data(device);
- int ret;
-
- if (wifi == NULL)
- return -EINVAL;
-
- connman_device_ref(device);
-
- ret = g_supplicant_interface_set_country(wifi->interface,
- wifi_regdom_callback,
- alpha2, device);
- if (ret != 0)
- connman_device_unref(device);
-
- return ret;
-}
-
static struct connman_device_driver wifi_ng_driver = {
.name = "wifi",
.type = CONNMAN_DEVICE_TYPE_WIFI,
.disable = wifi_disable,
.scan = wifi_scan,
.scan_fast = wifi_scan_fast,
- .scan_hidden = wifi_scan_hidden,
- .set_regdom = wifi_set_regdom,
};
static void system_ready(void)
static void connect_callback(int result, GSupplicantInterface *interface,
void *user_data)
{
+#if defined TIZEN_EXT
+ struct callback_data *cb_data = user_data;
+ struct connman_network *network;
+ struct wifi_data *wifi;
+
+ if (cb_data == NULL)
+ return;
+
+ wifi = cb_data->wifi_inf_data;
+
+ if (wifi == NULL) {
+ g_free(cb_data);
+ return;
+ }
+
+ if (g_list_find(iface_list, wifi) == NULL) {
+ g_free(cb_data);
+ return;
+ }
+
+ network = cb_data->data;
+#else
struct connman_network *network = user_data;
+#endif
DBG("network %p result %d", network, result);
+#if defined TIZEN_EXT
+ if (wifi->networks == NULL) {
+ g_free(cb_data);
+ return;
+ }
+
+ if (g_slist_find(wifi->networks, network) == NULL) {
+ g_free(cb_data);
+ return;
+ }
+#endif
if (result == -ENOKEY) {
connman_network_set_error(network,
CONNMAN_NETWORK_ERROR_INVALID_KEY);
connman_network_set_error(network,
CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
}
+#if defined TIZEN_EXT
+ g_free(cb_data);
+#endif
}
static GSupplicantSecurity network_security(const char *security)
ssid->use_wps = connman_network_get_bool(network, "WiFi.UseWPS");
ssid->pin_wps = connman_network_get_string(network, "WiFi.PinWPS");
- if (connman_setting_get_bool("BackgroundScanning") == TRUE)
- ssid->bgscan = BGSCAN_DEFAULT;
}
static int network_connect(struct connman_network *network)
{
struct connman_device *device = connman_network_get_device(network);
struct wifi_data *wifi;
+#if defined TIZEN_EXT
+ struct callback_data *cb_data;
+#endif
GSupplicantInterface *interface;
GSupplicantSSID *ssid;
if (ssid == NULL)
return -ENOMEM;
+#if defined TIZEN_EXT
+ cb_data = g_try_malloc0(sizeof(struct callback_data));
+ if (cb_data == NULL) {
+ g_free(ssid);
+ return -ENOMEM;
+ }
+#endif
interface = wifi->interface;
ssid_init(ssid, network);
wifi->network = network;
wifi->retries = 0;
+#if defined TIZEN_EXT
+ cb_data->wifi_inf_data = wifi;
+ cb_data->data = network;
+ return g_supplicant_interface_connect(interface, ssid,
+ connect_callback, cb_data);
+#else
return g_supplicant_interface_connect(interface, ssid,
connect_callback, network);
+#endif
}
return -EINPROGRESS;
static void disconnect_callback(int result, GSupplicantInterface *interface,
void *user_data)
{
+#if defined TIZEN_EXT
+ struct callback_data *cb_data = user_data;
+ struct wifi_data *wifi;
+
+ DBG("");
+
+ if (cb_data == NULL)
+ return;
+
+ wifi = cb_data->wifi_inf_data;
+
+ if (wifi == NULL) {
+ g_free(cb_data);
+ return;
+ }
+
+ if (g_list_find(iface_list, wifi) == NULL) {
+ g_free(cb_data);
+ return;
+ }
+#else
struct wifi_data *wifi = user_data;
+#endif
if (wifi->network != NULL) {
/*
wifi->pending_network = NULL;
}
- start_autoscan(wifi->device);
+#if defined TIZEN_EXT
+ g_free(cb_data);
+#endif
}
static int network_disconnect(struct connman_network *network)
{
struct connman_device *device = connman_network_get_device(network);
+#if defined TIZEN_EXT
+ struct callback_data *cb_data;
+#endif
struct wifi_data *wifi;
int err;
wifi->disconnecting = TRUE;
+#if defined TIZEN_EXT
+ cb_data = g_try_malloc0(sizeof(struct callback_data));
+
+ if (cb_data == NULL) {
+ return -ENOMEM;
+ }
+
+ cb_data->wifi_inf_data = wifi;
+ cb_data->data = NULL;
+
+ err = g_supplicant_interface_disconnect(wifi->interface,
+ disconnect_callback, cb_data);
+#else
err = g_supplicant_interface_disconnect(wifi->interface,
disconnect_callback, wifi);
+#endif
if (err < 0)
wifi->disconnecting = FALSE;
if (wifi->retries < MAXIMUM_RETRIES)
return TRUE;
+ /* We disable the selected network, if not then
+ * wpa_supplicant will loop retrying */
+ if (g_supplicant_interface_enable_selected_network(interface,
+ FALSE) != 0)
+ DBG("Could not disables selected network");
+
connman_network_set_error(network, CONNMAN_NETWORK_ERROR_INVALID_KEY);
return FALSE;
case G_SUPPLICANT_STATE_AUTHENTICATING:
case G_SUPPLICANT_STATE_ASSOCIATING:
- stop_autoscan(device);
-
- if (wifi->connected == FALSE)
- connman_network_set_associating(network, TRUE);
+#if !defined TIZEN_EXT
+ /*
+ * Dec. 2nd, 2011. TIZEN
+ *
+ * When associating state dbus signal is delivered with delay after disconnect
+ * connman's service state becomes associating state and connman ignores
+ * another state dbus signal since this time. Thus the associating state dbus signal
+ * should be ignored.
+ * It is reasonable because associating state is set also when connman try to connect.
+ */
+ connman_network_set_associating(network, TRUE);
+#endif
break;
case G_SUPPLICANT_STATE_COMPLETED:
- /* though it should be already stopped: */
- stop_autoscan(device);
-
if (handle_wps_completion(interface, network, device, wifi) ==
FALSE)
break;
+ /* reset scan trigger and schedule background scan */
+ connman_device_schedule_scan(device);
+
connman_network_set_connected(network, TRUE);
break;
network, wifi) == TRUE)
break;
- /* We disable the selected network, if not then
- * wpa_supplicant will loop retrying */
- if (g_supplicant_interface_enable_selected_network(interface,
- FALSE) != 0)
- DBG("Could not disables selected network");
+#if !defined TIZEN_EXT
+ /*
+ * Dec. 2nd, 2011. TIZEN
+ *
+ * There is not necessary to change associating variable to false because
+ * connman_network_set_connected sets it.
+ * Moreover, it cuases wrong operation when connman gets disconnect state dbus signal
+ * during connecting
+ *
+ */
- connman_network_set_connected(network, FALSE);
connman_network_set_associating(network, FALSE);
- wifi->disconnecting = FALSE;
-
- start_autoscan(device);
-
+#endif
+ connman_network_set_connected(network, FALSE);
break;
case G_SUPPLICANT_STATE_INACTIVE:
connman_network_set_associating(network, FALSE);
- start_autoscan(device);
-
break;
case G_SUPPLICANT_STATE_UNKNOWN:
wifi->state = state;
- /* Saving wpa_s state policy:
- * If connected and if the state changes are roaming related:
- * --> We stay connected
- * If completed
- * --> We are connected
- * All other case:
- * --> We are not connected
- * */
- switch (state) {
- case G_SUPPLICANT_STATE_AUTHENTICATING:
- case G_SUPPLICANT_STATE_ASSOCIATING:
- case G_SUPPLICANT_STATE_ASSOCIATED:
- case G_SUPPLICANT_STATE_4WAY_HANDSHAKE:
- case G_SUPPLICANT_STATE_GROUP_HANDSHAKE:
- if (wifi->connected == TRUE)
- connman_warn("Probably roaming right now!"
- " Staying connected...");
- else
- wifi->connected = FALSE;
- break;
- case G_SUPPLICANT_STATE_COMPLETED:
- wifi->connected = TRUE;
- break;
- default:
- wifi->connected = FALSE;
- break;
- }
-
DBG("DONE");
}
return;
if (wifi == NULL || wifi->device == NULL) {
- DBG("wifi interface already removed");
+ connman_error("Wrong wifi pointer");
return;
}
- wifi->interface = NULL;
connman_device_set_powered(wifi->device, FALSE);
}
const unsigned char *ssid;
unsigned int ssid_len;
connman_bool_t wps;
- connman_bool_t wps_pbc;
- connman_bool_t wps_ready;
- connman_bool_t wps_advertizing;
DBG("");
security = g_supplicant_network_get_security(supplicant_network);
group = g_supplicant_network_get_identifier(supplicant_network);
wps = g_supplicant_network_get_wps(supplicant_network);
- wps_pbc = g_supplicant_network_is_wps_pbc(supplicant_network);
- wps_ready = g_supplicant_network_is_wps_active(supplicant_network);
- wps_advertizing = g_supplicant_network_is_wps_advertizing(
- supplicant_network);
mode = g_supplicant_network_get_mode(supplicant_network);
if (wifi == NULL)
calculate_strength(supplicant_network));
connman_network_set_bool(network, "WiFi.WPS", wps);
- if (wps == TRUE) {
- /* Is AP advertizing for WPS association?
- * If so, we decide to use WPS by default */
- if (wps_ready == TRUE && wps_pbc == TRUE &&
- wps_advertizing == TRUE)
- connman_network_set_bool(network, "WiFi.UseWPS", TRUE);
- }
-
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);
if (ssid != NULL)
connman_network_set_group(network, group);
-
- if (wifi->hidden != NULL && ssid != NULL) {
- if (wifi->hidden->ssid_len == ssid_len &&
- memcmp(wifi->hidden->ssid, ssid,
- ssid_len) == 0) {
- connman_network_connect_hidden(network,
- wifi->hidden->identity,
- wifi->hidden->passphrase,
- wifi->hidden->user_data);
- wifi->hidden->user_data = NULL;
- hidden_free(wifi->hidden);
- wifi->hidden = NULL;
- }
- }
}
static void network_removed(GSupplicantNetwork *network)
calculate_strength(network));
connman_network_update(connman_network);
}
+
+#if defined TIZEN_EXT
+ const unsigned char *bssid;
+ unsigned int maxrate;
+ connman_uint16_t frequency;
+
+ 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)
return -EOPNOTSUPP;
}
-static void regdom_callback(int result, const char *alpha2, void *user_data)
+static void regdom_callback(void *user_data)
{
+ char *alpha2 = user_data;
+
DBG("");
if (wifi_technology == NULL)
return;
- if (result != 0)
- alpha2 = NULL;
-
connman_technology_regdom_notify(wifi_technology, alpha2);
}
static int tech_set_regdom(struct connman_technology *technology, const char *alpha2)
{
- return g_supplicant_set_country(alpha2, regdom_callback, NULL);
+ return g_supplicant_set_country(alpha2, regdom_callback, alpha2);
}
static struct connman_technology_driver tech_driver = {
--- /dev/null
+#!/bin/sh
+HARDWARE_MODEL=`grep Hardware /proc/cpuinfo | awk "{print \\$3}"`
+/bin/echo "Hardware Model=${HARDWARE_MODEL}"
+
+case $HARDWARE_MODEL in
+ "SLP_PQ") /bin/echo "This is PQ"
+ /usr/sbin/connmand -W nl80211 &
+ ;;
+ "U1SLP" | "U1HD") /bin/echo "This is U1SLP"
+ /usr/sbin/connmand -W wext &
+ ;;
+ "SLP7_C210") /bin/echo "This is C210"
+ /usr/sbin/connmand -W wext &
+ ;;
+ "SLP10_C210")
+ /usr/sbin/connmand -W wext &
+ ;;
+ *)
+ /usr/sbin/connmand -W nl80211 &
+ ;;
+esac
--- /dev/null
+[D-BUS Service]
+Name=net.connman
+Exec=/etc/rc.d/init.d/connman
+User=root
--- /dev/null
+
+[global]
+OfflineMode=false
+
+[WiFi]
+Enable=false
+
+[Bluetooth]
+Enable=false
+
+[Wired]
+Enable=true
+
+[3G]
+Enable=true
+
+[WiMAX]
+Enable=false
*
* Connection Manager
*
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
* Copyright (C) 2010 BMW Car IT GmbH. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
#include <errno.h>
#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
static char *tunnel_ip_address;
static GWeb *web;
static guint web_request_id;
-static unsigned int newlink_watch;
-static unsigned int newlink_flags;
-static int newlink_timeout_id;
#define STATUS_URL "http://ipv6.connman.net/online/status.html"
+#define NLMSG_TAIL(nmsg) \
+ ((struct rtattr *) (((void *)(nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
+
#ifndef IP_DF
#define IP_DF 0x4000 /* Flag: "Don't Fragment" */
#endif
+struct rtnl_handle {
+ int fd;
+ struct sockaddr_nl local;
+ struct sockaddr_nl peer;
+ __u32 seq;
+ __u32 dump;
+};
+
+static int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data)
+{
+ int len = RTA_LENGTH(4);
+ struct rtattr *rta;
+ if (NLMSG_ALIGN(n->nlmsg_len) + len > (unsigned int)maxlen) {
+ DBG("Error! max allowed bound %d exceeded", maxlen);
+ return -1;
+ }
+ rta = NLMSG_TAIL(n);
+ rta->rta_type = type;
+ rta->rta_len = len;
+ memcpy(RTA_DATA(rta), &data, 4);
+ n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
+
+ return 0;
+}
+
+static int addattr_l(struct nlmsghdr *n, int maxlen, int type,
+ const void *data, int alen)
+{
+ int len = RTA_LENGTH(alen);
+ struct rtattr *rta;
+
+ if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) >
+ (unsigned int)maxlen) {
+ DBG("addattr_l message exceeded bound of %d", maxlen);
+ return -1;
+ }
+ rta = NLMSG_TAIL(n);
+ rta->rta_type = type;
+ rta->rta_len = len;
+ memcpy(RTA_DATA(rta), data, alen);
+ n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
+
+ return 0;
+}
+
+static void rtnl_close(struct rtnl_handle *rth)
+{
+ if (rth->fd >= 0) {
+ close(rth->fd);
+ rth->fd = -1;
+ }
+}
+
+static int rtnl_open(struct rtnl_handle *rth)
+{
+ socklen_t addr_len;
+ int sndbuf = 1024;
+
+ memset(rth, 0, sizeof(*rth));
+
+ rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
+ if (rth->fd < 0) {
+ connman_error("Can not open netlink socket: %s",
+ strerror(errno));
+ return -1;
+ }
+
+ if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
+ sizeof(sndbuf)) < 0) {
+ connman_error("SO_SNDBUF: %s", strerror(errno));
+ return -1;
+ }
+
+ memset(&rth->local, 0, sizeof(rth->local));
+ rth->local.nl_family = AF_NETLINK;
+ rth->local.nl_groups = 0;
+
+ if (bind(rth->fd, (struct sockaddr *)&rth->local,
+ sizeof(rth->local)) < 0) {
+ connman_error("Can not bind netlink socket: %s",
+ strerror(errno));
+ return -1;
+ }
+ addr_len = sizeof(rth->local);
+ if (getsockname(rth->fd, (struct sockaddr *)&rth->local,
+ &addr_len) < 0) {
+ connman_error("Can not getsockname: %s", strerror(errno));
+ return -1;
+ }
+ if (addr_len != sizeof(rth->local)) {
+ connman_error("Wrong address length %d", addr_len);
+ return -1;
+ }
+ if (rth->local.nl_family != AF_NETLINK) {
+ connman_error("Wrong address family %d", rth->local.nl_family);
+ return -1;
+ }
+ rth->seq = time(NULL);
+
+ return 0;
+}
+
+static int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n)
+{
+ struct sockaddr_nl nladdr;
+ struct iovec iov = {
+ .iov_base = (void *)n,
+ .iov_len = n->nlmsg_len
+ };
+ struct msghdr msg = {
+ .msg_name = &nladdr,
+ .msg_namelen = sizeof(nladdr),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ };
+ unsigned seq;
+ int err;
+
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+
+ n->nlmsg_seq = seq = ++rtnl->seq;
+ n->nlmsg_flags |= NLM_F_ACK;
+
+ err = sendmsg(rtnl->fd, &msg, 0);
+ if (err < 0) {
+ connman_error("Can not talk to rtnetlink");
+ return err;
+ }
+
+ return 0;
+}
+
static int tunnel_create(struct in_addr *addr)
{
struct ip_tunnel_parm p;
static int tunnel_add_route()
{
- struct __connman_inet_rtnl_handle rth;
+ struct rtnl_handle rth;
struct in6_addr addr6;
int index;
int ret = 0;
+ struct {
+ struct nlmsghdr n;
+ struct rtmsg r;
+ char buf[1024];
+ } req;
+
/* ip -6 route add ::/0 via ::192.88.99.1 dev tun6to4 metric 1 */
index = if_nametoindex("tun6to4");
return -1;
}
- memset(&rth, 0, sizeof(rth));
+ memset(&req, 0, sizeof(req));
- rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
- rth.req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
- rth.req.n.nlmsg_type = RTM_NEWROUTE;
- rth.req.u.r.rt.rtm_family = AF_INET6;
- rth.req.u.r.rt.rtm_table = RT_TABLE_MAIN;
- rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
- rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
- rth.req.u.r.rt.rtm_type = RTN_UNICAST;
- rth.req.u.r.rt.rtm_dst_len = 0;
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
+ req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
+ req.n.nlmsg_type = RTM_NEWROUTE;
+ req.r.rtm_family = AF_INET6;
+ req.r.rtm_table = RT_TABLE_MAIN;
+ req.r.rtm_protocol = RTPROT_BOOT;
+ req.r.rtm_scope = RT_SCOPE_UNIVERSE;
+ req.r.rtm_type = RTN_UNICAST;
+ req.r.rtm_dst_len = 0;
inet_pton(AF_INET6, "::192.88.99.1", &addr6);
- __connman_inet_rtnl_addattr_l(&rth.req.n, sizeof(rth.req), RTA_GATEWAY,
- &addr6.s6_addr, 16);
- __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req), RTA_OIF,
- index);
- __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
- RTA_PRIORITY, 1);
+ addattr_l(&req.n, sizeof(req), RTA_GATEWAY, &addr6.s6_addr, 16);
+ addattr32(&req.n, sizeof(req), RTA_OIF, index);
+ addattr32(&req.n, sizeof(req), RTA_PRIORITY, 1);
- ret = __connman_inet_rtnl_open(&rth);
+ ret = rtnl_open(&rth);
if (ret < 0)
goto done;
- ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
+ ret = rtnl_talk(&rth, &req.n);
done:
- __connman_inet_rtnl_close(&rth);
+ rtnl_close(&rth);
return ret;
}
static int tunnel_set_addr(unsigned int a, unsigned int b,
unsigned int c, unsigned int d)
{
- struct __connman_inet_rtnl_handle rth;
+ struct rtnl_handle rth;
struct in6_addr addr6;
char *ip6addr;
int ret;
+ struct {
+ struct nlmsghdr n;
+ struct ifaddrmsg ifa;
+ char buf[256];
+ } req;
+
/* ip -6 addr add dev tun6to4 2002:0102:0304::1/64 */
- memset(&rth, 0, sizeof(rth));
+ memset(&req, 0, sizeof(req));
- rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
- rth.req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
- rth.req.n.nlmsg_type = RTM_NEWADDR;
- rth.req.u.i.ifa.ifa_family = AF_INET6;
- rth.req.u.i.ifa.ifa_prefixlen = 64;
- rth.req.u.i.ifa.ifa_index = if_nametoindex("tun6to4");
- if (rth.req.u.i.ifa.ifa_index == 0) {
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+ req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
+ req.n.nlmsg_type = RTM_NEWADDR;
+ req.ifa.ifa_family = AF_INET6;
+ req.ifa.ifa_prefixlen = 64;
+ req.ifa.ifa_index = if_nametoindex("tun6to4");
+ if (req.ifa.ifa_index == 0) {
connman_error("Can not find device tun6to4");
ret = -1;
goto done;
DBG("ipv6 address %s", ip6addr);
g_free(ip6addr);
- __connman_inet_rtnl_addattr_l(&rth.req.n, sizeof(rth.req), IFA_LOCAL,
- &addr6.s6_addr, 16);
- __connman_inet_rtnl_addattr_l(&rth.req.n, sizeof(rth.req), IFA_ADDRESS,
- &addr6.s6_addr, 16);
+ addattr_l(&req.n, sizeof(req), IFA_LOCAL, &addr6.s6_addr, 16);
+ addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &addr6.s6_addr, 16);
- ret = __connman_inet_rtnl_open(&rth);
+ ret = rtnl_open(&rth);
if (ret < 0)
goto done;
- ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
+ ret = rtnl_talk(&rth, &req.n);
done:
- __connman_inet_rtnl_close(&rth);
+ rtnl_close(&rth);
return ret;
}
return FALSE;
}
-static void web_debug(const char *str, void *data)
-{
- connman_info("%s: %s\n", (const char *) data, str);
-}
-
-static gboolean newlink_timeout(gpointer user_data)
-{
- /*
- * Stop if the timeout has been cancelled already by tun_newlink()
- */
- if (newlink_timeout_id == 0)
- return FALSE;
-
- DBG("");
-
- if (newlink_watch != 0) {
- connman_rtnl_remove_watch(newlink_watch);
- newlink_watch = 0;
- }
-
- newlink_flags = 0;
-
- if (web_request_id == 0)
- tunnel_destroy();
-
- newlink_timeout_id = 0;
-
- return FALSE;
-}
-
-static void tun_newlink(unsigned flags, unsigned change, void *user_data)
-{
- int index = GPOINTER_TO_INT(user_data);
-
- if ((newlink_flags & IFF_UP) == (flags & IFF_UP)) {
- newlink_flags = flags;
- return;
- }
-
- if (flags & IFF_UP) {
- /*
- * We try to verify that connectivity through tunnel works ok.
- */
- if (newlink_timeout_id > 0) {
- g_source_remove(newlink_timeout_id);
- newlink_timeout_id = 0;
- }
-
- web = g_web_new(index);
- if (web == NULL) {
- tunnel_destroy();
- return;
- }
-
- g_web_set_accept(web, NULL);
- g_web_set_user_agent(web, "ConnMan/%s", VERSION);
- g_web_set_close_connection(web, TRUE);
-
- if (getenv("CONNMAN_WEB_DEBUG"))
- g_web_set_debug(web, web_debug, "6to4");
-
- web_request_id = g_web_request_get(web, STATUS_URL,
- web_result, NULL, NULL);
-
- newlink_timeout(NULL);
- }
-
- newlink_flags = flags;
-}
-
static int init_6to4(struct in_addr *ip4addr)
{
unsigned int a, b, c, d;
if (if_index < 0)
goto error;
- newlink_watch = connman_rtnl_add_newlink_watch(if_index,
- tun_newlink, GINT_TO_POINTER(if_index));
+ /* We try to verify that connectivity through tunnel works ok.
+ */
+ web = g_web_new(if_index);
+ if (web == NULL)
+ goto error;
+
+ g_web_set_accept(web, NULL);
+ g_web_set_user_agent(web, "ConnMan/%s", VERSION);
+ g_web_set_close_connection(web, TRUE);
- newlink_timeout_id = g_timeout_add_seconds(1, newlink_timeout, NULL);
+ web_request_id = g_web_request_get(web, STATUS_URL, web_result, NULL);
return 0;
return -1;
}
-static void receive_rs_reply(struct nd_router_advert *reply,
- unsigned int length, void *user_data)
+static void receive_rs_reply(struct nd_router_advert *reply, void *user_data)
{
char *address = user_data;
struct in_addr ip4addr;
- DBG("reply %p len %d address %s", reply, length, address);
+ DBG("reply %p address %s", reply, address);
/* We try to create tunnel if autoconfiguration did not work i.e.,
* we did not receive any reply to router solicitation message.
(a == 172 && (b >= 16 && b <= 31)))
return -1;
- index = __connman_ipconfig_get_index(ip4config);
+ index = connman_ipconfig_get_index(ip4config);
ip_address = g_strdup(address);
tunnel_pending = 1;
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
return 0;
}
-static connman_bool_t check_reply_has_dict(DBusMessage *reply)
-{
- const char *signature = DBUS_TYPE_ARRAY_AS_STRING
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
-
- if (dbus_message_has_signature(reply, signature) == TRUE)
- return TRUE;
-
- connman_warn("Reply %s to %s from %s has wrong signature %s",
- signature,
- dbus_message_get_interface(reply),
- dbus_message_get_sender(reply),
- dbus_message_get_signature(reply));
-
- return FALSE;
-}
-
struct request_input_reply {
struct connman_service *service;
authentication_cb_t callback;
static void request_input_passphrase_reply(DBusPendingCall *call, void *user_data)
{
struct request_input_reply *passphrase_reply = user_data;
- connman_bool_t values_received = FALSE;
connman_bool_t wps = FALSE;
- const char *error = NULL;
char *identity = NULL;
char *passphrase = NULL;
char *wpspin = NULL;
char *key;
- char *name = NULL;
- int name_len = 0;
DBusMessageIter iter, dict;
DBusMessage *reply = dbus_pending_call_steal_reply(call);
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
- error = dbus_message_get_error_name(reply);
+ if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
goto done;
- }
-
- if (check_reply_has_dict(reply) == FALSE)
- goto done;
-
- values_received = TRUE;
dbus_message_iter_init(reply, &iter);
dbus_message_iter_recurse(&iter, &dict);
dbus_message_iter_recurse(&entry, &value);
dbus_message_iter_get_basic(&value, &wpspin);
break;
- } else if (g_str_equal(key, "Name")) {
- dbus_message_iter_next(&entry);
- if (dbus_message_iter_get_arg_type(&entry)
- != DBUS_TYPE_VARIANT)
- break;
- dbus_message_iter_recurse(&entry, &value);
- dbus_message_iter_get_basic(&value, &name);
- name_len = strlen(name);
- } else if (g_str_equal(key, "SSID")) {
- dbus_message_iter_next(&entry);
- if (dbus_message_iter_get_arg_type(&entry)
- != DBUS_TYPE_VARIANT)
- break;
- dbus_message_iter_recurse(&entry, &value);
- if (dbus_message_iter_get_arg_type(&value)
- != DBUS_TYPE_VARIANT)
- break;
- if (dbus_message_iter_get_element_type(&value)
- != DBUS_TYPE_VARIANT)
- break;
- dbus_message_iter_get_fixed_array(&value, &name,
- &name_len);
}
dbus_message_iter_next(&dict);
}
+ if (wps == TRUE) {
+ struct connman_network *network;
+
+ network = __connman_service_get_network(
+ passphrase_reply->service);
+ if (network == NULL)
+ goto done;
+
+ connman_network_set_bool(network, "WiFi.UseWPS", wps);
+
+ if (wpspin != NULL && strlen(wpspin) > 0)
+ connman_network_set_string(network,
+ "WiFi.PinWPS", wpspin);
+ else
+ connman_network_set_string(network,
+ "WiFi.PinWPS", NULL);
+ }
+
done:
- passphrase_reply->callback(passphrase_reply->service, values_received,
- name, name_len,
- identity, passphrase,
- wps, wpspin, error,
- passphrase_reply->user_data);
+ passphrase_reply->callback(passphrase_reply->service, identity,
+ passphrase, passphrase_reply->user_data);
connman_service_unref(passphrase_reply->service);
dbus_message_unref(reply);
- dbus_pending_call_unref(call);
g_free(passphrase_reply);
}
connman_dbus_dict_append_basic(iter, "Type",
DBUS_TYPE_STRING, &str);
- str = "mandatory";
+ str = "Mandatory";
connman_dbus_dict_append_basic(iter, "Requirement",
DBUS_TYPE_STRING, &str);
}
}
connman_dbus_dict_append_basic(iter, "Type",
DBUS_TYPE_STRING, &value);
- value = "mandatory";
+ value = "Mandatory";
connman_dbus_dict_append_basic(iter, "Requirement",
DBUS_TYPE_STRING, &value);
DBUS_TYPE_STRING, &str);
}
-static void request_input_append_name(DBusMessageIter *iter, void *user_data)
-{
- const char *str = "string";
-
- connman_dbus_dict_append_basic(iter, "Type",
- DBUS_TYPE_STRING, &str);
- str = "mandatory";
- connman_dbus_dict_append_basic(iter, "Requirement",
- DBUS_TYPE_STRING, &str);
- connman_dbus_dict_append_array(iter, "Alternates",
- DBUS_TYPE_STRING,
- request_input_append_alternates,
- "SSID");
-}
-
-static void request_input_append_ssid(DBusMessageIter *iter, void *user_data)
-{
- const char *str = "ssid";
-
- connman_dbus_dict_append_basic(iter, "Type",
- DBUS_TYPE_STRING, &str);
- str = "alternate";
- connman_dbus_dict_append_basic(iter, "Requirement",
- DBUS_TYPE_STRING, &str);
-}
-
static void request_input_append_password(DBusMessageIter *iter,
void *user_data)
{
connman_dbus_dict_append_basic(iter, "Type",
DBUS_TYPE_STRING, &str);
- str = "mandatory";
- connman_dbus_dict_append_basic(iter, "Requirement",
- DBUS_TYPE_STRING, &str);
-}
-
-static void request_input_append_previouspassphrase(DBusMessageIter *iter,
- void *user_data)
-{
- struct connman_service *service = user_data;
- enum connman_service_security security;
- const char *passphrase, *str = NULL;
-
- passphrase = __connman_service_get_passphrase(service);
-
- security = __connman_service_get_security(service);
- switch (security) {
- case CONNMAN_SERVICE_SECURITY_WEP:
- str = "wep";
- break;
- case CONNMAN_SERVICE_SECURITY_PSK:
- str = "psk";
- break;
- /*
- * This should never happen: no passphrase is set if security is not
- * one of the above.*/
- default:
- break;
- }
-
- connman_dbus_dict_append_basic(iter, "Type",
- DBUS_TYPE_STRING, &str);
-
- str = "informational";
+ str = "Mandatory";
connman_dbus_dict_append_basic(iter, "Requirement",
DBUS_TYPE_STRING, &str);
-
- connman_dbus_dict_append_basic(iter, "Value",
- DBUS_TYPE_STRING, &passphrase);
}
static void request_input_login_reply(DBusPendingCall *call, void *user_data)
{
struct request_input_reply *username_password_reply = user_data;
- const char *error = NULL;
- connman_bool_t values_received = FALSE;
char *username = NULL;
char *password = NULL;
char *key;
DBusMessageIter iter, dict;
DBusMessage *reply = dbus_pending_call_steal_reply(call);
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
- error = dbus_message_get_error_name(reply);
- goto done;
- }
-
- if (check_reply_has_dict(reply) == FALSE)
+ if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
goto done;
- values_received = TRUE;
-
dbus_message_iter_init(reply, &iter);
dbus_message_iter_recurse(&iter, &dict);
while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
done:
username_password_reply->callback(username_password_reply->service,
- values_received, NULL, 0,
username, password,
- FALSE, NULL, error,
username_password_reply->user_data);
connman_service_unref(username_password_reply->service);
dbus_message_unref(reply);
connman_dbus_dict_open(&iter, &dict);
- if (__connman_service_is_hidden(service)) {
- connman_dbus_dict_append_dict(&dict, "Name",
- request_input_append_name, NULL);
- connman_dbus_dict_append_dict(&dict, "SSID",
- request_input_append_ssid, NULL);
- }
-
if (__connman_service_get_security(service) ==
CONNMAN_SERVICE_SECURITY_8021X) {
connman_dbus_dict_append_dict(&dict, "Identity",
request_input_append_identity, service);
}
- if (__connman_service_get_security(service) !=
- CONNMAN_SERVICE_SECURITY_NONE) {
- connman_dbus_dict_append_dict(&dict, "Passphrase",
- request_input_append_passphrase, service);
-
- if (__connman_service_get_passphrase(service) != NULL)
- connman_dbus_dict_append_dict(&dict, "PreviousPassphrase",
- request_input_append_previouspassphrase,
- service);
- }
+ connman_dbus_dict_append_dict(&dict, "Passphrase",
+ request_input_append_passphrase, service);
if (__connman_service_wps_enabled(service) == TRUE) {
connman_dbus_dict_append_dict(&dict, "WPS",
return -ENOMEM;
}
- if (dbus_connection_send_with_reply(connection, message, &call,
- connman_timeout_input_request())
- == FALSE) {
+ if (dbus_connection_send_with_reply(connection, message,
+ &call, -1) == FALSE) {
dbus_message_unref(message);
g_free(passphrase_reply);
return -ESRCH;
dbus_message_unref(message);
- return -EINPROGRESS;
+ return -EIO;
}
int __connman_agent_request_login_input(struct connman_service *service,
return -ENOMEM;
}
- if (dbus_connection_send_with_reply(connection, message, &call,
- connman_timeout_input_request())
- == FALSE) {
+ if (dbus_connection_send_with_reply(connection, message,
+ &call, -1) == FALSE) {
dbus_message_unref(message);
g_free(username_password_reply);
return -ESRCH;
dbus_message_unref(message);
- return -EINPROGRESS;
-}
-
-struct request_browser_reply_data {
- struct connman_service *service;
- browser_authentication_cb_t callback;
- void *user_data;
-};
-
-static void request_browser_reply(DBusPendingCall *call, void *user_data)
-{
- struct request_browser_reply_data *browser_reply_data = user_data;
- DBusMessage *reply = dbus_pending_call_steal_reply(call);
- connman_bool_t result = FALSE;
- const char *error = NULL;
-
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
- error = dbus_message_get_error_name(reply);
- goto done;
- }
-
- result = TRUE;
-
-done:
- browser_reply_data->callback(browser_reply_data->service, result,
- error, browser_reply_data->user_data);
- connman_service_unref(browser_reply_data->service);
- dbus_message_unref(reply);
- g_free(browser_reply_data);
-}
-
-int __connman_agent_request_browser(struct connman_service *service,
- browser_authentication_cb_t callback,
- const char *url, void *user_data)
-{
- struct request_browser_reply_data *browser_reply_data;
- DBusPendingCall *call;
- DBusMessage *message;
- DBusMessageIter iter;
- const char *path;
-
- if (service == NULL || agent_path == NULL || callback == NULL)
- return -ESRCH;
-
- if (url == NULL)
- url = "";
-
- message = dbus_message_new_method_call(agent_sender, agent_path,
- CONNMAN_AGENT_INTERFACE,
- "RequestBrowser");
- if (message == NULL)
- return -ENOMEM;
-
- dbus_message_iter_init_append(message, &iter);
-
- path = __connman_service_get_path(service);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path);
-
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &url);
-
- browser_reply_data = g_try_new0(struct request_browser_reply_data, 1);
- if (browser_reply_data == NULL) {
- dbus_message_unref(message);
- return -ENOMEM;
- }
-
- if (dbus_connection_send_with_reply(connection, message, &call,
- connman_timeout_browser_launch())
- == FALSE) {
- dbus_message_unref(message);
- g_free(browser_reply_data);
- return -ESRCH;
- }
-
- if (call == NULL) {
- dbus_message_unref(message);
- g_free(browser_reply_data);
- return -ESRCH;
- }
-
- browser_reply_data->service = connman_service_ref(service);
- browser_reply_data->callback = callback;
- browser_reply_data->user_data = user_data;
-
- dbus_pending_call_set_notify(call, request_browser_reply,
- browser_reply_data, NULL);
-
- dbus_message_unref(message);
-
- return -EINPROGRESS;
+ return -EIO;
}
struct report_error_data {
connman_service_unref(report_error->service);
g_free(report_error);
dbus_message_unref(reply);
- dbus_pending_call_unref(call);
}
int __connman_agent_report_error(struct connman_service *service,
return -ENOMEM;
}
- if (dbus_connection_send_with_reply(connection, message, &call,
- connman_timeout_input_request())
- == FALSE) {
+ if (dbus_connection_send_with_reply(connection, message,
+ &call, -1) == FALSE) {
dbus_message_unref(message);
g_free(report_error);
return -ESRCH;
report_error, NULL);
dbus_message_unref(message);
- return -EINPROGRESS;
+ return -EIO;
}
int __connman_agent_init(void)
+++ /dev/null
-/*
- *
- * Connection Manager
- *
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
- * Copyright (C) 2012 BMW Car IT GmbH. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <linux/sockios.h>
-#include <string.h>
-#include <fcntl.h>
-#include <linux/if_tun.h>
-
-#include "connman.h"
-
-static int set_forward_delay(const char *name, unsigned int delay)
-{
- FILE *f;
- char *forward_delay_path;
-
- forward_delay_path =
- g_strdup_printf("/sys/class/net/%s/bridge/forward_delay", name);
-
- if (forward_delay_path == NULL)
- return -ENOMEM;
-
- f = fopen(forward_delay_path, "r+");
-
- g_free(forward_delay_path);
-
- if (f == NULL)
- return -errno;
-
- fprintf(f, "%d", delay);
-
- fclose(f);
-
- return 0;
-}
-
-int __connman_bridge_create(const char *name)
-{
- int sk, err;
-
- DBG("name %s", name);
-
- sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
- if (sk < 0)
- return -EOPNOTSUPP;
-
- if (ioctl(sk, SIOCBRADDBR, name) == -1) {
- err = -errno;
- if (err != -EEXIST)
- return -EOPNOTSUPP;
- }
-
- err = set_forward_delay(name, 0);
-
- if (err < 0)
- ioctl(sk, SIOCBRDELBR, name);
-
- close(sk);
-
- return err;
-}
-
-int __connman_bridge_remove(const char *name)
-{
- int sk, err;
-
- DBG("name %s", name);
-
- sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
- if (sk < 0)
- return -EOPNOTSUPP;
-
- err = ioctl(sk, SIOCBRDELBR, name);
-
- close(sk);
-
- if (err < 0)
- return -EOPNOTSUPP;
-
- return 0;
-}
-
-int __connman_bridge_enable(const char *name, const char *gateway,
- const char *broadcast)
-{
- int err, index;
-
- index = connman_inet_ifindex(name);
- if (index < 0)
- return index;
-
- err = __connman_inet_modify_address(RTM_NEWADDR,
- NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
- gateway, NULL, 24, broadcast);
- if (err < 0)
- return err;
-
- return connman_inet_ifup(index);
-}
-
-int __connman_bridge_disable(const char *name)
-{
- int index;
-
- index = connman_inet_ifindex(name);
- if (index < 0)
- return index;
-
- return connman_inet_ifdown(index);
-}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
static enum timezone_updates timezone_updates_config = TIMEZONE_UPDATES_AUTO;
static char *timezone_config = NULL;
+static char **timeservers_config = NULL;
static const char *time_updates2string(enum time_updates value)
{
static void append_timeservers(DBusMessageIter *iter, void *user_data)
{
int i;
- char **timeservers = __connman_timeserver_system_get();
- if (timeservers == NULL)
+ if (timeservers_config == NULL)
return;
- for (i = 0; timeservers[i] != NULL; i++) {
+ for (i = 0; timeservers_config[i] != NULL; i++) {
dbus_message_iter_append_basic(iter,
- DBUS_TYPE_STRING, ×ervers[i]);
+ DBUS_TYPE_STRING, ×ervers_config[i]);
}
-
- g_strfreev(timeservers);
}
static DBusMessage *get_properties(DBusConnection *conn,
if (dbus_message_iter_init(msg, &iter) == FALSE)
return __connman_error_invalid_arguments(msg);
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- return __connman_error_invalid_arguments(msg);
-
dbus_message_iter_get_basic(&iter, &name);
dbus_message_iter_next(&iter);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
- return __connman_error_invalid_arguments(msg);
-
dbus_message_iter_recurse(&iter, &value);
type = dbus_message_iter_get_arg_type(&value);
DBUS_TYPE_STRING, &strval);
} else if (g_str_equal(name, "Timeservers") == TRUE) {
DBusMessageIter entry;
- char **str = NULL;
- GSList *list = NULL;
- int count = 0;
+ GString *str;
if (type != DBUS_TYPE_ARRAY)
return __connman_error_invalid_arguments(msg);
+ str = g_string_new(NULL);
+ if (str == NULL)
+ return __connman_error_invalid_arguments(msg);
+
dbus_message_iter_recurse(&value, &entry);
while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
const char *val;
- GSList *new_head;
dbus_message_iter_get_basic(&entry, &val);
-
- new_head = __connman_timeserver_add_list(list, val);
- if (list != new_head) {
- count++;
- list = new_head;
- }
-
dbus_message_iter_next(&entry);
- }
-
- if (list != NULL) {
- str = g_new0(char *, count+1);
- while (list != NULL) {
- count--;
- str[count] = list->data;
- list = g_slist_delete_link(list, list);
- };
+ if (str->len > 0)
+ g_string_append_printf(str, " %s", val);
+ else
+ g_string_append(str, val);
}
- __connman_timeserver_system_set(str);
+ g_strfreev(timeservers_config);
+
+ if (str->len > 0)
+ timeservers_config = g_strsplit_set(str->str, " ", 0);
+ else
+ timeservers_config = NULL;
- if (str != NULL)
- g_strfreev(str);
+ g_string_free(str, TRUE);
connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
CONNMAN_CLOCK_INTERFACE, "Timeservers",
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
-static const GDBusMethodTable clock_methods[] = {
- { GDBUS_METHOD("GetProperties",
- NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
- get_properties) },
- { GDBUS_METHOD("SetProperty",
- GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL,
- set_property) },
+static GDBusMethodTable clock_methods[] = {
+ { "GetProperties", "", "a{sv}", get_properties },
+ { "SetProperty", "sv", "", set_property },
{ },
};
-static const GDBusSignalTable clock_signals[] = {
- { GDBUS_SIGNAL("PropertyChanged",
- GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
+static GDBusSignalTable clock_signals[] = {
+ { "PropertyChanged", "sv" },
{ },
};
__connman_timezone_cleanup();
g_free(timezone_config);
+ g_strfreev(timeservers_config);
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
char *private_key_passphrase_type;
char *phase2;
char *passphrase;
- GSList *service_identifiers;
- char *config_ident; /* file prefix */
- char *config_entry; /* entry name */
};
struct connman_config {
static GIOChannel *inotify_channel = NULL;
static uint inotify_watch = 0;
-static connman_bool_t cleanup = FALSE;
#define INTERNAL_CONFIG_PREFIX "__internal"
static void unregister_service(gpointer data)
{
- struct connman_config_service *config_service = data;
- struct connman_service *service;
- char *service_id;
- GSList *list;
-
- if (cleanup == TRUE)
- goto free_only;
-
- connman_info("Removing service configuration %s",
- config_service->ident);
-
- protected_services = g_slist_remove(protected_services,
- config_service);
-
- for (list = config_service->service_identifiers; list != NULL;
- list = list->next) {
- service_id = list->data;
-
- service = __connman_service_lookup_from_ident(service_id);
- if (service != NULL) {
- __connman_service_set_immutable(service, FALSE);
- __connman_service_remove(service);
- }
-
- if (__connman_storage_remove_service(service_id) == FALSE)
- DBG("Could not remove all files for service %s",
- service_id);
- }
-
-free_only:
- g_free(config_service->ident);
- g_free(config_service->type);
- g_free(config_service->name);
- g_free(config_service->ssid);
- g_free(config_service->eap);
- g_free(config_service->identity);
- g_free(config_service->ca_cert_file);
- g_free(config_service->client_cert_file);
- g_free(config_service->private_key_file);
- g_free(config_service->private_key_passphrase);
- g_free(config_service->private_key_passphrase_type);
- g_free(config_service->phase2);
- g_free(config_service->passphrase);
- g_slist_free_full(config_service->service_identifiers, g_free);
- g_free(config_service->config_ident);
- g_free(config_service->config_entry);
- g_free(config_service);
+ struct connman_config_service *service = data;
+
+ connman_info("Removing service configuration %s", service->ident);
+
+ protected_services = g_slist_remove(protected_services, service);
+
+ g_free(service->ident);
+ g_free(service->type);
+ g_free(service->name);
+ g_free(service->ssid);
+ g_free(service->eap);
+ g_free(service->identity);
+ g_free(service->ca_cert_file);
+ g_free(service->client_cert_file);
+ g_free(service->private_key_file);
+ g_free(service->private_key_passphrase);
+ g_free(service->private_key_passphrase_type);
+ g_free(service->phase2);
+ g_free(service->passphrase);
+ g_free(service);
}
static void check_keys(GKeyFile *keyfile, const char *group,
}
for (i = 0; i < hex_ssid_len; i += 2) {
- if (sscanf(hex_ssid + i, "%02x", &hex) <= 0) {
- connman_warn("Invalid SSID %s", hex_ssid);
- g_free(ssid);
- g_free(hex_ssid);
- err = -EILSEQ;
- goto err;
- }
+ sscanf(hex_ssid + i, "%02x", &hex);
ssid[j++] = hex;
}
service->passphrase = str;
}
- service->config_ident = g_strdup(config->ident);
- service->config_entry = g_strdup_printf("service_%s", service->ident);
-
if (service_created)
g_hash_table_insert(config->service_table, service->ident,
service);
gsize length;
char **groups;
char *str;
- gboolean protected, found = FALSE;
+ gboolean protected;
int i;
DBG("config %p", config);
groups = g_key_file_get_groups(keyfile, &length);
for (i = 0; groups[i] != NULL; i++) {
- if (g_str_has_prefix(groups[i], "service_") == TRUE) {
- if (load_service(keyfile, groups[i], config) == 0)
- found = TRUE;
- }
+ if (g_str_has_prefix(groups[i], "service_") == TRUE)
+ load_service(keyfile, groups[i], config);
}
- if (found == FALSE)
- connman_warn("Config file %s/%s.config does not contain any "
- "configuration that can be provisioned!",
- STORAGEDIR, config->ident);
-
g_strfreev(groups);
g_key_file_free(keyfile);
return config;
}
+int __connman_config_load_service(GKeyFile *keyfile, const char *group,
+ connman_bool_t persistent)
+{
+ struct connman_config *config;
+ const char *service_name;
+ char *ident, *content = NULL;
+ gsize content_length;
+ int err;
+
+ service_name = group + strlen("service_");
+ ident = g_strdup_printf("%s_%s", INTERNAL_CONFIG_PREFIX, service_name);
+ if (ident == NULL)
+ return -ENOMEM;
+
+ DBG("ident %s", ident);
+
+ config = g_hash_table_lookup(config_table, ident);
+ if (config == NULL) {
+ config = create_config(ident);
+ if (config == NULL) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ config->protected = FALSE;
+ }
+
+ err = load_service(keyfile, group, config);
+ if (persistent == FALSE || err < 0)
+ goto out;
+
+ g_key_file_set_string(keyfile, "global", CONFIG_KEY_NAME,
+ service_name);
+ g_key_file_set_string(keyfile, "global", CONFIG_KEY_DESC,
+ "Internal Config File");
+ g_key_file_set_boolean(keyfile, "global", CONFIG_KEY_PROT, FALSE);
+
+ content = g_key_file_to_data(keyfile, &content_length, NULL);
+ if (content == NULL) {
+ err = -EIO;
+ goto out;
+ }
+
+ DBG("Saving %zu bytes to %s", content_length, service_name);
+
+ __connman_storage_save_config(keyfile, ident);
+
+ return 0;
+
+out:
+ g_free(ident);
+ g_free(content);
+
+ return err;
+}
+
static connman_bool_t validate_ident(const char *ident)
{
unsigned int i;
config = g_hash_table_lookup(config_table, ident);
if (config != NULL) {
- int ret;
-
g_hash_table_remove_all(config->service_table);
load_config(config);
- ret = __connman_service_provision_changed(ident);
- if (ret > 0) {
- /*
- * Re-scan the config file for any
- * changes
- */
- g_hash_table_remove_all(config->service_table);
- load_config(config);
- __connman_service_provision_changed(ident);
- }
+ __connman_service_provision_changed(ident);
}
}
{
DBG("");
- cleanup = TRUE;
-
remove_watch();
g_hash_table_destroy(config_table);
config_table = NULL;
-
- cleanup = FALSE;
}
static char *config_pem_fsid(const char *pem_file)
struct connman_service *service = user_data;
struct connman_config_service *config = value;
struct connman_network *network;
- const void *ssid, *service_id;
+ const void *ssid;
unsigned int ssid_len;
/* For now only WiFi service entries are supported */
if (memcmp(config->ssid, ssid, ssid_len) != 0)
return;
- service_id = __connman_service_get_ident(service);
- config->service_identifiers =
- g_slist_prepend(config->service_identifiers,
- g_strdup(service_id));
-
__connman_service_set_immutable(service, TRUE);
- __connman_service_set_favorite_delayed(service, TRUE, TRUE);
-
- __connman_service_set_config(service, config->config_ident,
- config->config_entry);
+ __connman_service_set_favorite(service, TRUE);
if (config->eap != NULL)
__connman_service_set_string(service, "EAP", config->eap);
if (config->passphrase != NULL)
__connman_service_set_string(service, "Passphrase", config->passphrase);
-
- __connman_service_mark_dirty();
-
- __connman_service_save(service);
}
int __connman_config_provision_service(struct connman_service *service)
}
int __connman_config_provision_service_ident(struct connman_service *service,
- const char *ident, const char *file, const char *entry)
+ const char *ident)
{
enum connman_service_type type;
struct connman_config *config;
- int ret = 0;
DBG("service %p", service);
return -ENOSYS;
config = g_hash_table_lookup(config_table, ident);
- if(config != NULL) {
- GHashTableIter iter;
- gpointer value, key;
- gboolean found = FALSE;
-
- g_hash_table_iter_init(&iter, config->service_table);
-
- /*
- * Check if we need to remove individual service if it
- * is missing from config file.
- */
- if (file != NULL && entry != NULL) {
- while (g_hash_table_iter_next(&iter, &key,
- &value) == TRUE) {
- struct connman_config_service *config = value;
-
- if (g_strcmp0(config->config_ident,
- file) == 0 &&
- g_strcmp0(config->config_entry,
- entry) == 0) {
- found = TRUE;
- break;
- }
- }
-
- DBG("found %d ident %s file %s entry %s", found, ident,
- file, entry);
-
- if (found == FALSE) {
- /*
- * The entry+8 will skip "service_" prefix
- */
- g_hash_table_remove(config->service_table,
- entry + 8);
- ret = 1;
- }
- }
-
+ if(config != NULL)
g_hash_table_foreach(config->service_table,
provision_service, service);
- }
- return ret;
+ return 0;
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
* Copyright (C) 2011 BMW Car IT GmbH. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
unsigned int order;
struct gateway_config *ipv4_gateway;
struct gateway_config *ipv6_gateway;
- connman_bool_t default_checked;
};
static GHashTable *gateway_hash = NULL;
return NULL;
}
-static struct gateway_data *lookup_gateway_data(struct gateway_config *config)
-{
- GHashTableIter iter;
- gpointer value, key;
-
- if (config == NULL)
- return NULL;
-
- g_hash_table_iter_init(&iter, gateway_hash);
-
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- struct gateway_data *data = value;
-
- if (data->ipv4_gateway != NULL &&
- data->ipv4_gateway == config)
- return data;
-
- if (data->ipv6_gateway != NULL &&
- data->ipv6_gateway == config)
- return data;
- }
-
- return NULL;
-}
-
-/*
- * Find the gateway that is serving the VPN link
- */
-static struct gateway_data *find_phy_gateway(int index, const char *gateway)
-{
- GHashTableIter iter;
- gpointer value, key;
-
- if (gateway == NULL)
- return NULL;
-
- g_hash_table_iter_init(&iter, gateway_hash);
-
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- struct gateway_data *data = value;
-
- if (data->ipv4_gateway != NULL && data->index != index &&
- g_str_equal(data->ipv4_gateway->gateway,
- gateway) == TRUE)
- return data;
-
- if (data->ipv6_gateway != NULL && data->index != index &&
- g_str_equal(data->ipv6_gateway->gateway,
- gateway) == TRUE)
- return data;
- }
-
- return NULL;
-}
-
-static void set_vpn_routes(struct gateway_data *new_gateway,
- struct connman_service *service,
- const char *gateway,
- enum connman_ipconfig_type type,
- const char *peer,
- struct gateway_data *active_gateway)
-{
- struct gateway_config *config;
- struct gateway_data *data;
- struct connman_ipconfig *ipconfig;
- char *dest;
- int index;
-
- if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
- ipconfig = __connman_service_get_ip4config(service);
- config = new_gateway->ipv4_gateway;
- } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
- ipconfig = __connman_service_get_ip6config(service);
- config = new_gateway->ipv6_gateway;
- } else
- return;
-
- if (config == NULL)
- goto done;
-
- config->vpn = TRUE;
- if (peer != NULL)
- config->vpn_ip = g_strdup(peer);
- else if (gateway != NULL)
- config->vpn_ip = g_strdup(gateway);
-
- index = __connman_ipconfig_get_index(ipconfig);
- data = find_phy_gateway(index, gateway);
-
- if (data == NULL)
- goto done;
-
- /*
- * data->service points now to original
- * service that is serving the VPN link
- */
- if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
- ipconfig = __connman_service_get_ip4config(data->service);
- else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
- ipconfig = __connman_service_get_ip6config(data->service);
- else
- return;
-
- if (ipconfig != NULL) {
- const char *address;
-
- address = __connman_ipconfig_get_local(ipconfig);
- config->vpn_phy_ip = g_strdup(address);
- }
-
- config->vpn_phy_index = data->index;
-
- DBG("vpn %s phy %s index %d", config->vpn_ip,
- config->vpn_phy_ip, config->vpn_phy_index);
-
-done:
- if (active_gateway == NULL)
- return;
-
- if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
- /*
- * Special route to VPN server via gateway. This
- * is needed so that we can access hosts behind
- * the VPN. The route might already exist depending
- * on network topology.
- */
- if (active_gateway->ipv4_gateway == NULL)
- return;
-
- if (g_strcmp0(active_gateway->ipv4_gateway->gateway,
- "0.0.0.0") != 0)
- dest = active_gateway->ipv4_gateway->gateway;
- else
- dest = NULL;
-
- connman_inet_add_host_route(active_gateway->index, gateway,
- dest);
-
- } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
-
- if (active_gateway->ipv6_gateway == NULL)
- return;
-
- if (g_strcmp0(active_gateway->ipv6_gateway->gateway,
- "::") != 0)
- dest = active_gateway->ipv6_gateway->gateway;
- else
- dest = NULL;
-
- connman_inet_add_ipv6_host_route(active_gateway->index,
- gateway, dest);
- }
-}
-
static int del_routes(struct gateway_data *data,
enum connman_ipconfig_type type)
{
if (do_ipv4 == TRUE && data->ipv4_gateway != NULL) {
if (data->ipv4_gateway->vpn == TRUE) {
+ if (data->ipv4_gateway->vpn_phy_index >= 0)
+ connman_inet_del_host_route(
+ data->ipv4_gateway->vpn_phy_index,
+ data->ipv4_gateway->gateway);
+
status4 = connman_inet_clear_gateway_address(
data->index,
data->ipv4_gateway->vpn_ip);
if (do_ipv6 == TRUE && data->ipv6_gateway != NULL) {
if (data->ipv6_gateway->vpn == TRUE) {
+ if (data->ipv6_gateway->vpn_phy_index >= 0)
+ connman_inet_del_host_route(
+ data->ipv6_gateway->vpn_phy_index,
+ data->ipv6_gateway->gateway);
+
status6 = connman_inet_clear_ipv6_gateway_address(
data->index,
data->ipv6_gateway->vpn_ip);
data->ipv4_gateway = old->ipv4_gateway;
old->ipv4_gateway = NULL;
}
- } else {
- /*
- * Only take a ref if we are adding new stuff to hash.
- */
- connman_service_ref(service);
}
+ connman_service_ref(service);
g_hash_table_replace(gateway_hash, service, data);
return data;
}
+static void connection_newgateway(int index, const char *gateway)
+{
+ struct gateway_config *config;
+
+ DBG("index %d gateway %s", index, gateway);
+
+ config = find_gateway(index, gateway);
+ if (config == NULL)
+ return;
+
+ config->active = TRUE;
+}
+
static void set_default_gateway(struct gateway_data *data,
enum connman_ipconfig_type type)
{
data->ipv4_gateway->vpn == TRUE) {
connman_inet_set_gateway_address(data->index,
data->ipv4_gateway->vpn_ip);
- connman_inet_add_host_route(data->index,
- data->ipv4_gateway->vpn_ip, NULL);
+ connman_inet_add_host_route(data->ipv4_gateway->vpn_phy_index,
+ data->ipv4_gateway->vpn_ip,
+ data->ipv4_gateway->vpn_phy_ip);
data->ipv4_gateway->active = TRUE;
- DBG("set %p index %d vpn %s index %d phy %s",
- data, data->index, data->ipv4_gateway->vpn_ip,
- data->ipv4_gateway->vpn_phy_index,
- data->ipv4_gateway->vpn_phy_ip);
-
__connman_service_indicate_default(data->service);
return;
data->ipv6_gateway->vpn == TRUE) {
connman_inet_set_ipv6_gateway_address(data->index,
data->ipv6_gateway->vpn_ip);
- connman_inet_add_ipv6_host_route(data->index,
- data->ipv6_gateway->vpn_ip, NULL);
+ connman_inet_add_ipv6_host_route(
+ data->ipv6_gateway->vpn_phy_index,
+ data->ipv6_gateway->vpn_ip,
+ data->ipv6_gateway->vpn_phy_ip);
data->ipv6_gateway->active = TRUE;
- DBG("set %p index %d vpn %s index %d phy %s",
- data, data->index, data->ipv6_gateway->vpn_ip,
- data->ipv6_gateway->vpn_phy_index,
- data->ipv6_gateway->vpn_phy_ip);
-
__connman_service_indicate_default(data->service);
return;
data->ipv4_gateway->vpn_ip);
data->ipv4_gateway->active = FALSE;
- DBG("unset %p index %d vpn %s index %d phy %s",
- data, data->index, data->ipv4_gateway->vpn_ip,
- data->ipv4_gateway->vpn_phy_index,
- data->ipv4_gateway->vpn_phy_ip);
-
return;
}
data->ipv6_gateway->vpn_ip);
data->ipv6_gateway->active = FALSE;
- DBG("unset %p index %d vpn %s index %d phy %s",
- data, data->index, data->ipv6_gateway->vpn_ip,
- data->ipv6_gateway->vpn_phy_index,
- data->ipv6_gateway->vpn_phy_ip);
-
return;
}
if (found == NULL || data->order > order) {
found = data;
order = data->order;
-
- DBG("default %p order %d", found, order);
}
}
return found;
}
-static gboolean choose_default_gateway(struct gateway_data *data,
- struct gateway_data *candidate)
-{
- gboolean downgraded = FALSE;
-
- /*
- * If the current default is not active, then we mark
- * this one as default. If the other one is already active
- * we mark this one as non default.
- */
- if (data->ipv4_gateway != NULL) {
- if (candidate->ipv4_gateway != NULL &&
- candidate->ipv4_gateway->active == FALSE) {
- DBG("ipv4 downgrading %p", candidate);
- unset_default_gateway(candidate,
- CONNMAN_IPCONFIG_TYPE_IPV4);
- }
- if (candidate->ipv4_gateway != NULL &&
- candidate->ipv4_gateway->active == TRUE &&
- candidate->order > data->order) {
- DBG("ipv4 downgrading this %p", data);
- unset_default_gateway(data,
- CONNMAN_IPCONFIG_TYPE_IPV4);
- downgraded = TRUE;
- }
- }
-
- if (data->ipv6_gateway != NULL) {
- if (candidate->ipv6_gateway != NULL &&
- candidate->ipv6_gateway->active == FALSE) {
- DBG("ipv6 downgrading %p", candidate);
- unset_default_gateway(candidate,
- CONNMAN_IPCONFIG_TYPE_IPV6);
- }
-
- if (candidate->ipv6_gateway != NULL &&
- candidate->ipv6_gateway->active == TRUE &&
- candidate->order > data->order) {
- DBG("ipv6 downgrading this %p", data);
- unset_default_gateway(data,
- CONNMAN_IPCONFIG_TYPE_IPV6);
- downgraded = TRUE;
- }
- }
-
- return downgraded;
-}
-
-static void connection_newgateway(int index, const char *gateway)
-{
- struct gateway_config *config;
- struct gateway_data *data;
- GHashTableIter iter;
- gpointer value, key;
- gboolean found = FALSE;
-
- DBG("index %d gateway %s", index, gateway);
-
- config = find_gateway(index, gateway);
- if (config == NULL)
- return;
-
- config->active = TRUE;
-
- /*
- * It is possible that we have two default routes atm
- * if there are two gateways waiting rtnl activation at the
- * same time.
- */
- data = lookup_gateway_data(config);
- if (data == NULL)
- return;
-
- if (data->default_checked == TRUE)
- return;
-
- /*
- * The next checks are only done once, otherwise setting
- * the default gateway could lead into rtnl forever loop.
- */
-
- g_hash_table_iter_init(&iter, gateway_hash);
-
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- struct gateway_data *candidate = value;
-
- if (candidate == data)
- continue;
-
- found = choose_default_gateway(data, candidate);
- if (found == TRUE)
- break;
- }
-
- if (found == FALSE) {
- if (data->ipv4_gateway != NULL)
- set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV4);
-
- if (data->ipv6_gateway != NULL)
- set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV6);
- }
-
- data->default_checked = TRUE;
-}
-
static void remove_gateway(gpointer user_data)
{
struct gateway_data *data = user_data;
data->ipv6_gateway->active = TRUE;
}
-static void add_host_route(int family, int index, const char *gateway,
- enum connman_service_type service_type)
-{
- switch (family) {
- case AF_INET:
- if (g_strcmp0(gateway, "0.0.0.0") != 0) {
- /*
- * We must not set route to the phy dev gateway in
- * VPN link. The packets to VPN link might be routed
- * back to itself and not routed into phy link gateway.
- */
- if (service_type != CONNMAN_SERVICE_TYPE_VPN)
- connman_inet_add_host_route(index, gateway,
- NULL);
- } else {
- /*
- * Add host route to P-t-P link so that services can
- * be moved around and we can have some link to P-t-P
- * network (although those P-t-P links have limited
- * usage if default route is not directed to them)
- */
- char *dest;
- if (connman_inet_get_dest_addr(index, &dest) == 0) {
- connman_inet_add_host_route(index, dest, NULL);
- g_free(dest);
- }
- }
- break;
-
- case AF_INET6:
- if (g_strcmp0(gateway, "::") != 0) {
- if (service_type != CONNMAN_SERVICE_TYPE_VPN)
- connman_inet_add_ipv6_host_route(index,
- gateway, NULL);
- } else {
- /* P-t-P link, add route to destination */
- char *dest;
- if (connman_inet_ipv6_get_dest_addr(index,
- &dest) == 0) {
- connman_inet_add_ipv6_host_route(index, dest,
- NULL);
- g_free(dest);
- }
- }
- break;
- }
-}
-
int __connman_connection_gateway_add(struct connman_service *service,
const char *gateway,
enum connman_ipconfig_type type,
{
struct gateway_data *active_gateway = NULL;
struct gateway_data *new_gateway = NULL;
- enum connman_ipconfig_type type4 = CONNMAN_IPCONFIG_TYPE_UNKNOWN,
- type6 = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
- enum connman_service_type service_type =
- connman_service_get_type(service);
int index;
index = __connman_service_get_index(service);
+ DBG("service %p index %d gateway %s vpn ip %s type %d",
+ service, index, gateway, peer, type);
+
/*
* If gateway is NULL, it's a point to point link and the default
* gateway for ipv4 is 0.0.0.0 and for ipv6 is ::, meaning the
if (gateway == NULL && type == CONNMAN_IPCONFIG_TYPE_IPV6)
gateway = "::";
- DBG("service %p index %d gateway %s vpn ip %s type %d",
- service, index, gateway, peer, type);
-
+ active_gateway = find_active_gateway();
new_gateway = add_gateway(service, index, gateway, type);
if (new_gateway == NULL)
return -EINVAL;
- active_gateway = find_active_gateway();
+ if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
+ new_gateway->ipv6_gateway != NULL &&
+ g_strcmp0(new_gateway->ipv6_gateway->gateway,
+ "::") != 0)
+ connman_inet_add_ipv6_host_route(index,
+ new_gateway->ipv6_gateway->gateway,
+ NULL);
- DBG("active %p index %d new %p", active_gateway,
- active_gateway ? active_gateway->index : -1, new_gateway);
+ if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
+ new_gateway->ipv4_gateway != NULL &&
+ g_strcmp0(new_gateway->ipv4_gateway->gateway,
+ "0.0.0.0") != 0)
+ connman_inet_add_host_route(index,
+ new_gateway->ipv4_gateway->gateway,
+ NULL);
if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
new_gateway->ipv4_gateway != NULL) {
- add_host_route(AF_INET, index, gateway, service_type);
__connman_service_nameserver_add_routes(service,
new_gateway->ipv4_gateway->gateway);
- type4 = CONNMAN_IPCONFIG_TYPE_IPV4;
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_READY,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
}
if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
new_gateway->ipv6_gateway != NULL) {
- add_host_route(AF_INET6, index, gateway, service_type);
__connman_service_nameserver_add_routes(service,
new_gateway->ipv6_gateway->gateway);
- type6 = CONNMAN_IPCONFIG_TYPE_IPV6;
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_READY,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
}
- if (service_type == CONNMAN_SERVICE_TYPE_VPN) {
+ if (connman_service_get_type(service) == CONNMAN_SERVICE_TYPE_VPN) {
+ if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
+ new_gateway->ipv4_gateway != NULL) {
+ new_gateway->ipv4_gateway->vpn = TRUE;
+ if (peer != NULL)
+ new_gateway->ipv4_gateway->vpn_ip =
+ g_strdup(peer);
+ else if (gateway != NULL)
+ new_gateway->ipv4_gateway->vpn_ip =
+ g_strdup(gateway);
+ if (active_gateway) {
+ const char *new_ipv4_gateway;
+
+ new_ipv4_gateway =
+ active_gateway->ipv4_gateway->gateway;
+ if (new_ipv4_gateway != NULL &&
+ g_strcmp0(new_ipv4_gateway,
+ "0.0.0.0") != 0)
+ new_gateway->ipv4_gateway->vpn_phy_ip =
+ g_strdup(new_ipv4_gateway);
- set_vpn_routes(new_gateway, service, gateway, type, peer,
- active_gateway);
+ new_gateway->ipv4_gateway->vpn_phy_index =
+ active_gateway->index;
+ }
+ } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
+ new_gateway->ipv6_gateway != NULL) {
+ new_gateway->ipv6_gateway->vpn = TRUE;
+ if (peer != NULL)
+ new_gateway->ipv6_gateway->vpn_ip =
+ g_strdup(peer);
+ else if (gateway != NULL)
+ new_gateway->ipv6_gateway->vpn_ip =
+ g_strdup(gateway);
+ if (active_gateway) {
+ const char *new_ipv6_gateway;
+
+ new_ipv6_gateway =
+ active_gateway->ipv6_gateway->gateway;
+ if (new_ipv6_gateway != NULL &&
+ g_strcmp0(new_ipv6_gateway, "::") != 0)
+ new_gateway->ipv6_gateway->vpn_phy_ip =
+ g_strdup(new_ipv6_gateway);
+
+ new_gateway->ipv6_gateway->vpn_phy_index =
+ active_gateway->index;
+ }
+ }
} else {
if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
new_gateway->ipv4_gateway != NULL)
if (active_gateway == NULL) {
set_default_gateway(new_gateway, type);
- goto done;
+ return 0;
}
if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
new_gateway->ipv4_gateway != NULL &&
new_gateway->ipv4_gateway->vpn == TRUE) {
- if (__connman_service_is_split_routing(new_gateway->service) ==
- FALSE)
- connman_inet_clear_gateway_address(
- active_gateway->index,
+ connman_inet_add_host_route(active_gateway->index,
+ new_gateway->ipv4_gateway->gateway,
+ active_gateway->ipv4_gateway->gateway);
+ connman_inet_clear_gateway_address(active_gateway->index,
active_gateway->ipv4_gateway->gateway);
}
if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
new_gateway->ipv6_gateway != NULL &&
new_gateway->ipv6_gateway->vpn == TRUE) {
- if (__connman_service_is_split_routing(new_gateway->service) ==
- FALSE)
- connman_inet_clear_ipv6_gateway_address(
- active_gateway->index,
+ connman_inet_add_ipv6_host_route(active_gateway->index,
+ new_gateway->ipv6_gateway->gateway,
+ active_gateway->ipv6_gateway->gateway);
+ connman_inet_clear_ipv6_gateway_address(active_gateway->index,
active_gateway->ipv6_gateway->gateway);
}
-done:
- if (type4 == CONNMAN_IPCONFIG_TYPE_IPV4)
- __connman_service_ipconfig_indicate_state(service,
- CONNMAN_SERVICE_STATE_READY,
- CONNMAN_IPCONFIG_TYPE_IPV4);
-
- if (type6 == CONNMAN_IPCONFIG_TYPE_IPV6)
- __connman_service_ipconfig_indicate_state(service,
- CONNMAN_SERVICE_STATE_READY,
- CONNMAN_IPCONFIG_TYPE_IPV6);
return 0;
}
else
do_ipv4 = do_ipv6 = TRUE;
- __connman_service_nameserver_del_routes(service, type);
+ __connman_service_nameserver_del_routes(service);
data = g_hash_table_lookup(gateway_hash, service);
if (data == NULL)
connman_inet_del_ipv6_host_route(data->index,
data->ipv6_gateway->gateway);
+ __connman_service_nameserver_del_routes(service);
+
err = disable_gateway(data, type);
/*
gboolean __connman_connection_update_gateway(void)
{
- struct gateway_data *default_gateway;
+ struct gateway_data *active_gateway, *default_gateway;
gboolean updated = FALSE;
- GHashTableIter iter;
- gpointer value, key;
if (gateway_hash == NULL)
return updated;
+ active_gateway = find_active_gateway();
+
update_order();
default_gateway = find_default_gateway();
- __connman_service_update_ordering();
-
- DBG("default %p", default_gateway);
-
- /*
- * There can be multiple active gateways so we need to
- * check them all.
- */
- g_hash_table_iter_init(&iter, gateway_hash);
-
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- struct gateway_data *active_gateway = value;
-
- if (active_gateway == default_gateway)
- continue;
+ if (active_gateway && active_gateway != default_gateway) {
+ updated = TRUE;
- if (active_gateway->ipv4_gateway != NULL &&
- active_gateway->ipv4_gateway->active == TRUE) {
+ if (active_gateway->ipv4_gateway)
+ unset_default_gateway(active_gateway,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+ if (active_gateway->ipv6_gateway)
unset_default_gateway(active_gateway,
- CONNMAN_IPCONFIG_TYPE_IPV4);
- updated = TRUE;
- }
+ CONNMAN_IPCONFIG_TYPE_IPV6);
- if (active_gateway->ipv6_gateway != NULL &&
- active_gateway->ipv6_gateway->active == TRUE) {
+ if (default_gateway) {
+ if (default_gateway->ipv4_gateway)
+ set_default_gateway(default_gateway,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
- unset_default_gateway(active_gateway,
+ if (default_gateway->ipv6_gateway)
+ set_default_gateway(default_gateway,
CONNMAN_IPCONFIG_TYPE_IPV6);
- updated = TRUE;
}
}
- if (updated && default_gateway != NULL) {
- if (default_gateway->ipv4_gateway)
- set_default_gateway(default_gateway,
- CONNMAN_IPCONFIG_TYPE_IPV4);
-
- if (default_gateway->ipv6_gateway)
- set_default_gateway(default_gateway,
- CONNMAN_IPCONFIG_TYPE_IPV6);
- }
-
return updated;
}
-int __connman_connection_get_vpn_index(int phy_index)
-{
- GHashTableIter iter;
- gpointer value, key;
-
- g_hash_table_iter_init(&iter, gateway_hash);
-
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- struct gateway_data *data = value;
-
- if (data->ipv4_gateway != NULL &&
- data->ipv4_gateway->vpn_phy_index == phy_index)
- return data->index;
-
- if (data->ipv6_gateway != NULL &&
- data->ipv6_gateway->vpn_phy_index == phy_index)
- return data->index;
- }
-
- return -1;
-}
-
int __connman_connection_init(void)
{
int err;
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
- <policy user="root">
+ <policy user="0">
+ <allow own="net.connman"/>
+ <allow send_destination="net.connman"/>
+ <allow send_interface="net.connman.Agent"/>
+ <allow send_interface="net.connman.Counter"/>
+ <allow send_interface="net.connman.Notification"/>
+ </policy>
+ <policy user="5000">
<allow own="net.connman"/>
<allow send_destination="net.connman"/>
<allow send_interface="net.connman.Agent"/>
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
- <policy user="root">
+ <policy user="0">
+ <allow own="net.connman"/>
+ <allow send_interface="net.connman.Agent"/>
+ </policy>
+ <policy user="5000">
<allow own="net.connman"/>
<allow send_interface="net.connman.Agent"/>
</policy>
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <connman/dbus.h>
-dbus_bool_t __connman_dbus_append_objpath_dict_array(DBusMessage *msg,
- connman_dbus_append_cb_t function, void *user_data);
int __connman_dbus_init(DBusConnection *conn);
void __connman_dbus_cleanup(void);
struct connman_service;
-int __connman_service_add_passphrase(struct connman_service *service,
- const gchar *passphrase);
typedef void (* authentication_cb_t) (struct connman_service *service,
- connman_bool_t values_received,
- const char *name, int name_len,
const char *identifier, const char *secret,
- gboolean wps, const char *wpspin,
- const char *error, void *user_data);
-typedef void (* browser_authentication_cb_t) (struct connman_service *service,
- connman_bool_t authentication_done,
- const char *error, void *user_data);
+ void *user_data);
typedef void (* report_error_cb_t) (struct connman_service *service,
gboolean retry, void *user_data);
int __connman_agent_request_passphrase_input(struct connman_service *service,
authentication_cb_t callback, void *user_data);
int __connman_agent_request_login_input(struct connman_service *service,
authentication_cb_t callback, void *user_data);
-int __connman_agent_request_browser(struct connman_service *service,
- browser_authentication_cb_t callback,
- const char *url, void *user_data);
int __connman_agent_report_error(struct connman_service *service,
const char *error,
report_error_cb_t callback, void *user_data);
void __connman_log_enable(struct connman_debug_desc *start,
struct connman_debug_desc *stop);
+void __connman_debug_list_available(DBusMessageIter *iter, void *user_data);
+void __connman_debug_list_enabled(DBusMessageIter *iter, void *user_data);
+
#include <connman/option.h>
#include <connman/setting.h>
#include <connman/inet.h>
-char **__connman_inet_get_running_interfaces(void);
int __connman_inet_modify_address(int cmd, int flags, int index, int family,
const char *address,
const char *peer,
#include <netinet/icmp6.h>
typedef void (*__connman_inet_rs_cb_t) (struct nd_router_advert *reply,
- unsigned int length, void *user_data);
+ void *user_data);
int __connman_inet_ipv6_send_rs(int index, int timeout,
__connman_inet_rs_cb_t callback, void *user_data);
-int __connman_refresh_rs_ipv6(struct connman_network *network, int index);
-
-GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
- unsigned int length);
-
-struct __connman_inet_rtnl_handle {
- int fd;
- struct sockaddr_nl local;
- struct sockaddr_nl peer;
- __u32 seq;
- __u32 dump;
-
- struct {
- struct nlmsghdr n;
- union {
- struct {
- struct rtmsg rt;
- } r;
- struct {
- struct ifaddrmsg ifa;
- } i;
- } u;
- char buf[1024];
- } req;
-};
-
-int __connman_inet_rtnl_open(struct __connman_inet_rtnl_handle *rth);
-typedef void (*__connman_inet_rtnl_cb_t) (struct nlmsghdr *answer,
- void *user_data);
-int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
- struct nlmsghdr *n, int timeout,
- __connman_inet_rtnl_cb_t callback, void *user_data);
-static inline
-int __connman_inet_rtnl_send(struct __connman_inet_rtnl_handle *rtnl,
- struct nlmsghdr *n)
-{
- return __connman_inet_rtnl_talk(rtnl, n, 0, NULL, NULL);
-}
-
-void __connman_inet_rtnl_close(struct __connman_inet_rtnl_handle *rth);
-int __connman_inet_rtnl_addattr_l(struct nlmsghdr *n, size_t max_length,
- int type, const void *data, size_t data_length);
-int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen,
- int type, __u32 data);
-
#include <connman/resolver.h>
int __connman_resolver_init(connman_bool_t dnsproxy);
void __connman_resolver_cleanup(void);
int __connman_resolvfile_append(const char *interface, const char *domain, const char *server);
int __connman_resolvfile_remove(const char *interface, const char *domain, const char *server);
-int __connman_resolver_redo_servers(const char *interface);
void __connman_storage_migrate(void);
GKeyFile *__connman_storage_open_global();
GKeyFile *__connman_storage_load_global();
-int __connman_storage_save_global(GKeyFile *keyfile);
+void __connman_storage_save_global(GKeyFile *keyfile);
void __connman_storage_delete_global();
GKeyFile *__connman_storage_load_config(const char *ident);
+void __connman_storage_save_config(GKeyFile *keyfile, const char *ident);
+void __connman_storage_delete_config(const char *ident);
GKeyFile *__connman_storage_open_service(const char *ident);
-int __connman_storage_save_service(GKeyFile *keyfile, const char *ident);
+void __connman_storage_save_service(GKeyFile *keyfile, const char *ident);
GKeyFile *__connman_storage_load_provider(const char *identifier);
void __connman_storage_save_provider(GKeyFile *keyfile, const char *identifier);
-char **__connman_storage_get_providers(void);
-gboolean __connman_storage_remove_service(const char *service_id);
int __connman_detect_init(void);
void __connman_detect_cleanup(void);
#include <connman/ipconfig.h>
-struct connman_ipaddress {
- int family;
- unsigned char prefixlen;
- char *local;
- char *peer;
- char *broadcast;
- char *gateway;
-};
-
-struct connman_ipconfig_ops {
- void (*up) (struct connman_ipconfig *ipconfig);
- void (*down) (struct connman_ipconfig *ipconfig);
- void (*lower_up) (struct connman_ipconfig *ipconfig);
- void (*lower_down) (struct connman_ipconfig *ipconfig);
- void (*ip_bound) (struct connman_ipconfig *ipconfig);
- void (*ip_release) (struct connman_ipconfig *ipconfig);
- void (*route_set) (struct connman_ipconfig *ipconfig);
- void (*route_unset) (struct connman_ipconfig *ipconfig);
-};
-
-struct connman_ipconfig *__connman_ipconfig_create(int index,
- enum connman_ipconfig_type type);
-
-#define __connman_ipconfig_ref(ipconfig) \
- __connman_ipconfig_ref_debug(ipconfig, __FILE__, __LINE__, __func__)
-#define __connman_ipconfig_unref(ipconfig) \
- __connman_ipconfig_unref_debug(ipconfig, __FILE__, __LINE__, __func__)
-
-struct connman_ipconfig *
-__connman_ipconfig_ref_debug(struct connman_ipconfig *ipconfig,
- const char *file, int line, const char *caller);
-void __connman_ipconfig_unref_debug(struct connman_ipconfig *ipconfig,
- const char *file, int line, const char *caller);
-
-void *__connman_ipconfig_get_data(struct connman_ipconfig *ipconfig);
-void __connman_ipconfig_set_data(struct connman_ipconfig *ipconfig, void *data);
-
-int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig);
-const char *__connman_ipconfig_get_ifname(struct connman_ipconfig *ipconfig);
-
-void __connman_ipconfig_set_ops(struct connman_ipconfig *ipconfig,
- const struct connman_ipconfig_ops *ops);
-int __connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
- enum connman_ipconfig_method method);
-void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig);
-void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig);
-
int __connman_ipconfig_init(void);
void __connman_ipconfig_cleanup(void);
struct connman_ipconfig *ipconfig);
unsigned short __connman_ipconfig_get_type_from_index(int index);
unsigned int __connman_ipconfig_get_flags_from_index(int index);
-const char *__connman_ipconfig_get_gateway_from_index(int index,
- enum connman_ipconfig_type type);
+const char *__connman_ipconfig_get_gateway_from_index(int index);
void __connman_ipconfig_set_index(struct connman_ipconfig *ipconfig, int index);
const char *__connman_ipconfig_get_local(struct connman_ipconfig *ipconfig);
int __connman_ipconfig_address_add(struct connman_ipconfig *ipconfig);
int __connman_ipconfig_address_remove(struct connman_ipconfig *ipconfig);
int __connman_ipconfig_address_unset(struct connman_ipconfig *ipconfig);
+#if defined TIZEN_EXT
+/*
+ * Description: __connman_service_lookup_from_index cannot find correct service
+ */
+int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig, struct connman_service *service);
+#else
int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig);
+#endif
void __connman_ipconfig_gateway_remove(struct connman_ipconfig *ipconfig);
unsigned char __connman_ipconfig_netmask_prefix_len(const char *netmask);
GKeyFile *keyfile, const char *identifier, const char *prefix);
int __connman_ipconfig_save(struct connman_ipconfig *ipconfig,
GKeyFile *keyfile, const char *identifier, const char *prefix);
-gboolean __connman_ipconfig_ipv6_privacy_enabled(struct connman_ipconfig *ipconfig);
int __connman_ipconfig_set_rp_filter();
void __connman_ipconfig_unset_rp_filter(int old_value);
int __connman_timeserver_init(void);
void __connman_timeserver_cleanup(void);
-char **__connman_timeserver_system_get();
-
-GSList *__connman_timeserver_add_list(GSList *server_list,
- const char *timeserver);
-GSList *__connman_timeserver_get_all(struct connman_service *service);
-int __connman_timeserver_sync(struct connman_service *service);
-void __connman_timeserver_sync_next();
-
typedef void (* dhcp_cb) (struct connman_network *network,
connman_bool_t success);
int __connman_dhcp_start(struct connman_network *network, dhcp_cb callback);
void __connman_dhcp_stop(struct connman_network *network);
int __connman_dhcp_init(void);
void __connman_dhcp_cleanup(void);
-int __connman_dhcpv6_init(void);
-void __connman_dhcpv6_cleanup(void);
-int __connman_dhcpv6_start_info(struct connman_network *network,
- dhcp_cb callback);
-void __connman_dhcpv6_stop(struct connman_network *network);
-int __connman_dhcpv6_start(struct connman_network *network,
- GSList *prefixes, dhcp_cb callback);
-int __connman_dhcpv6_start_renew(struct connman_network *network,
- dhcp_cb callback);
-int __connman_dhcpv6_start_release(struct connman_network *network,
- dhcp_cb callback);
int __connman_ipv4_init(void);
void __connman_ipv4_cleanup(void);
const char *peer);
void __connman_connection_gateway_remove(struct connman_service *service,
enum connman_ipconfig_type type);
-int __connman_connection_get_vpn_index(int phy_index);
gboolean __connman_connection_update_gateway(void);
void __connman_connection_gateway_activate(struct connman_service *service,
enum connman_ipconfig_type type);
-int __connman_ntp_start(char *server);
-void __connman_ntp_stop();
+int __connman_ntp_start(const char *interface, const char *resolver,
+ const char *server);
+void __connman_ntp_stop(const char *interface);
int __connman_wpad_init(void);
void __connman_wpad_cleanup(void);
#include <connman/technology.h>
-void __connman_technology_list_struct(DBusMessageIter *array);
+void __connman_technology_list(DBusMessageIter *iter, void *user_data);
int __connman_technology_add_device(struct connman_device *device);
int __connman_technology_remove_device(struct connman_device *device);
int __connman_technology_enabled(enum connman_service_type type);
+int __connman_technology_enable(enum connman_service_type type, DBusMessage *msg);
int __connman_technology_disabled(enum connman_service_type type);
+int __connman_technology_disable(enum connman_service_type type, DBusMessage *msg);
int __connman_technology_set_offlinemode(connman_bool_t offlinemode);
connman_bool_t __connman_technology_get_offlinemode(void);
-void __connman_technology_set_connected(enum connman_service_type type,
- connman_bool_t connected);
int __connman_technology_add_rfkill(unsigned int index,
enum connman_service_type type,
int __connman_technology_remove_rfkill(unsigned int index,
enum connman_service_type type);
-void __connman_technology_scan_started(struct connman_device *device);
-void __connman_technology_scan_stopped(struct connman_device *device);
void __connman_technology_add_interface(enum connman_service_type type,
int index, const char *name, const char *ident);
void __connman_technology_remove_interface(enum connman_service_type type,
int index, const char *name, const char *ident);
-void __connman_technology_notify_regdom_by_device(struct connman_device *device,
- int result, const char *alpha2);
#include <connman/device.h>
enum connman_service_type __connman_device_get_service_type(struct connman_device *device);
struct connman_device *__connman_device_find_device(enum connman_service_type type);
int __connman_device_request_scan(enum connman_service_type type);
-int __connman_device_request_hidden_scan(struct connman_device *device,
- const char *ssid, unsigned int ssid_len,
- const char *identity, const char *passphrase,
- gpointer user_data);
connman_bool_t __connman_device_isfiltered(const char *devname);
struct connman_ipconfig *ipconfig_ipv4,
struct connman_ipconfig *ipconfig_ipv6);
+connman_bool_t __connman_network_has_driver(struct connman_network *network);
+
const char *__connman_network_get_type(struct connman_network *network);
const char *__connman_network_get_group(struct connman_network *network);
const char *__connman_network_get_ident(struct connman_network *network);
int __connman_config_load_service(GKeyFile *keyfile, const char *group, connman_bool_t persistent);
int __connman_config_provision_service(struct connman_service *service);
int __connman_config_provision_service_ident(struct connman_service *service,
- const char *ident, const char *file, const char *entry);
+ const char *ident);
int __connman_tethering_init(void);
void __connman_tethering_cleanup(void);
const char *__connman_tethering_get_bridge(void);
+void __connman_tethering_update_interface(const char *interface);
void __connman_tethering_set_enabled(void);
void __connman_tethering_set_disabled(void);
#include <connman/provider.h>
-connman_bool_t __connman_provider_check_routes(struct connman_provider *provider);
-int __connman_provider_append_user_route(struct connman_provider *provider,
- int family, const char *network, const char *netmask);
void __connman_provider_append_properties(struct connman_provider *provider, DBusMessageIter *iter);
void __connman_provider_list(DBusMessageIter *iter, void *user_data);
int __connman_provider_create_and_connect(DBusMessage *msg);
int __connman_service_init(void);
void __connman_service_cleanup(void);
+void __connman_service_list(DBusMessageIter *iter, void *user_data);
void __connman_service_list_struct(DBusMessageIter *iter);
+const char *__connman_service_default(void);
+
+void __connman_service_put(struct connman_service *service);
struct connman_service *__connman_service_lookup_from_network(struct connman_network *network);
struct connman_service *__connman_service_lookup_from_index(int index);
-struct connman_service *__connman_service_lookup_from_ident(const char *identifier);
struct connman_service *__connman_service_create_from_network(struct connman_network *network);
struct connman_service *__connman_service_create_from_provider(struct connman_provider *provider);
-struct connman_service *__connman_service_get_default(void);
void __connman_service_update_from_network(struct connman_network *network);
void __connman_service_remove_from_network(struct connman_network *network);
void __connman_service_read_ip4config(struct connman_service *service);
struct connman_service *service);
struct connman_ipconfig *__connman_service_get_ipconfig(
struct connman_service *service, int family);
-connman_bool_t __connman_service_is_connected_state(struct connman_service *service,
- enum connman_ipconfig_type type);
const char *__connman_service_get_ident(struct connman_service *service);
const char *__connman_service_get_path(struct connman_service *service);
unsigned int __connman_service_get_order(struct connman_service *service);
-void __connman_service_update_ordering(void);
struct connman_network *__connman_service_get_network(struct connman_service *service);
enum connman_service_security __connman_service_get_security(struct connman_service *service);
const char *__connman_service_get_phase2(struct connman_service *service);
connman_bool_t __connman_service_wps_enabled(struct connman_service *service);
int __connman_service_set_favorite(struct connman_service *service,
connman_bool_t favorite);
-int __connman_service_set_favorite_delayed(struct connman_service *service,
- connman_bool_t favorite,
- gboolean delay_ordering);
int __connman_service_set_immutable(struct connman_service *service,
connman_bool_t immutable);
-void __connman_service_set_userconnect(struct connman_service *service,
- connman_bool_t userconnect);
void __connman_service_set_string(struct connman_service *service,
const char *key, const char *value);
-int __connman_service_online_check_failed(struct connman_service *service,
- enum connman_ipconfig_type type);
int __connman_service_ipconfig_indicate_state(struct connman_service *service,
enum connman_service_state new_state,
enum connman_ipconfig_type type);
enum connman_service_error error);
int __connman_service_clear_error(struct connman_service *service);
int __connman_service_indicate_default(struct connman_service *service);
+int __connman_service_request_login(struct connman_service *service);
+int __connman_service_lookup(const char *pattern, const char **path);
int __connman_service_connect(struct connman_service *service);
int __connman_service_disconnect(struct connman_service *service);
int __connman_service_disconnect_all(void);
+int __connman_service_create_and_connect(DBusMessage *msg);
+int __connman_service_provision(DBusMessage *msg);
void __connman_service_auto_connect(void);
-gboolean __connman_service_remove(struct connman_service *service);
-void __connman_service_set_hidden_data(struct connman_service *service,
- gpointer user_data);
-void __connman_service_return_error(struct connman_service *service,
- int error, gpointer user_data);
-void __connman_service_reply_dbus_pending(DBusMessage *pending, int error);
-int __connman_service_provision_changed(const char *ident);
-void __connman_service_set_config(struct connman_service *service,
- const char *file_id, const char *section);
+void __connman_service_provision_changed(const char *ident);
const char *__connman_service_type2string(enum connman_service_type type);
-enum connman_service_type __connman_service_string2type(const char *str);
int __connman_service_nameserver_append(struct connman_service *service,
const char *nameserver, gboolean is_auto);
void __connman_service_nameserver_clear(struct connman_service *service);
void __connman_service_nameserver_add_routes(struct connman_service *service,
const char *gw);
-void __connman_service_nameserver_del_routes(struct connman_service *service,
- enum connman_ipconfig_type type);
+void __connman_service_nameserver_del_routes(struct connman_service *service);
int __connman_service_timeserver_append(struct connman_service *service,
const char *timeserver);
int __connman_service_timeserver_remove(struct connman_service *service,
const char *timeserver);
-void __connman_service_timeserver_changed(struct connman_service *service,
- GSList *ts_list);
void __connman_service_set_pac(struct connman_service *service,
const char *pac);
-connman_bool_t __connman_service_is_hidden(struct connman_service *service);
-connman_bool_t __connman_service_is_split_routing(struct connman_service *service);
+#if defined TIZEN_EXT
+/*
+ * Description: Telephony plug-in requires manual PROXY setting function
+ */
+void __connman_service_set_proxy(struct connman_service *service,
+ const char *proxies);
+#endif
int __connman_service_get_index(struct connman_service *service);
-void __connman_service_set_hidden(struct connman_service *service);
void __connman_service_set_domainname(struct connman_service *service,
const char *domainname);
const char *__connman_service_get_domainname(struct connman_service *service);
const char *identity);
void __connman_service_set_agent_identity(struct connman_service *service,
const char *agent_identity);
-int __connman_service_set_passphrase(struct connman_service *service,
- const char *passphrase);
-const char *__connman_service_get_passphrase(struct connman_service *service);
+void __connman_service_set_passphrase(struct connman_service *service,
+ const char* passphrase);
void __connman_service_set_agent_passphrase(struct connman_service *service,
const char *agent_passphrase);
void __connman_service_session_inc(struct connman_service *service);
connman_bool_t __connman_service_session_dec(struct connman_service *service);
-void __connman_service_mark_dirty();
-void __connman_service_save(struct connman_service *service);
#include <connman/notifier.h>
int __connman_notifier_init(void);
void __connman_notifier_cleanup(void);
+void __connman_notifier_list_registered(DBusMessageIter *iter, void *user_data);
+void __connman_notifier_list_enabled(DBusMessageIter *iter, void *user_data);
+void __connman_notifier_list_connected(DBusMessageIter *iter, void *user_data);
+
+void __connman_notifier_register(enum connman_service_type type);
+void __connman_notifier_unregister(enum connman_service_type type);
void __connman_notifier_service_add(struct connman_service *service,
const char *name);
void __connman_notifier_service_remove(struct connman_service *service);
-void __connman_notifier_enter_online(enum connman_service_type type);
-void __connman_notifier_leave_online(enum connman_service_type type);
+void __connman_notifier_enable(enum connman_service_type type);
+void __connman_notifier_disable(enum connman_service_type type);
void __connman_notifier_connect(enum connman_service_type type);
void __connman_notifier_disconnect(enum connman_service_type type);
void __connman_notifier_offlinemode(connman_bool_t enabled);
+#if defined TIZEN_EXT
+void __connman_notifier_scan_completed(connman_bool_t success);
+#endif
void __connman_notifier_default_changed(struct connman_service *service);
void __connman_notifier_proxy_changed(struct connman_service *service);
void __connman_notifier_service_state_changed(struct connman_service *service,
void __connman_notifier_ipconfig_changed(struct connman_service *service,
struct connman_ipconfig *ipconfig);
-connman_bool_t __connman_notifier_is_connected(void);
+connman_bool_t __connman_notifier_is_registered(enum connman_service_type type);
+connman_bool_t __connman_notifier_is_enabled(enum connman_service_type type);
+unsigned int __connman_notifier_count_connected(void);
const char *__connman_notifier_get_state(void);
#include <connman/rtnl.h>
int __connman_6to4_probe(struct connman_service *service);
void __connman_6to4_remove(struct connman_ipconfig *ipconfig);
int __connman_6to4_check(struct connman_ipconfig *ipconfig);
-
-struct connman_ippool;
-
-typedef void (*ippool_collision_cb_t) (struct connman_ippool *pool,
- void *user_data);
-
-int __connman_ippool_init(void);
-void __connman_ippool_cleanup(void);
-
-#define __connman_ippool_ref(ipconfig) \
- __connman_ippool_ref_debug(ipconfig, __FILE__, __LINE__, __func__)
-#define __connman_ippool_unref(ipconfig) \
- __connman_ippool_unref_debug(ipconfig, __FILE__, __LINE__, __func__)
-
-struct connman_ippool *__connman_ippool_ref_debug(struct connman_ippool *pool,
- const char *file, int line, const char *caller);
-void __connman_ippool_unref_debug(struct connman_ippool *pool,
- const char *file, int line, const char *caller);
-
-struct connman_ippool *__connman_ippool_create(int index,
- unsigned int start,
- unsigned int range,
- ippool_collision_cb_t collision_cb,
- void *user_data);
-
-const char *__connman_ippool_get_gateway(struct connman_ippool *pool);
-const char *__connman_ippool_get_broadcast(struct connman_ippool *pool);
-const char *__connman_ippool_get_subnet_mask(struct connman_ippool *pool);
-const char *__connman_ippool_get_start_ip(struct connman_ippool *pool);
-const char *__connman_ippool_get_end_ip(struct connman_ippool *pool);
-
-void __connman_ippool_newaddr(int index, const char *address,
- unsigned char prefixlen);
-void __connman_ippool_deladdr(int index, const char *address,
- unsigned char prefixlen);
-
-int __connman_bridge_create(const char *name);
-int __connman_bridge_remove(const char *name);
-int __connman_bridge_enable(const char *name, const char *gateway,
- const char *broadcast);
-int __connman_bridge_disable(const char *name);
-
-int __connman_nat_init(void);
-void __connman_nat_cleanup(void);
-
-int __connman_nat_enable(const char *name, const char *address,
- unsigned char prefixlen);
-void __connman_nat_disable(const char *name);
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
return TRUE;
}
+#if defined TIZEN_EXT
+/*
+ * Description: Extends state_changed signal to notify service error cause
+ */
+dbus_bool_t connman_dbus_service_property_changed_with_error_cause(const char *path,
+ const char *interface, const char *key1, int type1, void *val1,
+ const char *key2, int type2, void *val2)
+{
+ DBusMessage *signal;
+ DBusMessageIter iter;
+
+ if (path == NULL)
+ return FALSE;
+
+ signal = dbus_message_new_signal(path, interface, "PropertyChanged");
+ if (signal == NULL)
+ return FALSE;
+
+ dbus_message_iter_init_append(signal, &iter);
+ connman_dbus_property_append_basic(&iter, key1, type1, val1);
+ connman_dbus_property_append_basic(&iter, key2, type2, val2);
+
+ g_dbus_send_message(connection, signal);
+
+ return TRUE;
+}
+#endif
+
dbus_bool_t connman_dbus_property_changed_dict(const char *path,
const char *interface, const char *key,
connman_dbus_append_cb_t function, void *user_data)
return TRUE;
}
-dbus_bool_t __connman_dbus_append_objpath_dict_array(DBusMessage *msg,
- connman_dbus_append_cb_t function, void *user_data)
+#if defined TIZEN_EXT
+/*
+ * August 22nd, 2011. TIZEN
+ *
+ * This part is added to send a DBus signal which means scan is completed
+ * because scan UX of a Wi-Fi setting application has an active scan procedure
+ * and it needs scan complete signal whether success or not
+ */
+
+dbus_bool_t connman_dbus_scan_completed_basic(const char *path,
+ const char *interface, int type, void *val)
{
- DBusMessageIter iter, array;
+ DBusMessage *signal;
+ DBusMessageIter iter;
- if (msg == NULL || function == NULL)
+ if (path == NULL)
return FALSE;
- dbus_message_iter_init_append(msg, &iter);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_STRUCT_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_OBJECT_PATH_AS_STRING
- DBUS_TYPE_ARRAY_AS_STRING
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING
- DBUS_STRUCT_END_CHAR_AS_STRING, &array);
+ signal = dbus_message_new_signal(path, interface, "ScanCompleted");
+ if (signal == NULL)
+ return FALSE;
- function(&array, user_data);
+ dbus_message_iter_init_append(signal, &iter);
+
+ dbus_message_iter_append_basic(&iter, type, val);
- dbus_message_iter_close_container(&iter, &array);
+ g_dbus_send_message(connection, signal);
return TRUE;
}
+#endif
DBusConnection *connman_dbus_get_connection(void)
{
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include "connman.h"
+#if defined TIZEN_EXT
+#define CONNMAN_SIG_WIFI_REFCOUNT_GROUP_NAME "connman_significant_wifi_profile_refcount"
+#endif
+
static GSList *device_list = NULL;
static gchar **device_filter = NULL;
static gchar **nodevice_filter = NULL;
connman_bool_t scanning;
connman_bool_t disconnected;
connman_bool_t reconnect;
+ connman_uint16_t scan_interval;
+ connman_uint16_t backoff_interval;
char *name;
char *node;
char *address;
char *devname;
int phyindex;
int index;
+ guint scan_timeout;
guint pending_timeout;
struct connman_device_driver *driver;
char *last_network;
struct connman_network *network;
GHashTable *networks;
+
+#if defined TIZEN_EXT
+ /* It contains number of favorite Wi-Fi profile.
+ * If significant wifi profile is 0, Wi-Fi device does not trigger scan. */
+ gint significant_wifi_profile_refcount;
+#endif
};
+#define SCAN_INITIAL_DELAY 10
+
+#if defined TIZEN_EXT
+static void __connman_device_set_significant_wifi_profile_refcount(struct connman_device *device, gint refcount)
+{
+ g_atomic_int_set(&device->significant_wifi_profile_refcount, refcount);
+}
+
+void connman_device_significant_wifi_profile_ref(struct connman_device *device)
+{
+ g_atomic_int_inc(&device->significant_wifi_profile_refcount);
+}
+
+connman_bool_t connman_device_significant_wifi_profile_unref_and_test(struct connman_device *device)
+{
+ if (device->significant_wifi_profile_refcount > 0)
+ return (connman_bool_t)g_atomic_int_dec_and_test(&device->significant_wifi_profile_refcount);
+
+ return FALSE;
+}
+#endif
+
+static gboolean device_scan_trigger(gpointer user_data)
+{
+ struct connman_device *device = user_data;
+
+ DBG("device %p", device);
+
+ if (device->driver == NULL) {
+ device->scan_timeout = 0;
+ return FALSE;
+ }
+
+ if (device->driver->scan)
+ device->driver->scan(device);
+
+ return TRUE;
+}
+
+static void clear_scan_trigger(struct connman_device *device)
+{
+ if (device->scan_timeout > 0) {
+ g_source_remove(device->scan_timeout);
+ device->scan_timeout = 0;
+ }
+}
+
static void clear_pending_trigger(struct connman_device *device)
{
if (device->pending_timeout > 0) {
}
}
+static void reset_scan_trigger(struct connman_device *device)
+{
+ clear_scan_trigger(device);
+
+ if (device->scan_interval > 0) {
+ guint interval;
+
+ if (g_hash_table_size(device->networks) == 0) {
+ if (device->backoff_interval >= device->scan_interval)
+ device->backoff_interval = SCAN_INITIAL_DELAY;
+ interval = device->backoff_interval;
+ } else
+ interval = device->scan_interval;
+
+ DBG("interval %d", interval);
+
+ device->scan_timeout = g_timeout_add_seconds(interval,
+ device_scan_trigger, device);
+
+ device->backoff_interval *= 2;
+ if (device->backoff_interval > device->scan_interval)
+ device->backoff_interval = device->scan_interval;
+ }
+}
+
+static void force_scan_trigger(struct connman_device *device)
+{
+ clear_scan_trigger(device);
+
+ device->scan_timeout = g_timeout_add_seconds(5,
+ device_scan_trigger, device);
+}
+
+void connman_device_schedule_scan(struct connman_device *device)
+{
+ reset_scan_trigger(device);
+}
+
static const char *type2description(enum connman_device_type type)
{
switch (type) {
device->powered_pending = PENDING_DISABLE;
device->reconnect = FALSE;
+ clear_scan_trigger(device);
+
if (device->network) {
struct connman_service *service =
__connman_service_lookup_from_network(device->network);
}
err = device->driver->disable(device);
- if (err == 0 || err == -EALREADY) {
+ if (err == 0) {
+ connman_device_set_powered(device, FALSE);
+ goto done;
+ }
+
+ if (err == -EALREADY) {
connman_device_set_powered(device, FALSE);
goto done;
}
DBG("device %p name %s", device, device->name);
clear_pending_trigger(device);
+ clear_scan_trigger(device);
g_free(device->ident);
g_free(device->node);
g_free(device);
}
+#if defined TIZEN_EXT
+connman_bool_t connman_device_load_significant_wifi_profile_refcount_from_storage(struct connman_device *device)
+{
+ GKeyFile *keyfile = NULL;
+
+ keyfile = __connman_storage_load_global();
+
+ if (g_key_file_has_group(keyfile, CONNMAN_SIG_WIFI_REFCOUNT_GROUP_NAME) == FALSE) {
+ g_key_file_free(keyfile);
+ return FALSE;
+ }
+
+ __connman_device_set_significant_wifi_profile_refcount(device,
+ g_key_file_get_integer(keyfile, CONNMAN_SIG_WIFI_REFCOUNT_GROUP_NAME, "ReferenceCount", NULL));
+
+ g_key_file_free(keyfile);
+ return TRUE;
+}
+
+connman_bool_t connman_device_save_significant_wifi_profile_refcount_to_storage(struct connman_device *device)
+{
+ GKeyFile *keyfile = NULL;
+
+ keyfile = __connman_storage_load_global();
+
+ g_key_file_set_integer(keyfile, CONNMAN_SIG_WIFI_REFCOUNT_GROUP_NAME, "ReferenceCount",
+ device->significant_wifi_profile_refcount);
+
+ __connman_storage_save_global(keyfile);
+
+ g_key_file_free(keyfile);
+ return TRUE;
+}
+#endif
+
/**
* connman_device_create:
* @node: device node name (for example an address)
enum connman_device_type type)
{
struct connman_device *device;
+ connman_bool_t bg_scan;
DBG("node %s type %d", node, type);
device->refcount = 1;
+ bg_scan = connman_setting_get_bool("BackgroundScanning");
+
+#if defined TIZEN_EXT
+ if (type == CONNMAN_DEVICE_TYPE_WIFI) {
+ /* Load significant_wifi_profile_refcount */
+ if (connman_device_load_significant_wifi_profile_refcount_from_storage(device) == FALSE) {
+ __connman_device_set_significant_wifi_profile_refcount(device, 0);
+ connman_device_save_significant_wifi_profile_refcount_to_storage(device);
+ }
+ } else
+ __connman_device_set_significant_wifi_profile_refcount(device, 0);
+#endif
device->type = type;
device->name = g_strdup(type2description(device->type));
device->phyindex = -1;
+ device->backoff_interval = SCAN_INITIAL_DELAY;
+
+ switch (type) {
+ case CONNMAN_DEVICE_TYPE_UNKNOWN:
+ case CONNMAN_DEVICE_TYPE_ETHERNET:
+ case CONNMAN_DEVICE_TYPE_WIMAX:
+ case CONNMAN_DEVICE_TYPE_BLUETOOTH:
+ case CONNMAN_DEVICE_TYPE_CELLULAR:
+ case CONNMAN_DEVICE_TYPE_GPS:
+ case CONNMAN_DEVICE_TYPE_GADGET:
+ case CONNMAN_DEVICE_TYPE_VENDOR:
+ device->scan_interval = 0;
+ break;
+ case CONNMAN_DEVICE_TYPE_WIFI:
+ if (bg_scan == TRUE)
+ device->scan_interval = 300;
+ else
+ device->scan_interval = 0;
+ break;
+ }
+
device->networks = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, free_network);
*
* Increase reference counter of device
*/
-struct connman_device *connman_device_ref_debug(struct connman_device *device,
- const char *file, int line, const char *caller)
+struct connman_device *connman_device_ref(struct connman_device *device)
{
- DBG("%p ref %d by %s:%d:%s()", device, device->refcount + 1,
- file, line, caller);
+ DBG("%p", device);
__sync_fetch_and_add(&device->refcount, 1);
*
* Decrease reference counter of device
*/
-void connman_device_unref_debug(struct connman_device *device,
- const char *file, int line, const char *caller)
+void connman_device_unref(struct connman_device *device)
{
- DBG("%p ref %d by %s:%d:%s()", device, device->refcount - 1,
- file, line, caller);
-
if (__sync_fetch_and_sub(&device->refcount, 1) != 1)
return;
type = __connman_device_get_service_type(device);
- if (device->powered == FALSE) {
+ if (device->powered == TRUE)
+ __connman_technology_enabled(type);
+ else
__connman_technology_disabled(type);
- return 0;
- }
- __connman_technology_enabled(type);
+ if (powered == FALSE)
+ return 0;
connman_device_set_disconnected(device, FALSE);
device->scanning = FALSE;
+ reset_scan_trigger(device);
+
if (device->driver && device->driver->scan_fast)
device->driver->scan_fast(device);
else if (device->driver && device->driver->scan)
if (device->powered == FALSE)
return -ENOLINK;
+#if defined TIZEN_EXT
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_hash_table_iter_init(&iter, device->networks);
+
+ while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ struct connman_network *network = value;
+
+ DBG("network type %s", __connman_network_get_type(network));
+ if (connman_network_get_type(network) != CONNMAN_NETWORK_TYPE_WIFI)
+ continue;
+
+ /* If there is connecting network, don't try to scan. */
+ if (connman_network_get_connecting(network) == TRUE ||
+ connman_network_get_associating(network) == TRUE) {
+ DBG("network(%s) is connecting", connman_network_get_string(network, "Name"));
+ return 0;
+ }
+ }
+#endif
+
+ reset_scan_trigger(device);
+
return device->driver->scan(device);
}
void connman_device_reset_scanning(struct connman_device *device)
{
+ device->scanning = FALSE;
+
g_hash_table_foreach(device->networks,
mark_network_available, NULL);
+
+#if defined TIZEN_EXT
+ /*
+ * August 22nd, 2011. TIZEN
+ *
+ * This part is added to send a DBus signal which means scan is completed
+ * because scan UX of a Wi-Fi setting application has an active scan procedure
+ * and it needs scan complete signal whether success or not
+ */
+ __connman_notifier_scan_completed(FALSE);
+#endif
}
/**
device->scanning = scanning;
if (scanning == TRUE) {
- __connman_technology_scan_started(device);
+ reset_scan_trigger(device);
g_hash_table_foreach(device->networks,
mark_network_unavailable, NULL);
__connman_device_cleanup_networks(device);
- __connman_technology_scan_stopped(device);
+#if defined TIZEN_EXT
+ /*
+ * August 22nd, 2011. TIZEN
+ *
+ * This part is added to send a DBus signal which means scan is completed
+ * because scan UX of a Wi-Fi setting application has an active scan procedure
+ * and it needs scan complete signal whether success or not
+ */
+ __connman_notifier_scan_completed(TRUE);
+#endif
__connman_service_auto_connect();
device->disconnected = disconnected;
+#if defined TIZEN_EXT
+ if (device->type == CONNMAN_DEVICE_TYPE_CELLULAR)
+ {
+ DBG("Cellular device does not need to scan.");
+ return 0;
+ }
+#endif
+
+ if (disconnected == TRUE)
+ {
+ force_scan_trigger(device);
+ device->backoff_interval = SCAN_INITIAL_DELAY;
+ }
+
return 0;
}
__connman_network_set_device(network, device);
- g_hash_table_replace(device->networks, g_strdup(identifier),
+ g_hash_table_insert(device->networks, g_strdup(identifier),
network);
return 0;
return NULL;
}
-/**
- * connman_device_set_regdom
- * @device: device structure
- * @alpha2: string representing regulatory domain
- *
- * Set regulatory domain on device basis
- */
-int connman_device_set_regdom(struct connman_device *device,
- const char *alpha2)
-{
- if (device->driver == NULL || device->driver->set_regdom == NULL)
- return -ENOTSUP;
-
- return device->driver->set_regdom(device, alpha2);
-}
-
-/**
- * connman_device_regdom_notify
- * @device: device structure
- * @alpha2: string representing regulatory domain
- *
- * Notify on setting regulatory domain on device basis
- */
-void connman_device_regdom_notify(struct connman_device *device,
- int result, const char *alpha2)
-{
- __connman_technology_notify_regdom_by_device(device, result, alpha2);
-}
-
int __connman_device_request_scan(enum connman_service_type type)
{
- connman_bool_t success = FALSE;
- int last_err = -ENOSYS;
GSList *list;
int err;
case CONNMAN_SERVICE_TYPE_GPS:
case CONNMAN_SERVICE_TYPE_VPN:
case CONNMAN_SERVICE_TYPE_GADGET:
- return -EOPNOTSUPP;
+ return 0;
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_WIMAX:
break;
}
err = device_scan(device);
- if (err == 0 || err == -EALREADY || err == -EINPROGRESS) {
- success = TRUE;
- } else {
- last_err = err;
- DBG("device %p err %d", device, err);
+ if (err < 0 && err != -EINPROGRESS) {
+ DBG("err %d", err);
+ /* XXX maybe only a continue? */
+ return err;
}
}
- if (success == TRUE)
- return 0;
-
- return last_err;
-}
-
-int __connman_device_request_hidden_scan(struct connman_device *device,
- const char *ssid, unsigned int ssid_len,
- const char *identity, const char *passphrase,
- void *user_data)
-{
- DBG("device %p", device);
-
- if (device == NULL || device->driver == NULL ||
- device->driver->scan_hidden == NULL)
- return -EINVAL;
-
- if (device->scanning == TRUE)
- return -EALREADY;
-
- return device->driver->scan_hidden(device, ssid, ssid_len,
- identity, passphrase, user_data);
+ return 0;
}
connman_bool_t __connman_device_isfiltered(const char *devname)
{
char **pattern;
- char **blacklisted_interfaces;
if (device_filter == NULL)
goto nodevice;
}
if (nodevice_filter == NULL)
- goto list;
+ return FALSE;
for (pattern = nodevice_filter; *pattern; pattern++) {
if (g_pattern_match_simple(*pattern, devname) == TRUE) {
}
}
-list:
- blacklisted_interfaces =
- connman_setting_get_string_list("NetworkInterfaceBlacklist");
- if (blacklisted_interfaces == NULL)
- return FALSE;
-
- for (pattern = blacklisted_interfaces; *pattern; pattern++) {
- if (g_str_has_prefix(devname, *pattern) == TRUE) {
- DBG("ignoring device %s (blacklist)", devname);
- return TRUE;
- }
- }
-
return FALSE;
}
-static void cleanup_devices(void)
-{
- /*
- * Check what interfaces are currently up and if connman is
- * suppose to handle the interface, then cleanup the mess
- * related to that interface. There might be weird routes etc
- * that are related to that interface and that might confuse
- * connmand. So in this case we just turn the interface down
- * so that kernel removes routes/addresses automatically and
- * then proceed the startup.
- *
- * Note that this cleanup must be done before rtnl/detect code
- * has activated interface watches.
- */
-
- char **interfaces;
- int i;
-
- interfaces = __connman_inet_get_running_interfaces();
-
- if (interfaces == NULL)
- return;
-
- for (i = 0; interfaces[i] != NULL; i++) {
- connman_bool_t filtered;
- int index;
-
- filtered = __connman_device_isfiltered(interfaces[i]);
- if (filtered == TRUE)
- continue;
-
- index = connman_inet_ifindex(interfaces[i]);
- if (index < 0)
- continue;
-
- DBG("cleaning up %s index %d", interfaces[i], index);
-
- connman_inet_ifdown(index);
-
- /*
- * ConnMan will turn the interface UP automatically so
- * no need to do it here.
- */
- }
-
- g_strfreev(interfaces);
-}
-
int __connman_device_init(const char *device, const char *nodevice)
{
DBG("");
if (nodevice != NULL)
nodevice_filter = g_strsplit(nodevice, ",", -1);
- cleanup_devices();
-
return 0;
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
dhcp_cb callback;
char **nameservers;
- char **timeservers;
+ char *timeserver;
char *pac;
GDHCPClient *dhcp_client;
static void dhcp_free(struct connman_dhcp *dhcp)
{
g_strfreev(dhcp->nameservers);
- g_strfreev(dhcp->timeservers);
+ g_free(dhcp->timeserver);
g_free(dhcp->pac);
dhcp->nameservers = NULL;
- dhcp->timeservers = NULL;
+ dhcp->timeserver = NULL;
dhcp->pac = NULL;
}
__connman_service_set_domainname(service, NULL);
__connman_service_set_pac(service, NULL);
-
- if (dhcp->timeservers != NULL) {
- for (i = 0; dhcp->timeservers[i] != NULL; i++) {
- __connman_service_timeserver_remove(service,
- dhcp->timeservers[i]);
- }
- }
+ __connman_service_timeserver_remove(service, dhcp->timeserver);
if (dhcp->nameservers != NULL) {
for (i = 0; dhcp->nameservers[i] != NULL; i++) {
char *address, *netmask = NULL, *gateway = NULL;
const char *c_address, *c_gateway;
char *domainname = NULL, *hostname = NULL;
- char **nameservers, **timeservers, *pac = NULL;
+ char **nameservers, *timeserver = NULL, *pac = NULL;
int ns_entries;
struct connman_ipconfig *ipconfig;
struct connman_service *service;
gateway = g_strdup(option->data);
prefixlen = __connman_ipconfig_netmask_prefix_len(netmask);
- if (prefixlen == 255)
- connman_warn("netmask: %s is invalid", netmask);
DBG("c_address %s", c_address);
ip_change = FALSE;
option = g_dhcp_client_get_option(dhcp_client, G_DHCP_DNS_SERVER);
- ns_entries = g_list_length(option);
+ for (ns_entries = 0, list = option; list; list = list->next)
+ ns_entries += 1;
nameservers = g_try_new0(char *, ns_entries + 1);
if (nameservers != NULL) {
for (i = 0, list = option; list; list = list->next, i++)
hostname = g_strdup(option->data);
option = g_dhcp_client_get_option(dhcp_client, G_DHCP_NTP_SERVER);
- ns_entries = g_list_length(option);
- timeservers = g_try_new0(char *, ns_entries + 1);
- if (timeservers != NULL) {
- for (i = 0, list = option; list; list = list->next, i++)
- timeservers[i] = g_strdup(list->data);
- timeservers[ns_entries] = NULL;
- }
+ if (option != NULL)
+ timeserver = g_strdup(option->data);
option = g_dhcp_client_get_option(dhcp_client, 252);
if (option != NULL)
pac = g_strdup(option->data);
- __connman_ipconfig_set_method(ipconfig, CONNMAN_IPCONFIG_METHOD_DHCP);
+ connman_ipconfig_set_method(ipconfig, CONNMAN_IPCONFIG_METHOD_DHCP);
if (ip_change == TRUE) {
__connman_ipconfig_set_local(ipconfig, address);
dhcp->nameservers = nameservers;
- for (i = 0; dhcp->nameservers != NULL &&
- dhcp->nameservers[i] != NULL; i++) {
+ for (i = 0; dhcp->nameservers[i] != NULL; i++) {
__connman_service_nameserver_append(service,
dhcp->nameservers[i], FALSE);
}
g_strfreev(nameservers);
}
- if (compare_string_arrays(timeservers, dhcp->timeservers) == FALSE) {
- if (dhcp->timeservers != NULL) {
- for (i = 0; dhcp->timeservers[i] != NULL; i++) {
- __connman_service_timeserver_remove(service,
- dhcp->timeservers[i]);
- }
- g_strfreev(dhcp->timeservers);
+ if (g_strcmp0(timeserver, dhcp->timeserver) != 0) {
+ if (dhcp->timeserver != NULL) {
+ __connman_service_timeserver_remove(service,
+ dhcp->timeserver);
+ g_free(dhcp->timeserver);
}
- dhcp->timeservers = timeservers;
+ dhcp->timeserver = timeserver;
- for (i = 0; dhcp->timeservers != NULL &&
- dhcp->timeservers[i] != NULL; i++) {
+ if (dhcp->timeserver != NULL)
__connman_service_timeserver_append(service,
- dhcp->timeservers[i]);
- }
- } else {
- g_strfreev(timeservers);
+ dhcp->timeserver);
}
if (g_strcmp0(pac, dhcp->pac) != 0) {
DBG("IPV4LL available");
+#if defined TIZEN_EXT
+ /*
+ * Description: When DHCP is failed,
+ * most of naive users cannot understand auto-generated IP
+ * (IPV4 link local) and serious troubles to make Internet connection.
+ */
+ dhcp_invalidate(dhcp, TRUE);
+
+ service = __connman_service_lookup_from_network(dhcp->network);
+ if (service == NULL)
+ return;
+
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_IDLE,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_IDLE,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+
+ return;
+#endif
+
service = __connman_service_lookup_from_network(dhcp->network);
if (service == NULL)
return;
prefixlen = __connman_ipconfig_netmask_prefix_len(netmask);
- __connman_ipconfig_set_method(ipconfig, CONNMAN_IPCONFIG_METHOD_DHCP);
+ connman_ipconfig_set_method(ipconfig, CONNMAN_IPCONFIG_METHOD_DHCP);
__connman_ipconfig_set_local(ipconfig, address);
__connman_ipconfig_set_prefixlen(ipconfig, prefixlen);
__connman_ipconfig_set_gateway(ipconfig, NULL);
GDHCPClientError error;
const char *hostname;
int index;
+#if defined TIZEN_EXT
+ const char *last_address;
+#endif
DBG("dhcp %p", dhcp);
if (getenv("CONNMAN_DHCP_DEBUG"))
g_dhcp_client_set_debug(dhcp_client, dhcp_debug, "DHCP");
- g_dhcp_client_set_id(dhcp_client);
-
hostname = connman_utsname_get_hostname();
if (hostname != NULL)
g_dhcp_client_set_send(dhcp_client, G_DHCP_HOST_NAME, hostname);
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
return g_dhcp_client_start(dhcp_client,
__connman_ipconfig_get_dhcp_address(ipconfig));
+#endif
}
static int dhcp_release(struct connman_dhcp *dhcp)
+++ /dev/null
-/*
- *
- * Connection Manager
- *
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <connman/ipconfig.h>
-#include <connman/storage.h>
-
-#include <gdhcp/gdhcp.h>
-
-#include <glib.h>
-
-#include "connman.h"
-
-/* Transmission params in msec, RFC 3315 chapter 5.5 */
-#define INF_MAX_DELAY (1 * 1000)
-#define INF_TIMEOUT (1 * 1000)
-#define INF_MAX_RT (120 * 1000)
-#define SOL_MAX_DELAY (1 * 1000)
-#define SOL_TIMEOUT (1 * 1000)
-#define SOL_MAX_RT (120 * 1000)
-#define REQ_TIMEOUT (1 * 1000)
-#define REQ_MAX_RT (30 * 1000)
-#define REQ_MAX_RC 10
-#define REN_TIMEOUT (10 * 1000)
-#define REN_MAX_RT (600 * 1000)
-#define REB_TIMEOUT (10 * 1000)
-#define REB_MAX_RT (600 * 1000)
-
-
-struct connman_dhcpv6 {
- struct connman_network *network;
- dhcp_cb callback;
-
- char **nameservers;
- char **timeservers;
-
- GDHCPClient *dhcp_client;
-
- guint timeout; /* operation timeout in msec */
- guint RT; /* in msec */
- gboolean use_ta; /* set to TRUE if IPv6 privacy is enabled */
- GSList *prefixes; /* network prefixes from radvd */
- int request_count; /* how many times REQUEST have been sent */
- gboolean stateless; /* TRUE if stateless DHCPv6 is used */
- gboolean started; /* TRUE if we have DHCPv6 started */
-};
-
-static GHashTable *network_table;
-
-static int dhcpv6_request(struct connman_dhcpv6 *dhcp, gboolean add_addresses);
-
-static void clear_timer(struct connman_dhcpv6 *dhcp)
-{
- if (dhcp->timeout > 0) {
- g_source_remove(dhcp->timeout);
- dhcp->timeout = 0;
- }
-}
-
-static inline float get_random()
-{
- return (rand() % 200 - 100) / 1000.0;
-}
-
-/* Calculate a random delay, RFC 3315 chapter 14 */
-/* RT and MRT are milliseconds */
-static guint calc_delay(guint RT, guint MRT)
-{
- float delay = get_random();
- float rt = RT * (2 + delay);
-
- if (rt > MRT)
- rt = MRT * (1 + delay);
-
- if (rt < 0)
- rt = MRT;
-
- return (guint)rt;
-}
-
-static void free_prefix(gpointer data, gpointer user_data)
-{
- g_free(data);
-}
-
-static void dhcpv6_free(struct connman_dhcpv6 *dhcp)
-{
- g_strfreev(dhcp->nameservers);
- g_strfreev(dhcp->timeservers);
-
- dhcp->nameservers = NULL;
- dhcp->timeservers = NULL;
- dhcp->started = FALSE;
-
- g_slist_foreach(dhcp->prefixes, free_prefix, NULL);
- g_slist_free(dhcp->prefixes);
-}
-
-static gboolean compare_string_arrays(char **array_a, char **array_b)
-{
- int i;
-
- if (array_a == NULL || array_b == NULL)
- return FALSE;
-
- if (g_strv_length(array_a) != g_strv_length(array_b))
- return FALSE;
-
- for (i = 0; array_a[i] != NULL && array_b[i] != NULL; i++)
- if (g_strcmp0(array_a[i], array_b[i]) != 0)
- return FALSE;
-
- return TRUE;
-}
-
-static void dhcpv6_debug(const char *str, void *data)
-{
- connman_info("%s: %s\n", (const char *) data, str);
-}
-
-static gchar *convert_to_hex(unsigned char *buf, int len)
-{
- gchar *ret = g_try_malloc(len * 2 + 1);
- int i;
-
- for (i = 0; ret != NULL && i < len; i++)
- g_snprintf(ret + i * 2, 3, "%02x", buf[i]);
-
- return ret;
-}
-
-/*
- * DUID should not change over time so save it to file.
- * See RFC 3315 chapter 9 for details.
- */
-static int set_duid(struct connman_service *service,
- struct connman_network *network,
- GDHCPClient *dhcp_client, int index)
-{
- GKeyFile *keyfile;
- const char *ident;
- char *hex_duid;
- unsigned char *duid;
- int duid_len;
-
- ident = __connman_service_get_ident(service);
-
- keyfile = connman_storage_load_service(ident);
- if (keyfile == NULL)
- return -EINVAL;
-
- hex_duid = g_key_file_get_string(keyfile, ident, "IPv6.DHCP.DUID",
- NULL);
- if (hex_duid != NULL) {
- unsigned int i, j = 0, hex;
- size_t hex_duid_len = strlen(hex_duid);
-
- duid = g_try_malloc0(hex_duid_len / 2);
- if (duid == NULL) {
- g_key_file_free(keyfile);
- g_free(hex_duid);
- return -ENOMEM;
- }
-
- for (i = 0; i < hex_duid_len; i += 2) {
- sscanf(hex_duid + i, "%02x", &hex);
- duid[j++] = hex;
- }
-
- duid_len = hex_duid_len / 2;
- } else {
- int ret;
- int type = __connman_ipconfig_get_type_from_index(index);
-
- ret = g_dhcpv6_create_duid(G_DHCPV6_DUID_LLT, index, type,
- &duid, &duid_len);
- if (ret < 0) {
- g_key_file_free(keyfile);
- return ret;
- }
-
- hex_duid = convert_to_hex(duid, duid_len);
- if (hex_duid == NULL) {
- g_key_file_free(keyfile);
- return -ENOMEM;
- }
-
- g_key_file_set_string(keyfile, ident, "IPv6.DHCP.DUID",
- hex_duid);
-
- __connman_storage_save_service(keyfile, ident);
- }
- g_free(hex_duid);
-
- g_key_file_free(keyfile);
-
- g_dhcpv6_client_set_duid(dhcp_client, duid, duid_len);
-
- return 0;
-}
-
-static void clear_callbacks(GDHCPClient *dhcp_client)
-{
- g_dhcp_client_register_event(dhcp_client,
- G_DHCP_CLIENT_EVENT_SOLICITATION,
- NULL, NULL);
-
- g_dhcp_client_register_event(dhcp_client,
- G_DHCP_CLIENT_EVENT_ADVERTISE,
- NULL, NULL);
-
- g_dhcp_client_register_event(dhcp_client,
- G_DHCP_CLIENT_EVENT_REQUEST,
- NULL, NULL);
-
- g_dhcp_client_register_event(dhcp_client,
- G_DHCP_CLIENT_EVENT_RENEW,
- NULL, NULL);
-
- g_dhcp_client_register_event(dhcp_client,
- G_DHCP_CLIENT_EVENT_REBIND,
- NULL, NULL);
-
- g_dhcp_client_register_event(dhcp_client,
- G_DHCP_CLIENT_EVENT_RELEASE,
- NULL, NULL);
-
- g_dhcp_client_register_event(dhcp_client,
- G_DHCP_CLIENT_EVENT_INFORMATION_REQ,
- NULL, NULL);
-}
-
-static void info_req_cb(GDHCPClient *dhcp_client, gpointer user_data)
-{
- struct connman_dhcpv6 *dhcp = user_data;
- struct connman_service *service;
- int entries, i;
- GList *option, *list;
- char **nameservers, **timeservers;
-
- DBG("dhcpv6 information-request %p", dhcp);
-
- service = __connman_service_lookup_from_network(dhcp->network);
- if (service == NULL) {
- connman_error("Can not lookup service");
- return;
- }
-
- option = g_dhcp_client_get_option(dhcp_client, G_DHCPV6_DNS_SERVERS);
- entries = g_list_length(option);
-
- nameservers = g_try_new0(char *, entries + 1);
- if (nameservers != NULL) {
- for (i = 0, list = option; list; list = list->next, i++)
- nameservers[i] = g_strdup(list->data);
- }
-
- if (compare_string_arrays(nameservers, dhcp->nameservers) == FALSE) {
- if (dhcp->nameservers != NULL) {
- for (i = 0; dhcp->nameservers[i] != NULL; i++)
- __connman_service_nameserver_remove(service,
- dhcp->nameservers[i],
- FALSE);
- g_strfreev(dhcp->nameservers);
- }
-
- dhcp->nameservers = nameservers;
-
- for (i = 0; dhcp->nameservers != NULL &&
- dhcp->nameservers[i] != NULL; i++)
- __connman_service_nameserver_append(service,
- dhcp->nameservers[i],
- FALSE);
- } else
- g_strfreev(nameservers);
-
-
- option = g_dhcp_client_get_option(dhcp_client, G_DHCPV6_SNTP_SERVERS);
- entries = g_list_length(option);
-
- timeservers = g_try_new0(char *, entries + 1);
- if (timeservers != NULL) {
- for (i = 0, list = option; list; list = list->next, i++)
- timeservers[i] = g_strdup(list->data);
- }
-
- if (compare_string_arrays(timeservers, dhcp->timeservers) == FALSE) {
- if (dhcp->timeservers != NULL) {
- for (i = 0; dhcp->timeservers[i] != NULL; i++)
- __connman_service_timeserver_remove(service,
- dhcp->timeservers[i]);
- g_strfreev(dhcp->timeservers);
- }
-
- dhcp->timeservers = timeservers;
-
- for (i = 0; dhcp->timeservers != NULL &&
- dhcp->timeservers[i] != NULL; i++)
- __connman_service_timeserver_append(service,
- dhcp->timeservers[i]);
- } else
- g_strfreev(timeservers);
-
-
- if (dhcp->callback != NULL) {
- uint16_t status = g_dhcpv6_client_get_status(dhcp_client);
- dhcp->callback(dhcp->network, status == 0 ? TRUE : FALSE);
- }
-}
-
-static int dhcpv6_info_request(struct connman_dhcpv6 *dhcp)
-{
- struct connman_service *service;
- GDHCPClient *dhcp_client;
- GDHCPClientError error;
- int index, ret;
-
- DBG("dhcp %p", dhcp);
-
- index = connman_network_get_index(dhcp->network);
-
- dhcp_client = g_dhcp_client_new(G_DHCP_IPV6, index, &error);
- if (error != G_DHCP_CLIENT_ERROR_NONE) {
- clear_timer(dhcp);
- return -EINVAL;
- }
-
- if (getenv("CONNMAN_DHCPV6_DEBUG"))
- g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6");
-
- service = __connman_service_lookup_from_network(dhcp->network);
- if (service == NULL) {
- clear_timer(dhcp);
- g_dhcp_client_unref(dhcp_client);
- return -EINVAL;
- }
-
- ret = set_duid(service, dhcp->network, dhcp_client, index);
- if (ret < 0) {
- clear_timer(dhcp);
- g_dhcp_client_unref(dhcp_client);
- return ret;
- }
-
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_CLIENTID);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_DNS_SERVERS);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SNTP_SERVERS);
-
- g_dhcpv6_client_set_oro(dhcp_client, 2, G_DHCPV6_DNS_SERVERS,
- G_DHCPV6_SNTP_SERVERS);
-
- g_dhcp_client_register_event(dhcp_client,
- G_DHCP_CLIENT_EVENT_INFORMATION_REQ, info_req_cb, dhcp);
-
- dhcp->dhcp_client = dhcp_client;
-
- return g_dhcp_client_start(dhcp_client, NULL);
-}
-
-static int check_ipv6_addr_prefix(GSList *prefixes, char *address)
-{
- struct in6_addr addr_prefix, addr;
- GSList *list;
- int ret = 128, len;
-
- for (list = prefixes; list; list = list->next) {
- char *prefix = list->data;
- const char *slash = g_strrstr(prefix, "/");
- const unsigned char bits[] = { 0x00, 0xFE, 0xFC, 0xF8,
- 0xF0, 0xE0, 0xC0, 0x80 };
- int left, count, i, plen;
-
- if (slash == NULL)
- continue;
-
- prefix = g_strndup(prefix, slash - prefix);
- len = strtol(slash + 1, NULL, 10);
- plen = 128 - len;
-
- count = plen / 8;
- left = plen % 8;
- i = 16 - count;
-
- inet_pton(AF_INET6, prefix, &addr_prefix);
- inet_pton(AF_INET6, address, &addr);
-
- memset(&addr_prefix.s6_addr[i], 0, count);
- memset(&addr.s6_addr[i], 0, count);
-
- if (left) {
- addr_prefix.s6_addr[i - 1] &= bits[left];
- addr.s6_addr[i - 1] &= bits[left];
- }
-
- g_free(prefix);
-
- if (memcmp(&addr_prefix, &addr, 16) == 0) {
- ret = len;
- break;
- }
- }
-
- return ret;
-}
-
-static int set_addresses(GDHCPClient *dhcp_client,
- struct connman_dhcpv6 *dhcp)
-{
- struct connman_service *service;
- struct connman_ipconfig *ipconfig;
- int entries, i;
- GList *option, *list;
- char **nameservers, **timeservers;
- const char *c_address;
- char *address = NULL;
-
- service = __connman_service_lookup_from_network(dhcp->network);
- if (service == NULL) {
- connman_error("Can not lookup service");
- return -EINVAL;
- }
-
- ipconfig = __connman_service_get_ip6config(service);
- if (ipconfig == NULL) {
- connman_error("Could not lookup ip6config");
- return -EINVAL;
- }
-
- option = g_dhcp_client_get_option(dhcp_client, G_DHCPV6_DNS_SERVERS);
- entries = g_list_length(option);
-
- nameservers = g_try_new0(char *, entries + 1);
- if (nameservers != NULL) {
- for (i = 0, list = option; list; list = list->next, i++)
- nameservers[i] = g_strdup(list->data);
- }
-
- if (compare_string_arrays(nameservers, dhcp->nameservers) == FALSE) {
- if (dhcp->nameservers != NULL) {
- for (i = 0; dhcp->nameservers[i] != NULL; i++)
- __connman_service_nameserver_remove(service,
- dhcp->nameservers[i],
- FALSE);
- g_strfreev(dhcp->nameservers);
- }
-
- dhcp->nameservers = nameservers;
-
- for (i = 0; dhcp->nameservers != NULL &&
- dhcp->nameservers[i] != NULL; i++)
- __connman_service_nameserver_append(service,
- dhcp->nameservers[i],
- FALSE);
- } else
- g_strfreev(nameservers);
-
-
- option = g_dhcp_client_get_option(dhcp_client, G_DHCPV6_SNTP_SERVERS);
- entries = g_list_length(option);
-
- timeservers = g_try_new0(char *, entries + 1);
- if (timeservers != NULL) {
- for (i = 0, list = option; list; list = list->next, i++)
- timeservers[i] = g_strdup(list->data);
- }
-
- if (compare_string_arrays(timeservers, dhcp->timeservers) == FALSE) {
- if (dhcp->timeservers != NULL) {
- for (i = 0; dhcp->timeservers[i] != NULL; i++)
- __connman_service_timeserver_remove(service,
- dhcp->timeservers[i]);
- g_strfreev(dhcp->timeservers);
- }
-
- dhcp->timeservers = timeservers;
-
- for (i = 0; dhcp->timeservers != NULL &&
- dhcp->timeservers[i] != NULL; i++)
- __connman_service_timeserver_append(service,
- dhcp->timeservers[i]);
- } else
- g_strfreev(timeservers);
-
-
- option = g_dhcp_client_get_option(dhcp_client, G_DHCPV6_IA_NA);
- if (option != NULL)
- address = g_strdup(option->data);
- else {
- option = g_dhcp_client_get_option(dhcp_client, G_DHCPV6_IA_TA);
- if (option != NULL)
- address = g_strdup(option->data);
- }
-
- c_address = __connman_ipconfig_get_local(ipconfig);
-
- if (address != NULL &&
- ((c_address != NULL &&
- g_strcmp0(address, c_address) != 0) ||
- (c_address == NULL))) {
- int prefix_len;
-
- /* Is this prefix part of the subnet we are suppose to use? */
- prefix_len = check_ipv6_addr_prefix(dhcp->prefixes, address);
-
- __connman_ipconfig_set_local(ipconfig, address);
- __connman_ipconfig_set_prefixlen(ipconfig, prefix_len);
-
- DBG("new address %s/%d", address, prefix_len);
- }
-
- return 0;
-}
-
-static void re_cb(GDHCPClient *dhcp_client, gpointer user_data)
-{
- struct connman_dhcpv6 *dhcp = user_data;
- uint16_t status;
- int ret;
-
- ret = set_addresses(dhcp_client, dhcp);
-
- status = g_dhcpv6_client_get_status(dhcp_client);
-
- DBG("dhcpv6 cb msg %p ret %d status %d", dhcp, ret, status);
-
- if (ret < 0) {
- if (dhcp->callback != NULL)
- dhcp->callback(dhcp->network, FALSE);
- return;
- }
-
- if (status == G_DHCPV6_ERROR_BINDING) {
- /* RFC 3315, 18.1.8 */
- dhcpv6_request(dhcp, FALSE);
- } else {
- if (dhcp->callback != NULL)
- dhcp->callback(dhcp->network,
- status == 0 ? TRUE : FALSE);
- }
-}
-
-static void rebind_cb(GDHCPClient *dhcp_client, gpointer user_data)
-{
- DBG("");
-
- g_dhcpv6_client_reset_rebind(dhcp_client);
- g_dhcpv6_client_reset_renew(dhcp_client);
-
- re_cb(dhcp_client, user_data);
-}
-
-static int dhcpv6_rebind(struct connman_dhcpv6 *dhcp)
-{
- GDHCPClient *dhcp_client;
-
- DBG("dhcp %p", dhcp);
-
- dhcp_client = dhcp->dhcp_client;
-
- g_dhcp_client_clear_requests(dhcp_client);
-
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_CLIENTID);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_DNS_SERVERS);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SNTP_SERVERS);
-
- g_dhcpv6_client_set_oro(dhcp_client, 2, G_DHCPV6_DNS_SERVERS,
- G_DHCPV6_SNTP_SERVERS);
-
- g_dhcpv6_client_set_ia(dhcp_client,
- connman_network_get_index(dhcp->network),
- dhcp->use_ta == TRUE ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
- NULL, NULL, FALSE);
-
- clear_callbacks(dhcp_client);
-
- g_dhcp_client_register_event(dhcp_client, G_DHCP_CLIENT_EVENT_REBIND,
- rebind_cb, dhcp);
-
- dhcp->dhcp_client = dhcp_client;
-
- return g_dhcp_client_start(dhcp_client, NULL);
-}
-
-static gboolean dhcpv6_restart(gpointer user_data)
-{
- struct connman_dhcpv6 *dhcp = user_data;
-
- if (dhcp->callback != NULL)
- dhcp->callback(dhcp->network, FALSE);
-
- return FALSE;
-}
-
-/*
- * Check if we need to restart the solicitation procedure. This
- * is done if all the addresses have expired. RFC 3315, 18.1.4
- */
-static int check_restart(struct connman_dhcpv6 *dhcp)
-{
- time_t current, expired;
-
- g_dhcpv6_client_get_timeouts(dhcp->dhcp_client, NULL, NULL,
- NULL, NULL, &expired);
- current = time(NULL);
-
- if (current > expired) {
- DBG("expired by %d secs", (int)(current - expired));
-
- g_timeout_add(0, dhcpv6_restart, dhcp);
-
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-static gboolean timeout_rebind(gpointer user_data)
-{
- struct connman_dhcpv6 *dhcp = user_data;
-
- if (check_restart(dhcp) < 0)
- return FALSE;
-
- dhcp->RT = calc_delay(dhcp->RT, REB_MAX_RT);
-
- DBG("rebind RT timeout %d msec", dhcp->RT);
-
- dhcp->timeout = g_timeout_add(dhcp->RT, timeout_rebind, dhcp);
-
- g_dhcp_client_start(dhcp->dhcp_client, NULL);
-
- return FALSE;
-}
-
-static gboolean start_rebind(gpointer user_data)
-{
- struct connman_dhcpv6 *dhcp = user_data;
-
- dhcp->RT = REB_TIMEOUT * (1 + get_random());
-
- DBG("rebind initial RT timeout %d msec", dhcp->RT);
-
- dhcp->timeout = g_timeout_add(dhcp->RT, timeout_rebind, dhcp);
-
- dhcpv6_rebind(dhcp);
-
- return FALSE;
-}
-
-static void request_cb(GDHCPClient *dhcp_client, gpointer user_data)
-{
- DBG("");
-
- re_cb(dhcp_client, user_data);
-}
-
-static int dhcpv6_request(struct connman_dhcpv6 *dhcp,
- gboolean add_addresses)
-{
- GDHCPClient *dhcp_client;
- uint32_t T1, T2;
-
- DBG("dhcp %p add %d", dhcp, add_addresses);
-
- dhcp_client = dhcp->dhcp_client;
-
- g_dhcp_client_clear_requests(dhcp_client);
-
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_CLIENTID);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SERVERID);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_DNS_SERVERS);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SNTP_SERVERS);
-
- g_dhcpv6_client_set_oro(dhcp_client, 2, G_DHCPV6_DNS_SERVERS,
- G_DHCPV6_SNTP_SERVERS);
-
- g_dhcpv6_client_get_timeouts(dhcp_client, &T1, &T2, NULL, NULL, NULL);
- g_dhcpv6_client_set_ia(dhcp_client,
- connman_network_get_index(dhcp->network),
- dhcp->use_ta == TRUE ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
- &T1, &T2, add_addresses);
-
- clear_callbacks(dhcp_client);
-
- g_dhcp_client_register_event(dhcp_client, G_DHCP_CLIENT_EVENT_REQUEST,
- request_cb, dhcp);
-
- dhcp->dhcp_client = dhcp_client;
-
- return g_dhcp_client_start(dhcp_client, NULL);
-}
-
-static gboolean timeout_request(gpointer user_data)
-{
- struct connman_dhcpv6 *dhcp = user_data;
-
- if (dhcp->request_count >= REQ_MAX_RC) {
- DBG("max request retry attempts %d", dhcp->request_count);
- dhcp->request_count = 0;
- if (dhcp->callback != NULL)
- dhcp->callback(dhcp->network, FALSE);
- return FALSE;
- }
-
- dhcp->request_count++;
-
- dhcp->RT = calc_delay(dhcp->RT, REQ_MAX_RT);
- DBG("request RT timeout %d msec", dhcp->RT);
- dhcp->timeout = g_timeout_add(dhcp->RT, timeout_request, dhcp);
-
- g_dhcp_client_start(dhcp->dhcp_client, NULL);
-
- return FALSE;
-}
-
-static void renew_cb(GDHCPClient *dhcp_client, gpointer user_data)
-{
- DBG("");
-
- g_dhcpv6_client_reset_renew(dhcp_client);
-
- re_cb(dhcp_client, user_data);
-}
-
-static int dhcpv6_renew(struct connman_dhcpv6 *dhcp)
-{
- GDHCPClient *dhcp_client;
- uint32_t T1, T2;
-
- DBG("dhcp %p", dhcp);
-
- dhcp_client = dhcp->dhcp_client;
-
- g_dhcp_client_clear_requests(dhcp_client);
-
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_CLIENTID);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SERVERID);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_DNS_SERVERS);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SNTP_SERVERS);
-
- g_dhcpv6_client_set_oro(dhcp_client, 2, G_DHCPV6_DNS_SERVERS,
- G_DHCPV6_SNTP_SERVERS);
-
- g_dhcpv6_client_get_timeouts(dhcp_client, &T1, &T2, NULL, NULL, NULL);
- g_dhcpv6_client_set_ia(dhcp_client,
- connman_network_get_index(dhcp->network),
- dhcp->use_ta == TRUE ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
- &T1, &T2, TRUE);
-
- clear_callbacks(dhcp_client);
-
- g_dhcp_client_register_event(dhcp_client, G_DHCP_CLIENT_EVENT_RENEW,
- renew_cb, dhcp);
-
- dhcp->dhcp_client = dhcp_client;
-
- return g_dhcp_client_start(dhcp_client, NULL);
-}
-
-static gboolean timeout_renew(gpointer user_data)
-{
- struct connman_dhcpv6 *dhcp = user_data;
-
- if (check_restart(dhcp) < 0)
- return FALSE;
-
- dhcp->RT = calc_delay(dhcp->RT, REN_MAX_RT);
-
- DBG("renew RT timeout %d msec", dhcp->RT);
-
- dhcp->timeout = g_timeout_add(dhcp->RT, timeout_renew, dhcp);
-
- g_dhcp_client_start(dhcp->dhcp_client, NULL);
-
- return FALSE;
-}
-
-static gboolean start_renew(gpointer user_data)
-{
- struct connman_dhcpv6 *dhcp = user_data;
-
- dhcp->RT = REN_TIMEOUT * (1 + get_random());
-
- DBG("renew initial RT timeout %d msec", dhcp->RT);
-
- dhcp->timeout = g_timeout_add(dhcp->RT, timeout_renew, dhcp);
-
- dhcpv6_renew(dhcp);
-
- return FALSE;
-}
-
-int __connman_dhcpv6_start_renew(struct connman_network *network,
- dhcp_cb callback)
-{
- struct connman_dhcpv6 *dhcp;
- uint32_t T1, T2;
- time_t last_renew, last_rebind, current, expired;
-
- dhcp = g_hash_table_lookup(network_table, network);
- if (dhcp == NULL)
- return -ENOENT;
-
- DBG("network %p dhcp %p", network, dhcp);
-
- clear_timer(dhcp);
-
- g_dhcpv6_client_get_timeouts(dhcp->dhcp_client, &T1, &T2,
- &last_renew, &last_rebind, &expired);
-
- current = time(NULL);
-
- DBG("T1 %u T2 %u expires %lu current %lu", T1, T2,
- (unsigned long)expired, current);
-
- if (T1 == 0xffffffff)
- /* RFC 3315, 22.4 */
- return 0;
-
- if (T1 == 0)
- /* RFC 3315, 22.4
- * Client can choose the timeout.
- */
- T1 = 1800;
-
- /* RFC 3315, 18.1.4, start solicit if expired */
- if (current > expired) {
- DBG("expired by %d secs", (int)(current - expired));
- return -ETIMEDOUT;
- }
-
- dhcp->callback = callback;
-
- if (T2 != 0xffffffff && T2 > 0 &&
- (unsigned)current > (unsigned)last_rebind + T2) {
- int timeout;
-
- /* RFC 3315, chapter 18.1.3, start rebind */
- if ((unsigned)current > (unsigned)last_renew + T1)
- timeout = 0;
- else
- timeout = last_renew - current + T1;
-
- /*
- * If we just did a renew, do not restart the rebind
- * immediately.
- */
- dhcp->timeout = g_timeout_add_seconds(timeout, start_rebind,
- dhcp);
- } else {
- DBG("renew after %d secs", T1);
-
- dhcp->timeout = g_timeout_add_seconds(T1, start_renew, dhcp);
- }
- return 0;
-}
-
-int __connman_dhcpv6_start_release(struct connman_network *network,
- dhcp_cb callback)
-{
- struct connman_dhcpv6 *dhcp;
- GDHCPClient *dhcp_client;
-
- if (network_table == NULL)
- return 0; /* we are already released */
-
- dhcp = g_hash_table_lookup(network_table, network);
- if (dhcp == NULL)
- return -ENOENT;
-
- DBG("network %p dhcp %p client %p stateless %d", network, dhcp,
- dhcp->dhcp_client, dhcp->stateless);
-
- if (dhcp->stateless == TRUE)
- return -EINVAL;
-
- clear_timer(dhcp);
-
- dhcp_client = dhcp->dhcp_client;
- if (dhcp_client == NULL) {
- /*
- * We had started the DHCPv6 handshaking i.e., we have called
- * __connman_dhcpv6_start() but it has not yet sent
- * a solicitation message to server. This means that we do not
- * have DHCPv6 configured yet so we can just quit here.
- */
- DBG("DHCPv6 was not started");
- return 0;
- }
-
- g_dhcp_client_clear_requests(dhcp_client);
- g_dhcp_client_clear_values(dhcp_client);
-
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_CLIENTID);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SERVERID);
-
- g_dhcpv6_client_set_ia(dhcp_client,
- connman_network_get_index(dhcp->network),
- dhcp->use_ta == TRUE ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
- NULL, NULL, TRUE);
-
- clear_callbacks(dhcp_client);
-
- /*
- * We do not register callback here because the answer might take too
- * long time and network code might be in the middle of the disconnect.
- * So we just inform the server that we are done with the addresses
- * but ignore the reply from server. This is allowed by RFC 3315
- * chapter 18.1.6.
- */
-
- dhcp->dhcp_client = dhcp_client;
-
- return g_dhcp_client_start(dhcp_client, NULL);
-}
-
-static int dhcpv6_release(struct connman_dhcpv6 *dhcp)
-{
- DBG("dhcp %p", dhcp);
-
- clear_timer(dhcp);
-
- dhcpv6_free(dhcp);
-
- if (dhcp->dhcp_client == NULL)
- return 0;
-
- g_dhcp_client_stop(dhcp->dhcp_client);
- g_dhcp_client_unref(dhcp->dhcp_client);
-
- dhcp->dhcp_client = NULL;
-
- return 0;
-}
-
-static void remove_network(gpointer user_data)
-{
- struct connman_dhcpv6 *dhcp = user_data;
-
- DBG("dhcp %p", dhcp);
-
- dhcpv6_release(dhcp);
-
- g_free(dhcp);
-}
-
-static gboolean timeout_info_req(gpointer user_data)
-{
- struct connman_dhcpv6 *dhcp = user_data;
-
- dhcp->RT = calc_delay(dhcp->RT, INF_MAX_RT);
-
- DBG("info RT timeout %d msec", dhcp->RT);
-
- dhcp->timeout = g_timeout_add(dhcp->RT, timeout_info_req, dhcp);
-
- g_dhcp_client_start(dhcp->dhcp_client, NULL);
-
- return FALSE;
-}
-
-static gboolean start_info_req(gpointer user_data)
-{
- struct connman_dhcpv6 *dhcp = user_data;
-
- /* Set the retransmission timeout, RFC 3315 chapter 14 */
- dhcp->RT = INF_TIMEOUT * (1 + get_random());
-
- DBG("info initial RT timeout %d msec", dhcp->RT);
-
- dhcp->timeout = g_timeout_add(dhcp->RT, timeout_info_req, dhcp);
-
- dhcpv6_info_request(dhcp);
-
- return FALSE;
-}
-
-int __connman_dhcpv6_start_info(struct connman_network *network,
- dhcp_cb callback)
-{
- struct connman_dhcpv6 *dhcp;
- int delay;
-
- DBG("");
-
- if (network_table != NULL) {
- dhcp = g_hash_table_lookup(network_table, network);
- if (dhcp != NULL && dhcp->started == TRUE)
- return -EBUSY;
- }
-
- dhcp = g_try_new0(struct connman_dhcpv6, 1);
- if (dhcp == NULL)
- return -ENOMEM;
-
- dhcp->network = network;
- dhcp->callback = callback;
- dhcp->stateless = TRUE;
- dhcp->started = TRUE;
-
- connman_network_ref(network);
-
- DBG("replace network %p dhcp %p", network, dhcp);
-
- g_hash_table_replace(network_table, network, dhcp);
-
- /* Initial timeout, RFC 3315, 18.1.5 */
- delay = rand() % 1000;
-
- dhcp->timeout = g_timeout_add(delay, start_info_req, dhcp);
-
- return 0;
-}
-
-static void advertise_cb(GDHCPClient *dhcp_client, gpointer user_data)
-{
- struct connman_dhcpv6 *dhcp = user_data;
-
- DBG("dhcpv6 advertise msg %p", dhcp);
-
- clear_timer(dhcp);
-
- if (g_dhcpv6_client_get_status(dhcp_client) != 0) {
- if (dhcp->callback != NULL)
- dhcp->callback(dhcp->network, FALSE);
- return;
- }
-
- dhcp->RT = REQ_TIMEOUT * (1 + get_random());
- DBG("request initial RT timeout %d msec", dhcp->RT);
- dhcp->timeout = g_timeout_add(dhcp->RT, timeout_request, dhcp);
-
- dhcp->request_count = 1;
-
- dhcpv6_request(dhcp, TRUE);
-}
-
-static void solicitation_cb(GDHCPClient *dhcp_client, gpointer user_data)
-{
- /* We get here if server supports rapid commit */
- struct connman_dhcpv6 *dhcp = user_data;
-
- DBG("dhcpv6 solicitation msg %p", dhcp);
-
- clear_timer(dhcp);
-
- set_addresses(dhcp_client, dhcp);
-}
-
-static gboolean timeout_solicitation(gpointer user_data)
-{
- struct connman_dhcpv6 *dhcp = user_data;
-
- dhcp->RT = calc_delay(dhcp->RT, SOL_MAX_RT);
-
- DBG("solicit RT timeout %d msec", dhcp->RT);
-
- dhcp->timeout = g_timeout_add(dhcp->RT, timeout_solicitation, dhcp);
-
- g_dhcp_client_start(dhcp->dhcp_client, NULL);
-
- return FALSE;
-}
-
-static int dhcpv6_solicitation(struct connman_dhcpv6 *dhcp)
-{
- struct connman_service *service;
- struct connman_ipconfig *ipconfig_ipv6;
- GDHCPClient *dhcp_client;
- GDHCPClientError error;
- int index, ret;
-
- DBG("dhcp %p", dhcp);
-
- index = connman_network_get_index(dhcp->network);
-
- dhcp_client = g_dhcp_client_new(G_DHCP_IPV6, index, &error);
- if (error != G_DHCP_CLIENT_ERROR_NONE) {
- clear_timer(dhcp);
- return -EINVAL;
- }
-
- if (getenv("CONNMAN_DHCPV6_DEBUG"))
- g_dhcp_client_set_debug(dhcp_client, dhcpv6_debug, "DHCPv6");
-
- service = __connman_service_lookup_from_network(dhcp->network);
- if (service == NULL) {
- clear_timer(dhcp);
- g_dhcp_client_unref(dhcp_client);
- return -EINVAL;
- }
-
- ret = set_duid(service, dhcp->network, dhcp_client, index);
- if (ret < 0) {
- clear_timer(dhcp);
- g_dhcp_client_unref(dhcp_client);
- return ret;
- }
-
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_CLIENTID);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_RAPID_COMMIT);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_DNS_SERVERS);
- g_dhcp_client_set_request(dhcp_client, G_DHCPV6_SNTP_SERVERS);
-
- g_dhcpv6_client_set_oro(dhcp_client, 2, G_DHCPV6_DNS_SERVERS,
- G_DHCPV6_SNTP_SERVERS);
-
- ipconfig_ipv6 = __connman_service_get_ip6config(service);
- dhcp->use_ta = __connman_ipconfig_ipv6_privacy_enabled(ipconfig_ipv6);
-
- g_dhcpv6_client_set_ia(dhcp_client, index,
- dhcp->use_ta == TRUE ? G_DHCPV6_IA_TA : G_DHCPV6_IA_NA,
- NULL, NULL, FALSE);
-
- clear_callbacks(dhcp_client);
-
- g_dhcp_client_register_event(dhcp_client,
- G_DHCP_CLIENT_EVENT_SOLICITATION,
- solicitation_cb, dhcp);
-
- g_dhcp_client_register_event(dhcp_client,
- G_DHCP_CLIENT_EVENT_ADVERTISE,
- advertise_cb, dhcp);
-
- dhcp->dhcp_client = dhcp_client;
-
- return g_dhcp_client_start(dhcp_client, NULL);
-}
-
-static gboolean start_solicitation(gpointer user_data)
-{
- struct connman_dhcpv6 *dhcp = user_data;
-
- /* Set the retransmission timeout, RFC 3315 chapter 14 */
- dhcp->RT = SOL_TIMEOUT * (1 + get_random());
-
- DBG("solicit initial RT timeout %d msec", dhcp->RT);
-
- dhcp->timeout = g_timeout_add(dhcp->RT, timeout_solicitation, dhcp);
-
- dhcpv6_solicitation(dhcp);
-
- return FALSE;
-}
-
-int __connman_dhcpv6_start(struct connman_network *network,
- GSList *prefixes, dhcp_cb callback)
-{
- struct connman_dhcpv6 *dhcp;
- int delay;
-
- DBG("");
-
- if (network_table != NULL) {
- dhcp = g_hash_table_lookup(network_table, network);
- if (dhcp != NULL && dhcp->started == TRUE)
- return -EBUSY;
- }
-
- dhcp = g_try_new0(struct connman_dhcpv6, 1);
- if (dhcp == NULL)
- return -ENOMEM;
-
- dhcp->network = network;
- dhcp->callback = callback;
- dhcp->prefixes = prefixes;
- dhcp->started = TRUE;
-
- connman_network_ref(network);
-
- DBG("replace network %p dhcp %p", network, dhcp);
-
- g_hash_table_replace(network_table, network, dhcp);
-
- /* Initial timeout, RFC 3315, 17.1.2 */
- delay = rand() % 1000;
-
- dhcp->timeout = g_timeout_add(delay, start_solicitation, dhcp);
-
- return 0;
-}
-
-void __connman_dhcpv6_stop(struct connman_network *network)
-{
- DBG("");
-
- if (network_table == NULL)
- return;
-
- if (g_hash_table_remove(network_table, network) == TRUE)
- connman_network_unref(network);
-}
-
-int __connman_dhcpv6_init(void)
-{
- DBG("");
-
- srand(time(NULL));
-
- network_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, remove_network);
-
- return 0;
-}
-
-void __connman_dhcpv6_cleanup(void)
-{
- DBG("");
-
- g_hash_table_destroy(network_table);
- network_table = NULL;
-}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#endif
#include <errno.h>
-#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
-#include <resolv.h>
-#include <gweb/gresolv.h>
#include <glib.h>
guint tcp_listener_watch;
};
-struct cache_data {
- time_t inserted;
- time_t valid_until;
- time_t cache_until;
- int timeout;
- uint16_t type;
- uint16_t answers;
- unsigned int data_len;
- unsigned char *data; /* contains DNS header + body */
-};
-
-struct cache_entry {
- char *key;
- int want_refresh;
- int hits;
- struct cache_data *ipv4;
- struct cache_data *ipv6;
-};
-
-struct domain_question {
- uint16_t type;
- uint16_t class;
-} __attribute__ ((packed));
-
-struct domain_rr {
- uint16_t type;
- uint16_t class;
- uint32_t ttl;
- uint16_t rdlen;
-} __attribute__ ((packed));
-
-/*
- * We limit how long the cached DNS entry stays in the cache.
- * By default the TTL (time-to-live) of the DNS response is used
- * when setting the cache entry life time. The value is in seconds.
- */
-#define MAX_CACHE_TTL (60 * 30)
-/*
- * Also limit the other end, cache at least for 30 seconds.
- */
-#define MIN_CACHE_TTL (30)
-
-/*
- * We limit the cache size to some sane value so that cached data does
- * not occupy too much memory. Each cached entry occupies on average
- * about 100 bytes memory (depending on DNS name length).
- * Example: caching www.connman.net uses 97 bytes memory.
- * The value is the max amount of cached DNS responses (count).
- */
-#define MAX_CACHE_SIZE 256
-
-static int cache_size;
-static GHashTable *cache;
-static int cache_refcount;
static GSList *server_list = NULL;
static GSList *request_list = NULL;
+static GSList *request_pending_list = NULL;
+static guint16 request_id = 0x0000;
static GHashTable *listener_table = NULL;
-static time_t next_refresh;
-
-static guint16 get_id()
-{
- return random();
-}
static int protocol_offset(int protocol)
{
}
-/*
- * There is a power and efficiency benefit to have entries
- * in our cache expire at the same time. To this extend,
- * we round down the cache valid time to common boundaries.
- */
-static time_t round_down_ttl(time_t end_time, int ttl)
-{
- if (ttl < 15)
- return end_time;
-
- /* Less than 5 minutes, round to 10 second boundary */
- if (ttl < 300) {
- end_time = end_time / 10;
- end_time = end_time * 10;
- } else { /* 5 or more minutes, round to 30 seconds */
- end_time = end_time / 30;
- end_time = end_time * 30;
- }
- return end_time;
-}
-
static struct request_data *find_request(guint16 id)
{
GSList *list;
return NULL;
}
-/* we can keep using the same resolve's */
-static GResolv *ipv4_resolve;
-static GResolv *ipv6_resolve;
-
-static void dummy_resolve_func(GResolvResultStatus status,
- char **results, gpointer user_data)
-{
-}
-
-/*
- * Refresh a DNS entry, but also age the hit count a bit */
-static void refresh_dns_entry(struct cache_entry *entry, char *name)
-{
- int age = 1;
-
- if (ipv4_resolve == NULL) {
- ipv4_resolve = g_resolv_new(0);
- g_resolv_set_address_family(ipv4_resolve, AF_INET);
- g_resolv_add_nameserver(ipv4_resolve, "127.0.0.1", 53, 0);
- }
-
- if (ipv6_resolve == NULL) {
- ipv6_resolve = g_resolv_new(0);
- g_resolv_set_address_family(ipv6_resolve, AF_INET6);
- g_resolv_add_nameserver(ipv6_resolve, "127.0.0.1", 53, 0);
- }
-
- if (entry->ipv4 == NULL) {
- DBG("Refresing A record for %s", name);
- g_resolv_lookup_hostname(ipv4_resolve, name,
- dummy_resolve_func, NULL);
- age = 4;
- }
-
- if (entry->ipv6 == NULL) {
- DBG("Refresing AAAA record for %s", name);
- g_resolv_lookup_hostname(ipv6_resolve, name,
- dummy_resolve_func, NULL);
- age = 4;
- }
-
- entry->hits -= age;
- if (entry->hits < 0)
- entry->hits = 0;
-}
-
-static int dns_name_length(unsigned char *buf)
-{
- if ((buf[0] & NS_CMPRSFLGS) == NS_CMPRSFLGS) /* compressed name */
- return 2;
- return strlen((char *)buf);
-}
-
-static void update_cached_ttl(unsigned char *buf, int len, int new_ttl)
-{
- unsigned char *c;
- uint32_t *i;
- uint16_t *w;
- int l;
-
- /* skip the header */
- c = buf + 12;
- len -= 12;
-
- /* skip the query, which is a name and 2 16 bit words */
- l = dns_name_length(c);
- c += l;
- len -= l;
- c += 4;
- len -= 4;
-
- /* now we get the answer records */
-
- while (len > 0) {
- /* first a name */
- l = dns_name_length(c);
- c += l;
- len -= l;
- if (len < 0)
- break;
- /* then type + class, 2 bytes each */
- c += 4;
- len -= 4;
- if (len < 0)
- break;
-
- /* now the 4 byte TTL field */
- i = (uint32_t *)c;
- *i = htonl(new_ttl);
- c += 4;
- len -= 4;
- if (len < 0)
- break;
-
- /* now the 2 byte rdlen field */
- w = (uint16_t *)c;
- c += ntohs(*w) + 2;
- len -= ntohs(*w) + 2;
- }
-}
-
-static void send_cached_response(int sk, unsigned char *buf, int len,
- const struct sockaddr *to, socklen_t tolen,
- int protocol, int id, uint16_t answers, int ttl)
-{
- struct domain_hdr *hdr;
- unsigned char *ptr = buf;
- int err, offset, dns_len, adj_len = len - 2;
-
- /*
- * The cached packet contains always the TCP offset (two bytes)
- * so skip them for UDP.
- */
- switch (protocol) {
- case IPPROTO_UDP:
- ptr += 2;
- len -= 2;
- dns_len = len;
- offset = 0;
- break;
- case IPPROTO_TCP:
- offset = 2;
- dns_len = ptr[0] * 256 + ptr[1];
- break;
- default:
- return;
- }
-
- if (len < 12)
- return;
-
- hdr = (void *) (ptr + offset);
-
- hdr->id = id;
- hdr->qr = 1;
- hdr->rcode = 0;
- hdr->ancount = htons(answers);
- hdr->nscount = 0;
- hdr->arcount = 0;
-
- /* if this is a negative reply, we are authorative */
- if (answers == 0)
- hdr->aa = 1;
- else
- update_cached_ttl((unsigned char *)hdr, adj_len, ttl);
-
- DBG("sk %d id 0x%04x answers %d ptr %p length %d dns %d",
- sk, hdr->id, answers, ptr, len, dns_len);
-
- err = sendto(sk, ptr, len, MSG_NOSIGNAL, to, tolen);
- if (err < 0) {
- connman_error("Cannot send cached DNS response: %s",
- strerror(errno));
- return;
- }
-
- if (err != len || (dns_len != (len - 2) && protocol == IPPROTO_TCP) ||
- (dns_len != len && protocol == IPPROTO_UDP))
- DBG("Packet length mismatch, sent %d wanted %d dns %d",
- err, len, dns_len);
-}
-
-static void send_response(int sk, unsigned char *buf, int len,
- const struct sockaddr *to, socklen_t tolen,
- int protocol)
-{
- struct domain_hdr *hdr;
- int err, offset = protocol_offset(protocol);
-
- DBG("sk %d", sk);
-
- if (offset < 0)
- return;
-
- if (len < 12)
- return;
-
- hdr = (void *) (buf + offset);
-
- DBG("id 0x%04x qr %d opcode %d", hdr->id, hdr->qr, hdr->opcode);
-
- hdr->qr = 1;
- hdr->rcode = 2;
-
- hdr->ancount = 0;
- hdr->nscount = 0;
- hdr->arcount = 0;
-
- err = sendto(sk, buf, len, MSG_NOSIGNAL, to, tolen);
- if (err < 0) {
- connman_error("Failed to send DNS response to %d: %s",
- sk, strerror(errno));
- return;
- }
-}
-
-static gboolean request_timeout(gpointer user_data)
-{
- struct request_data *req = user_data;
- struct listener_data *ifdata;
-
- DBG("id 0x%04x", req->srcid);
-
- if (req == NULL)
- return FALSE;
-
- ifdata = req->ifdata;
-
- request_list = g_slist_remove(request_list, req);
- req->numserv--;
-
- if (req->resplen > 0 && req->resp != NULL) {
- int sk, err;
-
- sk = g_io_channel_unix_get_fd(ifdata->udp_listener_channel);
-
- err = sendto(sk, req->resp, req->resplen, MSG_NOSIGNAL,
- &req->sa, req->sa_len);
- if (err < 0)
- return FALSE;
- } else if (req->request && req->numserv == 0) {
- struct domain_hdr *hdr;
-
- if (req->protocol == IPPROTO_TCP) {
- hdr = (void *) (req->request + 2);
- hdr->id = req->srcid;
- send_response(req->client_sk, req->request,
- req->request_len, NULL, 0, IPPROTO_TCP);
-
- } else if (req->protocol == IPPROTO_UDP) {
- int sk;
-
- hdr = (void *) (req->request);
- hdr->id = req->srcid;
- sk = g_io_channel_unix_get_fd(
- ifdata->udp_listener_channel);
- send_response(sk, req->request, req->request_len,
- &req->sa, req->sa_len, IPPROTO_UDP);
- }
- }
-
- g_free(req->resp);
- g_free(req);
-
- return FALSE;
-}
-
-static int append_query(unsigned char *buf, unsigned int size,
- const char *query, const char *domain)
-{
- unsigned char *ptr = buf;
- int len;
-
- DBG("query %s domain %s", query, domain);
-
- while (query != NULL) {
- const char *tmp;
-
- tmp = strchr(query, '.');
- if (tmp == NULL) {
- len = strlen(query);
- if (len == 0)
- break;
- *ptr = len;
- memcpy(ptr + 1, query, len);
- ptr += len + 1;
- break;
- }
-
- *ptr = tmp - query;
- memcpy(ptr + 1, query, tmp - query);
- ptr += tmp - query + 1;
-
- query = tmp + 1;
- }
-
- while (domain != NULL) {
- const char *tmp;
-
- tmp = strchr(domain, '.');
- if (tmp == NULL) {
- len = strlen(domain);
- if (len == 0)
- break;
- *ptr = len;
- memcpy(ptr + 1, domain, len);
- ptr += len + 1;
- break;
- }
-
- *ptr = tmp - domain;
- memcpy(ptr + 1, domain, tmp - domain);
- ptr += tmp - domain + 1;
-
- domain = tmp + 1;
- }
-
- *ptr++ = 0x00;
-
- return ptr - buf;
-}
-
-static gboolean cache_check_is_valid(struct cache_data *data,
- time_t current_time)
-{
- if (data == NULL)
- return FALSE;
-
- if (data->cache_until < current_time)
- return FALSE;
-
- return TRUE;
-}
-
-/*
- * remove stale cached entries so that they can be refreshed
- */
-static void cache_enforce_validity(struct cache_entry *entry)
-{
- time_t current_time = time(NULL);
-
- if (cache_check_is_valid(entry->ipv4, current_time) == FALSE
- && entry->ipv4) {
- DBG("cache timeout \"%s\" type A", entry->key);
- g_free(entry->ipv4->data);
- g_free(entry->ipv4);
- entry->ipv4 = NULL;
-
- }
-
- if (cache_check_is_valid(entry->ipv6, current_time) == FALSE
- && entry->ipv6) {
- DBG("cache timeout \"%s\" type AAAA", entry->key);
- g_free(entry->ipv6->data);
- g_free(entry->ipv6);
- entry->ipv6 = NULL;
- }
-}
-
-static uint16_t cache_check_validity(char *question, uint16_t type,
- struct cache_entry *entry)
-{
- time_t current_time = time(NULL);
- int want_refresh = 0;
-
- /*
- * if we have a popular entry, we want a refresh instead of
- * total destruction of the entry.
- */
- if (entry->hits > 2)
- want_refresh = 1;
-
- cache_enforce_validity(entry);
-
- switch (type) {
- case 1: /* IPv4 */
- if (cache_check_is_valid(entry->ipv4, current_time) == FALSE) {
- DBG("cache %s \"%s\" type A", entry->ipv4 ?
- "timeout" : "entry missing", question);
-
- if (want_refresh)
- entry->want_refresh = 1;
-
- /*
- * We do not remove cache entry if there is still
- * valid IPv6 entry found in the cache.
- */
- if (cache_check_is_valid(entry->ipv6, current_time)
- == FALSE && want_refresh == FALSE) {
- g_hash_table_remove(cache, question);
- type = 0;
- }
- }
- break;
-
- case 28: /* IPv6 */
- if (cache_check_is_valid(entry->ipv6, current_time) == FALSE) {
- DBG("cache %s \"%s\" type AAAA", entry->ipv6 ?
- "timeout" : "entry missing", question);
-
- if (want_refresh)
- entry->want_refresh = 1;
-
- if (cache_check_is_valid(entry->ipv4, current_time)
- == FALSE && want_refresh == FALSE) {
- g_hash_table_remove(cache, question);
- type = 0;
- }
- }
- break;
- }
-
- return type;
-}
-
-static struct cache_entry *cache_check(gpointer request, int *qtype, int proto)
-{
- char *question;
- struct cache_entry *entry;
- struct domain_question *q;
- uint16_t type;
- int offset, proto_offset;
-
- if (request == NULL)
- return NULL;
-
- proto_offset = protocol_offset(proto);
- if (proto_offset < 0)
- return NULL;
-
- question = request + proto_offset + 12;
-
- offset = strlen(question) + 1;
- q = (void *) (question + offset);
- type = ntohs(q->type);
-
- /* We only cache either A (1) or AAAA (28) requests */
- if (type != 1 && type != 28)
- return NULL;
-
- entry = g_hash_table_lookup(cache, question);
- if (entry == NULL)
- return NULL;
-
- type = cache_check_validity(question, type, entry);
- if (type == 0)
- return NULL;
-
- *qtype = type;
- return entry;
-}
-
-/*
- * Get a label/name from DNS resource record. The function decompresses the
- * label if necessary. The function does not convert the name to presentation
- * form. This means that the result string will contain label lengths instead
- * of dots between labels. We intentionally do not want to convert to dotted
- * format so that we can cache the wire format string directly.
- */
-static int get_name(int counter,
- unsigned char *pkt, unsigned char *start, unsigned char *max,
- unsigned char *output, int output_max, int *output_len,
- unsigned char **end, char *name, int *name_len)
-{
- unsigned char *p;
-
- /* Limit recursion to 10 (this means up to 10 labels in domain name) */
- if (counter > 10)
- return -EINVAL;
-
- p = start;
- while (*p) {
- if ((*p & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
- uint16_t offset = (*p & 0x3F) * 256 + *(p + 1);
-
- if (offset >= max - pkt)
- return -ENOBUFS;
-
- if (*end == NULL)
- *end = p + 2;
-
- return get_name(counter + 1, pkt, pkt + offset, max,
- output, output_max, output_len, end,
- name, name_len);
- } else {
- unsigned label_len = *p;
-
- if (pkt + label_len > max)
- return -ENOBUFS;
-
- if (*output_len > output_max)
- return -ENOBUFS;
-
- /*
- * We need the original name in order to check
- * if this answer is the correct one.
- */
- name[(*name_len)++] = label_len;
- memcpy(name + *name_len, p + 1, label_len + 1);
- *name_len += label_len;
-
- /* We compress the result */
- output[0] = NS_CMPRSFLGS;
- output[1] = 0x0C;
- *output_len = 2;
-
- p += label_len + 1;
-
- if (*end == NULL)
- *end = p;
-
- if (p >= max)
- return -ENOBUFS;
- }
- }
-
- return 0;
-}
-
-static int parse_rr(unsigned char *buf, unsigned char *start,
- unsigned char *max,
- unsigned char *response, unsigned int *response_size,
- uint16_t *type, uint16_t *class, int *ttl, int *rdlen,
- unsigned char **end,
- char *name)
-{
- struct domain_rr *rr;
- int err, offset;
- int name_len = 0, output_len = 0, max_rsp = *response_size;
-
- err = get_name(0, buf, start, max, response, max_rsp,
- &output_len, end, name, &name_len);
- if (err < 0)
- return err;
-
- offset = output_len;
-
- if ((unsigned int) offset > *response_size)
- return -ENOBUFS;
-
- rr = (void *) (*end);
-
- if (rr == NULL)
- return -EINVAL;
-
- *type = ntohs(rr->type);
- *class = ntohs(rr->class);
- *ttl = ntohl(rr->ttl);
- *rdlen = ntohs(rr->rdlen);
-
- if (*ttl < 0)
- return -EINVAL;
-
- memcpy(response + offset, *end, sizeof(struct domain_rr));
-
- offset += sizeof(struct domain_rr);
- *end += sizeof(struct domain_rr);
-
- if ((unsigned int) (offset + *rdlen) > *response_size)
- return -ENOBUFS;
-
- memcpy(response + offset, *end, *rdlen);
-
- *end += *rdlen;
-
- *response_size = offset + *rdlen;
-
- return 0;
-}
-
-static gboolean check_alias(GSList *aliases, char *name)
-{
- GSList *list;
-
- if (aliases != NULL) {
- for (list = aliases; list; list = list->next) {
- int len = strlen((char *)list->data);
- if (strncmp((char *)list->data, name, len) == 0)
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static int parse_response(unsigned char *buf, int buflen,
- char *question, int qlen,
- uint16_t *type, uint16_t *class, int *ttl,
- unsigned char *response, unsigned int *response_len,
- uint16_t *answers)
-{
- struct domain_hdr *hdr = (void *) buf;
- struct domain_question *q;
- unsigned char *ptr;
- uint16_t qdcount = ntohs(hdr->qdcount);
- uint16_t ancount = ntohs(hdr->ancount);
- int err, i;
- uint16_t qtype, qclass;
- unsigned char *next = NULL;
- unsigned int maxlen = *response_len;
- GSList *aliases = NULL, *list;
- char name[NS_MAXDNAME + 1];
-
- if (buflen < 12)
- return -EINVAL;
-
- DBG("qr %d qdcount %d", hdr->qr, qdcount);
-
- /* We currently only cache responses where question count is 1 */
- if (hdr->qr != 1 || qdcount != 1)
- return -EINVAL;
-
- ptr = buf + sizeof(struct domain_hdr);
-
- strncpy(question, (char *) ptr, qlen);
- qlen = strlen(question);
- ptr += qlen + 1; /* skip \0 */
-
- q = (void *) ptr;
- qtype = ntohs(q->type);
-
- /* We cache only A and AAAA records */
- if (qtype != 1 && qtype != 28)
- return -ENOMSG;
-
- qclass = ntohs(q->class);
-
- ptr += 2 + 2; /* ptr points now to answers */
-
- err = -ENOMSG;
- *response_len = 0;
- *answers = 0;
-
- /*
- * We have a bunch of answers (like A, AAAA, CNAME etc) to
- * A or AAAA question. We traverse the answers and parse the
- * resource records. Only A and AAAA records are cached, all
- * the other records in answers are skipped.
- */
- for (i = 0; i < ancount; i++) {
- /*
- * Get one address at a time to this buffer.
- * The max size of the answer is
- * 2 (pointer) + 2 (type) + 2 (class) +
- * 4 (ttl) + 2 (rdlen) + addr (16 or 4) = 28
- * for A or AAAA record.
- * For CNAME the size can be bigger.
- */
- unsigned char rsp[NS_MAXCDNAME];
- unsigned int rsp_len = sizeof(rsp) - 1;
- int ret, rdlen;
-
- memset(rsp, 0, sizeof(rsp));
-
- ret = parse_rr(buf, ptr, buf + buflen, rsp, &rsp_len,
- type, class, ttl, &rdlen, &next, name);
- if (ret != 0) {
- err = ret;
- goto out;
- }
-
- /*
- * Now rsp contains compressed or uncompressed resource
- * record. Next we check if this record answers the question.
- * The name var contains the uncompressed label.
- * One tricky bit is the CNAME records as they alias
- * the name we might be interested in.
- */
-
- /*
- * Go to next answer if the class is not the one we are
- * looking for.
- */
- if (*class != qclass) {
- ptr = next;
- next = NULL;
- continue;
- }
-
- /*
- * Try to resolve aliases also, type is CNAME(5).
- * This is important as otherwise the aliased names would not
- * be cached at all as the cache would not contain the aliased
- * question.
- *
- * If any CNAME is found in DNS packet, then we cache the alias
- * IP address instead of the question (as the server
- * said that question has only an alias).
- * This means in practice that if e.g., ipv6.google.com is
- * queried, DNS server returns CNAME of that name which is
- * ipv6.l.google.com. We then cache the address of the CNAME
- * but return the question name to client. So the alias
- * status of the name is not saved in cache and thus not
- * returned to the client. We do not return DNS packets from
- * cache to client saying that ipv6.google.com is an alias to
- * ipv6.l.google.com but we return instead a DNS packet that
- * says ipv6.google.com has address xxx which is in fact the
- * address of ipv6.l.google.com. For caching purposes this
- * should not cause any issues.
- */
- if (*type == 5 && strncmp(question, name, qlen) == 0) {
- /*
- * So now the alias answered the question. This is
- * not very useful from caching point of view as
- * the following A or AAAA records will not match the
- * question. We need to find the real A/AAAA record
- * of the alias and cache that.
- */
- unsigned char *end = NULL;
- int name_len = 0, output_len;
-
- memset(rsp, 0, sizeof(rsp));
- rsp_len = sizeof(rsp) - 1;
-
- /*
- * Alias is in rdata part of the message,
- * and next-rdlen points to it. So we need to get
- * the real name of the alias.
- */
- ret = get_name(0, buf, next - rdlen, buf + buflen,
- rsp, rsp_len, &output_len, &end,
- name, &name_len);
- if (ret != 0) {
- /* just ignore the error at this point */
- ptr = next;
- next = NULL;
- continue;
- }
-
- /*
- * We should now have the alias of the entry we might
- * want to cache. Just remember it for a while.
- * We check the alias list when we have parsed the
- * A or AAAA record.
- */
- aliases = g_slist_prepend(aliases, g_strdup(name));
-
- ptr = next;
- next = NULL;
- continue;
- }
-
- if (*type == qtype) {
- /*
- * We found correct type (A or AAAA)
- */
- if (check_alias(aliases, name) == TRUE ||
- (aliases == NULL && strncmp(question, name,
- qlen) == 0)) {
- /*
- * We found an alias or the name of the rr
- * matches the question. If so, we append
- * the compressed label to the cache.
- * The end result is a response buffer that
- * will contain one or more cached and
- * compressed resource records.
- */
- if (*response_len + rsp_len > maxlen) {
- err = -ENOBUFS;
- goto out;
- }
- memcpy(response + *response_len, rsp, rsp_len);
- *response_len += rsp_len;
- (*answers)++;
- err = 0;
- }
- }
-
- ptr = next;
- next = NULL;
- }
-
-out:
- for (list = aliases; list; list = list->next)
- g_free(list->data);
- g_slist_free(aliases);
-
- return err;
-}
-
-struct cache_timeout {
- time_t current_time;
- int max_timeout;
- int try_harder;
-};
-
-static gboolean cache_check_entry(gpointer key, gpointer value,
- gpointer user_data)
-{
- struct cache_timeout *data = user_data;
- struct cache_entry *entry = value;
- int max_timeout;
-
- /* Scale the number of hits by half as part of cache aging */
-
- entry->hits /= 2;
-
- /*
- * If either IPv4 or IPv6 cached entry has expired, we
- * remove both from the cache.
- */
-
- if (entry->ipv4 != NULL && entry->ipv4->timeout > 0) {
- max_timeout = entry->ipv4->cache_until;
- if (max_timeout > data->max_timeout)
- data->max_timeout = max_timeout;
-
- if (entry->ipv4->cache_until < data->current_time)
- return TRUE;
- }
-
- if (entry->ipv6 != NULL && entry->ipv6->timeout > 0) {
- max_timeout = entry->ipv6->cache_until;
- if (max_timeout > data->max_timeout)
- data->max_timeout = max_timeout;
-
- if (entry->ipv6->cache_until < data->current_time)
- return TRUE;
- }
-
- /*
- * if we're asked to try harder, also remove entries that have
- * few hits
- */
- if (data->try_harder && entry->hits < 4)
- return TRUE;
-
- return FALSE;
-}
-
-static void cache_cleanup(void)
-{
- static int max_timeout;
- struct cache_timeout data;
- int count = 0;
-
- data.current_time = time(NULL);
- data.max_timeout = 0;
- data.try_harder = 0;
-
- /*
- * In the first pass, we only remove entries that have timed out.
- * We use a cache of the first time to expire to do this only
- * when it makes sense.
- */
- if (max_timeout <= data.current_time) {
- count = g_hash_table_foreach_remove(cache, cache_check_entry,
- &data);
- }
- DBG("removed %d in the first pass", count);
-
- /*
- * In the second pass, if the first pass turned up blank,
- * we also expire entries with a low hit count,
- * while aging the hit count at the same time.
- */
- data.try_harder = 1;
- if (count == 0)
- count = g_hash_table_foreach_remove(cache, cache_check_entry,
- &data);
-
- if (count == 0)
- /*
- * If we could not remove anything, then remember
- * what is the max timeout and do nothing if we
- * have not yet reached it. This will prevent
- * constant traversal of the cache if it is full.
- */
- max_timeout = data.max_timeout;
- else
- max_timeout = 0;
-}
-
-static gboolean cache_invalidate_entry(gpointer key, gpointer value,
- gpointer user_data)
-{
- struct cache_entry *entry = value;
-
- /* first, delete any expired elements */
- cache_enforce_validity(entry);
-
- /* if anything is not expired, mark the entry for refresh */
- if (entry->hits > 0 && (entry->ipv4 || entry->ipv6))
- entry->want_refresh = 1;
-
- /* delete the cached data */
- if (entry->ipv4) {
- g_free(entry->ipv4->data);
- g_free(entry->ipv4);
- entry->ipv4 = NULL;
- }
-
- if (entry->ipv6) {
- g_free(entry->ipv6->data);
- g_free(entry->ipv6);
- entry->ipv6 = NULL;
- }
-
- /* keep the entry if we want it refreshed, delete it otherwise */
- if (entry->want_refresh)
- return FALSE;
- else
- return TRUE;
-}
-
-/*
- * cache_invalidate is called from places where the DNS landscape
- * has changed, say because connections are added or we entered a VPN.
- * The logic is to wipe all cache data, but mark all non-expired
- * parts of the cache for refresh rather than deleting the whole cache.
- */
-static void cache_invalidate(void)
+
+static void send_response(int sk, unsigned char *buf, int len,
+ const struct sockaddr *to, socklen_t tolen,
+ int protocol)
{
- DBG("Invalidating the DNS cache %p", cache);
+ struct domain_hdr *hdr;
+ int err, offset = protocol_offset(protocol);
+
+ DBG("");
- if (cache == NULL)
+ if (offset < 0)
return;
- g_hash_table_foreach_remove(cache, cache_invalidate_entry, NULL);
-}
+ if (len < 12)
+ return;
-static void cache_refresh_entry(struct cache_entry *entry)
-{
+ hdr = (void *) (buf + offset);
- cache_enforce_validity(entry);
-
- if (entry->hits > 2 && entry->ipv4 == NULL)
- entry->want_refresh = 1;
- if (entry->hits > 2 && entry->ipv6 == NULL)
- entry->want_refresh = 1;
-
- if (entry->want_refresh) {
- char *c;
- char dns_name[NS_MAXDNAME + 1];
- entry->want_refresh = 0;
-
- /* turn a DNS name into a hostname with dots */
- strncpy(dns_name, entry->key, NS_MAXDNAME);
- c = dns_name;
- while (c && *c) {
- int jump;
- jump = *c;
- *c = '.';
- c += jump + 1;
- }
- DBG("Refreshing %s\n", dns_name);
- /* then refresh the hostname */
- refresh_dns_entry(entry, &dns_name[1]);
- }
-}
+ DBG("id 0x%04x qr %d opcode %d", hdr->id, hdr->qr, hdr->opcode);
-static void cache_refresh_iterator(gpointer key, gpointer value,
- gpointer user_data)
-{
- struct cache_entry *entry = value;
+ hdr->qr = 1;
+ hdr->rcode = 2;
- cache_refresh_entry(entry);
-}
+ hdr->ancount = 0;
+ hdr->nscount = 0;
+ hdr->arcount = 0;
-static void cache_refresh(void)
-{
- if (cache == NULL)
+ err = sendto(sk, buf, len, 0, to, tolen);
+ if (err < 0) {
+ connman_error("Failed to send DNS response: %s",
+ strerror(errno));
return;
-
- g_hash_table_foreach(cache, cache_refresh_iterator, NULL);
+ }
}
-static int reply_query_type(unsigned char *msg, int len)
+static gboolean request_timeout(gpointer user_data)
{
- unsigned char *c;
- uint16_t *w;
- int l;
- int type;
-
- /* skip the header */
- c = msg + sizeof(struct domain_hdr);
- len -= sizeof(struct domain_hdr);
+ struct request_data *req = user_data;
+ struct listener_data *ifdata;
- if (len < 0)
- return 0;
+ DBG("id 0x%04x", req->srcid);
- /* now the query, which is a name and 2 16 bit words */
- l = dns_name_length(c) + 1;
- c += l;
- w = (uint16_t *) c;
- type = ntohs(*w);
+ if (req == NULL)
+ return FALSE;
- return type;
-}
+ ifdata = req->ifdata;
-static int cache_update(struct server_data *srv, unsigned char *msg,
- unsigned int msg_len)
-{
- int offset = protocol_offset(srv->protocol);
- int err, qlen, ttl = 0;
- uint16_t answers = 0, type = 0, class = 0;
- struct domain_hdr *hdr = (void *)(msg + offset);
- struct domain_question *q;
- struct cache_entry *entry;
- struct cache_data *data;
- char question[NS_MAXDNAME + 1];
- unsigned char response[NS_MAXDNAME + 1];
- unsigned char *ptr;
- unsigned int rsplen;
- gboolean new_entry = TRUE;
- time_t current_time;
-
- if (cache_size >= MAX_CACHE_SIZE) {
- cache_cleanup();
- if (cache_size >= MAX_CACHE_SIZE)
- return 0;
- }
+ request_list = g_slist_remove(request_list, req);
+ req->numserv--;
- current_time = time(NULL);
+ if (req->resplen > 0 && req->resp != NULL) {
+ int sk, err;
- /* don't do a cache refresh more than twice a minute */
- if (next_refresh < current_time) {
- cache_refresh();
- next_refresh = current_time + 30;
- }
+ sk = g_io_channel_unix_get_fd(ifdata->udp_listener_channel);
- if (offset < 0)
- return 0;
+ err = sendto(sk, req->resp, req->resplen, 0,
+ &req->sa, req->sa_len);
+ if (err < 0)
+ return FALSE;
+ } else if (req->request && req->numserv == 0) {
+ struct domain_hdr *hdr;
- DBG("offset %d hdr %p msg %p rcode %d", offset, hdr, msg, hdr->rcode);
+ if (req->protocol == IPPROTO_TCP) {
+ hdr = (void *) (req->request + 2);
+ hdr->id = req->srcid;
+ send_response(req->client_sk, req->request,
+ req->request_len, NULL, 0, IPPROTO_TCP);
- /* Continue only if response code is 0 (=ok) */
- if (hdr->rcode != 0)
- return 0;
+ } else if (req->protocol == IPPROTO_UDP) {
+ int sk;
- rsplen = sizeof(response) - 1;
- question[sizeof(question) - 1] = '\0';
-
- err = parse_response(msg + offset, msg_len - offset,
- question, sizeof(question) - 1,
- &type, &class, &ttl,
- response, &rsplen, &answers);
-
- /*
- * special case: if we do a ipv6 lookup and get no result
- * for a record that's already in our ipv4 cache.. we want
- * to cache the negative response.
- */
- if ((err == -ENOMSG || err == -ENOBUFS) &&
- reply_query_type(msg + offset,
- msg_len - offset) == 28) {
- entry = g_hash_table_lookup(cache, question);
- if (entry && entry->ipv4 && entry->ipv6 == NULL) {
- int cache_offset = 0;
-
- data = g_try_new(struct cache_data, 1);
- if (data == NULL)
- return -ENOMEM;
- data->inserted = entry->ipv4->inserted;
- data->type = type;
- data->answers = hdr->ancount;
- data->timeout = entry->ipv4->timeout;
- if (srv->protocol == IPPROTO_UDP)
- cache_offset = 2;
- data->data_len = msg_len + cache_offset;
- data->data = ptr = g_malloc(data->data_len);
- ptr[0] = (data->data_len - 2) / 256;
- ptr[1] = (data->data_len - 2) - ptr[0] * 256;
- if (srv->protocol == IPPROTO_UDP)
- ptr += 2;
- data->valid_until = entry->ipv4->valid_until;
- data->cache_until = entry->ipv4->cache_until;
- memcpy(ptr, msg, msg_len);
- entry->ipv6 = data;
- /*
- * we will get a "hit" when we serve the response
- * out of the cache
- */
- entry->hits--;
- if (entry->hits < 0)
- entry->hits = 0;
- return 0;
+ hdr = (void *) (req->request);
+ hdr->id = req->srcid;
+ sk = g_io_channel_unix_get_fd(
+ ifdata->udp_listener_channel);
+ send_response(sk, req->request, req->request_len,
+ &req->sa, req->sa_len, IPPROTO_UDP);
}
}
- if (err < 0 || ttl == 0)
- return 0;
+ g_free(req->resp);
+ g_free(req);
- qlen = strlen(question);
-
- /*
- * If the cache contains already data, check if the
- * type of the cached data is the same and do not add
- * to cache if data is already there.
- * This is needed so that we can cache both A and AAAA
- * records for the same name.
- */
- entry = g_hash_table_lookup(cache, question);
- if (entry == NULL) {
- entry = g_try_new(struct cache_entry, 1);
- if (entry == NULL)
- return -ENOMEM;
+ return FALSE;
+}
- data = g_try_new(struct cache_data, 1);
- if (data == NULL) {
- g_free(entry);
- return -ENOMEM;
- }
+static int append_query(unsigned char *buf, unsigned int size,
+ const char *query, const char *domain)
+{
+ unsigned char *ptr = buf;
+ char *offset;
+ int len;
- entry->key = g_strdup(question);
- entry->ipv4 = entry->ipv6 = NULL;
- entry->want_refresh = 0;
- entry->hits = 0;
+ DBG("query %s domain %s", query, domain);
- if (type == 1)
- entry->ipv4 = data;
- else
- entry->ipv6 = data;
- } else {
- if (type == 1 && entry->ipv4 != NULL)
- return 0;
+ offset = (char *) query;
+ while (offset != NULL) {
+ char *tmp;
- if (type == 28 && entry->ipv6 != NULL)
- return 0;
+ tmp = strchr(offset, '.');
+ if (tmp == NULL) {
+ len = strlen(offset);
+ if (len == 0)
+ break;
+ *ptr = len;
+ memcpy(ptr + 1, offset, len);
+ ptr += len + 1;
+ break;
+ }
- data = g_try_new(struct cache_data, 1);
- if (data == NULL)
- return -ENOMEM;
+ *ptr = tmp - offset;
+ memcpy(ptr + 1, offset, tmp - offset);
+ ptr += tmp - offset + 1;
- if (type == 1)
- entry->ipv4 = data;
- else
- entry->ipv6 = data;
+ offset = tmp + 1;
+ }
- /*
- * compensate for the hit we'll get for serving
- * the response out of the cache
- */
- entry->hits--;
- if (entry->hits < 0)
- entry->hits = 0;
+ offset = (char *) domain;
+ while (offset != NULL) {
+ char *tmp;
- new_entry = FALSE;
- }
+ tmp = strchr(offset, '.');
+ if (tmp == NULL) {
+ len = strlen(offset);
+ if (len == 0)
+ break;
+ *ptr = len;
+ memcpy(ptr + 1, offset, len);
+ ptr += len + 1;
+ break;
+ }
- if (ttl < MIN_CACHE_TTL)
- ttl = MIN_CACHE_TTL;
-
- data->inserted = current_time;
- data->type = type;
- data->answers = answers;
- data->timeout = ttl;
- /*
- * The "2" in start of the length is the TCP offset. We allocate it
- * here even for UDP packet because it simplifies the sending
- * of cached packet.
- */
- data->data_len = 2 + 12 + qlen + 1 + 2 + 2 + rsplen;
- data->data = ptr = g_malloc(data->data_len);
- data->valid_until = current_time + ttl;
-
- /*
- * Restrict the cached DNS record TTL to some sane value
- * in order to prevent data staying in the cache too long.
- */
- if (ttl > MAX_CACHE_TTL)
- ttl = MAX_CACHE_TTL;
-
- data->cache_until = round_down_ttl(current_time + ttl, ttl);
-
- if (data->data == NULL) {
- g_free(entry->key);
- g_free(data);
- g_free(entry);
- return -ENOMEM;
- }
+ *ptr = tmp - offset;
+ memcpy(ptr + 1, offset, tmp - offset);
+ ptr += tmp - offset + 1;
- /*
- * We cache the two extra bytes at the start of the message
- * in a TCP packet. When sending UDP packet, we skip the first
- * two bytes. This way we do not need to know the format
- * (UDP/TCP) of the cached message.
- */
- ptr[0] = (data->data_len - 2) / 256;
- ptr[1] = (data->data_len - 2) - ptr[0] * 256;
- if (srv->protocol == IPPROTO_UDP)
- ptr += 2;
-
- memcpy(ptr, msg, offset + 12);
- memcpy(ptr + offset + 12, question, qlen + 1); /* copy also the \0 */
-
- q = (void *) (ptr + offset + 12 + qlen + 1);
- q->type = htons(type);
- q->class = htons(class);
- memcpy(ptr + offset + 12 + qlen + 1 + sizeof(struct domain_question),
- response, rsplen);
-
- if (new_entry == TRUE) {
- g_hash_table_replace(cache, entry->key, entry);
- cache_size++;
+ offset = tmp + 1;
}
- DBG("cache %d %squestion \"%s\" type %d ttl %d size %zd packet %u "
- "dns len %u",
- cache_size, new_entry ? "new " : "old ",
- question, type, ttl,
- sizeof(*entry) + sizeof(*data) + data->data_len + qlen,
- data->data_len,
- srv->protocol == IPPROTO_TCP ?
- (unsigned int)(data->data[0] * 256 + data->data[1]) :
- data->data_len);
+ *ptr++ = 0x00;
- return 0;
+ return ptr - buf;
}
static int ns_resolv(struct server_data *server, struct request_data *req,
gpointer request, gpointer name)
{
GList *list;
- int sk, err, type = 0;
+ int sk, err;
char *dot, *lookup = (char *) name;
- struct cache_entry *entry;
-
- entry = cache_check(request, &type, req->protocol);
- if (entry != NULL) {
- int ttl_left = 0;
- struct cache_data *data;
-
- DBG("cache hit %s type %s", lookup, type == 1 ? "A" : "AAAA");
- if (type == 1)
- data = entry->ipv4;
- else
- data = entry->ipv6;
-
- if (data) {
- ttl_left = data->valid_until - time(NULL);
- entry->hits++;
- }
-
- if (data != NULL && req->protocol == IPPROTO_TCP) {
- send_cached_response(req->client_sk, data->data,
- data->data_len, NULL, 0, IPPROTO_TCP,
- req->srcid, data->answers, ttl_left);
- return 1;
- }
-
- if (data != NULL && req->protocol == IPPROTO_UDP) {
- int sk;
- sk = g_io_channel_unix_get_fd(
- req->ifdata->udp_listener_channel);
-
- send_cached_response(sk, data->data,
- data->data_len, &req->sa, req->sa_len,
- IPPROTO_UDP, req->srcid, data->answers,
- ttl_left);
- return 1;
- }
- }
sk = g_io_channel_unix_get_fd(server->channel);
- err = send(sk, request, req->request_len, MSG_NOSIGNAL);
- if (err < 0)
- return -EIO;
+ err = send(sk, request, req->request_len, 0);
req->numserv++;
alt[1] = req_len & 0xff;
}
- err = send(sk, alt, req->request_len + domlen, MSG_NOSIGNAL);
+ err = send(sk, alt, req->request_len + domlen, 0);
if (err < 0)
return -EIO;
return 0;
}
-static void destroy_request_data(struct request_data *req)
-{
- if (req->timeout > 0)
- g_source_remove(req->timeout);
-
- g_free(req->resp);
- g_free(req->request);
- g_free(req->name);
- g_free(req);
-}
-
-static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol,
- struct server_data *data)
+static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol)
{
struct domain_hdr *hdr;
struct request_data *req;
*/
ptr = reply + offset + sizeof(struct domain_hdr);
host_len = *ptr;
- domain_len = strlen((const char *)ptr + host_len + 1);
+ domain_len = strlen((const char *)ptr) - host_len - 1;
/*
- * Remove the domain name and replace it by the end
- * of reply. Check if the domain is really there
- * before trying to copy the data. The domain_len can
- * be 0 because if the original query did not contain
- * a domain name, then we are sending two packets,
- * first without the domain name and the second packet
- * with domain name. The append_domain is set to true
- * even if we sent the first packet without domain
- * name. In this case we end up in this branch.
+ * remove the domain name and replaced it by the end
+ * of reply.
*/
- if (domain_len > 0) {
- /*
- * Note that we must use memmove() here,
- * because the memory areas can overlap.
- */
- memmove(ptr + host_len + 1,
- ptr + host_len + domain_len + 1,
- reply_len - (ptr - reply + domain_len));
-
- reply_len = reply_len - domain_len;
- }
+ memmove(ptr + host_len + 1,
+ ptr + host_len + domain_len + 1,
+ reply_len - (ptr - reply + domain_len));
+
+ reply_len = reply_len - domain_len;
}
g_free(req->resp);
memcpy(req->resp, reply, reply_len);
req->resplen = reply_len;
-
- cache_update(data, reply, reply_len);
}
if (hdr->rcode > 0 && req->numresp < req->numserv)
return -EINVAL;
+ if (req->timeout > 0)
+ g_source_remove(req->timeout);
+
request_list = g_slist_remove(request_list, req);
if (protocol == IPPROTO_UDP) {
&req->sa, req->sa_len);
} else {
sk = req->client_sk;
- err = send(sk, req->resp, req->resplen, MSG_NOSIGNAL);
+ err = send(sk, req->resp, req->resplen, 0);
close(sk);
}
- if (err < 0)
- DBG("Cannot send msg, sk %d proto %d errno %d/%s", sk,
- protocol, errno, strerror(errno));
- else
- DBG("proto %d sent %d bytes to %d", protocol, err, sk);
-
- destroy_request_data(req);
+ g_free(req->resp);
+ g_free(req);
return err;
}
-static void cache_element_destroy(gpointer value)
-{
- struct cache_entry *entry = value;
-
- if (entry == NULL)
- return;
-
- if (entry->ipv4 != NULL) {
- g_free(entry->ipv4->data);
- g_free(entry->ipv4);
- }
-
- if (entry->ipv6 != NULL) {
- g_free(entry->ipv6->data);
- g_free(entry->ipv6);
- }
-
- g_free(entry->key);
- g_free(entry);
-
- if (--cache_size < 0)
- cache_size = 0;
-}
-
-static gboolean try_remove_cache(gpointer user_data)
-{
- if (__sync_fetch_and_sub(&cache_refcount, 1) == 1) {
- DBG("No cache users, removing it.");
-
- g_hash_table_destroy(cache);
- cache = NULL;
- }
-
- return FALSE;
-}
-
static void destroy_server(struct server_data *server)
{
GList *list;
- DBG("interface %s server %s sock %d", server->interface, server->server,
- g_io_channel_unix_get_fd(server->channel));
+ DBG("interface %s server %s", server->interface, server->server);
server_list = g_slist_remove(server_list, server);
g_io_channel_unref(server->channel);
if (server->protocol == IPPROTO_UDP)
- DBG("Removing DNS server %s", server->server);
+ connman_info("Removing DNS server %s", server->server);
g_free(server->incoming_reply);
g_free(server->server);
g_free(domain);
}
g_free(server->interface);
-
- /*
- * We do not remove cache right away but delay it few seconds.
- * The idea is that when IPv6 DNS server is added via RDNSS, it has a
- * lifetime. When the lifetime expires we decrease the refcount so it
- * is possible that the cache is then removed. Because a new DNS server
- * is usually created almost immediately we would then loose the cache
- * without any good reason. The small delay allows the new RDNSS to
- * create a new DNS server instance and the refcount does not go to 0.
- */
- g_timeout_add_seconds(3, try_remove_cache, NULL);
-
g_free(server);
}
{
unsigned char buf[4096];
int sk, err, len;
- struct server_data *data = user_data;
if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+ struct server_data *data = user_data;
+
connman_error("Error with UDP server %s", data->server);
data->watch = 0;
return FALSE;
if (len < 12)
return TRUE;
- err = forward_dns_reply(buf, len, IPPROTO_UDP, data);
+ err = forward_dns_reply(buf, len, IPPROTO_UDP);
if (err < 0)
return TRUE;
if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
GSList *list;
hangup:
- DBG("TCP server channel closed, sk %d", sk);
+ DBG("TCP server channel closed");
/*
* Discard any partial response which is buffered; better
if ((condition & G_IO_OUT) && !server->connected) {
GSList *list;
GList *domains;
- int no_request_sent = TRUE;
struct server_data *udp_server;
udp_server = find_server(server->interface, server->server,
server->timeout = 0;
}
- for (list = request_list; list; ) {
+ for (list = request_list; list; list = list->next) {
struct request_data *req = list->data;
- int status;
- if (req->protocol == IPPROTO_UDP) {
- list = list->next;
+ if (req->protocol == IPPROTO_UDP)
continue;
- }
DBG("Sending req %s over TCP", (char *)req->name);
- status = ns_resolv(server, req,
- req->request, req->name);
- if (status > 0) {
- /*
- * A cached result was sent,
- * so the request can be released
- */
- list = list->next;
- request_list = g_slist_remove(request_list, req);
- destroy_request_data(req);
- continue;
- }
-
- if (status < 0) {
- list = list->next;
- continue;
- }
-
- no_request_sent = FALSE;
-
if (req->timeout > 0)
g_source_remove(req->timeout);
req->timeout = g_timeout_add_seconds(30,
request_timeout, req);
- list = list->next;
- }
-
- if (no_request_sent == TRUE) {
- destroy_server(server);
- return FALSE;
+ ns_resolv(server, req, req->request, req->name);
}
} else if (condition & G_IO_IN) {
reply_len = reply_len_buf[1] | reply_len_buf[0] << 8;
reply_len += 2;
- DBG("TCP reply %d bytes from %d", reply_len, sk);
+ DBG("TCP reply %d bytes", reply_len);
reply = g_try_malloc(sizeof(*reply) + reply_len + 2);
if (!reply)
reply->received += bytes_recv;
}
- forward_dns_reply(reply->buf, reply->received, IPPROTO_TCP,
- server);
+ forward_dns_reply(reply->buf, reply->received, IPPROTO_TCP);
g_free(reply);
server->incoming_reply = NULL;
return NULL;
}
- DBG("sk %d", sk);
-
if (interface != NULL) {
if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
interface, strlen(interface) + 1) < 0) {
}
}
- if (__sync_fetch_and_add(&cache_refcount, 1) == 0)
- cache = g_hash_table_new_full(g_str_hash,
- g_str_equal,
- NULL,
- cache_element_destroy);
-
if (protocol == IPPROTO_UDP) {
/* Enable new servers by default */
data->enabled = TRUE;
- DBG("Adding DNS server %s", data->server);
+ connman_info("Adding DNS server %s", data->server);
server_list = g_slist_append(server_list, data);
+
+ return data;
}
- return data;
+ return NULL;
}
static gboolean resolv(struct request_data *req,
G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
udp_server_event, data);
- if (ns_resolv(data, req, request, name) > 0)
- return TRUE;
+ if (ns_resolv(data, req, request, name) < 0)
+ continue;
}
- return FALSE;
+ return TRUE;
}
static void append_domain(const char *interface, const char *domain)
{
GSList *list;
- list = request_list;
+ list = request_pending_list;
while (list) {
struct request_data *req = list->data;
list = list->next;
- if (resolv(req, req->request, req->name) == TRUE) {
- /*
- * A cached result was sent,
- * so the request can be released
- */
- request_list =
- g_slist_remove(request_list, req);
- destroy_request_data(req);
- continue;
- }
-
- if (req->timeout > 0)
- g_source_remove(req->timeout);
- req->timeout = g_timeout_add_seconds(5, request_timeout, req);
+ request_pending_list =
+ g_slist_remove(request_pending_list, req);
+ resolv(req, req->request, req->name);
+ g_free(req->request);
+ g_free(req->name);
}
}
struct server_data *data = list->data;
if (enabled == FALSE) {
- DBG("Enabling DNS server %s", data->server);
+ connman_info("Enabling DNS server %s", data->server);
data->enabled = TRUE;
- cache_invalidate();
- cache_refresh();
} else {
- DBG("Disabling DNS server %s", data->server);
+ connman_info("Disabling DNS server %s", data->server);
data->enabled = FALSE;
- cache_invalidate();
}
}
}
DBG("service %p", service);
- /* DNS has changed, invalidate the cache */
- cache_invalidate();
-
if (service == NULL) {
/* When no services are active, then disable DNS proxying */
dnsproxy_offline_mode(TRUE);
struct server_data *data = list->data;
if (g_strcmp0(data->interface, interface) == 0) {
- DBG("Enabling DNS server %s", data->server);
+ connman_info("Enabling DNS server %s", data->server);
data->enabled = TRUE;
} else {
- DBG("Disabling DNS server %s", data->server);
+ connman_info("Disabling DNS server %s", data->server);
data->enabled = FALSE;
}
}
g_free(interface);
- cache_refresh();
}
static struct connman_notifier dnsproxy_notifier = {
if (hdr->qr != 0 || qdcount != 1)
return -EINVAL;
- name[0] = '\0';
+ memset(name, 0, size);
ptr = buf + sizeof(struct domain_hdr);
remain = len - sizeof(struct domain_hdr);
unsigned char buf[768];
char query[512];
struct request_data *req;
+ struct server_data *server;
int sk, client_sk, len, err;
struct sockaddr_in6 client_addr;
socklen_t client_addr_len = sizeof(client_addr);
GSList *list;
struct listener_data *ifdata = user_data;
- int waiting_for_connect = FALSE, qtype = 0;
- struct cache_entry *entry;
DBG("condition 0x%x", condition);
if (len < 2)
return TRUE;
- DBG("Received %d bytes (id 0x%04x) from %d", len,
- buf[2] | buf[3] << 8, client_sk);
+ DBG("Received %d bytes (id 0x%04x)", len, buf[2] | buf[3] << 8);
err = parse_request(buf + 2, len - 2, query, sizeof(query));
if (err < 0 || (g_slist_length(server_list) == 0)) {
req->client_sk = client_sk;
req->protocol = IPPROTO_TCP;
+ request_id += 2;
+ if (request_id == 0x0000 || request_id == 0xffff)
+ request_id += 2;
+
req->srcid = buf[2] | (buf[3] << 8);
- req->dstid = get_id();
- req->altid = get_id();
+ req->dstid = request_id;
+ req->altid = request_id + 1;
req->request_len = len;
buf[2] = req->dstid & 0xff;
req->numserv = 0;
req->ifdata = (struct listener_data *) ifdata;
req->append_domain = FALSE;
-
- /*
- * Check if the answer is found in the cache before
- * creating sockets to the server.
- */
- entry = cache_check(buf, &qtype, IPPROTO_TCP);
- if (entry != NULL) {
- int ttl_left = 0;
- struct cache_data *data;
-
- DBG("cache hit %s type %s", query, qtype == 1 ? "A" : "AAAA");
- if (qtype == 1)
- data = entry->ipv4;
- else
- data = entry->ipv6;
-
- if (data != NULL) {
- ttl_left = data->valid_until - time(NULL);
- entry->hits++;
-
- send_cached_response(client_sk, data->data,
- data->data_len, NULL, 0, IPPROTO_TCP,
- req->srcid, data->answers, ttl_left);
-
- g_free(req);
- return TRUE;
- } else
- DBG("data missing, ignoring cache for this query");
- }
+ request_list = g_slist_append(request_list, req);
for (list = server_list; list; list = list->next) {
struct server_data *data = list->data;
+ GList *domains;
if (data->protocol != IPPROTO_UDP || data->enabled == FALSE)
continue;
- if(create_server(data->interface, NULL,
- data->server, IPPROTO_TCP) == NULL)
- continue;
+ server = create_server(data->interface, NULL,
+ data->server, IPPROTO_TCP);
- waiting_for_connect = TRUE;
- }
+ /*
+ * If server is NULL, we're not connected yet.
+ * Copy the relevant buffers and continue with
+ * the next nameserver.
+ * The request will actually be sent once we're
+ * properly connected over TCP to this nameserver.
+ */
+ if (server == NULL) {
+ req->request = g_try_malloc0(req->request_len);
+ if (req->request == NULL)
+ return TRUE;
- if (waiting_for_connect == FALSE) {
- /* No server is waiting for connect */
- send_response(client_sk, buf, len, NULL, 0, IPPROTO_TCP);
- g_free(req);
- return TRUE;
- }
+ memcpy(req->request, buf, req->request_len);
- /*
- * The server is not connected yet.
- * Copy the relevant buffers.
- * The request will actually be sent once we're
- * properly connected over TCP to the nameserver.
- */
- req->request = g_try_malloc0(req->request_len);
- if (req->request == NULL) {
- send_response(client_sk, buf, len, NULL, 0, IPPROTO_TCP);
- g_free(req);
- return TRUE;
- }
- memcpy(req->request, buf, req->request_len);
+ req->name = g_try_malloc0(sizeof(query));
+ if (req->name == NULL) {
+ g_free(req->request);
+ return TRUE;
+ }
+ memcpy(req->name, query, sizeof(query));
- req->name = g_try_malloc0(sizeof(query));
- if (req->name == NULL) {
- send_response(client_sk, buf, len, NULL, 0, IPPROTO_TCP);
- g_free(req->request);
- g_free(req);
- return TRUE;
- }
- memcpy(req->name, query, sizeof(query));
+ continue;
+ }
- req->timeout = g_timeout_add_seconds(30, request_timeout, req);
+ if (req->timeout > 0)
+ g_source_remove(req->timeout);
- request_list = g_slist_append(request_list, req);
+ for (domains = data->domains; domains;
+ domains = domains->next) {
+ char *dom = domains->data;
+
+ DBG("Adding domain %s to %s", dom, server->server);
+
+ server->domains = g_list_append(server->domains,
+ g_strdup(dom));
+ }
+
+ req->timeout = g_timeout_add_seconds(30, request_timeout, req);
+ ns_resolv(server, req, buf, query);
+ }
return TRUE;
}
req->client_sk = 0;
req->protocol = IPPROTO_UDP;
+ request_id += 2;
+ if (request_id == 0x0000 || request_id == 0xffff)
+ request_id += 2;
+
req->srcid = buf[0] | (buf[1] << 8);
- req->dstid = get_id();
- req->altid = get_id();
+ req->dstid = request_id;
+ req->altid = request_id + 1;
req->request_len = len;
buf[0] = req->dstid & 0xff;
req->numserv = 0;
req->ifdata = (struct listener_data *) ifdata;
- req->append_domain = FALSE;
-
- if (resolv(req, buf, query) == TRUE) {
- /* a cached result was sent, so the request can be released */
- g_free(req);
- return TRUE;
- }
-
req->timeout = g_timeout_add_seconds(5, request_timeout, req);
+ req->append_domain = FALSE;
request_list = g_slist_append(request_list, req);
- return TRUE;
+ return resolv(req, buf, query);
}
static int create_dns_listener(int protocol, struct listener_data *ifdata)
if (g_strcmp0(ifdata->ifname, "lo") == 0)
__connman_resolvfile_remove("lo", NULL, "127.0.0.1");
+ for (list = request_pending_list; list; list = list->next) {
+ struct request_data *req = list->data;
+
+ DBG("Dropping pending request (id 0x%04x -> 0x%04x)",
+ req->srcid, req->dstid);
+
+ g_free(req->resp);
+ g_free(req->request);
+ g_free(req->name);
+ g_free(req);
+ list->data = NULL;
+ }
+
+ g_slist_free(request_pending_list);
+ request_pending_list = NULL;
+
for (list = request_list; list; list = list->next) {
struct request_data *req = list->data;
DBG("Dropping request (id 0x%04x -> 0x%04x)",
req->srcid, req->dstid);
- destroy_request_data(req);
+
+ g_free(req->resp);
+ g_free(req->request);
+ g_free(req->name);
+ g_free(req);
list->data = NULL;
}
static void remove_listener(gpointer key, gpointer value, gpointer user_data)
{
- const char *interface = key;
- struct listener_data *ifdata = value;
-
- DBG("interface %s", interface);
-
- destroy_listener(ifdata);
+ __connman_dnsproxy_remove_listener(key);
}
int __connman_dnsproxy_init(void)
DBG("");
- srandom(time(NULL));
-
listener_table = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, g_free);
err = __connman_dnsproxy_add_listener("lo");
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
* Copyright (C) 2003-2005 Go-Core Project
* Copyright (C) 2003-2006 Helsinki University of Technology
*
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/sockios.h>
-#include <netdb.h>
#include <arpa/inet.h>
#include <net/route.h>
#include <net/ethernet.h>
#include <netinet/icmp6.h>
#include <fcntl.h>
#include <linux/if_tun.h>
-#include <ctype.h>
#include "connman.h"
((struct rtattr *) (((uint8_t*) (nmsg)) + \
NLMSG_ALIGN((nmsg)->nlmsg_len)))
-int __connman_inet_rtnl_addattr_l(struct nlmsghdr *n, size_t max_length,
- int type, const void *data, size_t data_length)
+static int add_rtattr(struct nlmsghdr *n, size_t max_length, int type,
+ const void *data, size_t data_length)
{
size_t length;
struct rtattr *rta;
if (inet_pton(AF_INET, peer, &ipv4_dest) < 1)
return -1;
- err = __connman_inet_rtnl_addattr_l(header,
- sizeof(request),
- IFA_ADDRESS,
- &ipv4_dest,
- sizeof(ipv4_dest));
- if (err < 0)
- return err;
+ if ((err = add_rtattr(header, sizeof(request),
+ IFA_ADDRESS,
+ &ipv4_dest, sizeof(ipv4_dest))) < 0)
+ return err;
}
- err = __connman_inet_rtnl_addattr_l(header,
- sizeof(request),
- IFA_LOCAL,
- &ipv4_addr,
- sizeof(ipv4_addr));
- if (err < 0)
+ if ((err = add_rtattr(header, sizeof(request), IFA_LOCAL,
+ &ipv4_addr, sizeof(ipv4_addr))) < 0)
return err;
- err = __connman_inet_rtnl_addattr_l(header,
- sizeof(request),
- IFA_BROADCAST,
- &ipv4_bcast,
- sizeof(ipv4_bcast));
- if (err < 0)
+ if ((err = add_rtattr(header, sizeof(request), IFA_BROADCAST,
+ &ipv4_bcast, sizeof(ipv4_bcast))) < 0)
return err;
} else if (family == AF_INET6) {
if (inet_pton(AF_INET6, address, &ipv6_addr) < 1)
return -1;
- err = __connman_inet_rtnl_addattr_l(header,
- sizeof(request),
- IFA_LOCAL,
- &ipv6_addr,
- sizeof(ipv6_addr));
- if (err < 0)
+ if ((err = add_rtattr(header, sizeof(request), IFA_LOCAL,
+ &ipv6_addr, sizeof(ipv6_addr))) < 0)
return err;
}
struct sockaddr_in addr;
int sk, err;
- DBG("index %d host %s gateway %s netmask %s", index,
- host, gateway, netmask);
-
sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
return -1;
struct sockaddr_in addr;
int sk, err;
- DBG("index %d host %s", index, host);
-
sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
return -1;
struct in6_rtmsg rt;
int sk, err;
- DBG("index %d gateway %s", index, gateway);
+ DBG("index %d, gateway %s", index, gateway);
if (gateway == NULL)
return -EINVAL;
struct in6_rtmsg rt;
int sk, err;
- DBG("index %d gateway %s", index, gateway);
+ DBG("index %d, gateway %s", index, gateway);
if (gateway == NULL)
return -EINVAL;
struct sockaddr_in addr;
int sk, err;
- DBG("index %d gateway %s", index, gateway);
-
sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
return -1;
struct sockaddr_in addr;
int sk, err;
- DBG("index %d", index);
+ DBG("");
sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
const struct in6_addr any = IN6ADDR_ANY_INIT;
int sk, err;
- DBG("index %d", index);
+ DBG("");
sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
struct sockaddr_in addr;
int sk, err;
- DBG("index %d gateway %s", index, gateway);
+ DBG("");
sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
struct sockaddr_in addr;
int sk, err;
- DBG("index %d", index);
+ DBG("");
sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
const struct in6_addr any = IN6ADDR_ANY_INIT;
int sk, err;
- DBG("index %d", index);
+ DBG("");
sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sk < 0)
static void rs_cleanup(struct rs_cb_data *data)
{
- if (data->channel != NULL) {
- g_io_channel_shutdown(data->channel, TRUE, NULL);
- g_io_channel_unref(data->channel);
- data->channel = NULL;
- }
+ g_io_channel_shutdown(data->channel, TRUE, NULL);
+ g_io_channel_unref(data->channel);
+ data->channel = 0;
if (data->rs_timeout > 0)
g_source_remove(data->rs_timeout);
return FALSE;
if (data->callback != NULL)
- data->callback(NULL, 0, data->user_data);
+ data->callback(NULL, data->user_data);
data->rs_timeout = 0;
rs_cleanup(data);
len = recvmsg(fd, &mhdr, 0);
if (len < 0) {
- data->callback(NULL, 0, data->user_data);
+ data->callback(NULL, data->user_data);
rs_cleanup(data);
return -errno;
}
hdr = (struct nd_router_advert *)buf;
- DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
- sizeof(struct nd_router_advert));
if (hdr->nd_ra_code != 0)
return 0;
- data->callback(hdr, len, data->user_data);
+ data->callback(hdr, data->user_data);
rs_cleanup(data);
return len;
return 0;
}
-
-GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
- unsigned int length)
-{
- GSList *prefixes = NULL;
- uint8_t *pos;
- int len;
-
- if (length <= sizeof(struct nd_router_advert))
- return NULL;
-
- len = length - sizeof(struct nd_router_advert);
- pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
-
- while (len > 0) {
- struct nd_opt_prefix_info *pinfo;
- char prefix_str[INET6_ADDRSTRLEN+1], *str;
- const char *prefix;
- int optlen;
-
- if (len < 2)
- break;
-
- optlen = pos[1] << 3;
- if (optlen == 0 || optlen > len)
- break;
-
- switch (pos[0]) {
- case ND_OPT_PREFIX_INFORMATION:
- pinfo = (struct nd_opt_prefix_info *)pos;
- prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
- prefix_str, INET6_ADDRSTRLEN);
- if (prefix == NULL)
- break;
-
- str = g_strdup_printf("%s/%d", prefix,
- pinfo->nd_opt_pi_prefix_len);
- prefixes = g_slist_append(prefixes, str);
-
- DBG("prefix %s", str);
-
- break;
- }
-
- len -= optlen;
- pos += optlen;
- }
-
- return prefixes;
-}
-
-static int get_dest_addr(int family, int index, char *buf, int len)
-{
- struct ifreq ifr;
- void *addr;
- int sk;
-
- sk = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
- if (sk < 0)
- return -errno;
-
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_ifindex = index;
-
- if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
- DBG("SIOCGIFNAME (%d/%s)", errno, strerror(errno));
- close(sk);
- return -errno;
- }
-
- if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
- DBG("SIOCGIFFLAGS (%d/%s)", errno, strerror(errno));
- close(sk);
- return -errno;
- }
-
- if ((ifr.ifr_flags & IFF_POINTOPOINT) == 0) {
- close(sk);
- errno = EINVAL;
- return -errno;
- }
-
- DBG("index %d %s", index, ifr.ifr_name);
-
- if (ioctl(sk, SIOCGIFDSTADDR, &ifr) < 0) {
- connman_error("Get destination address failed (%s)",
- strerror(errno));
- close(sk);
- return -errno;
- }
-
- close(sk);
-
- switch (family) {
- case AF_INET:
- addr = &((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr;
- break;
- case AF_INET6:
- addr = &((struct sockaddr_in6 *)&ifr.ifr_dstaddr)->sin6_addr;
- break;
- default:
- errno = EINVAL;
- return -errno;
- }
-
- if (inet_ntop(family, addr, buf, len) == NULL) {
- DBG("error %d/%s", errno, strerror(errno));
- return -errno;
- }
-
- return 0;
-}
-
-int connman_inet_get_dest_addr(int index, char **dest)
-{
- char addr[INET_ADDRSTRLEN];
- int ret;
-
- ret = get_dest_addr(PF_INET, index, addr, INET_ADDRSTRLEN);
- if (ret < 0)
- return ret;
-
- *dest = g_strdup(addr);
-
- DBG("destination %s", *dest);
-
- return 0;
-}
-
-int connman_inet_ipv6_get_dest_addr(int index, char **dest)
-{
- char addr[INET6_ADDRSTRLEN];
- int ret;
-
- ret = get_dest_addr(PF_INET6, index, addr, INET6_ADDRSTRLEN);
- if (ret < 0)
- return ret;
-
- *dest = g_strdup(addr);
-
- DBG("destination %s", *dest);
-
- return 0;
-}
-
-int __connman_inet_rtnl_open(struct __connman_inet_rtnl_handle *rth)
-{
- int sndbuf = 1024;
- int rcvbuf = 1024 * 4;
-
- rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
- if (rth->fd < 0) {
- connman_error("Can not open netlink socket: %s",
- strerror(errno));
- return -errno;
- }
-
- if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
- sizeof(sndbuf)) < 0) {
- connman_error("SO_SNDBUF: %s", strerror(errno));
- return -errno;
- }
-
- if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
- sizeof(rcvbuf)) < 0) {
- connman_error("SO_RCVBUF: %s", strerror(errno));
- return -errno;
- }
-
- memset(&rth->local, 0, sizeof(rth->local));
- rth->local.nl_family = AF_NETLINK;
- rth->local.nl_groups = 0;
-
- if (bind(rth->fd, (struct sockaddr *)&rth->local,
- sizeof(rth->local)) < 0) {
- connman_error("Can not bind netlink socket: %s",
- strerror(errno));
- return -errno;
- }
-
- rth->seq = time(NULL);
-
- DBG("fd %d", rth->fd);
-
- return 0;
-}
-
-struct inet_rtnl_cb_data {
- GIOChannel *channel;
- __connman_inet_rtnl_cb_t callback;
- guint rtnl_timeout;
- guint watch_id;
- struct __connman_inet_rtnl_handle *rtnl;
- void *user_data;
-};
-
-static void inet_rtnl_cleanup(struct inet_rtnl_cb_data *data)
-{
- struct __connman_inet_rtnl_handle *rth = data->rtnl;
-
- if (data->channel != NULL) {
- g_io_channel_shutdown(data->channel, TRUE, NULL);
- g_io_channel_unref(data->channel);
- data->channel = NULL;
- }
-
- DBG("data %p", data);
-
- if (data->rtnl_timeout > 0)
- g_source_remove(data->rtnl_timeout);
-
- if (data->watch_id > 0)
- g_source_remove(data->watch_id);
-
- if (rth != NULL) {
- __connman_inet_rtnl_close(rth);
- g_free(rth);
- }
-
- g_free(data);
-}
-
-static gboolean inet_rtnl_timeout_cb(gpointer user_data)
-{
- struct inet_rtnl_cb_data *data = user_data;
-
- DBG("user data %p", user_data);
-
- if (data == NULL)
- return FALSE;
-
- if (data->callback != NULL)
- data->callback(NULL, data->user_data);
-
- data->rtnl_timeout = 0;
- inet_rtnl_cleanup(data);
- return FALSE;
-}
-
-static int inet_rtnl_recv(GIOChannel *chan, gpointer user_data)
-{
- struct inet_rtnl_cb_data *rtnl_data = user_data;
- struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl;
- struct nlmsghdr *h = NULL;
- struct sockaddr_nl nladdr;
- socklen_t addr_len = sizeof(nladdr);
- unsigned char buf[4096];
- void *ptr = buf;
- gsize len;
- int status, fd;
-
- memset(buf, 0, sizeof(buf));
- memset(&nladdr, 0, sizeof(nladdr));
-
- fd = g_io_channel_unix_get_fd(chan);
-
- status = recvfrom(fd, buf, sizeof(buf), 0,
- (struct sockaddr *) &nladdr, &addr_len);
- if (status < 0) {
- if (errno == EINTR || errno == EAGAIN)
- return 0;
-
- return -1;
- }
-
- if (status == 0)
- return -1;
-
- if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
- DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
- return 0;
- }
-
- len = status;
-
- while (len > 0) {
- struct nlmsgerr *err;
-
- h = ptr;
-
- if (!NLMSG_OK(h, len)) {
- return -1;
- break;
- }
-
- if (h->nlmsg_seq != rth->seq) {
- /* Skip this msg */
- DBG("skip %d/%d len %d", rth->seq,
- h->nlmsg_seq, h->nlmsg_len);
-
- len -= h->nlmsg_len;
- ptr += h->nlmsg_len;
- continue;
- }
-
- switch (h->nlmsg_type) {
- case NLMSG_NOOP:
- case NLMSG_OVERRUN:
- return -1;
-
- case NLMSG_ERROR:
- err = (struct nlmsgerr *)NLMSG_DATA(h);
- connman_error("RTNETLINK answers %s (%d)",
- strerror(-err->error), -err->error);
- return err->error;
- }
-
- break;
- }
-
- if (h->nlmsg_seq == rth->seq) {
- DBG("received %d seq %d", h->nlmsg_len, h->nlmsg_seq);
-
- rtnl_data->callback(h, rtnl_data->user_data);
-
- if (rtnl_data->rtnl_timeout > 0) {
- g_source_remove(rtnl_data->rtnl_timeout);
- rtnl_data->rtnl_timeout = 0;
- }
-
- __connman_inet_rtnl_close(rth);
- g_free(rth);
- }
-
- return 0;
-}
-
-static gboolean inet_rtnl_event(GIOChannel *chan, GIOCondition cond,
- gpointer user_data)
-{
- int ret;
-
- DBG("");
-
- if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
- return FALSE;
-
- ret = inet_rtnl_recv(chan, user_data);
- if (ret != 0)
- return TRUE;
-
- return FALSE;
-}
-
-int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
- struct nlmsghdr *n, int timeout,
- __connman_inet_rtnl_cb_t callback, void *user_data)
-{
- struct sockaddr_nl nladdr;
- struct inet_rtnl_cb_data *data;
- unsigned seq;
- int err;
-
- memset(&nladdr, 0, sizeof(nladdr));
- nladdr.nl_family = AF_NETLINK;
-
- n->nlmsg_seq = seq = ++rtnl->seq;
-
- if (callback != NULL) {
- data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
- if (data == NULL)
- return -ENOMEM;
-
- data->callback = callback;
- data->user_data = user_data;
- data->rtnl = rtnl;
- data->rtnl_timeout = g_timeout_add_seconds(timeout,
- inet_rtnl_timeout_cb, data);
-
- data->channel = g_io_channel_unix_new(rtnl->fd);
- g_io_channel_set_close_on_unref(data->channel, TRUE);
-
- g_io_channel_set_encoding(data->channel, NULL, NULL);
- g_io_channel_set_buffered(data->channel, FALSE);
-
- data->watch_id = g_io_add_watch(data->channel,
- G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
- inet_rtnl_event, data);
- } else
- n->nlmsg_flags |= NLM_F_ACK;
-
- err = sendto(rtnl->fd, &rtnl->req.n, rtnl->req.n.nlmsg_len, 0,
- (struct sockaddr *) &nladdr, sizeof(nladdr));
- DBG("handle %p len %d err %d", rtnl, rtnl->req.n.nlmsg_len, err);
- if (err < 0) {
- connman_error("Can not talk to rtnetlink");
- return -errno;
- }
-
- if ((unsigned int)err != rtnl->req.n.nlmsg_len) {
- connman_error("Sent %d bytes, msg truncated", err);
- return -EINVAL;
- }
-
- return 0;
-}
-
-void __connman_inet_rtnl_close(struct __connman_inet_rtnl_handle *rth)
-{
- DBG("handle %p", rth);
-
- if (rth->fd >= 0) {
- close(rth->fd);
- rth->fd = -1;
- }
-}
-
-int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen, int type,
- __u32 data)
-{
- int len = RTA_LENGTH(4);
- struct rtattr *rta;
-
- if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
- DBG("Error! max allowed bound %zd exceeded", maxlen);
- return -1;
- }
- rta = NLMSG_TAIL(n);
- rta->rta_type = type;
- rta->rta_len = len;
- memcpy(RTA_DATA(rta), &data, 4);
- n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
-
- return 0;
-}
-
-int connman_inet_check_ipaddress(const char *host)
-{
- struct addrinfo hints;
- struct addrinfo *addr;
- int result;
-
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_flags = AI_NUMERICHOST;
- addr = NULL;
-
- result = getaddrinfo(host, NULL, &hints, &addr);
- if (result == 0)
- result = addr->ai_family;
- freeaddrinfo(addr);
-
- return result;
-}
-
-/* Check routine modified from ics-dhcp 4.2.3-P2 */
-connman_bool_t connman_inet_check_hostname(const char *ptr, size_t len)
-{
- const char *p;
-
- /*
- * Not empty or complete length not over 255 characters.
- */
- if ((len == 0) || (len > 256))
- return FALSE;
-
- /*
- * Consists of [[:alnum:]-]+ labels separated by [.]
- * a [_] is against RFC but seems to be "widely used"
- */
- for (p = ptr; (*p != 0) && (len-- > 0); p++) {
-
- if ((*p == '-') || (*p == '_')) {
- /*
- * Not allowed at begin or end of a label.
- */
- if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
- return FALSE;
-
- } else if (*p == '.') {
- /*
- * Each label has to be 1-63 characters;
- * we allow [.] at the end ('foo.bar.')
- */
- size_t d = p - ptr;
-
- if ((d <= 0) || (d >= 64))
- return FALSE;
-
- ptr = p + 1; /* Jump to the next label */
-
- } else if (isalnum((unsigned char)*p) == 0) {
- /*
- * Also numbers at the begin are fine
- */
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-char **__connman_inet_get_running_interfaces(void)
-{
- char **result;
- struct ifconf ifc;
- struct ifreq *ifr = NULL;
- int sk, i, numif, count = 0;
-
- memset(&ifc, 0, sizeof(ifc));
-
- sk = socket(AF_INET, SOCK_DGRAM, 0);
- if (sk < 0)
- return NULL;
-
- if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
- goto error;
-
- /*
- * Allocate some extra bytes just in case there will
- * be new interfaces added between two SIOCGIFCONF
- * calls.
- */
- ifr = g_try_malloc0(ifc.ifc_len * 2);
- if (ifr == NULL)
- goto error;
-
- ifc.ifc_req = ifr;
-
- if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
- goto error;
-
- numif = ifc.ifc_len / sizeof(struct ifreq);
-
- result = g_try_malloc0((numif + 1) * sizeof(char *));
- if (result == NULL)
- goto error;
-
- close(sk);
-
- for (i = 0; i < numif; i++) {
- struct ifreq *r = &ifr[i];
- struct in6_addr *addr6;
- in_addr_t addr4;
-
- /*
- * Note that we do not return loopback interfaces here as they
- * are not needed for our purposes.
- */
- switch (r->ifr_addr.sa_family) {
- case AF_INET:
- addr4 = ntohl(((struct sockaddr_in *)
- &r->ifr_addr)->sin_addr.s_addr);
- if (((addr4 & 0xff000000) >> 24) == 127)
- continue;
- break;
- case AF_INET6:
- addr6 = &((struct sockaddr_in6 *)
- &r->ifr_addr)->sin6_addr;
- if (IN6_IS_ADDR_LINKLOCAL(addr6))
- continue;
- break;
- }
-
- result[count++] = g_strdup(r->ifr_name);
- }
-
- free(ifr);
-
- if (count < numif)
- result = g_try_realloc(result, (count + 1) * sizeof(char *));
-
- return result;
-
-error:
- close(sk);
- free(ifr);
- return NULL;
-}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
const struct connman_ipconfig_ops *ops;
void *ops_data;
- connman_bool_t enabled;
enum connman_ipconfig_method method;
struct connman_ipaddress *address;
struct connman_ipaddress *system;
connman_info("rp_filter restored to %d", old_value);
}
-gboolean __connman_ipconfig_ipv6_privacy_enabled(struct connman_ipconfig *ipconfig)
-{
- if (ipconfig == NULL)
- return FALSE;
-
- return ipconfig->ipv6_privacy_config == 0 ? FALSE : TRUE;
-}
-
static void free_ipdevice(gpointer data)
{
struct connman_ipdevice *ipdevice = data;
ipdevice->index);
if (ipdevice->config_ipv4 != NULL) {
- __connman_ipconfig_unref(ipdevice->config_ipv4);
+ connman_ipconfig_unref(ipdevice->config_ipv4);
ipdevice->config_ipv4 = NULL;
}
if (ipdevice->config_ipv6 != NULL) {
- __connman_ipconfig_unref(ipdevice->config_ipv6);
+ connman_ipconfig_unref(ipdevice->config_ipv6);
ipdevice->config_ipv6 = NULL;
}
{
DBG("ipconfig ipv4 %p ipv6 %p", ipdevice->config_ipv4,
ipdevice->config_ipv6);
-
- if (ipdevice->config_ipv6 != NULL &&
- ipdevice->config_ipv6->enabled == TRUE)
- return;
-
- if (__connman_device_isfiltered(ipdevice->ifname) == FALSE) {
- ipdevice->ipv6_enabled = get_ipv6_state(ipdevice->ifname);
- set_ipv6_state(ipdevice->ifname, FALSE);
- }
}
static void __connman_ipconfig_lower_down(struct connman_ipdevice *ipdevice)
return;
if (ipdevice->config_ipv4)
- service = __connman_ipconfig_get_data(ipdevice->config_ipv4);
+ service = connman_ipconfig_get_data(ipdevice->config_ipv4);
else if (ipdevice->config_ipv6)
- service = __connman_ipconfig_get_data(ipdevice->config_ipv6);
+ service = connman_ipconfig_get_data(ipdevice->config_ipv6);
else
return;
ipconfig->ops->down(ipconfig);
}
+#if defined TIZEN_EXT
+ if (g_strcmp0(ipdevice->address, address) != 0) {
+ g_free(ipdevice->address);
+ ipdevice->address = g_strdup(address);
+ }
+#endif
+
if (lower_up)
__connman_ipconfig_lower_up(ipdevice);
if (lower_down)
connman_info("%s {add} address %s/%u label %s family %d",
ipdevice->ifname, address, prefixlen, label, family);
- if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
- __connman_ippool_newaddr(index, address, prefixlen);
-
if (ipdevice->config_ipv4 != NULL && family == AF_INET)
connman_ipaddress_copy(ipdevice->config_ipv4->system,
ipaddress);
ipdevice->address_list = g_slist_remove(ipdevice->address_list,
ipaddress);
- if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
- __connman_ippool_deladdr(index, address, prefixlen);
-
connman_ipaddress_clear(ipaddress);
g_free(ipaddress);
if (scope == 0 && (g_strcmp0(dst, "0.0.0.0") == 0 ||
g_strcmp0(dst, "::") == 0)) {
+ GSList *list;
GList *config_list;
enum connman_ipconfig_type type;
} else
return;
+ for (list = ipdevice->address_list; list; list = list->next) {
+ struct connman_ipaddress *ipaddress = list->data;
+
+ g_free(ipaddress->gateway);
+ ipaddress->gateway = g_strdup(gateway);
+ }
+
for (config_list = g_list_first(ipconfig_list); config_list;
config_list = g_list_next(config_list)) {
struct connman_ipconfig *ipconfig = config_list->data;
if (ipconfig->ops == NULL)
continue;
- if (ipconfig->ops->route_set)
- ipconfig->ops->route_set(ipconfig);
+ if (ipconfig->ops->ip_bound)
+ ipconfig->ops->ip_bound(ipconfig);
}
}
if (scope == 0 && (g_strcmp0(dst, "0.0.0.0") == 0 ||
g_strcmp0(dst, "::") == 0)) {
+ GSList *list;
GList *config_list;
enum connman_ipconfig_type type;
} else
return;
+ for (list = ipdevice->address_list; list; list = list->next) {
+ struct connman_ipaddress *ipaddress = list->data;
+
+ g_free(ipaddress->gateway);
+ ipaddress->gateway = NULL;
+ }
+
for (config_list = g_list_first(ipconfig_list); config_list;
config_list = g_list_next(config_list)) {
struct connman_ipconfig *ipconfig = config_list->data;
if (ipconfig->ops == NULL)
continue;
- if (ipconfig->ops->route_unset)
- ipconfig->ops->route_unset(ipconfig);
+ if (ipconfig->ops->ip_release)
+ ipconfig->ops->ip_release(ipconfig);
}
}
return ipdevice->flags;
}
-const char *__connman_ipconfig_get_gateway_from_index(int index,
- enum connman_ipconfig_type type)
+const char *__connman_ipconfig_get_gateway_from_index(int index)
{
struct connman_ipdevice *ipdevice;
if (ipdevice == NULL)
return NULL;
- if (type != CONNMAN_IPCONFIG_TYPE_IPV6) {
- if (ipdevice->ipv4_gateway != NULL)
- return ipdevice->ipv4_gateway;
+ if (ipdevice->ipv4_gateway != NULL)
+ return ipdevice->ipv4_gateway;
- if (ipdevice->config_ipv4 != NULL &&
- ipdevice->config_ipv4->address != NULL)
- return ipdevice->config_ipv4->address->gateway;
- }
+ if (ipdevice->config_ipv4 != NULL &&
+ ipdevice->config_ipv4->address != NULL)
+ return ipdevice->config_ipv4->address->gateway;
- if (type != CONNMAN_IPCONFIG_TYPE_IPV4) {
- if (ipdevice->ipv6_gateway != NULL)
- return ipdevice->ipv6_gateway;
+ if (ipdevice->ipv6_gateway != NULL)
+ return ipdevice->ipv6_gateway;
- if (ipdevice->config_ipv6 != NULL &&
- ipdevice->config_ipv6->address != NULL)
- return ipdevice->config_ipv6->address->gateway;
- }
+ if (ipdevice->config_ipv6 != NULL &&
+ ipdevice->config_ipv6->address != NULL)
+ return ipdevice->config_ipv6->address->gateway;
return NULL;
}
ipconfig->address->gateway = g_strdup(gateway);
}
+#if defined TIZEN_EXT
+/*
+ * Description: __connman_service_lookup_from_index cannot find correct service
+ */
+int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig, struct connman_service *service)
+#else
int __connman_ipconfig_gateway_add(struct connman_ipconfig *ipconfig)
+#endif
{
+#if !defined TIZEN_EXT
struct connman_service *service;
+#endif
DBG("");
if (ipconfig->address == NULL)
return -EINVAL;
+#if !defined TIZEN_EXT
service = __connman_service_lookup_from_index(ipconfig->index);
+#endif
if (service == NULL)
return -EINVAL;
static struct connman_ipconfig *create_ipv6config(int index)
{
struct connman_ipconfig *ipv6config;
- struct connman_ipdevice *ipdevice;
DBG("index %d", index);
ipv6config->refcount = 1;
ipv6config->index = index;
- ipv6config->enabled = FALSE;
ipv6config->type = CONNMAN_IPCONFIG_TYPE_IPV6;
ipv6config->method = CONNMAN_IPCONFIG_METHOD_AUTO;
-
- ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
- if (ipdevice != NULL)
- ipv6config->ipv6_privacy_config = ipdevice->ipv6_privacy;
+ ipv6config->ipv6_privacy_config = 0;
ipv6config->address = connman_ipaddress_alloc(AF_INET6);
if (ipv6config->address == NULL) {
*
* Returns: a newly-allocated #connman_ipconfig structure
*/
-struct connman_ipconfig *__connman_ipconfig_create(int index,
+struct connman_ipconfig *connman_ipconfig_create(int index,
enum connman_ipconfig_type type)
{
struct connman_ipconfig *ipconfig;
ipconfig->refcount = 1;
ipconfig->index = index;
- ipconfig->enabled = FALSE;
ipconfig->type = CONNMAN_IPCONFIG_TYPE_IPV4;
ipconfig->address = connman_ipaddress_alloc(AF_INET);
*
* Increase reference counter of ipconfig
*/
-struct connman_ipconfig *
-__connman_ipconfig_ref_debug(struct connman_ipconfig *ipconfig,
- const char *file, int line, const char *caller)
+struct connman_ipconfig *connman_ipconfig_ref(struct connman_ipconfig *ipconfig)
{
- DBG("%p ref %d by %s:%d:%s()", ipconfig, ipconfig->refcount + 1,
- file, line, caller);
+ DBG("ipconfig %p refcount %d", ipconfig, ipconfig->refcount + 1);
__sync_fetch_and_add(&ipconfig->refcount, 1);
*
* Decrease reference counter of ipconfig
*/
-void __connman_ipconfig_unref_debug(struct connman_ipconfig *ipconfig,
- const char *file, int line, const char *caller)
+void connman_ipconfig_unref(struct connman_ipconfig *ipconfig)
{
if (ipconfig == NULL)
return;
- DBG("%p ref %d by %s:%d:%s()", ipconfig, ipconfig->refcount - 1,
- file, line, caller);
+ DBG("ipconfig %p refcount %d", ipconfig, ipconfig->refcount - 1);
if (__sync_fetch_and_sub(&ipconfig->refcount, 1) != 1)
return;
if (__connman_ipconfig_disable(ipconfig) < 0)
ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
- __connman_ipconfig_set_ops(ipconfig, NULL);
+ connman_ipconfig_set_ops(ipconfig, NULL);
- if (ipconfig->origin != NULL && ipconfig->origin != ipconfig) {
- __connman_ipconfig_unref(ipconfig->origin);
+ if (ipconfig->origin != NULL) {
+ connman_ipconfig_unref(ipconfig->origin);
ipconfig->origin = NULL;
}
*
* Get private data pointer
*/
-void *__connman_ipconfig_get_data(struct connman_ipconfig *ipconfig)
+void *connman_ipconfig_get_data(struct connman_ipconfig *ipconfig)
{
if (ipconfig == NULL)
return NULL;
*
* Set private data pointer
*/
-void __connman_ipconfig_set_data(struct connman_ipconfig *ipconfig, void *data)
+void connman_ipconfig_set_data(struct connman_ipconfig *ipconfig, void *data)
{
ipconfig->ops_data = data;
}
*
* Get interface index
*/
-int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig)
+int connman_ipconfig_get_index(struct connman_ipconfig *ipconfig)
{
if (ipconfig == NULL)
return -1;
*
* Get interface name
*/
-const char *__connman_ipconfig_get_ifname(struct connman_ipconfig *ipconfig)
+const char *connman_ipconfig_get_ifname(struct connman_ipconfig *ipconfig)
{
struct connman_ipdevice *ipdevice;
*
* Set the operation callbacks
*/
-void __connman_ipconfig_set_ops(struct connman_ipconfig *ipconfig,
+void connman_ipconfig_set_ops(struct connman_ipconfig *ipconfig,
const struct connman_ipconfig_ops *ops)
{
ipconfig->ops = ops;
*
* Set the configuration method
*/
-int __connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
+int connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
enum connman_ipconfig_method method)
{
ipconfig->method = method;
switch (ipconfig->method) {
case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
case CONNMAN_IPCONFIG_METHOD_OFF:
- break;
case CONNMAN_IPCONFIG_METHOD_AUTO:
+ break;
case CONNMAN_IPCONFIG_METHOD_FIXED:
case CONNMAN_IPCONFIG_METHOD_DHCP:
case CONNMAN_IPCONFIG_METHOD_MANUAL:
switch (ipconfig->method) {
case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
case CONNMAN_IPCONFIG_METHOD_OFF:
- break;
case CONNMAN_IPCONFIG_METHOD_AUTO:
+ break;
case CONNMAN_IPCONFIG_METHOD_FIXED:
case CONNMAN_IPCONFIG_METHOD_DHCP:
case CONNMAN_IPCONFIG_METHOD_MANUAL:
switch (ipconfig->method) {
case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
case CONNMAN_IPCONFIG_METHOD_OFF:
- break;
case CONNMAN_IPCONFIG_METHOD_AUTO:
+ break;
case CONNMAN_IPCONFIG_METHOD_FIXED:
case CONNMAN_IPCONFIG_METHOD_DHCP:
case CONNMAN_IPCONFIG_METHOD_MANUAL:
} else
return -EINVAL;
- ipconfig->enabled = TRUE;
-
if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
ipdevice->config_ipv4 != NULL) {
ipconfig_list = g_list_remove(ipconfig_list,
connman_ipaddress_clear(ipdevice->config_ipv4->system);
- __connman_ipconfig_unref(ipdevice->config_ipv4);
+ connman_ipconfig_unref(ipdevice->config_ipv4);
}
if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
connman_ipaddress_clear(ipdevice->config_ipv6->system);
- __connman_ipconfig_unref(ipdevice->config_ipv6);
+ connman_ipconfig_unref(ipdevice->config_ipv6);
}
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
- ipdevice->config_ipv4 = __connman_ipconfig_ref(ipconfig);
+ ipdevice->config_ipv4 = connman_ipconfig_ref(ipconfig);
else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
- ipdevice->config_ipv6 = __connman_ipconfig_ref(ipconfig);
+ ipdevice->config_ipv6 = connman_ipconfig_ref(ipconfig);
ipconfig_list = g_list_append(ipconfig_list, ipconfig);
if (ipdevice->config_ipv4 == NULL && ipdevice->config_ipv6 == NULL)
return -EINVAL;
- ipconfig->enabled = FALSE;
-
if (ipdevice->config_ipv4 == ipconfig) {
ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
connman_ipaddress_clear(ipdevice->config_ipv4->system);
- __connman_ipconfig_unref(ipdevice->config_ipv4);
+ connman_ipconfig_unref(ipdevice->config_ipv4);
ipdevice->config_ipv4 = NULL;
return 0;
}
disable_ipv6(ipdevice->config_ipv6);
connman_ipaddress_clear(ipdevice->config_ipv6->system);
- __connman_ipconfig_unref(ipdevice->config_ipv6);
+ connman_ipconfig_unref(ipdevice->config_ipv6);
ipdevice->config_ipv6 = NULL;
return 0;
}
void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
DBusMessageIter *iter)
{
- struct connman_ipaddress *append_addr = NULL;
const char *str;
DBG("");
connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
- append_addr = ipconfig->system;
-
- switch (ipconfig->method) {
- case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
- case CONNMAN_IPCONFIG_METHOD_OFF:
+ if (ipconfig->system == NULL)
return;
- case CONNMAN_IPCONFIG_METHOD_FIXED:
- if (append_addr == NULL)
- append_addr = ipconfig->address;
- break;
-
- case CONNMAN_IPCONFIG_METHOD_MANUAL:
- case CONNMAN_IPCONFIG_METHOD_DHCP:
- case CONNMAN_IPCONFIG_METHOD_AUTO:
- break;
- }
-
- if (append_addr == NULL)
- return;
-
- if (append_addr->local != NULL) {
+ if (ipconfig->system->local != NULL) {
in_addr_t addr;
struct in_addr netmask;
char *mask;
connman_dbus_dict_append_basic(iter, "Address",
- DBUS_TYPE_STRING, &append_addr->local);
+ DBUS_TYPE_STRING, &ipconfig->system->local);
- addr = 0xffffffff << (32 - append_addr->prefixlen);
+ addr = 0xffffffff << (32 - ipconfig->system->prefixlen);
netmask.s_addr = htonl(addr);
mask = inet_ntoa(netmask);
connman_dbus_dict_append_basic(iter, "Netmask",
DBUS_TYPE_STRING, &mask);
}
- if (append_addr->gateway != NULL)
+ if (ipconfig->system->gateway != NULL)
connman_dbus_dict_append_basic(iter, "Gateway",
- DBUS_TYPE_STRING, &append_addr->gateway);
+ DBUS_TYPE_STRING, &ipconfig->system->gateway);
}
void __connman_ipconfig_append_ipv6(struct connman_ipconfig *ipconfig,
DBusMessageIter *iter,
struct connman_ipconfig *ipconfig_ipv4)
{
- struct connman_ipaddress *append_addr = NULL;
const char *str, *privacy;
DBG("");
connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
- append_addr = ipconfig->system;
-
- switch (ipconfig->method) {
- case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
- case CONNMAN_IPCONFIG_METHOD_OFF:
+ if (ipconfig->system == NULL)
return;
- case CONNMAN_IPCONFIG_METHOD_FIXED:
- if (append_addr == NULL)
- append_addr = ipconfig->address;
- break;
-
- case CONNMAN_IPCONFIG_METHOD_MANUAL:
- case CONNMAN_IPCONFIG_METHOD_DHCP:
- case CONNMAN_IPCONFIG_METHOD_AUTO:
- break;
- }
-
- if (append_addr == NULL)
- return;
-
- if (append_addr->local != NULL) {
+ if (ipconfig->system->local != NULL) {
connman_dbus_dict_append_basic(iter, "Address",
- DBUS_TYPE_STRING, &append_addr->local);
+ DBUS_TYPE_STRING, &ipconfig->system->local);
connman_dbus_dict_append_basic(iter, "PrefixLength",
DBUS_TYPE_BYTE,
- &append_addr->prefixlen);
+ &ipconfig->system->prefixlen);
}
- if (append_addr->gateway != NULL)
+ if (ipconfig->system->gateway != NULL)
connman_dbus_dict_append_basic(iter, "Gateway",
- DBUS_TYPE_STRING, &append_addr->gateway);
+ DBUS_TYPE_STRING, &ipconfig->system->gateway);
privacy = privacy2string(ipconfig->ipv6_privacy_config);
connman_dbus_dict_append_basic(iter, "Privacy",
dbus_message_iter_recurse(array, &dict);
while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
- DBusMessageIter entry, value;
+ DBusMessageIter entry;
const char *key;
int type;
dbus_message_iter_get_basic(&entry, &key);
dbus_message_iter_next(&entry);
- if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
- return -EINVAL;
-
- dbus_message_iter_recurse(&entry, &value);
-
- type = dbus_message_iter_get_arg_type(&value);
+ type = dbus_message_iter_get_arg_type(&entry);
if (g_str_equal(key, "Method") == TRUE) {
const char *str;
if (type != DBUS_TYPE_STRING)
return -EINVAL;
- dbus_message_iter_get_basic(&value, &str);
+ dbus_message_iter_get_basic(&entry, &str);
method = __connman_ipconfig_string2method(str);
} else if (g_str_equal(key, "Address") == TRUE) {
if (type != DBUS_TYPE_STRING)
return -EINVAL;
- dbus_message_iter_get_basic(&value, &address);
+ dbus_message_iter_get_basic(&entry, &address);
} else if (g_str_equal(key, "PrefixLength") == TRUE) {
if (type != DBUS_TYPE_STRING)
return -EINVAL;
- dbus_message_iter_get_basic(&value,
+ dbus_message_iter_get_basic(&entry,
&prefix_length_string);
prefix_length = atoi(prefix_length_string);
if (prefix_length < 0 || prefix_length > 128)
return -EINVAL;
+
} else if (g_str_equal(key, "Netmask") == TRUE) {
if (type != DBUS_TYPE_STRING)
return -EINVAL;
- dbus_message_iter_get_basic(&value, &netmask);
+ dbus_message_iter_get_basic(&entry, &netmask);
} else if (g_str_equal(key, "Gateway") == TRUE) {
if (type != DBUS_TYPE_STRING)
return -EINVAL;
- dbus_message_iter_get_basic(&value, &gateway);
+ dbus_message_iter_get_basic(&entry, &gateway);
} else if (g_str_equal(key, "Privacy") == TRUE) {
if (type != DBUS_TYPE_STRING)
return -EINVAL;
- dbus_message_iter_get_basic(&value, &privacy_string);
+ dbus_message_iter_get_basic(&entry, &privacy_string);
privacy = string2privacy(privacy_string);
}
-
dbus_message_iter_next(&dict);
}
key = g_strdup_printf("%smethod", prefix);
method = g_key_file_get_string(keyfile, identifier, key, NULL);
if (method == NULL) {
- switch (ipconfig->type) {
- case CONNMAN_IPCONFIG_TYPE_IPV4:
+ if (ipconfig->type == CONNMAN_IPCONFIG_TYPE_IPV4)
ipconfig->method = CONNMAN_IPCONFIG_METHOD_DHCP;
- break;
- case CONNMAN_IPCONFIG_TYPE_IPV6:
- ipconfig->method = CONNMAN_IPCONFIG_METHOD_AUTO;
- break;
- case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
+ else
ipconfig->method = CONNMAN_IPCONFIG_METHOD_OFF;
- break;
- }
} else
ipconfig->method = __connman_ipconfig_string2method(method);
ipconfig->ipv6_privacy_config = string2privacy(privacy);
g_free(pprefix);
g_free(privacy);
+
+ __connman_ipconfig_enable(ipconfig);
+ enable_ipv6(ipconfig);
}
}
}
key = g_strdup_printf("%snetmask_prefixlen", prefix);
- if (ipconfig->address->prefixlen != 0)
- g_key_file_set_integer(keyfile, identifier,
- key, ipconfig->address->prefixlen);
+ g_key_file_set_integer(keyfile, identifier,
+ key, ipconfig->address->prefixlen);
g_free(key);
key = g_strdup_printf("%slocal_address", prefix);
+++ /dev/null
-/*
- *
- * Connection Manager
- *
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
- * Copyright (C) 2012 BMW Car IT GmbH. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <getopt.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/errno.h>
-#include <sys/socket.h>
-
-#include "connman.h"
-
-struct address_info {
- int index;
- uint32_t start;
- uint32_t end;
-
- unsigned int use_count;
- struct connman_ippool *pool;
-};
-
-struct connman_ippool {
- unsigned int refcount;
-
- struct address_info *info;
-
- char *gateway;
- char *broadcast;
- char *start_ip;
- char *end_ip;
- char *subnet_mask;
-
- ippool_collision_cb_t collision_cb;
- void *user_data;
-};
-
-GSList *allocated_blocks;
-GHashTable *pool_hash;
-
-static uint32_t last_block;
-static uint32_t block_16_bits;
-static uint32_t block_20_bits;
-static uint32_t block_24_bits;
-static uint32_t subnet_mask_24;
-
-struct connman_ippool *
-__connman_ippool_ref_debug(struct connman_ippool *pool,
- const char *file, int line, const char *caller)
-{
- DBG("%p ref %d by %s:%d:%s()", pool, pool->refcount + 1,
- file, line, caller);
-
- __sync_fetch_and_add(&pool->refcount, 1);
-
- return pool;
-}
-
-void __connman_ippool_unref_debug(struct connman_ippool *pool,
- const char *file, int line, const char *caller)
-{
- if (pool == NULL)
- return;
-
- DBG("%p ref %d by %s:%d:%s()", pool, pool->refcount - 1,
- file, line, caller);
-
- if (__sync_fetch_and_sub(&pool->refcount, 1) != 1)
- return;
-
- g_hash_table_remove(pool_hash, pool);
-}
-
-static char *get_ip(uint32_t ip)
-{
- struct in_addr addr;
-
- addr.s_addr = htonl(ip);
-
- return g_strdup(inet_ntoa(addr));
-}
-
-static uint32_t next_block(uint32_t block)
-{
- uint32_t next;
-
- /*
- * Return the next IP block within the private IP range
- *
- * 16-bit block 192.168.0.0 – 192.168.255.255
- * 20-bit block 172.16.0.0 – 172.31.255.255
- * 24-bit block 10.0.0.0 – 10.255.255.255
- */
-
- next = (block & 0x0000ff00) >> 8;
- next += 1;
-
- if (next == 255) {
- if ((block & 0xffff0000) == block_16_bits) {
- /*
- * Reached the end of the 16 bit block, switch
- * to the 20-bit block.
- */
- return block_20_bits;
- }
-
- if ((block & 0xffff0000) >= block_20_bits) {
- next = (block & 0x00ff0000) >> 16;
- if (next >= 16 && next < 32)
- next += 1;
-
- if (next == 32) {
- /*
- * Reached the end of the 20 bit
- * block, switch to the 24-bit block.
- */
- return block_24_bits;
- }
-
- return (block & 0xff000000) |
- ((next << 16) & 0x00ff0000);
- }
-
- if ((block & 0xff000000) == block_24_bits) {
- next = (block & 0x00ff0000) >> 16;
- if (next < 255)
- next += 1;
-
- if (next == 255) {
- /*
- * Reached the end of the 24 bit
- * block, switch to the 16-bit block.
- */
- return block_16_bits;
- }
-
- return (block & 0xff000000) |
- ((next << 16) & 0x00ff0000);
- }
- }
-
- return (block & 0xffff0000) | ((next << 8) & 0x0000ff00);
-}
-
-static uint32_t get_free_block(unsigned int size)
-{
- struct address_info *info;
- uint32_t block;
- GSList *list;
- connman_bool_t collision;
-
- /*
- * Instead starting always from the 16 bit block, we start
- * from the last assigned block. This is a simple optimimazion
- * for the case where a lot of blocks have been assigned, e.g.
- * the first half of the private IP pool is in use and a new
- * we need to find a new block.
- *
- * To only thing we have to make sure is that we terminated if
- * there is no block left.
- */
- if (last_block == 0)
- block = block_16_bits;
- else
- block = next_block(last_block);
-
- do {
- collision = FALSE;
- for (list = allocated_blocks; list != NULL; list = list->next) {
- info = list->data;
-
- if (info->start <= block && block <= info->end) {
- collision = TRUE;
- break;
- }
- }
-
- if (collision == FALSE)
- return block;
-
- block = next_block(block);
- } while (block != last_block);
-
- return 0;
-}
-
-static struct address_info *lookup_info(int index, uint32_t start)
-{
- GSList *list;
-
- for (list = allocated_blocks; list != NULL; list = list->next) {
- struct address_info *info = list->data;
-
- if (info->index == index && info->start == start)
- return info;
- }
-
- return NULL;
-}
-
-static connman_bool_t is_private_address(uint32_t address)
-{
- uint32_t val;
-
- if ((address & 0xff000000) == block_24_bits)
- return TRUE;
-
- if ((address & 0xffff0000) == block_20_bits) {
- val = (address & 0x00ff0000) >> 16;
-
- if (val < 16 || val > 31)
- return FALSE;
-
- return TRUE;
- }
-
- if ((address & 0xffffff00) == block_16_bits)
- return TRUE;
-
- return FALSE;
-}
-
-void __connman_ippool_newaddr(int index, const char *address,
- unsigned char prefixlen)
-{
- struct address_info *info, *it;
- struct in_addr inp;
- uint32_t start, end, mask;
- GSList *list;
-
- if (inet_aton(address, &inp) == 0)
- return;
-
- start = ntohl(inp.s_addr);
- if (is_private_address(start) == FALSE)
- return;
-
- if (prefixlen >= 32)
- mask = 0xffffffff;
- else
- mask = ~(0xffffffff >> prefixlen);
-
- start = start & mask;
- end = start | ~mask;
-
- info = lookup_info(index, start);
- if (info != NULL)
- goto update;
-
- info = g_try_new0(struct address_info, 1);
- if (info == NULL)
- return;
-
- info->index = index;
- info->start = start;
- info->end = end;
-
- allocated_blocks = g_slist_prepend(allocated_blocks, info);
-
-update:
- info->use_count = info->use_count + 1;
-
- if (info->use_count > 1 || info->pool != NULL) {
- /*
- * We need only to check for the first IP in a block for
- * collisions.
- */
- return;
- }
-
- for (list = allocated_blocks; list != NULL; list = list->next) {
- it = list->data;
-
- if (it == info)
- continue;
-
- if (!(it->start <= info->start || info->start <= it->end))
- continue;
-
- if (it->pool != NULL && it->pool->collision_cb != NULL)
- it->pool->collision_cb(it->pool, it->pool->user_data);
-
- return;
- }
-}
-
-void __connman_ippool_deladdr(int index, const char *address,
- unsigned char prefixlen)
-{
- struct address_info *info;
- struct in_addr inp;
- uint32_t start, mask;
-
- if (inet_aton(address, &inp) == 0)
- return;
-
- start = ntohl(inp.s_addr);
- if (is_private_address(start) == FALSE)
- return;
-
- mask = ~(0xffffffff >> prefixlen);
- start = start & mask;
-
- info = lookup_info(index, start);
- if (info == NULL) {
- /* In theory this should never happen */
- connman_error("Inconsistent IP pool management (start not found)");
- return;
- }
-
- info->use_count = info->use_count - 1;
- if (info->pool != NULL)
- return;
-
- if (info->use_count > 0)
- return;
-
- allocated_blocks = g_slist_remove(allocated_blocks, info);
-}
-
-struct connman_ippool *__connman_ippool_create(int index,
- unsigned int start,
- unsigned int range,
- ippool_collision_cb_t collision_cb,
- void *user_data)
-{
- struct connman_ippool *pool;
- struct address_info *info;
- uint32_t block;
-
- DBG("");
-
- /*
- * The range is at max 255 and we don't support overlapping
- * blocks.
- */
- if (start + range > 254) {
- connman_error("IP pool does not support pool size larger than 254");
- return NULL;
- }
-
- block = get_free_block(start + range);
- if (block == 0) {
- connman_warn("Could not find a free IP block");
- return NULL;
- }
-
- pool = g_try_new0(struct connman_ippool, 1);
- if (pool == NULL)
- return NULL;
-
- info = g_try_new0(struct address_info, 1);
- if (info == NULL) {
- g_free(pool);
- return NULL;
- }
-
- last_block = block;
-
- info->index = index;
- info->start = block;
- info->end = block + range;
-
- pool->refcount = 1;
- pool->info = info;
- pool->collision_cb = collision_cb;
- pool->user_data = user_data;
-
- info->pool = pool;
-
- if (range == 0)
- range = 1;
-
- pool->gateway = get_ip(info->start + 1);
- pool->broadcast = get_ip(info->start + 255);
- pool->subnet_mask = get_ip(subnet_mask_24);
- pool->start_ip = get_ip(block + start);
- pool->end_ip = get_ip(block + start + range);
-
- allocated_blocks = g_slist_prepend(allocated_blocks, info);
- g_hash_table_insert(pool_hash, pool, pool);
-
- return pool;
-}
-
-const char *__connman_ippool_get_gateway(struct connman_ippool *pool)
-{
- return pool->gateway;
-}
-
-const char *__connman_ippool_get_broadcast(struct connman_ippool *pool)
-{
- return pool->broadcast;
-}
-
-const char *__connman_ippool_get_start_ip(struct connman_ippool *pool)
-{
- return pool->start_ip;
-}
-
-const char *__connman_ippool_get_end_ip(struct connman_ippool *pool)
-{
- return pool->end_ip;
-}
-
-const char *__connman_ippool_get_subnet_mask(struct connman_ippool *pool)
-{
- return pool->subnet_mask;
-}
-
-static void pool_free(gpointer data)
-{
- struct connman_ippool *pool = data;
-
- if (pool->info != NULL) {
- allocated_blocks = g_slist_remove(allocated_blocks, pool->info);
- g_free(pool->info);
- }
-
- g_free(pool->gateway);
- g_free(pool->broadcast);
- g_free(pool->start_ip);
- g_free(pool->end_ip);
- g_free(pool->subnet_mask);
-
- g_free(pool);
-}
-
-int __connman_ippool_init(void)
-{
- DBG("");
-
- block_16_bits = ntohl(inet_addr("192.168.0.0"));
- block_20_bits = ntohl(inet_addr("172.16.0.0"));
- block_24_bits = ntohl(inet_addr("10.0.0.0"));
- subnet_mask_24 = ntohl(inet_addr("255.255.255.0"));
-
- pool_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
- pool_free);
-
- return 0;
-}
-
-void __connman_ippool_cleanup(void)
-{
- DBG("");
-
- g_hash_table_destroy(pool_hash);
- pool_hash = NULL;
-
- g_slist_free(allocated_blocks);
- last_block = 0;
-}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2011 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
if (new_entry == NULL)
return -EINVAL;
- if (builtin == -1)
- chain_head = chain_head->next;
-
- ret = iptables_add_entry(table, new_entry, chain_head, builtin);
+ ret = iptables_add_entry(table, new_entry, chain_head->next, builtin);
if (ret < 0)
g_free(new_entry);
return TRUE;
}
-static GList *find_existing_rule(struct connman_iptables *table,
+static int iptables_delete_rule(struct connman_iptables *table,
struct ipt_ip *ip, char *chain_name,
char *target_name, struct xtables_target *xt_t,
struct xtables_match *xt_m,
struct xt_entry_match *xt_e_m = NULL;
struct connman_iptables_entry *entry;
struct ipt_entry *entry_test;
- int builtin;
+ int builtin, removed;
+
+ removed = 0;
chain_head = find_chain_head(table, chain_name);
if (chain_head == NULL)
- return NULL;
+ return -EINVAL;
chain_tail = find_chain_tail(table, chain_name);
if (chain_tail == NULL)
- return NULL;
+ return -EINVAL;
if (!xt_t && !xt_m)
- return NULL;
+ return -EINVAL;
entry_test = new_rule(ip, target_name, xt_t, xt_rm);
if (entry_test == NULL)
- return NULL;
+ return -EINVAL;
if (xt_t != NULL)
xt_e_t = ipt_get_target(entry_test);
else
list = chain_head->next;
- for (; list != chain_tail->prev; list = list->next) {
+ for (entry = NULL; list != chain_tail->prev; list = list->next) {
struct connman_iptables_entry *tmp;
struct ipt_entry *tmp_e;
continue;
}
+ entry = tmp;
break;
}
- g_free(entry_test);
-
- if (list != chain_tail->prev)
- return list;
-
- return NULL;
-}
-
-static int iptables_delete_rule(struct connman_iptables *table,
- struct ipt_ip *ip, char *chain_name,
- char *target_name, struct xtables_target *xt_t,
- struct xtables_match *xt_m,
- struct xtables_rule_match *xt_rm)
-{
- struct connman_iptables_entry *entry;
- GList *chain_tail, *list;
- int builtin, removed;
-
- removed = 0;
-
- chain_tail = find_chain_tail(table, chain_name);
- if (chain_tail == NULL)
- return -EINVAL;
-
- list = find_existing_rule(table, ip, chain_name, target_name,
- xt_t, xt_m, xt_rm);
- if (list == NULL)
- return -EINVAL;
-
- entry = list->data;
- if (entry == NULL)
+ if (entry == NULL) {
+ g_free(entry_test);
return -EINVAL;
-
- builtin = entry->builtin;
+ }
/* We have deleted a rule,
* all references should be bumped accordingly */
return 0;
}
-static int iptables_compare_rule(struct connman_iptables *table,
- struct ipt_ip *ip, char *chain_name,
- char *target_name, struct xtables_target *xt_t,
- struct xtables_match *xt_m,
- struct xtables_rule_match *xt_rm)
-{
- struct connman_iptables_entry *entry;
- GList *found;
-
- found = find_existing_rule(table, ip, chain_name, target_name,
- xt_t, xt_m, xt_rm);
- if (found == NULL)
- return -EINVAL;
-
- entry = found->data;
- if (entry == NULL)
- return -EINVAL;
-
- return 0;
-}
-
-
static int iptables_change_policy(struct connman_iptables *table,
char *chain_name, char *policy)
{
GList *list;
struct connman_iptables_entry *entry;
- if (table == NULL)
- return;
-
close(table->ipt_sock);
for (list = table->entries; list; list = list->next) {
DBG("%s", table_name);
if (xtables_insmod("ip_tables", NULL, TRUE) != 0)
- return NULL;
+ goto err;
module = g_strconcat("iptable_", table_name, NULL);
if (module == NULL)
- return NULL;
+ goto err;
- if (xtables_insmod(module, NULL, TRUE) != 0) {
- g_free(module);
- return NULL;
- }
+ if (xtables_insmod(module, NULL, TRUE) != 0)
+ goto err;
g_free(module);
+ module = NULL;
table = g_hash_table_lookup(table_hash, table_name);
if (table != NULL)
return table;
err:
+ g_free(module);
+
table_cleanup(table);
return NULL;
static struct option iptables_opts[] = {
{.name = "append", .has_arg = 1, .val = 'A'},
- {.name = "compare", .has_arg = 1, .val = 'C'},
{.name = "delete", .has_arg = 1, .val = 'D'},
{.name = "flush-chain", .has_arg = 1, .val = 'F'},
{.name = "insert", .has_arg = 1, .val = 'I'},
return xt_m;
}
-static int parse_ip_and_mask(const char *str, struct in_addr *ip, struct in_addr *mask)
-{
- char **tokens;
- uint32_t prefixlength;
- uint32_t tmp;
- int err;
-
- tokens = g_strsplit(str, "/", 2);
- if (tokens == NULL)
- return -1;
-
- if (!inet_pton(AF_INET, tokens[0], ip)) {
- err = -1;
- goto out;
- }
-
- if (tokens[1] != NULL) {
- prefixlength = strtol(tokens[1], NULL, 10);
- if (prefixlength > 31) {
- err = -1;
- goto out;
- }
-
- tmp = ~(0xffffffff >> prefixlength);
- } else {
- tmp = 0xffffffff;
- }
-
- mask->s_addr = htonl(tmp);
- ip->s_addr = ip->s_addr & mask->s_addr;
- err = 0;
-out:
- g_strfreev(tokens);
-
- return err;
-}
-
static int iptables_command(int argc, char *argv[])
{
struct connman_iptables *table;
char *table_name, *chain, *new_chain, *match_name, *target_name;
char *flush_chain, *delete_chain, *policy;
int c, ret, in_len, out_len;
- gboolean dump, invert, insert, delete, compare;
+ gboolean dump, invert, insert, delete;
+ struct in_addr src, dst;
if (argc == 0)
return -EINVAL;
invert = FALSE;
insert = FALSE;
delete = FALSE;
- compare = FALSE;
- chain = new_chain = match_name = target_name = NULL;
+ table_name = chain = new_chain = match_name = target_name = NULL;
flush_chain = delete_chain = policy = NULL;
memset(&ip, 0, sizeof(struct ipt_ip));
table = NULL;
optind = 0;
- while ((c = getopt_long(argc, argv,
- "-A:C:D:F:I:L::N:P:X:d:j:i:m:o:s:t:",
+ while ((c = getopt_long(argc, argv, "-A:F:I:L::N:P:X:d:j:i:m:o:s:t:",
iptables_globals.opts, NULL)) != -1) {
switch (c) {
case 'A':
- /* It is either -A, -C, -D or -I at once */
+ /* It is either -A, -D or -I at once */
if (chain)
goto out;
chain = optarg;
break;
- case 'C':
- /* It is either -A, -C, -D or -I at once */
- if (chain)
- goto out;
-
- chain = optarg;
- compare = TRUE;
- break;
-
case 'D':
- /* It is either -A, -C, -D or -I at once */
+ /* It is either -A, -D or -I at once */
if (chain)
goto out;
break;
case 'I':
- /* It is either -A, -C, -D or -I at once */
+ /* It is either -A, -D or -I at once */
if (chain)
goto out;
break;
case 'd':
- if (!parse_ip_and_mask(optarg, &ip.dst, &ip.dmsk))
+ if (!inet_pton(AF_INET, optarg, &dst))
break;
+ ip.dst = dst;
+ inet_pton(AF_INET, "255.255.255.255", &ip.dmsk);
+
if (invert)
ip.invflags |= IPT_INV_DSTIP;
break;
case 's':
- if (!parse_ip_and_mask(optarg, &ip.src, &ip.smsk))
+ if (!inet_pton(AF_INET, optarg, &src))
break;
+ ip.src = src;
+ inet_pton(AF_INET, "255.255.255.255", &ip.smsk);
+
if (invert)
ip.invflags |= IPT_INV_SRCIP;
if (xt_t == NULL)
goto out;
- if (compare == TRUE) {
- ret = iptables_compare_rule(table, &ip, chain,
- target_name, xt_t, xt_m, xt_rm);
- goto out;
- }
-
if (delete == TRUE) {
DBG("Deleting %s to %s (match %s)\n",
target_name, chain, match_name);
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
static const char *program_exec;
static const char *program_path;
+#if defined TIZEN_EXT
+#include <sys/stat.h>
+
+#define LOG_FILE_PATH "/var/log/connman.log"
+#define MAX_LOG_SIZE 2 * 1024 * 1024
+#define MAX_LOG_COUNT 9
+
+#define openlog __connman_log_open
+#define closelog __connman_log_close
+#define vsyslog __connman_log
+#define syslog __connman_log_s
+
+static FILE *log_file = NULL;
+
+void __connman_log_open(const char *ident, int option, int facility)
+{
+ if (log_file == NULL)
+ log_file = (FILE *)fopen(LOG_FILE_PATH, "a+");
+}
+
+void __connman_log_close(void)
+{
+ fclose(log_file);
+ log_file = NULL;
+}
+
+static void __connman_log_update_file_revision(int rev)
+{
+ int next_log_rev = 0;
+ char *log_file = NULL;
+ char *next_log_file = NULL;
+
+ next_log_rev = rev + 1;
+
+ log_file = g_strdup_printf("%s.%d", LOG_FILE_PATH, rev);
+ next_log_file = g_strdup_printf("%s.%d", LOG_FILE_PATH, next_log_rev);
+
+ if (next_log_rev >= MAX_LOG_COUNT)
+ remove(next_log_file);
+
+ if (access(next_log_file, F_OK) == 0)
+ __connman_log_update_file_revision(next_log_rev);
+
+ if (rename(log_file, next_log_file) != 0)
+ remove(log_file);
+
+ g_free(log_file);
+ g_free(next_log_file);
+}
+
+static void __connman_log_make_backup(void)
+{
+ const int rev = 0;
+ char *backup = NULL;
+
+ backup = g_strdup_printf("%s.%d", LOG_FILE_PATH, rev);
+
+ if (access(backup, F_OK) == 0)
+ __connman_log_update_file_revision(rev);
+
+ if (rename(LOG_FILE_PATH, backup) != 0)
+ remove(LOG_FILE_PATH);
+
+ g_free(backup);
+}
+
+static void __connman_log_get_local_time(char *strtime, const int size)
+{
+ time_t buf;
+ struct tm *local_ptm;
+
+ time(&buf);
+ buf = time(NULL);
+ local_ptm = localtime(&buf);
+
+ strftime(strtime, size, "%D %H:%M:%S", local_ptm);
+}
+
+void __connman_log(const int log_priority, const char *format, va_list ap)
+{
+ int log_size = 0;
+ struct stat buf;
+ char str[256];
+ char strtime[40];
+
+ if (log_file == NULL)
+ log_file = (FILE *)fopen(LOG_FILE_PATH, "a+");
+
+ if (log_file == NULL)
+ return;
+
+ fstat(fileno(log_file), &buf);
+ log_size = buf.st_size;
+
+ if (log_size >= MAX_LOG_SIZE) {
+ fclose(log_file);
+ log_file = NULL;
+
+ __connman_log_make_backup();
+
+ log_file = (FILE *)fopen(LOG_FILE_PATH, "a+");
+
+ if (log_file == NULL)
+ return;
+ }
+
+ __connman_log_get_local_time(strtime, sizeof(strtime));
+
+ if (vsnprintf(str, sizeof(str), format, ap) > 0)
+ fprintf(log_file, "%s %s\n", strtime, str);
+}
+
+void __connman_log_s(int log_priority, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+
+ vsyslog(LOG_DEBUG, format, ap);
+
+ va_end(ap);
+}
+#endif
+
/**
* connman_info:
* @format: format string
va_end(ap);
}
+#if !defined TIZEN_EXT
static void print_backtrace(unsigned int offset)
{
void *frames[99];
sigaction(SIGABRT, &sa, NULL);
sigaction(SIGPIPE, &sa, NULL);
}
+#endif
extern struct connman_debug_desc __start___debug[];
extern struct connman_debug_desc __stop___debug[];
+void __connman_debug_list_available(DBusMessageIter *iter, void *user_data)
+{
+ struct connman_debug_desc *desc;
+
+ for (desc = __start___debug; desc < __stop___debug; desc++) {
+ if ((desc->flags & CONNMAN_DEBUG_FLAG_ALIAS) &&
+ desc->name != NULL)
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &desc->name);
+ }
+}
+
static gchar **enabled = NULL;
+void __connman_debug_list_enabled(DBusMessageIter *iter, void *user_data)
+{
+ int i;
+
+ if (enabled == NULL)
+ return;
+
+ for (i = 0; enabled[i] != NULL; i++)
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &enabled[i]);
+}
+
static connman_bool_t is_enabled(struct connman_debug_desc *desc)
{
int i;
if (detach == FALSE)
option |= LOG_PERROR;
+#if !defined TIZEN_EXT
signal_setup(signal_handler);
+#endif
openlog(basename(program), option, LOG_DAEMON);
closelog();
+#if !defined TIZEN_EXT
signal_setup(SIG_DFL);
+#endif
g_strfreev(enabled);
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#if !defined TIZEN_EXT
#include <signal.h>
#include <sys/signalfd.h>
+#endif
#include <getopt.h>
#include <sys/stat.h>
#include <net/if.h>
-#include <netdb.h>
#include <gdbus.h>
-#include "connman.h"
-
-#define DEFAULT_INPUT_REQUEST_TIMEOUT 120 * 1000
-#define DEFAULT_BROWSER_LAUNCH_TIMEOUT 300 * 1000
-
-static char *default_auto_connect[] = {
- "wifi",
- "ethernet",
- "cellular",
- NULL
-};
+#ifdef HAVE_CAPNG
+#include <cap-ng.h>
+#endif
-static char *default_blacklist[] = {
- "vmnet",
- "vboxnet",
- "virbr",
- NULL
-};
+#include "connman.h"
static struct {
connman_bool_t bg_scan;
- char **pref_timeservers;
- unsigned int *auto_connect;
- unsigned int *preferred_techs;
- char **fallback_nameservers;
- unsigned int timeout_inputreq;
- unsigned int timeout_browserlaunch;
- char **blacklisted_interfaces;
+ connman_bool_t single_connection;
} connman_settings = {
.bg_scan = TRUE,
- .pref_timeservers = NULL,
- .auto_connect = NULL,
- .preferred_techs = NULL,
- .fallback_nameservers = NULL,
- .timeout_inputreq = DEFAULT_INPUT_REQUEST_TIMEOUT,
- .timeout_browserlaunch = DEFAULT_BROWSER_LAUNCH_TIMEOUT,
- .blacklisted_interfaces = NULL,
+ .single_connection = FALSE,
};
static GKeyFile *load_config(const char *file)
return keyfile;
}
-static uint *parse_service_types(char **str_list, gsize len)
-{
- unsigned int *type_list;
- int i, j;
- enum connman_service_type type;
-
- type_list = g_try_new0(unsigned int, len + 1);
- if (type_list == NULL)
- return NULL;
-
- i = 0;
- j = 0;
- while (str_list[i] != NULL)
- {
- type = __connman_service_string2type(str_list[i]);
-
- if (type != CONNMAN_SERVICE_TYPE_UNKNOWN) {
- type_list[j] = type;
- j += 1;
- }
- i += 1;
- }
-
- return type_list;
-}
-
-static char **parse_fallback_nameservers(char **nameservers, gsize len)
-{
- char **servers;
- int i, j;
-
- servers = g_try_new0(char *, len + 1);
- if (servers == NULL)
- return NULL;
-
- i = 0;
- j = 0;
- while (nameservers[i] != NULL) {
- if (connman_inet_check_ipaddress(nameservers[i]) > 0) {
- servers[j] = g_strdup(nameservers[i]);
- j += 1;
- }
- i += 1;
- }
-
- return servers;
-}
-
static void parse_config(GKeyFile *config)
{
GError *error = NULL;
gboolean boolean;
- char **timeservers;
- char **interfaces;
- char **str_list;
- gsize len;
- int timeout;
-
- if (config == NULL) {
- connman_settings.auto_connect =
- parse_service_types(default_auto_connect, 3);
- connman_settings.blacklisted_interfaces =
- g_strdupv(default_blacklist);
+
+ if (config == NULL)
return;
- }
DBG("parsing main.conf");
g_clear_error(&error);
- timeservers = g_key_file_get_string_list(config, "General",
- "FallbackTimeservers", NULL, &error);
- if (error == NULL)
- connman_settings.pref_timeservers = timeservers;
-
- g_clear_error(&error);
-
- str_list = g_key_file_get_string_list(config, "General",
- "DefaultAutoConnectTechnologies", &len, &error);
-
- if (error == NULL)
- connman_settings.auto_connect =
- parse_service_types(str_list, len);
- else
- connman_settings.auto_connect =
- parse_service_types(default_auto_connect, 3);
-
- g_strfreev(str_list);
-
- g_clear_error(&error);
-
- str_list = g_key_file_get_string_list(config, "General",
- "PreferredTechnologies", &len, &error);
-
- if (error == NULL)
- connman_settings.preferred_techs =
- parse_service_types(str_list, len);
-
- g_strfreev(str_list);
-
- g_clear_error(&error);
-
- str_list = g_key_file_get_string_list(config, "General",
- "FallbackNameservers", &len, &error);
-
- if (error == NULL)
- connman_settings.fallback_nameservers =
- parse_fallback_nameservers(str_list, len);
-
- g_strfreev(str_list);
-
- g_clear_error(&error);
-
- timeout = g_key_file_get_integer(config, "General",
- "InputRequestTimeout", &error);
- if (error == NULL && timeout >= 0)
- connman_settings.timeout_inputreq = timeout * 1000;
-
- g_clear_error(&error);
-
- timeout = g_key_file_get_integer(config, "General",
- "BrowserLaunchTimeout", &error);
- if (error == NULL && timeout >= 0)
- connman_settings.timeout_browserlaunch = timeout * 1000;
-
- g_clear_error(&error);
-
- interfaces = g_key_file_get_string_list(config, "General",
- "NetworkInterfaceBlacklist", &len, &error);
-
+ boolean = g_key_file_get_boolean(config, "General",
+ "SingleConnection", &error);
if (error == NULL)
- connman_settings.blacklisted_interfaces = interfaces;
- else
- connman_settings.blacklisted_interfaces =
- g_strdupv(default_blacklist);
+ connman_settings.single_connection = boolean;
g_clear_error(&error);
}
static GMainLoop *main_loop = NULL;
+#if !defined TIZEN_EXT
static unsigned int __terminated = 0;
static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
return source;
}
+#endif
static void disconnect_callback(DBusConnection *conn, void *user_data)
{
if (g_str_equal(key, "BackgroundScanning") == TRUE)
return connman_settings.bg_scan;
- return FALSE;
-}
-
-char **connman_setting_get_string_list(const char *key)
-{
- if (g_str_equal(key, "FallbackTimeservers") == TRUE)
- return connman_settings.pref_timeservers;
-
- if (g_str_equal(key, "FallbackNameservers") == TRUE)
- return connman_settings.fallback_nameservers;
+ if (g_str_equal(key, "SingleConnection") == TRUE)
+ return connman_settings.single_connection;
- if (g_str_equal(key, "NetworkInterfaceBlacklist") == TRUE)
- return connman_settings.blacklisted_interfaces;
-
- return NULL;
-}
-
-unsigned int *connman_setting_get_uint_list(const char *key)
-{
- if (g_str_equal(key, "DefaultAutoConnectTechnologies") == TRUE)
- return connman_settings.auto_connect;
-
- if (g_str_equal(key, "PreferredTechnologies") == TRUE)
- return connman_settings.preferred_techs;
-
- return NULL;
-}
-
-unsigned int connman_timeout_input_request(void) {
- return connman_settings.timeout_inputreq;
-}
-
-unsigned int connman_timeout_browser_launch(void) {
- return connman_settings.timeout_browserlaunch;
+ return FALSE;
}
int main(int argc, char *argv[])
DBusConnection *conn;
DBusError err;
GKeyFile *config;
+#if !defined TIZEN_EXT
guint signal;
+#endif
+
+#ifdef HAVE_CAPNG
+ /* Drop capabilities */
+#endif
#ifdef NEED_THREADS
if (g_thread_supported() == FALSE)
}
#endif
+#if !defined TIZEN_EXT
signal = setup_signalfd();
+#endif
dbus_error_init(&err);
__connman_dbus_init(conn);
config = load_config(CONFIGDIR "/main.conf");
+
parse_config(config);
- if (config != NULL)
- g_key_file_free(config);
__connman_storage_migrate();
__connman_technology_init();
__connman_device_init(option_device, option_nodevice);
__connman_agent_init();
- __connman_ippool_init();
__connman_iptables_init();
- __connman_nat_init();
__connman_tethering_init();
__connman_counter_init();
__connman_manager_init();
__connman_rtnl_start();
__connman_dhcp_init();
- __connman_dhcpv6_init();
__connman_wpad_init();
__connman_wispr_init();
__connman_rfkill_init();
g_main_loop_run(main_loop);
+#if !defined TIZEN_EXT
g_source_remove(signal);
+#endif
__connman_rfkill_cleanup();
__connman_wispr_cleanup();
__connman_wpad_cleanup();
- __connman_dhcpv6_cleanup();
__connman_dhcp_cleanup();
__connman_provider_cleanup();
__connman_plugin_cleanup();
__connman_counter_cleanup();
__connman_agent_cleanup();
__connman_tethering_cleanup();
- __connman_nat_cleanup();
__connman_iptables_cleanup();
- __connman_ippool_cleanup();
__connman_device_cleanup();
__connman_network_cleanup();
__connman_service_cleanup();
g_main_loop_unref(main_loop);
- if (connman_settings.pref_timeservers != NULL)
- g_strfreev(connman_settings.pref_timeservers);
-
- g_free(connman_settings.auto_connect);
- g_free(connman_settings.preferred_techs);
- g_strfreev(connman_settings.fallback_nameservers);
- g_strfreev(connman_settings.blacklisted_interfaces);
+ if (config)
+ g_key_file_free(config);
g_free(option_debug);
[General]
-# Set input request timeout. Default is 120 seconds
-# The request for inputs like passphrase will timeout
-# after certain amount of time. Use this setting to
-# increase the value in case of different user
-# interface designs.
-# InputRequestTimeout = 120
-
-# Set browser launch timeout. Default is 300 seconds
-# The request for launching a browser for portal pages
-# will timeout after certain amount of time. Use this
-# setting to increase the value in case of different
-# user interface designs.
-# BrowserLaunchTimeout = 300
-
# Enable background scanning. Default is true.
# Background scanning will start every 5 minutes unless
# the scan list is empty. In that case, a simple backoff
# mechanism starting from 10s up to 5 minutes will run.
-# BackgroundScanning = true
-
-# List of Fallback timeservers separated by ",".
-# These timeservers are used for NTP sync when there are
-# no timeserver set by the user or by the service.
-# These can contain mixed combination of fully qualified
-# domain names, IPv4 and IPv6 addresses.
-# FallbackTimeservers =
-
-# List of fallback nameservers separated by "," appended
-# to the list of nameservers given by the service. The
-# nameserver entries must be in numeric format, host
-# names are ignored.
-# FallbackNameservers =
-
-# List of technologies that are marked autoconnectable
-# by default, separated by commas ",". The default value
-# for this entry when empty is ethernet,wifi,cellular.
-# Services that are automatically connected must have been
-# set up and saved to storage beforehand.
-# DefaultAutoConnectTechnologies =
-
-# List of preferred technologies from the most preferred
-# one to the least preferred one separated by commas ",".
-# Services of the listed technology type will be tried one
-# by one in the order given, until one of them gets connected
-# with state 'online' or they are all tried. A service of a
-# preferred technology type in state 'ready' will get the
-# default route when compared to a non-preferred type; a
-# service of a preferred technology type in state 'online'
-# will get the default route when compared to either a
-# non-preferred type or a preferred type in state 'ready'.
-# PreferredTechnologies =
-# List of blacklisted network interfaces separated by ",".
-# Found interfaces will be compared to the list and will
-# not be handled by connman, if their first characters
-# match any of the list entries. Default value is
-# vmnet,vboxnet,virbr.
-# NetworkInterfaceBlacklist = vmnet,vboxnet,virbr
+BackgroundScanning = true
+SingleConnection = true
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include "connman.h"
-static connman_bool_t connman_state_idle;
-static DBusMessage *session_mode_pending = NULL;
+connman_bool_t connman_state_idle;
+DBusMessage *session_mode_pending = NULL;
static DBusMessage *get_properties(DBusConnection *conn,
DBusMessage *msg, void *data)
connman_dbus_dict_open(&array, &dict);
+ connman_dbus_dict_append_array(&dict, "Services",
+ DBUS_TYPE_OBJECT_PATH, __connman_service_list, NULL);
+ connman_dbus_dict_append_array(&dict, "Technologies",
+ DBUS_TYPE_OBJECT_PATH, __connman_technology_list, NULL);
+
str = __connman_notifier_get_state();
connman_dbus_dict_append_basic(&dict, "State",
DBUS_TYPE_STRING, &str);
connman_dbus_dict_append_basic(&dict, "OfflineMode",
DBUS_TYPE_BOOLEAN, &offlinemode);
+ connman_dbus_dict_append_array(&dict, "AvailableTechnologies",
+ DBUS_TYPE_STRING, __connman_notifier_list_registered, NULL);
+ connman_dbus_dict_append_array(&dict, "EnabledTechnologies",
+ DBUS_TYPE_STRING, __connman_notifier_list_enabled, NULL);
+ connman_dbus_dict_append_array(&dict, "ConnectedTechnologies",
+ DBUS_TYPE_STRING, __connman_notifier_list_connected, NULL);
+
+ str = __connman_service_default();
+ if (str != NULL)
+ connman_dbus_dict_append_basic(&dict, "DefaultTechnology",
+ DBUS_TYPE_STRING, &str);
+
+ connman_dbus_dict_append_array(&dict, "AvailableDebugs",
+ DBUS_TYPE_STRING, __connman_debug_list_available, NULL);
+ connman_dbus_dict_append_array(&dict, "EnabledDebugs",
+ DBUS_TYPE_STRING, __connman_debug_list_enabled, NULL);
+
sessionmode = __connman_session_mode();
connman_dbus_dict_append_basic(&dict, "SessionMode",
DBUS_TYPE_BOOLEAN,
if (dbus_message_iter_init(msg, &iter) == FALSE)
return __connman_error_invalid_arguments(msg);
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- return __connman_error_invalid_arguments(msg);
-
dbus_message_iter_get_basic(&iter, &name);
dbus_message_iter_next(&iter);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
- return __connman_error_invalid_arguments(msg);
-
dbus_message_iter_recurse(&iter, &value);
type = dbus_message_iter_get_arg_type(&value);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
-static void append_technology_structs(DBusMessageIter *iter, void *user_data)
-{
- __connman_technology_list_struct(iter);
-}
-
-static DBusMessage *get_technologies(DBusConnection *conn,
- DBusMessage *msg, void *data)
+static DBusMessage *get_state(DBusConnection *conn,
+ DBusMessage *msg, void *data)
{
- DBusMessage *reply;
-
- DBG("");
+ const char *str;
- reply = dbus_message_new_method_return(msg);
- if (reply == NULL)
- return NULL;
+ DBG("conn %p", conn);
- __connman_dbus_append_objpath_dict_array(reply,
- append_technology_structs, NULL);
+ str = __connman_notifier_get_state();
- return reply;
+ return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &str,
+ DBUS_TYPE_INVALID);
}
static DBusMessage *remove_provider(DBusConnection *conn,
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
+static DBusMessage *request_scan(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ enum connman_service_type type;
+ const char *str;
+ int err;
+
+ DBG("conn %p", conn);
+
+ dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
+ DBUS_TYPE_INVALID);
+
+ if (g_strcmp0(str, "") == 0)
+ type = CONNMAN_SERVICE_TYPE_UNKNOWN;
+ else if (g_strcmp0(str, "wifi") == 0)
+ type = CONNMAN_SERVICE_TYPE_WIFI;
+ else if (g_strcmp0(str, "wimax") == 0)
+ type = CONNMAN_SERVICE_TYPE_WIMAX;
+ else
+ return __connman_error_invalid_arguments(msg);
+
+ err = __connman_device_request_scan(type);
+ if (err < 0) {
+ if (err == -EINPROGRESS) {
+ connman_error("Invalid return code from scan");
+ err = -EINVAL;
+ }
+
+ return __connman_error_failed(msg, -err);
+ }
+
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
static DBusConnection *connection = NULL;
static void session_mode_notify(void)
.idle_state = idle_state,
};
-static void append_service_structs(DBusMessageIter *iter, void *user_data)
+static DBusMessage *enable_technology(DBusConnection *conn,
+ DBusMessage *msg, void *data)
{
- __connman_service_list_struct(iter);
+ enum connman_service_type type;
+ const char *str;
+
+ DBG("conn %p", conn);
+
+ dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
+ DBUS_TYPE_INVALID);
+
+ if (g_strcmp0(str, "ethernet") == 0)
+ type = CONNMAN_SERVICE_TYPE_ETHERNET;
+ else if (g_strcmp0(str, "wifi") == 0)
+ type = CONNMAN_SERVICE_TYPE_WIFI;
+ else if (g_strcmp0(str, "wimax") == 0)
+ type = CONNMAN_SERVICE_TYPE_WIMAX;
+ else if (g_strcmp0(str, "bluetooth") == 0)
+ type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
+ else if (g_strcmp0(str, "cellular") == 0)
+ type = CONNMAN_SERVICE_TYPE_CELLULAR;
+ else
+ return __connman_error_invalid_arguments(msg);
+
+ if (__connman_notifier_is_registered(type) == FALSE)
+ return __connman_error_not_registered(msg);
+
+ if (__connman_notifier_is_enabled(type) == TRUE)
+ return __connman_error_already_enabled(msg);
+
+ __connman_technology_enable(type, msg);
+
+ return NULL;
+}
+
+static DBusMessage *disable_technology(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ enum connman_service_type type;
+ const char *str;
+
+ DBG("conn %p", conn);
+
+ dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
+ DBUS_TYPE_INVALID);
+
+ if (g_strcmp0(str, "ethernet") == 0)
+ type = CONNMAN_SERVICE_TYPE_ETHERNET;
+ else if (g_strcmp0(str, "wifi") == 0)
+ type = CONNMAN_SERVICE_TYPE_WIFI;
+ else if (g_strcmp0(str, "wimax") == 0)
+ type = CONNMAN_SERVICE_TYPE_WIMAX;
+ else if (g_strcmp0(str, "bluetooth") == 0)
+ type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
+ else if (g_strcmp0(str, "cellular") == 0)
+ type = CONNMAN_SERVICE_TYPE_CELLULAR;
+ else
+ return __connman_error_invalid_arguments(msg);
+
+ if (__connman_notifier_is_registered(type) == FALSE)
+ return __connman_error_not_registered(msg);
+
+ if (__connman_notifier_is_enabled(type) == FALSE)
+ return __connman_error_already_disabled(msg);
+
+ __connman_technology_disable(type, msg);
+
+ return NULL;
}
static DBusMessage *get_services(DBusConnection *conn,
DBusMessage *msg, void *data)
{
DBusMessage *reply;
+ DBusMessageIter iter, array;
reply = dbus_message_new_method_return(msg);
if (reply == NULL)
return NULL;
- __connman_dbus_append_objpath_dict_array(reply,
- append_service_structs, NULL);
+ dbus_message_iter_init_append(reply, &iter);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_STRUCT_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_OBJECT_PATH_AS_STRING
+ DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING
+ DBUS_STRUCT_END_CHAR_AS_STRING, &array);
+
+ __connman_service_list_struct(&array);
+
+ dbus_message_iter_close_container(&iter, &array);
return reply;
}
+static DBusMessage *lookup_service(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ const char *pattern, *path;
+ int err;
+
+ DBG("conn %p", conn);
+
+ dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
+ DBUS_TYPE_INVALID);
+
+ err = __connman_service_lookup(pattern, &path);
+ if (err < 0)
+ return __connman_error_failed(msg, -err);
+
+ return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+}
+
+static DBusMessage *connect_service(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ int err;
+
+ DBG("conn %p", conn);
+
+ if (__connman_session_mode() == TRUE) {
+ connman_info("Session mode enabled: "
+ "direct service connect disabled");
+
+ return __connman_error_failed(msg, -EINVAL);
+ }
+
+ err = __connman_service_create_and_connect(msg);
+ if (err < 0) {
+ if (err == -EINPROGRESS) {
+ connman_error("Invalid return code from connect");
+ err = -EINVAL;
+ }
+
+ return __connman_error_failed(msg, -err);
+ }
+
+ return NULL;
+}
+
+static DBusMessage *provision_service(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ int err;
+
+ DBG("conn %p", conn);
+
+ err = __connman_service_provision(msg);
+ if (err < 0)
+ return __connman_error_failed(msg, -err);
+
+ return NULL;
+}
+
static DBusMessage *connect_provider(DBusConnection *conn,
DBusMessage *msg, void *data)
{
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
-static const GDBusMethodTable manager_methods[] = {
- { GDBUS_METHOD("GetProperties",
- NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
- get_properties) },
- { GDBUS_ASYNC_METHOD("SetProperty",
- GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
- NULL, set_property) },
- { GDBUS_METHOD("GetTechnologies",
- NULL, GDBUS_ARGS({ "technologies", "a(oa{sv})" }),
- get_technologies) },
- { GDBUS_METHOD("RemoveProvider",
- GDBUS_ARGS({ "provider", "o" }), NULL,
- remove_provider) },
- { GDBUS_METHOD("GetServices",
- NULL, GDBUS_ARGS({ "services", "a(oa{sv})" }),
- get_services) },
- { GDBUS_ASYNC_METHOD("ConnectProvider",
- GDBUS_ARGS({ "provider", "a{sv}" }),
- GDBUS_ARGS({ "path", "o" }),
- connect_provider) },
- { GDBUS_METHOD("RegisterAgent",
- GDBUS_ARGS({ "path", "o" }), NULL,
- register_agent) },
- { GDBUS_METHOD("UnregisterAgent",
- GDBUS_ARGS({ "path", "o" }), NULL,
- unregister_agent) },
- { GDBUS_METHOD("RegisterCounter",
- GDBUS_ARGS({ "path", "o" }, { "accuracy", "u" },
- { "period", "u" }),
- NULL, register_counter) },
- { GDBUS_METHOD("UnregisterCounter",
- GDBUS_ARGS({ "path", "o" }), NULL,
- unregister_counter) },
- { GDBUS_METHOD("CreateSession",
- GDBUS_ARGS({ "settings", "a{sv}" },
- { "notifier", "o" }),
- GDBUS_ARGS({ "session", "o" }),
- create_session) },
- { GDBUS_METHOD("DestroySession",
- GDBUS_ARGS({ "session", "o" }), NULL,
- destroy_session) },
- { GDBUS_ASYNC_METHOD("RequestPrivateNetwork",
- NULL, GDBUS_ARGS({ "path", "o" },
- { "settings", "a{sv}" },
- { "socket", "h" }),
- request_private_network) },
- { GDBUS_METHOD("ReleasePrivateNetwork",
- GDBUS_ARGS({ "path", "o" }), NULL,
- release_private_network) },
+static GDBusMethodTable manager_methods[] = {
+ { "GetProperties", "", "a{sv}", get_properties },
+ { "SetProperty", "sv", "", set_property,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "GetState", "", "s", get_state },
+ { "RemoveProvider", "o", "", remove_provider },
+ { "RequestScan", "s", "", request_scan },
+ { "EnableTechnology", "s", "", enable_technology,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "DisableTechnology", "s", "", disable_technology,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "GetServices", "", "a(oa{sv})", get_services },
+ { "LookupService", "s", "o", lookup_service, },
+ { "ConnectService", "a{sv}", "o", connect_service,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "ProvisionService", "s", "", provision_service,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "ConnectProvider", "a{sv}", "o", connect_provider,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "RegisterAgent", "o", "", register_agent },
+ { "UnregisterAgent", "o", "", unregister_agent },
+ { "RegisterCounter", "ouu", "", register_counter },
+ { "UnregisterCounter", "o", "", unregister_counter },
+ { "CreateSession", "a{sv}o", "o", create_session },
+ { "DestroySession", "o", "", destroy_session },
+ { "RequestPrivateNetwork", "", "oa{sv}h",
+ request_private_network,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "ReleasePrivateNetwork", "o", "",
+ release_private_network },
{ },
};
-static const GDBusSignalTable manager_signals[] = {
- { GDBUS_SIGNAL("PropertyChanged",
- GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
- { GDBUS_SIGNAL("TechnologyAdded",
- GDBUS_ARGS({ "path", "o" },
- { "properties", "a{sv}" })) },
- { GDBUS_SIGNAL("TechnologyRemoved",
- GDBUS_ARGS({ "path", "o" })) },
- { GDBUS_SIGNAL("ServicesChanged",
- GDBUS_ARGS({ "changed", "a(oa{sv})" },
- { "removed", "ao" })) },
+static GDBusSignalTable manager_signals[] = {
+ { "PropertyChanged", "sv" },
+ { "StateChanged", "s" },
{ },
};
+++ /dev/null
-/*
- *
- * Connection Manager
- *
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
- * Copyright (C) 2012 BMW Car IT GmbH. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-#include <stdio.h>
-
-#include "connman.h"
-
-static char *default_interface;
-static GHashTable *nat_hash;
-
-struct connman_nat {
- char *address;
- unsigned char prefixlen;
-
- char *interface;
-};
-
-static int enable_ip_forward(connman_bool_t enable)
-{
- FILE *f;
-
- f = fopen("/proc/sys/net/ipv4/ip_forward", "r+");
- if (f == NULL)
- return -errno;
-
- if (enable == TRUE)
- fprintf(f, "1");
- else
- fprintf(f, "0");
-
- fclose(f);
-
- return 0;
-}
-
-static void flush_nat(void)
-{
- int err;
-
- err = __connman_iptables_command("-t nat -F POSTROUTING");
- if (err < 0) {
- DBG("Flushing the nat table failed");
-
- return;
- }
-
- __connman_iptables_commit("nat");
-}
-
-static int enable_nat(struct connman_nat *nat)
-{
- int err;
-
- g_free(nat->interface);
- nat->interface = g_strdup(default_interface);
-
- if (nat->interface == NULL)
- return 0;
-
- /* Enable masquerading */
- err = __connman_iptables_command("-t nat -A POSTROUTING "
- "-s %s/%d -o %s -j MASQUERADE",
- nat->address,
- nat->prefixlen,
- nat->interface);
- if (err < 0)
- return err;
-
- return __connman_iptables_commit("nat");
-}
-
-static void disable_nat(struct connman_nat *nat)
-{
- int err;
-
- if (nat->interface == NULL)
- return;
-
- /* Disable masquerading */
- err = __connman_iptables_command("-t nat -D POSTROUTING "
- "-s %s/%d -o %s -j MASQUERADE",
- nat->address,
- nat->prefixlen,
- nat->interface);
- if (err < 0)
- return;
-
- __connman_iptables_commit("nat");
-}
-
-int __connman_nat_enable(const char *name, const char *address,
- unsigned char prefixlen)
-{
- struct connman_nat *nat;
- int err;
-
- if (g_hash_table_size(nat_hash) == 0) {
- err = enable_ip_forward(TRUE);
- if (err < 0)
- return err;
- }
-
- nat = g_try_new0(struct connman_nat, 1);
- if (nat == NULL) {
- if (g_hash_table_size(nat_hash) == 0)
- enable_ip_forward(FALSE);
-
- return -ENOMEM;
- }
-
- nat->address = g_strdup(address);
- nat->prefixlen = prefixlen;
-
- g_hash_table_replace(nat_hash, g_strdup(name), nat);
-
- return enable_nat(nat);
-}
-
-void __connman_nat_disable(const char *name)
-{
- struct connman_nat *nat;
-
- nat = g_hash_table_lookup(nat_hash, name);
- if (nat == NULL)
- return;
-
- disable_nat(nat);
-
- g_hash_table_remove(nat_hash, name);
-
- if (g_hash_table_size(nat_hash) == 0)
- enable_ip_forward(FALSE);
-}
-
-static void update_default_interface(struct connman_service *service)
-{
- GHashTableIter iter;
- gpointer key, value;
- char *interface;
- int err;
-
- interface = connman_service_get_interface(service);
-
- DBG("interface %s", interface);
-
- g_free(default_interface);
- default_interface = interface;
-
- g_hash_table_iter_init(&iter, nat_hash);
-
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- const char *name = key;
- struct connman_nat *nat = value;
-
- disable_nat(nat);
- err = enable_nat(nat);
- if (err < 0)
- DBG("Failed to enable nat for %s", name);
- }
-}
-
-static void shutdown_nat(gpointer key, gpointer value, gpointer user_data)
-{
- const char *name = key;
-
- __connman_nat_disable(name);
-}
-
-static void cleanup_nat(gpointer data)
-{
- struct connman_nat *nat = data;
-
- g_free(nat->address);
- g_free(nat->interface);
-}
-
-static struct connman_notifier nat_notifier = {
- .name = "nat",
- .default_changed = update_default_interface,
-};
-
-int __connman_nat_init(void)
-{
- int err;
-
- DBG("");
-
- err = connman_notifier_register(&nat_notifier);
- if (err < 0)
- return err;
-
- nat_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, cleanup_nat);
-
- flush_nat();
-
- return 0;
-}
-
-void __connman_nat_cleanup(void)
-{
- DBG("");
-
- g_hash_table_foreach(nat_hash, shutdown_nat, NULL);
- g_hash_table_destroy(nat_hash);
- nat_hash = NULL;
-
- flush_nat();
-
- connman_notifier_unregister(&nat_notifier);
-}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include "connman.h"
-/*
- * How many times to send RS with the purpose of
- * refreshing RDNSS entries before they actually expire.
- * With a value of 1, one RS will be sent, with no retries.
- */
-#define RS_REFRESH_COUNT 1
-
-/*
- * Value in seconds to wait for RA after RS was sent.
- * After this time elapsed, we can send another RS.
- */
-#define RS_REFRESH_TIMEOUT 3
-
static GSList *network_list = NULL;
static GSList *driver_list = NULL;
char *group;
char *path;
int index;
- int router_solicit_count;
- int router_solicit_refresh_count;
struct connman_network_driver *driver;
void *driver_data;
connman_bool_t wps;
connman_bool_t use_wps;
char *pin_wps;
+#if defined TIZEN_EXT
+ char encryption_mode[6];
+ unsigned char bssid[6];
+ unsigned int maxrate;
+#endif
} wifi;
struct {
return NULL;
}
+connman_bool_t __connman_network_has_driver(struct connman_network *network)
+{
+ if (network == NULL || network->driver == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
static gboolean match_driver(struct connman_network *network,
struct connman_network_driver *driver)
{
*
* Increase reference counter of network
*/
-struct connman_network *
-connman_network_ref_debug(struct connman_network *network,
- const char *file, int line, const char *caller)
+struct connman_network *connman_network_ref(struct connman_network *network)
{
- DBG("%p name %s ref %d by %s:%d:%s()", network, network->name,
- network->refcount + 1, file, line, caller);
+ DBG("network %p name %s refcount %d", network, network->name,
+ network->refcount + 1);
__sync_fetch_and_add(&network->refcount, 1);
*
* Decrease reference counter of network
*/
-void connman_network_unref_debug(struct connman_network *network,
- const char *file, int line, const char *caller)
+void connman_network_unref(struct connman_network *network)
{
- DBG("%p name %s ref %d by %s:%d:%s()", network, network->name,
- network->refcount - 1, file, line, caller);
+ DBG("network %p name %s refcount %d", network, network->name,
+ network->refcount - 1);
if (__sync_fetch_and_sub(&network->refcount, 1) != 1)
return;
static void set_connect_error(struct connman_network *network)
{
+
+#if defined TIZEN_EXT
+ if (network->associating != FALSE)
+ network->associating = FALSE;
+#endif
+
struct connman_service *service;
service = __connman_service_lookup_from_network(network);
if (ipconfig == NULL)
return;
- __connman_ipconfig_set_method(ipconfig, method);
+ connman_ipconfig_set_method(ipconfig, method);
}
void connman_network_set_ipv6_method(struct connman_network *network,
if (ipconfig == NULL)
return;
- __connman_ipconfig_set_method(ipconfig, method);
+ connman_ipconfig_set_method(ipconfig, method);
}
void connman_network_set_error(struct connman_network *network,
__connman_service_clear_error(service);
}
-static void set_configuration(struct connman_network *network,
- enum connman_ipconfig_type type)
+static void set_configuration(struct connman_network *network)
{
struct connman_service *service;
service = __connman_service_lookup_from_network(network);
__connman_service_ipconfig_indicate_state(service,
CONNMAN_SERVICE_STATE_CONFIGURATION,
- type);
+ CONNMAN_IPCONFIG_TYPE_IPV4);
}
static void dhcp_success(struct connman_network *network)
if (err < 0)
goto err;
+#if defined TIZEN_EXT
+/*
+ * Description: __connman_service_lookup_from_index cannot find correct service
+ */
+ err = __connman_ipconfig_gateway_add(ipconfig_ipv4, service);
+#else
err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
+#endif
if (err < 0)
goto err;
ipconfig_ipv4 = __connman_service_get_ip4config(service);
- set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV4);
+ set_configuration(network);
network->connecting = FALSE;
if (err < 0)
goto err;
+#if defined TIZEN_EXT
+/*
+ * Description: __connman_service_lookup_from_index cannot find correct service
+ */
+ err = __connman_ipconfig_gateway_add(ipconfig_ipv4, service);
+#else
err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
+#endif
if (err < 0)
goto err;
if (__connman_ipconfig_get_local(ipconfig) == NULL)
__connman_service_read_ip4config(service);
- set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV4);
+ set_configuration(network);
err = __connman_ipconfig_address_add(ipconfig);
if (err < 0)
goto err;
+#if defined TIZEN_EXT
+/*
+ * Description: __connman_service_lookup_from_index cannot find correct service
+ */
+ err = __connman_ipconfig_gateway_add(ipconfig, service);
+#else
err = __connman_ipconfig_gateway_add(ipconfig);
+#endif
if (err < 0)
goto err;
DBG("network %p", network);
- set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV4);
+ set_configuration(network);
err = __connman_dhcp_start(network, dhcp_callback);
if (err < 0) {
return err;
}
+#if defined TIZEN_EXT
+/*
+ * Description: __connman_service_lookup_from_index cannot find correct service
+ */
+ err = __connman_ipconfig_gateway_add(ipconfig_ipv6, service);
+#else
err = __connman_ipconfig_gateway_add(ipconfig_ipv6);
+#endif
if (err < 0)
return err;
return 0;
}
-static void stop_dhcpv6(struct connman_network *network)
-{
- __connman_dhcpv6_stop(network);
-}
-
-static void dhcpv6_release_callback(struct connman_network *network,
- connman_bool_t success)
-{
- DBG("success %d", success);
-
- stop_dhcpv6(network);
-}
-
-static void release_dhcpv6(struct connman_network *network)
-{
- __connman_dhcpv6_start_release(network, dhcpv6_release_callback);
- stop_dhcpv6(network);
-}
-
-static void dhcpv6_info_callback(struct connman_network *network,
- connman_bool_t success)
-{
- DBG("success %d", success);
-
- stop_dhcpv6(network);
-}
-
-static gboolean dhcpv6_set_addresses(struct connman_network *network)
-{
- struct connman_service *service;
- struct connman_ipconfig *ipconfig_ipv6;
- int err = -EINVAL;
-
- service = __connman_service_lookup_from_network(network);
- if (service == NULL)
- goto err;
-
- connman_network_set_associating(network, FALSE);
-
- network->connecting = FALSE;
-
- ipconfig_ipv6 = __connman_service_get_ip6config(service);
- err = __connman_ipconfig_address_add(ipconfig_ipv6);
- if (err < 0)
- goto err;
-
- err = __connman_ipconfig_gateway_add(ipconfig_ipv6);
- if (err < 0)
- goto err;
-
- return 0;
-
-err:
- connman_network_set_error(network,
- CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
- return err;
-}
-
-static void autoconf_ipv6_set(struct connman_network *network);
-static void dhcpv6_callback(struct connman_network *network,
- connman_bool_t success);
-
-/*
- * Have a separate callback for renew so that we do not do autoconf
- * in wrong phase as the dhcpv6_callback() is also called when doing
- * DHCPv6 solicitation.
- */
-static void dhcpv6_renew_callback(struct connman_network *network,
- connman_bool_t success)
-{
- if (success == TRUE)
- dhcpv6_callback(network, success);
- else {
- stop_dhcpv6(network);
-
- /* restart and do solicit again. */
- autoconf_ipv6_set(network);
- }
-}
-
-static void dhcpv6_callback(struct connman_network *network,
- connman_bool_t success)
-{
- DBG("success %d", success);
-
- /* Start the renew process if necessary */
- if (success == TRUE) {
-
- if (dhcpv6_set_addresses(network) < 0) {
- stop_dhcpv6(network);
- return;
- }
-
- if (__connman_dhcpv6_start_renew(network,
- dhcpv6_renew_callback) == -ETIMEDOUT)
- dhcpv6_renew_callback(network, FALSE);
- } else
- stop_dhcpv6(network);
-}
-
-static void check_dhcpv6(struct nd_router_advert *reply,
- unsigned int length, void *user_data)
-{
- struct connman_network *network = user_data;
- GSList *prefixes;
-
- DBG("reply %p", reply);
-
- if (reply == NULL) {
- /*
- * Router solicitation message seem to get lost easily so
- * try to send it again.
- */
- if (network->router_solicit_count > 0) {
- DBG("re-send router solicitation %d",
- network->router_solicit_count);
- network->router_solicit_count--;
- __connman_inet_ipv6_send_rs(network->index, 1,
- check_dhcpv6, network);
- return;
- }
- connman_network_unref(network);
- return;
- }
-
- network->router_solicit_count = 0;
-
- /*
- * If we were disconnected while waiting router advertisement,
- * we just quit and do not start DHCPv6
- */
- if (network->connected == FALSE) {
- connman_network_unref(network);
- return;
- }
-
- prefixes = __connman_inet_ipv6_get_prefixes(reply, length);
-
- /*
- * We do stateful/stateless DHCPv6 if router advertisement says so.
- */
- if (reply->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED)
- __connman_dhcpv6_start(network, prefixes, dhcpv6_callback);
- else if (reply->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)
- __connman_dhcpv6_start_info(network, dhcpv6_info_callback);
-
- connman_network_unref(network);
-}
-
-static void receive_refresh_rs_reply(struct nd_router_advert *reply,
- unsigned int length, void *user_data)
-{
- struct connman_network *network = user_data;
-
- DBG("reply %p", reply);
-
- if (reply == NULL) {
- /*
- * Router solicitation message seem to get lost easily so
- * try to send it again.
- */
- if (network->router_solicit_refresh_count > 1) {
- network->router_solicit_refresh_count--;
- DBG("re-send router solicitation %d",
- network->router_solicit_refresh_count);
- __connman_inet_ipv6_send_rs(network->index,
- RS_REFRESH_TIMEOUT,
- receive_refresh_rs_reply,
- network);
- return;
- }
- }
-
- /* RS refresh not in progress anymore */
- network->router_solicit_refresh_count = 0;
-
- connman_network_unref(network);
- return;
-}
-
-int __connman_refresh_rs_ipv6(struct connman_network *network, int index)
-{
- int ret = 0;
-
- DBG("network %p index %d", network, index);
-
- /* Send only one RS for all RDNSS entries which are about to expire */
- if (network->router_solicit_refresh_count > 0) {
- DBG("RS refresh already started");
- return 0;
- }
-
- network->router_solicit_refresh_count = RS_REFRESH_COUNT;
-
- connman_network_ref(network);
-
- ret = __connman_inet_ipv6_send_rs(index, RS_REFRESH_TIMEOUT,
- receive_refresh_rs_reply, network);
- return ret;
-}
-
static void autoconf_ipv6_set(struct connman_network *network)
{
- struct connman_service *service;
- struct connman_ipconfig *ipconfig;
- int index;
-
DBG("network %p", network);
- if (network->router_solicit_count > 0) {
- /*
- * The autoconfiguration is already pending and we have sent
- * router solicitation messages and are now waiting answers.
- * There is no need to continue any further.
- */
- DBG("autoconfiguration already started");
- return;
- }
-
__connman_device_set_network(network->device, network);
connman_device_set_disconnected(network->device, FALSE);
- network->connecting = FALSE;
-
- service = __connman_service_lookup_from_network(network);
- if (service == NULL)
- return;
-
- ipconfig = __connman_service_get_ip6config(service);
- if (ipconfig == NULL)
- return;
+ /* XXX: Append IPv6 nameservers here */
- index = __connman_ipconfig_get_index(ipconfig);
-
- connman_network_ref(network);
-
- /* Try to get stateless DHCPv6 information, RFC 3736 */
- network->router_solicit_count = 3;
- __connman_inet_ipv6_send_rs(index, 1, check_dhcpv6, network);
+ network->connecting = FALSE;
}
-static void set_connected(struct connman_network *network)
+static gboolean set_connected(gpointer user_data)
{
+ struct connman_network *network = user_data;
+ struct connman_service *service;
struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
enum connman_ipconfig_method ipv4_method, ipv6_method;
- struct connman_service *service;
- int ret;
-
- if (network->connected == TRUE)
- return;
-
- network->connected = TRUE;
service = __connman_service_lookup_from_network(network);
ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6);
DBG("method ipv4 %d ipv6 %d", ipv4_method, ipv6_method);
+ DBG("network connected %d", network->connected);
- switch (ipv6_method) {
- case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
- case CONNMAN_IPCONFIG_METHOD_OFF:
- break;
- case CONNMAN_IPCONFIG_METHOD_DHCP:
- case CONNMAN_IPCONFIG_METHOD_AUTO:
- autoconf_ipv6_set(network);
- break;
- case CONNMAN_IPCONFIG_METHOD_FIXED:
- case CONNMAN_IPCONFIG_METHOD_MANUAL:
- ret = manual_ipv6_set(network, ipconfig_ipv6);
- if (ret != 0) {
- connman_network_set_error(network,
+ if (network->connected == TRUE) {
+ int ret;
+
+ switch (ipv6_method) {
+ case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+ case CONNMAN_IPCONFIG_METHOD_OFF:
+ break;
+ case CONNMAN_IPCONFIG_METHOD_AUTO:
+ autoconf_ipv6_set(network);
+ break;
+ case CONNMAN_IPCONFIG_METHOD_FIXED:
+ case CONNMAN_IPCONFIG_METHOD_MANUAL:
+ ret = manual_ipv6_set(network, ipconfig_ipv6);
+ if (ret != 0) {
+ connman_network_set_error(network,
CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
- return;
+ return FALSE;
+ }
+ break;
+ case CONNMAN_IPCONFIG_METHOD_DHCP:
+ break;
}
- break;
- }
- switch (ipv4_method) {
- case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
- case CONNMAN_IPCONFIG_METHOD_OFF:
- case CONNMAN_IPCONFIG_METHOD_AUTO:
- return;
- case CONNMAN_IPCONFIG_METHOD_FIXED:
- if (set_connected_fixed(network) < 0) {
- connman_network_set_error(network,
+ switch (ipv4_method) {
+ case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+ case CONNMAN_IPCONFIG_METHOD_OFF:
+ case CONNMAN_IPCONFIG_METHOD_AUTO:
+ return FALSE;
+ case CONNMAN_IPCONFIG_METHOD_FIXED:
+ if (set_connected_fixed(network) < 0) {
+ connman_network_set_error(network,
CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
- return;
- }
- return;
- case CONNMAN_IPCONFIG_METHOD_MANUAL:
- set_connected_manual(network);
- return;
- case CONNMAN_IPCONFIG_METHOD_DHCP:
- if (set_connected_dhcp(network) < 0) {
- connman_network_set_error(network,
+ return FALSE;
+ }
+ return TRUE;
+ case CONNMAN_IPCONFIG_METHOD_MANUAL:
+ set_connected_manual(network);
+ return TRUE;
+ case CONNMAN_IPCONFIG_METHOD_DHCP:
+ if (set_connected_dhcp(network) < 0) {
+ connman_network_set_error(network,
CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
- return;
+ return FALSE;
+ }
}
- }
-
- network->connecting = FALSE;
-
- connman_network_set_associating(network, FALSE);
-}
-
-static void set_disconnected(struct connman_network *network)
-{
- struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
- enum connman_ipconfig_method ipv4_method, ipv6_method;
- enum connman_service_state state;
- struct connman_service *service;
-
- if (network->connected == FALSE)
- return;
-
- network->connected = FALSE;
-
- service = __connman_service_lookup_from_network(network);
- ipconfig_ipv4 = __connman_service_get_ip4config(service);
- ipconfig_ipv6 = __connman_service_get_ip6config(service);
+ } else {
+ enum connman_service_state state;
- DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4,
- ipconfig_ipv6);
+ __connman_device_set_network(network->device, NULL);
- ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4);
- ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6);
+ switch (ipv4_method) {
+ case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+ case CONNMAN_IPCONFIG_METHOD_OFF:
+ case CONNMAN_IPCONFIG_METHOD_AUTO:
+ case CONNMAN_IPCONFIG_METHOD_FIXED:
+ case CONNMAN_IPCONFIG_METHOD_MANUAL:
+ break;
+ case CONNMAN_IPCONFIG_METHOD_DHCP:
+ __connman_dhcp_stop(network);
+ break;
+ }
- DBG("method ipv4 %d ipv6 %d", ipv4_method, ipv6_method);
+ /*
+ * We only set the disconnect state if we were not in idle
+ * or in failure. It does not make sense to go to disconnect
+ * state if we were not connected.
+ */
+ state = __connman_service_ipconfig_get_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+ if (state != CONNMAN_SERVICE_STATE_IDLE &&
+ state != CONNMAN_SERVICE_STATE_FAILURE)
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_DISCONNECT,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
- /*
- * Resetting solicit count here will prevent the RS resend loop
- * from sending packets in check_dhcpv6()
- */
- network->router_solicit_count = 0;
+ state = __connman_service_ipconfig_get_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+ if (state != CONNMAN_SERVICE_STATE_IDLE &&
+ state != CONNMAN_SERVICE_STATE_FAILURE)
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_DISCONNECT,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
- __connman_device_set_network(network->device, NULL);
+ __connman_connection_gateway_remove(service,
+ CONNMAN_IPCONFIG_TYPE_ALL);
- switch (ipv6_method) {
- case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
- case CONNMAN_IPCONFIG_METHOD_OFF:
- case CONNMAN_IPCONFIG_METHOD_FIXED:
- case CONNMAN_IPCONFIG_METHOD_MANUAL:
- break;
- case CONNMAN_IPCONFIG_METHOD_DHCP:
- case CONNMAN_IPCONFIG_METHOD_AUTO:
- release_dhcpv6(network);
- break;
- }
+ __connman_ipconfig_address_unset(ipconfig_ipv4);
+ __connman_ipconfig_address_unset(ipconfig_ipv6);
- switch (ipv4_method) {
- case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
- case CONNMAN_IPCONFIG_METHOD_OFF:
- case CONNMAN_IPCONFIG_METHOD_AUTO:
- case CONNMAN_IPCONFIG_METHOD_FIXED:
- case CONNMAN_IPCONFIG_METHOD_MANUAL:
- break;
- case CONNMAN_IPCONFIG_METHOD_DHCP:
- __connman_dhcp_stop(network);
- break;
- }
+ /*
+ * Special handling for IPv6 autoconfigured address.
+ * The simplest way to remove autoconfigured routes is to
+ * disable IPv6 temporarily so that kernel will do the cleanup
+ * automagically.
+ */
+ if (ipv6_method == CONNMAN_IPCONFIG_METHOD_AUTO) {
+ __connman_ipconfig_disable_ipv6(ipconfig_ipv6);
+ __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
+ }
- /*
- * We only set the disconnect state if we were not in idle
- * or in failure. It does not make sense to go to disconnect
- * state if we were not connected.
- */
- state = __connman_service_ipconfig_get_state(service,
- CONNMAN_IPCONFIG_TYPE_IPV4);
- if (state != CONNMAN_SERVICE_STATE_IDLE &&
- state != CONNMAN_SERVICE_STATE_FAILURE)
+#if defined TIZEN_EXT
+ if (connman_service_get_type(service) ==
+ CONNMAN_SERVICE_TYPE_CELLULAR) {
+ network->connecting = FALSE;
+ connman_network_set_associating(network, FALSE);
+ }
+#endif
__connman_service_ipconfig_indicate_state(service,
- CONNMAN_SERVICE_STATE_DISCONNECT,
+ CONNMAN_SERVICE_STATE_IDLE,
CONNMAN_IPCONFIG_TYPE_IPV4);
- state = __connman_service_ipconfig_get_state(service,
- CONNMAN_IPCONFIG_TYPE_IPV6);
- if (state != CONNMAN_SERVICE_STATE_IDLE &&
- state != CONNMAN_SERVICE_STATE_FAILURE)
__connman_service_ipconfig_indicate_state(service,
- CONNMAN_SERVICE_STATE_DISCONNECT,
+ CONNMAN_SERVICE_STATE_IDLE,
CONNMAN_IPCONFIG_TYPE_IPV6);
-
- __connman_connection_gateway_remove(service,
- CONNMAN_IPCONFIG_TYPE_ALL);
-
- __connman_ipconfig_address_unset(ipconfig_ipv4);
- __connman_ipconfig_address_unset(ipconfig_ipv6);
-
- /*
- * Special handling for IPv6 autoconfigured address.
- * The simplest way to remove autoconfigured routes is to
- * disable IPv6 temporarily so that kernel will do the cleanup
- * automagically.
- */
- if (ipv6_method == CONNMAN_IPCONFIG_METHOD_AUTO) {
- __connman_ipconfig_disable_ipv6(ipconfig_ipv6);
- __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
+#if defined TIZEN_EXT
+ if (connman_service_get_type(service) ==
+ CONNMAN_SERVICE_TYPE_CELLULAR)
+ return FALSE;
+#endif
}
- __connman_service_ipconfig_indicate_state(service,
- CONNMAN_SERVICE_STATE_IDLE,
- CONNMAN_IPCONFIG_TYPE_IPV4);
-
- __connman_service_ipconfig_indicate_state(service,
- CONNMAN_SERVICE_STATE_IDLE,
- CONNMAN_IPCONFIG_TYPE_IPV6);
-
network->connecting = FALSE;
connman_network_set_associating(network, FALSE);
+
+ return FALSE;
}
/**
int connman_network_set_connected(struct connman_network *network,
connman_bool_t connected)
{
- DBG("network %p connected %d/%d connecting %d associating %d",
- network, network->connected, connected, network->connecting,
- network->associating);
+ DBG("network %p connected %d", network, connected);
if ((network->connecting == TRUE || network->associating == TRUE) &&
connected == FALSE) {
connman_network_set_error(network,
CONNMAN_NETWORK_ERROR_CONNECT_FAIL);
- if (__connman_network_disconnect(network) == 0)
- return 0;
+ __connman_network_disconnect(network);
}
if (network->connected == connected)
return -EALREADY;
- if (connected == FALSE)
- set_disconnected(network);
- else
- set_connected(network);
+ network->connected = connected;
+
+ set_connected(network);
return 0;
}
return network->associating;
}
-void connman_network_clear_hidden(void *user_data)
-{
- if (user_data == NULL)
- return;
-
- DBG("user_data %p", user_data);
-
- /*
- * Hidden service does not have a connect timeout so
- * we do not need to remove it. We can just return
- * error to the caller telling that we could not find
- * any network that we could connect to.
- */
- __connman_service_reply_dbus_pending(user_data, EIO);
-}
-
-int connman_network_connect_hidden(struct connman_network *network,
- char *identity, char* passphrase, void *user_data)
-{
- int err = 0;
- struct connman_service *service;
-
- service = __connman_service_lookup_from_network(network);
-
- DBG("network %p service %p user_data %p", network, service, user_data);
-
- if (service == NULL) {
- err = -EINVAL;
- goto out;
- }
-
- if (identity != NULL)
- __connman_service_set_agent_identity(service, identity);
-
- if (passphrase != NULL)
- err = __connman_service_add_passphrase(service, passphrase);
-
- if (err == -ENOKEY) {
- __connman_service_indicate_error(service,
- CONNMAN_SERVICE_ERROR_INVALID_KEY);
- goto out;
- } else {
- __connman_service_set_hidden(service);
- __connman_service_set_userconnect(service, TRUE);
- __connman_service_set_hidden_data(service, user_data);
- return __connman_service_connect(service);
- }
-
-out:
- __connman_service_return_error(service, -err, user_data);
- return err;
-}
-
/**
* __connman_network_connect:
* @network: network structure
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);
return err;
}
+ network->connected = TRUE;
set_connected(network);
return err;
network->connecting = FALSE;
err = network->driver->disconnect(network);
- if (err == 0)
- set_disconnected(network);
+ if (err == 0) {
+ connman_network_set_connected(network, FALSE);
+ set_connected(network);
+ }
return err;
}
return err;
}
+#if defined TIZEN_EXT
+/*
+ * Description: __connman_service_lookup_from_index cannot find correct service
+ */
+ return __connman_ipconfig_gateway_add(ipconfig, service);
+#else
return __connman_ipconfig_gateway_add(ipconfig);
+#endif
}
int __connman_network_clear_ipconfig(struct connman_network *network,
case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
case CONNMAN_IPCONFIG_METHOD_OFF:
case CONNMAN_IPCONFIG_METHOD_FIXED:
- return -EINVAL;
case CONNMAN_IPCONFIG_METHOD_AUTO:
- release_dhcpv6(network);
- break;
+ return -EINVAL;
case CONNMAN_IPCONFIG_METHOD_MANUAL:
__connman_ipconfig_address_remove(ipconfig);
break;
return 0;
}
+#if defined TIZEN_EXT
+/*
+ * Description: Telephony plug-in requires manual PROXY setting function
+ */
+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;
+}
+
+/*
+ * Description: Network client requires additional wifi specific info
+ */
+int connman_network_set_bssid(struct connman_network *network,
+ const unsigned char *bssid)
+{
+ 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]);
+
+ int i = 0;
+ for (;i < 6;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, 6);
+
+ return 0;
+}
+
+const char *connman_network_get_enc_mode(struct connman_network *network)
+{
+ return (const char *)network->wifi.encryption_mode;
+}
+
+const char *connman_network_get_ifname(struct connman_network *network)
+{
+ struct connman_service *service;
+ struct connman_ipconfig *ipconfig;
+ const char *ifname = NULL;
+
+ service = __connman_service_lookup_from_network(network);
+ if (service == NULL)
+ return NULL;
+
+ ipconfig = __connman_service_get_ip4config(service);
+
+ if (ipconfig != NULL)
+ ifname = connman_ipconfig_get_ifname(ipconfig);
+
+ DBG("index %d, service %p ip4config %p ifname %s",
+ network->index, service, ipconfig, ifname);
+ return ifname;
+}
+#endif
+
int connman_network_set_nameservers(struct connman_network *network,
const char *nameservers)
{
}
/**
+ * connman_network_set_roaming:
+ * @network: network structure
+ * @roaming: roaming state
+ *
+ * Set roaming state for network
+ */
+int connman_network_set_roaming(struct connman_network *network,
+ connman_bool_t roaming)
+{
+ DBG("network %p roaming %d", network, roaming);
+
+ network->roaming = roaming;
+
+ return 0;
+}
+
+/**
* connman_network_set_string:
* @network: network structure
* @key: unique identifier
DBG("network %p key %s value %d", network, key, value);
if (g_strcmp0(key, "Roaming") == 0)
- network->roaming = value;
+ return connman_network_set_roaming(network, value);
else if (g_strcmp0(key, "WiFi.WPS") == 0)
network->wifi.wps = value;
else if (g_strcmp0(key, "WiFi.UseWPS") == 0)
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
static GSList *notifier_list = NULL;
static GHashTable *service_hash = NULL;
-static const char *notifier_state;
-
static gint compare_priority(gconstpointer a, gconstpointer b)
{
const struct connman_notifier *notifier1 = a;
#define MAX_TECHNOLOGIES 10
-static int connected[MAX_TECHNOLOGIES];
-static int online[MAX_TECHNOLOGIES];
+static volatile int registered[MAX_TECHNOLOGIES];
+static volatile int enabled[MAX_TECHNOLOGIES];
+static volatile int connected[MAX_TECHNOLOGIES];
-static connman_bool_t notifier_is_online(void)
+void __connman_notifier_list_registered(DBusMessageIter *iter, void *user_data)
{
- unsigned int i;
+ int i;
__sync_synchronize();
for (i = 0; i < MAX_TECHNOLOGIES; i++) {
- if (online[i] > 0)
- return TRUE;
+ const char *type = __connman_service_type2string(i);
+
+ if (type == NULL)
+ continue;
+
+ if (registered[i] > 0)
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &type);
}
+}
- return FALSE;
+void __connman_notifier_list_enabled(DBusMessageIter *iter, void *user_data)
+{
+ int i;
+
+ __sync_synchronize();
+ for (i = 0; i < MAX_TECHNOLOGIES; i++) {
+ const char *type = __connman_service_type2string(i);
+
+ if (type == NULL)
+ continue;
+
+ if (enabled[i] > 0)
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &type);
+ }
}
-connman_bool_t __connman_notifier_is_connected(void)
+void __connman_notifier_list_connected(DBusMessageIter *iter, void *user_data)
{
- unsigned int i;
+ int i;
__sync_synchronize();
for (i = 0; i < MAX_TECHNOLOGIES; i++) {
+ const char *type = __connman_service_type2string(i);
+
+ if (type == NULL)
+ continue;
+
if (connected[i] > 0)
- return TRUE;
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &type);
}
+}
- return FALSE;
+static void technology_registered(enum connman_service_type type,
+ connman_bool_t registered)
+{
+ DBG("type %d registered %d", type, registered);
+
+ connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE, "AvailableTechnologies",
+ DBUS_TYPE_STRING, __connman_notifier_list_registered, NULL);
}
-static const char *evaluate_notifier_state(void)
+static void technology_enabled(enum connman_service_type type,
+ connman_bool_t enabled)
{
- if (notifier_is_online() == TRUE)
- return "online";
+ GSList *list;
+
+ DBG("type %d enabled %d", type, enabled);
- if (__connman_notifier_is_connected() == TRUE)
- return "ready";
+ connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE, "EnabledTechnologies",
+ DBUS_TYPE_STRING, __connman_notifier_list_enabled, NULL);
- if ( __connman_technology_get_offlinemode() == TRUE)
- return "offline";
+ for (list = notifier_list; list; list = list->next) {
+ struct connman_notifier *notifier = list->data;
- return "idle";
+ if (notifier->service_enabled)
+ notifier->service_enabled(type, enabled);
+ }
}
-const char *__connman_notifier_get_state(void)
+unsigned int __connman_notifier_count_connected(void)
{
- return notifier_state;
+ unsigned int i, count = 0;
+
+ __sync_synchronize();
+ for (i = 0; i < MAX_TECHNOLOGIES; i++) {
+ if (connected[i] > 0)
+ count++;
+ }
+
+ return count;
}
-static void state_changed(void)
+const char *__connman_notifier_get_state(void)
{
- const char *state;
+ unsigned int count = __connman_notifier_count_connected();
+
+ if (count > 0)
+ return "online";
- state = evaluate_notifier_state();
+ return "offline";
+}
- if (g_strcmp0(state, notifier_state) == 0)
+static void state_changed(connman_bool_t connected)
+{
+ unsigned int count = __connman_notifier_count_connected();
+ char *state = "offline";
+ DBusMessage *signal;
+
+ if (count > 1)
return;
- notifier_state = state;
+ if (count == 1) {
+ if (connected == FALSE)
+ return;
+
+ state = "online";
+ }
connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
CONNMAN_MANAGER_INTERFACE, "State",
- DBUS_TYPE_STRING, ¬ifier_state);
+ DBUS_TYPE_STRING, &state);
+
+ signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE, "StateChanged");
+ if (signal == NULL)
+ return;
+
+ dbus_message_append_args(signal, DBUS_TYPE_STRING, &state,
+ DBUS_TYPE_INVALID);
+
+ g_dbus_send_message(connection, signal);
}
static void technology_connected(enum connman_service_type type,
{
DBG("type %d connected %d", type, connected);
- __connman_technology_set_connected(type, connected);
- state_changed();
+ connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE, "ConnectedTechnologies",
+ DBUS_TYPE_STRING, __connman_notifier_list_connected, NULL);
+
+ state_changed(connected);
}
-void __connman_notifier_connect(enum connman_service_type type)
+void __connman_notifier_register(enum connman_service_type type)
{
DBG("type %d", type);
break;
}
- if (__sync_fetch_and_add(&connected[type], 1) == 0)
- technology_connected(type, TRUE);
+ if (__sync_fetch_and_add(®istered[type], 1) == 0)
+ technology_registered(type, TRUE);
}
-void __connman_notifier_enter_online(enum connman_service_type type)
+void __connman_notifier_unregister(enum connman_service_type type)
{
DBG("type %d", type);
- if (__sync_fetch_and_add(&online[type], 1) == 0)
- state_changed();
+ __sync_synchronize();
+ if (registered[type] == 0) {
+ connman_error("notifier unregister underflow");
+ return;
+ }
+
+ switch (type) {
+ case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_GPS:
+ case CONNMAN_SERVICE_TYPE_VPN:
+ case CONNMAN_SERVICE_TYPE_GADGET:
+ return;
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ case CONNMAN_SERVICE_TYPE_WIMAX:
+ case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ break;
+ }
+
+ if (__sync_fetch_and_sub(®istered[type], 1) != 1)
+ return;
+
+ technology_registered(type, FALSE);
}
-void __connman_notifier_leave_online(enum connman_service_type type)
+void __connman_notifier_enable(enum connman_service_type type)
{
DBG("type %d", type);
- if (__sync_fetch_and_sub(&online[type], 1) == 1)
- state_changed();
+ switch (type) {
+ case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_GPS:
+ case CONNMAN_SERVICE_TYPE_VPN:
+ case CONNMAN_SERVICE_TYPE_GADGET:
+ return;
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ case CONNMAN_SERVICE_TYPE_WIMAX:
+ case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ break;
+ }
+
+ if (__sync_fetch_and_add(&enabled[type], 1) == 0)
+ technology_enabled(type, TRUE);
+}
+
+void __connman_notifier_disable(enum connman_service_type type)
+{
+ DBG("type %d", type);
+
+ __sync_synchronize();
+ if (enabled[type] == 0) {
+ connman_error("notifier disable underflow");
+ return;
+ }
+
+ switch (type) {
+ case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_GPS:
+ case CONNMAN_SERVICE_TYPE_VPN:
+ case CONNMAN_SERVICE_TYPE_GADGET:
+ return;
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ case CONNMAN_SERVICE_TYPE_WIMAX:
+ case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ break;
+ }
+
+ if (__sync_fetch_and_sub(&enabled[type], 1) != 1)
+ return;
+
+ technology_enabled(type, FALSE);
+}
+
+void __connman_notifier_connect(enum connman_service_type type)
+{
+ DBG("type %d", type);
+
+ switch (type) {
+ case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_GPS:
+ case CONNMAN_SERVICE_TYPE_VPN:
+ case CONNMAN_SERVICE_TYPE_GADGET:
+ return;
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ case CONNMAN_SERVICE_TYPE_WIMAX:
+ case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ break;
+ }
+
+ if (__sync_fetch_and_add(&connected[type], 1) == 0)
+ technology_connected(type, TRUE);
}
void __connman_notifier_disconnect(enum connman_service_type type)
technology_connected(type, FALSE);
}
+static void technology_default(enum connman_service_type type)
+{
+ const char *str;
+
+ str = __connman_service_type2string(type);
+ if (str == NULL)
+ str = "";
+
+ connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE, "DefaultTechnology",
+ DBUS_TYPE_STRING, &str);
+}
+
void __connman_notifier_default_changed(struct connman_service *service)
{
+ enum connman_service_type type = connman_service_get_type(service);
+ char *interface;
GSList *list;
+ technology_default(type);
+
+ interface = connman_service_get_interface(service);
+#if !defined TIZEN_EXT
+/*
+ * Description: Tethering service is provided by external module in TIZEN
+ */
+ __connman_tethering_update_interface(interface);
+#endif
+ g_free(interface);
+
for (list = notifier_list; list; list = list->next) {
struct connman_notifier *notifier = list->data;
DBG("enabled %d", enabled);
offlinemode_changed(enabled);
- state_changed();
for (list = notifier_list; list; list = list->next) {
struct connman_notifier *notifier = list->data;
}
}
+#if defined TIZEN_EXT
+/*
+ * August 22nd, 2011. TIZEN
+ *
+ * This part is added to send a DBus signal which means scan is completed
+ * because scan UX of a Wi-Fi setting application has an active scan procedure
+ * and it needs scan complete signal whether success or not
+ */
+
+void __connman_notifier_scan_completed(connman_bool_t success)
+{
+ DBG("scan completed : %s", success == TRUE ? "success" : "failed");
+
+ connman_dbus_scan_completed_basic(CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE, DBUS_TYPE_BOOLEAN, &success);
+}
+#endif
+
void __connman_notifier_service_state_changed(struct connman_service *service,
enum connman_service_state state)
{
}
}
+static connman_bool_t technology_supported(enum connman_service_type type)
+{
+ switch (type) {
+ case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_GPS:
+ case CONNMAN_SERVICE_TYPE_VPN:
+ case CONNMAN_SERVICE_TYPE_GADGET:
+ return FALSE;
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ case CONNMAN_SERVICE_TYPE_WIMAX:
+ case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ break;
+ }
+
+ return TRUE;
+}
+
+connman_bool_t __connman_notifier_is_registered(enum connman_service_type type)
+{
+ DBG("type %d", type);
+
+ if (technology_supported(type) == FALSE)
+ return FALSE;
+
+ __sync_synchronize();
+ if (registered[type] > 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+connman_bool_t __connman_notifier_is_enabled(enum connman_service_type type)
+{
+ DBG("type %d", type);
+
+ if (technology_supported(type) == FALSE)
+ return FALSE;
+
+ __sync_synchronize();
+ if (enabled[type] > 0)
+ return TRUE;
+
+ return FALSE;
+}
+
int __connman_notifier_init(void)
{
DBG("");
service_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
NULL, NULL);
- notifier_state = evaluate_notifier_state();
return 0;
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <glib.h>
+#include <gweb/gresolv.h>
+
#include "connman.h"
struct ntp_short {
#define LOGTOD(a) ((a) < 0 ? 1. / (1L << -(a)) : 1L << (int)(a))
-static guint channel_watch = 0;
static struct timeval transmit_timeval;
-static int transmit_fd = 0;
-
-static char *timeserver = NULL;
-static gint poll_id = 0;
-static gint timeout_id = 0;
+static char *transmit_server;
+static int transmit_fd;
+static guint transmit_delay = 16;
static void send_packet(int fd, const char *server)
{
}
}
-static gboolean next_server(gpointer user_data)
-{
- if (timeserver != NULL) {
- g_free(timeserver);
- timeserver = NULL;
- }
-
- __connman_timeserver_sync_next();
-
- return FALSE;
-}
-
-static gboolean next_poll(gpointer user_data)
+static gboolean next_request(gpointer user_data)
{
- if (timeserver == NULL || transmit_fd == 0)
- return FALSE;
+ DBG("server %s", transmit_server);
- send_packet(transmit_fd, timeserver);
+ send_packet(transmit_fd, transmit_server);
return FALSE;
}
struct ntp_msg *msg = base;
double org, rec, xmt, dst;
double delay, offset;
- static guint transmit_delay;
if (len < sizeof(*msg)) {
connman_error("Invalid response from time server");
DBG("offset=%f delay=%f", offset, delay);
- /* Remove the timeout, as timeserver has responded */
- if (timeout_id > 0)
- g_source_remove(timeout_id);
-
- /*
- * Now poll the server every transmit_delay seconds
- * for time correction.
- */
- if (poll_id > 0)
- g_source_remove(poll_id);
-
- DBG("Timeserver %s, next sync in %d seconds", timeserver, transmit_delay);
-
- poll_id = g_timeout_add_seconds(transmit_delay, next_poll, NULL);
-
- connman_info("ntp: time slew %+.6f s", offset);
-
if (offset < STEPTIME_MIN_OFFSET && offset > -STEPTIME_MIN_OFFSET) {
struct timeval adj;
}
}
+static guint channel_watch = 0;
+
static gboolean received_data(GIOChannel *channel, GIOCondition condition,
gpointer user_data)
{
decode_msg(iov.iov_base, iov.iov_len, tv);
+ g_timeout_add_seconds(transmit_delay, next_request, NULL);
+
return TRUE;
}
-static void start_ntp(char *server)
+static void start_ntp(const char *server)
{
GIOChannel *channel;
struct sockaddr_in addr;
- int tos = IPTOS_LOWDELAY, timestamp = 1;
-
- if (server == NULL)
- return;
+ int fd, tos = IPTOS_LOWDELAY, timestamp = 1;
DBG("server %s", server);
if (channel_watch > 0)
- goto send;
+ return;
- transmit_fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
- if (transmit_fd < 0) {
+ fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ if (fd < 0) {
connman_error("Failed to open time server socket");
return;
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
- if (bind(transmit_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
connman_error("Failed to bind time server socket");
- close(transmit_fd);
+ close(fd);
return;
}
- if (setsockopt(transmit_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) {
+ if (setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) {
connman_error("Failed to set type of service option");
- close(transmit_fd);
+ close(fd);
return;
}
- if (setsockopt(transmit_fd, SOL_SOCKET, SO_TIMESTAMP, ×tamp,
+ if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, ×tamp,
sizeof(timestamp)) < 0) {
connman_error("Failed to enable timestamp support");
- close(transmit_fd);
+ close(fd);
return;
}
- channel = g_io_channel_unix_new(transmit_fd);
+ channel = g_io_channel_unix_new(fd);
if (channel == NULL) {
- close(transmit_fd);
+ close(fd);
return;
}
g_io_channel_unref(channel);
-send:
- send_packet(transmit_fd, server);
+ transmit_fd = fd;
+ transmit_server = g_strdup(server);
+
+ send_packet(fd, server);
}
-int __connman_ntp_start(char *server)
+static void resolv_debug(const char *str, void *data)
{
- DBG("%s", server);
+ connman_info("%s: %s\n", (const char *) data, str);
+}
- if (server == NULL)
- return -EINVAL;
+static GResolv *resolv = NULL;
+static guint resolv_lookup = 0;
- if (timeserver != NULL)
- g_free(timeserver);
+static void resolv_result(GResolvResultStatus status,
+ char **results, gpointer user_data)
+{
+ int i;
- timeserver = g_strdup(server);
+ resolv_lookup = 0;
- start_ntp(timeserver);
+ if (results != NULL) {
+ for (i = 0; results[i]; i++)
+ DBG("result: %s", results[i]);
- /*
- * Add a fallback timeout , preferably short, 5 sec here,
- * to fallback on the next server.
- */
+ if (results[0] != NULL)
+ start_ntp(results[0]);
+ }
+}
- timeout_id = g_timeout_add_seconds(5, next_server, NULL);
+int __connman_ntp_start(const char *interface, const char *resolver,
+ const char *server)
+{
+ DBG("interface %s server %s", interface, server);
+
+ resolv = g_resolv_new(0);
+ if (resolv == NULL)
+ return -ENOMEM;
+
+ if (getenv("CONNMAN_RESOLV_DEBUG"))
+ g_resolv_set_debug(resolv, resolv_debug, "RESOLV");
+
+ if (resolver != NULL)
+ g_resolv_add_nameserver(resolv, resolver, 53, 0);
+
+ g_resolv_lookup_hostname(resolv, server, resolv_result, NULL);
return 0;
}
-void __connman_ntp_stop()
+void __connman_ntp_stop(const char *interface)
{
- DBG("");
+ DBG("interface %s", interface);
- if (poll_id > 0)
- g_source_remove(poll_id);
+ if (resolv == NULL)
+ return;
- if (timeout_id > 0)
- g_source_remove(timeout_id);
+ if (resolv_lookup > 0) {
+ g_resolv_cancel_lookup(resolv, resolv_lookup);
+ resolv_lookup = 0;
+ }
if (channel_watch > 0) {
g_source_remove(channel_watch);
channel_watch = 0;
- transmit_fd = 0;
}
- if (timeserver != NULL) {
- g_free(timeserver);
- timeserver = NULL;
- }
+ g_resolv_unref(resolv);
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
struct connman_provider_driver *driver;
void *driver_data;
GHashTable *setting_strings;
- GHashTable *user_routes;
- gchar **user_networks;
- gsize num_user_networks;
};
void __connman_provider_append_properties(struct connman_provider *provider,
&provider->type);
}
-int __connman_provider_append_user_route(struct connman_provider *provider,
- int family, const char *network, const char *netmask)
-{
- struct connman_route *route;
- char *key = g_strdup_printf("%d/%s/%s", family, network, netmask);
-
- DBG("family %d network %s netmask %s", family, network, netmask);
-
- route = g_hash_table_lookup(provider->user_routes, key);
- if (route == NULL) {
- route = g_try_new0(struct connman_route, 1);
- if (route == NULL) {
- connman_error("out of memory");
- return -ENOMEM;
- }
-
- route->family = family;
- route->host = g_strdup(network);
- route->netmask = g_strdup(netmask);
-
- g_hash_table_replace(provider->user_routes, key, route);
- } else
- g_free(key);
-
- return 0;
-}
-
-static void set_user_networks(struct connman_provider *provider,
- char **networks)
-{
- int i = 0;
-
- while (networks[i] != NULL) {
- char **elems = g_strsplit(networks[i], "/", 0);
- char *network, *netmask;
- int family = PF_UNSPEC, ret;
-
- if (elems == NULL)
- break;
-
- network = elems[0];
- if (network == NULL || *network == '\0') {
- DBG("no network/netmask set");
- g_strfreev(elems);
- break;
- }
-
- netmask = elems[1];
- if (netmask != NULL && *netmask == '\0') {
- DBG("no netmask set");
- g_strfreev(elems);
- break;
- }
-
- if (g_strrstr(network, ":") != NULL)
- family = AF_INET6;
- else if (g_strrstr(network, ".") != NULL) {
- family = AF_INET;
-
- if (g_strrstr(netmask, ".") == NULL) {
- /* We have netmask length */
- in_addr_t addr;
- struct in_addr netmask_in;
- unsigned char prefix_len = 32;
-
- if (netmask != NULL)
- prefix_len = atoi(netmask);
-
- addr = 0xffffffff << (32 - prefix_len);
- netmask_in.s_addr = htonl(addr);
- netmask = inet_ntoa(netmask_in);
-
- DBG("network %s netmask %s", network, netmask);
- }
- }
-
- ret = __connman_provider_append_user_route(provider,
- family, network, netmask);
- g_strfreev(elems);
-
- if (ret != 0)
- break;
-
- i++;
- }
-}
-
-static int provider_load_from_keyfile(struct connman_provider *provider,
- GKeyFile *keyfile)
+static int connman_provider_load(struct connman_provider *provider)
{
gsize idx = 0;
+ GKeyFile *keyfile;
gchar **settings;
gchar *key, *value;
gsize length;
+ DBG("provider %p", provider);
+
+ keyfile = __connman_storage_load_provider(provider->identifier);
+ if (keyfile == NULL)
+ return -ENOENT;
+
settings = g_key_file_get_keys(keyfile, provider->identifier, &length,
NULL);
if (settings == NULL) {
while (idx < length) {
key = settings[idx];
+ DBG("found key %s", key);
if (key != NULL) {
- if (g_str_equal(key, "Networks") == TRUE) {
- g_strfreev(provider->user_networks);
- provider->user_networks =
- g_key_file_get_string_list(keyfile,
+ value = g_key_file_get_string(keyfile,
provider->identifier,
- key,
- &provider->num_user_networks,
- NULL);
- } else {
- value = g_key_file_get_string(keyfile,
- provider->identifier,
- key, NULL);
- connman_provider_set_string(provider, key,
- value);
- g_free(value);
- }
+ key, NULL);
+ connman_provider_set_string(provider, key, value);
+ g_free(value);
}
idx += 1;
}
g_strfreev(settings);
- if (provider->user_networks != NULL)
- set_user_networks(provider, provider->user_networks);
-
- return 0;
-}
-
-static int connman_provider_load(struct connman_provider *provider)
-{
- GKeyFile *keyfile;
-
- DBG("provider %p", provider);
-
- keyfile = __connman_storage_load_provider(provider->identifier);
- if (keyfile == NULL)
- return -ENOENT;
-
- provider_load_from_keyfile(provider, keyfile);
-
g_key_file_free(keyfile);
return 0;
}
"Host", provider->host);
g_key_file_set_string(keyfile, provider->identifier,
"VPN.Domain", provider->domain);
- if (provider->user_networks != NULL)
- g_key_file_set_string_list(keyfile, provider->identifier,
- "Networks",
- (const gchar **)provider->user_networks,
- provider->num_user_networks);
if (provider->driver != NULL && provider->driver->save != NULL)
provider->driver->save(provider, keyfile);
static int provider_register(struct connman_provider *provider)
{
+ connman_provider_load(provider);
return provider_probe(provider);
}
provider_remove(provider);
}
-struct connman_provider *
-connman_provider_ref_debug(struct connman_provider *provider,
- const char *file, int line, const char *caller)
+struct connman_provider *connman_provider_ref(struct connman_provider *provider)
{
- DBG("%p ref %d by %s:%d:%s()", provider, provider->refcount + 1,
- file, line, caller);
+ DBG("provider %p refcount %d", provider, provider->refcount + 1);
__sync_fetch_and_add(&provider->refcount, 1);
g_free(provider->host);
g_free(provider->domain);
g_free(provider->identifier);
- g_strfreev(provider->user_networks);
g_hash_table_destroy(provider->routes);
- g_hash_table_destroy(provider->user_routes);
g_hash_table_destroy(provider->setting_strings);
- g_free(provider);
}
-void connman_provider_unref_debug(struct connman_provider *provider,
- const char *file, int line, const char *caller)
+void connman_provider_unref(struct connman_provider *provider)
{
- DBG("%p ref %d by %s:%d:%s()", provider, provider->refcount - 1,
- file, line, caller);
+ DBG("provider %p refcount %d", provider, provider->refcount - 1);
if (__sync_fetch_and_sub(&provider->refcount, 1) != 1)
return;
}
__connman_ipconfig_address_add(ipconfig);
+#if defined TIZEN_EXT
+/*
+ * Description: __connman_service_lookup_from_index cannot find correct service
+ */
+ __connman_ipconfig_gateway_add(ipconfig, service);
+#else
__connman_ipconfig_gateway_add(ipconfig);
+#endif
provider_indicate_state(provider,
CONNMAN_SERVICE_STATE_READY);
g_hash_table_foreach(provider->routes, provider_append_routes,
provider);
- g_hash_table_foreach(provider->user_routes, provider_append_routes,
- provider);
-
} else {
if (ipconfig != NULL) {
provider_indicate_state(provider,
enum connman_provider_error error)
{
enum connman_service_error service_error;
+ const char *path;
+ int ret;
switch (error) {
case CONNMAN_PROVIDER_ERROR_LOGIN_FAILED:
break;
}
- return __connman_service_indicate_error(provider->vpn_service,
+ ret = __connman_service_indicate_error(provider->vpn_service,
service_error);
+ path = __connman_service_get_path(provider->vpn_service);
+ __connman_provider_remove(path);
+
+ return ret;
}
static void unregister_provider(gpointer data)
{
struct connman_provider *provider = data;
+ struct connman_service *service = provider->vpn_service;
- DBG("provider %p service %p", provider, provider->vpn_service);
+ DBG("provider %p", provider);
- if (provider->vpn_service != NULL) {
- connman_service_unref(provider->vpn_service);
- provider->vpn_service = NULL;
- }
+ provider->vpn_service = NULL;
+ __connman_service_put(service);
connman_provider_unref(provider);
}
provider->type = NULL;
provider->domain = NULL;
provider->identifier = NULL;
- provider->user_networks = NULL;
provider->routes = g_hash_table_new_full(g_direct_hash, g_direct_equal,
NULL, destroy_route);
- provider->user_routes = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, destroy_route);
provider->setting_strings = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, g_free);
}
g_hash_table_insert(provider_hash, provider->identifier, provider);
+ provider->name = g_strdup(identifier);
+
return provider;
}
}
}
-static struct connman_provider *provider_create_from_keyfile(GKeyFile *keyfile,
- const char *ident)
-{
- struct connman_provider *provider;
-
- if (keyfile == NULL || ident == NULL)
- return NULL;
-
- provider = connman_provider_lookup(ident);
- if (provider == NULL) {
- provider = connman_provider_get(ident);
- if (provider == NULL) {
- DBG("can not create provider");
- return NULL;
- }
-
- provider_load_from_keyfile(provider, keyfile);
-
- if (provider->name == NULL || provider->host == NULL ||
- provider->domain == NULL) {
- DBG("cannot get name, host or domain");
- connman_provider_unref(provider);
- return NULL;
- }
-
- provider_register(provider);
- }
- return provider;
-}
-
-static int provider_create_service(struct connman_provider *provider)
-{
- if (provider->vpn_service != NULL)
- return -EALREADY;
-
- provider->vpn_service =
- __connman_service_create_from_provider(provider);
-
- if (provider->vpn_service == NULL)
- return -EOPNOTSUPP;
-
- return 0;
-}
-
-static void provider_create_all_from_type(const char *provider_type)
-{
- unsigned int i;
- char **providers;
- char *id, *type;
- GKeyFile *keyfile;
- struct connman_provider *provider;
-
- DBG("provider type %s", provider_type);
-
- providers = __connman_storage_get_providers();
-
- for (i = 0; providers[i] != NULL; i+=1) {
-
- if (strncmp(providers[i], "provider_", 9) != 0)
- continue;
-
- id = providers[i] + 9;
- keyfile = __connman_storage_load_provider(id);
-
- if (keyfile == NULL)
- continue;
-
- type = g_key_file_get_string(keyfile, id, "Type", NULL);
-
- DBG("keyfile %p id %s type %s", keyfile, id, type);
-
- if (strcmp(provider_type, type) != 0) {
- g_free(type);
- g_key_file_free(keyfile);
- continue;
- }
-
- provider = provider_create_from_keyfile(keyfile, id);
- if (provider != NULL) {
- if (provider_create_service(provider) == -EOPNOTSUPP) {
- DBG("could not create service");
- connman_provider_unref(provider);
- }
- }
-
- g_free(type);
- g_key_file_free(keyfile);
- }
- g_strfreev(providers);
-}
-
-static char **get_user_networks(DBusMessageIter *array, int *count)
-{
- DBusMessageIter entry;
- char **networks = NULL;
- GSList *list = NULL, *l;
- int len;
-
- dbus_message_iter_recurse(array, &entry);
-
- while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
- const char *val;
- dbus_message_iter_get_basic(&entry, &val);
-
- list = g_slist_prepend(list, g_strdup(val));
- dbus_message_iter_next(&entry);
- }
-
- len = g_slist_length(list);
- if (len == 0)
- goto out;
-
- networks = g_try_new(char *, len + 1);
- if (networks == NULL)
- goto out;
-
- *count = len;
- networks[len] = 0;
-
- for (l = list; l != NULL; l = g_slist_next(l))
- networks[--len] = l->data;
-
-out:
- g_slist_free(list);
-
- return networks;
-}
-
int __connman_provider_create_and_connect(DBusMessage *msg)
{
struct connman_provider *provider;
DBusMessageIter iter, array;
const char *type = NULL, *name = NULL, *service_path;
const char *host = NULL, *domain = NULL;
- char **networks = NULL;
char *ident;
- int err, count = 0;
+ int err;
dbus_message_iter_init(msg, &iter);
dbus_message_iter_recurse(&iter, &array);
else if (g_str_equal(key, "VPN.Domain") == TRUE)
dbus_message_iter_get_basic(&value, &domain);
break;
- case DBUS_TYPE_ARRAY:
- if (g_str_equal(key, "Networks") == TRUE)
- networks = get_user_networks(&value, &count);
- break;
}
dbus_message_iter_next(&array);
if (host == NULL || domain == NULL)
return -EINVAL;
- DBG("Type %s name %s networks %p", type, name, networks);
+ DBG("Type %s name %s", type, name);
if (type == NULL || name == NULL)
return -EOPNOTSUPP;
provider->host = g_strdup(host);
provider->domain = g_strdup(domain);
+ g_free(provider->name);
provider->name = g_strdup(name);
provider->type = g_strdup(type);
- if (provider_register(provider) == 0)
- connman_provider_load(provider);
- }
-
- if (networks != NULL) {
- g_strfreev(provider->user_networks);
- provider->user_networks = networks;
- provider->num_user_networks = count;
- set_user_networks(provider, provider->user_networks);
+ provider_register(provider);
}
dbus_message_iter_init(msg, &iter);
g_free(ident);
- err = provider_create_service(provider);
- if (err == -EALREADY) {
- DBG("provider already connected");
- } else {
- if (err == -EOPNOTSUPP) {
+ if (provider->vpn_service == NULL) {
+ provider->vpn_service =
+ __connman_service_create_from_provider(provider);
+ if (provider->vpn_service == NULL) {
+ err = -EOPNOTSUPP;
goto unref;
- } else {
- err = __connman_service_connect(provider->vpn_service);
-
- if (err < 0 && err != -EINPROGRESS)
- goto failed;
}
- }
+
+ err = __connman_service_connect(provider->vpn_service);
+ if (err < 0 && err != -EINPROGRESS)
+ goto failed;
+ } else
+ DBG("provider already connected");
connman_provider_save(provider);
service_path = __connman_service_get_path(provider->vpn_service);
return 0;
failed:
- connman_service_unref(provider->vpn_service);
+ __connman_service_put(provider->vpn_service);
provider->vpn_service = NULL;
unref:
DBG("can not connect, delete provider");
- g_hash_table_remove(provider_hash, provider->identifier);
+ connman_provider_unref(provider);
return err;
}
return g_hash_table_lookup(provider->setting_strings, key);
}
-connman_bool_t
-__connman_provider_check_routes(struct connman_provider *provider)
-{
- if (provider == NULL)
- return FALSE;
-
- if (provider->user_routes != NULL &&
- g_hash_table_size(provider->user_routes) > 0)
- return TRUE;
-
- if (provider->routes != NULL &&
- g_hash_table_size(provider->routes) > 0)
- return TRUE;
-
- return FALSE;
-}
-
void *connman_provider_get_data(struct connman_provider *provider)
{
return provider->driver_data;
}
}
- __connman_ipconfig_set_method(ipconfig, CONNMAN_IPCONFIG_METHOD_FIXED);
+ connman_ipconfig_set_method(ipconfig, CONNMAN_IPCONFIG_METHOD_FIXED);
__connman_ipconfig_set_index(ipconfig, index);
}
}
- __connman_ipconfig_set_method(ipconfig, CONNMAN_IPCONFIG_METHOD_OFF);
+ connman_ipconfig_set_method(ipconfig, CONNMAN_IPCONFIG_METHOD_OFF);
__connman_ipconfig_set_index(ipconfig, index);
done:
driver_list = g_slist_insert_sorted(driver_list, driver,
compare_priority);
- provider_create_all_from_type(driver->name);
return 0;
}
}
-static struct connman_provider *provider_get(int index)
-{
- GHashTableIter iter;
- gpointer value, key;
-
- g_hash_table_iter_init(&iter, provider_hash);
-
- while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
- struct connman_provider *provider = value;
-
- if (provider->index == index)
- return provider;
- }
-
- return NULL;
-}
-
-static void provider_service_changed(struct connman_service *service,
- enum connman_service_state state)
-{
- struct connman_provider *provider;
- int vpn_index, service_index;
-
- if (service == NULL)
- return;
-
- switch (state) {
- case CONNMAN_SERVICE_STATE_UNKNOWN:
- case CONNMAN_SERVICE_STATE_IDLE:
- case CONNMAN_SERVICE_STATE_ASSOCIATION:
- case CONNMAN_SERVICE_STATE_CONFIGURATION:
- case CONNMAN_SERVICE_STATE_READY:
- case CONNMAN_SERVICE_STATE_ONLINE:
- return;
- case CONNMAN_SERVICE_STATE_DISCONNECT:
- case CONNMAN_SERVICE_STATE_FAILURE:
- break;
- }
-
- service_index = __connman_service_get_index(service);
-
- vpn_index = __connman_connection_get_vpn_index(service_index);
-
- DBG("service %p %s state %d index %d/%d", service,
- __connman_service_get_ident(service),
- state, service_index, vpn_index);
-
- if (vpn_index < 0)
- return;
-
- provider = provider_get(vpn_index);
- if (provider == NULL)
- return;
-
- DBG("disconnect %p index %d", provider, vpn_index);
-
- __connman_provider_disconnect(provider);
-
- return;
-}
-
static struct connman_notifier provider_notifier = {
.name = "provider",
.offline_mode = provider_offline_mode,
- .service_state_changed = provider_service_changed,
};
int __connman_provider_init(void)
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
{
lookup_list = g_slist_remove(lookup_list, lookup);
- connman_service_unref(lookup->service);
g_free(lookup->url);
g_free(lookup);
}
lookup->cb = cb;
lookup->user_data = user_data;
lookup->url = g_strdup(url);
- lookup->service = connman_service_ref(service);
+ lookup->service = service;
lookup->watch = g_timeout_add_seconds(0, lookup_callback, lookup);
if (lookup->watch == 0) {
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#define RESOLVER_FLAG_PUBLIC (1 << 0)
-/*
- * Threshold for RDNSS lifetime. Will be used to trigger RS
- * before RDNSS entries actually expire
- */
-#define RESOLVER_LIFETIME_REFRESH_THRESHOLD 0.8
-
struct entry_data {
char *interface;
char *domain;
char *server;
unsigned int flags;
- unsigned int lifetime;
guint timeout;
};
old_umask = umask(022);
+#if defined TIZEN_EXT
+/*
+ * Description: /etc path is read-only in SLP
+ * /opt/etc/resolv.conf rather than /etc/resolv.conf
+ */
+ fd = open("/opt/etc/resolv.conf", O_RDWR | O_CREAT | O_CLOEXEC,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+#else
fd = open("/etc/resolv.conf", O_RDWR | O_CREAT | O_CLOEXEC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+#endif
if (fd < 0) {
err = -errno;
goto done;
return FALSE;
}
-static gboolean resolver_refresh_cb(gpointer user_data)
-{
- struct entry_data *entry = user_data;
- int index;
- unsigned int interval;
- struct connman_service *service = NULL;
-
- /* Round up what we have left from lifetime */
- interval = entry->lifetime *
- (1 - RESOLVER_LIFETIME_REFRESH_THRESHOLD) + 1.0;
-
- DBG("RDNSS start interface %s domain %s "
- "server %s remaining lifetime %d",
- entry->interface, entry->domain,
- entry->server, interval);
-
- entry->timeout = g_timeout_add_seconds(interval,
- resolver_expire_cb, entry);
-
- index = connman_inet_ifindex(entry->interface);
- if (index >= 0) {
- service = __connman_service_lookup_from_index(index);
- if (service != NULL) {
- /*
- * Send Router Solicitation to refresh RDNSS entries
- * before their lifetime expires
- */
- __connman_refresh_rs_ipv6(
- __connman_service_get_network(service),
- index);
- }
- }
- return FALSE;
-}
-
static int append_resolver(const char *interface, const char *domain,
const char *server, unsigned int lifetime,
unsigned int flags)
{
struct entry_data *entry;
- unsigned int interval;
DBG("interface %s domain %s server %s lifetime %d flags %d",
interface, domain, server, lifetime, flags);
entry->domain = g_strdup(domain);
entry->server = g_strdup(server);
entry->flags = flags;
- entry->lifetime = lifetime;
if (lifetime) {
int index;
- interval = lifetime * RESOLVER_LIFETIME_REFRESH_THRESHOLD;
-
- DBG("RDNSS start interface %s domain %s "
- "server %s lifetime threshold %d",
- interface, domain, server, interval);
-
- entry->timeout = g_timeout_add_seconds(interval,
- resolver_refresh_cb, entry);
+ entry->timeout = g_timeout_add_seconds(lifetime,
+ resolver_expire_cb, entry);
/*
* We update the service only for those nameservers
* that are automagically added via netlink (lifetime > 0)
*/
index = connman_inet_ifindex(interface);
- if (server != NULL && index >= 0) {
+ if (index >= 0) {
struct connman_service *service;
service = __connman_service_lookup_from_index(index);
if (service != NULL)
int connman_resolver_append(const char *interface, const char *domain,
const char *server)
{
- GSList *list;
+ GSList *list, *matches = NULL;
DBG("interface %s domain %s server %s", interface, domain, server);
for (list = entry_list; list; list = list->next) {
struct entry_data *entry = list->data;
- if (entry->timeout > 0)
+ if (entry->timeout > 0 ||
+ g_strcmp0(entry->interface, interface) != 0 ||
+ g_strcmp0(entry->domain, domain) != 0 ||
+ g_strcmp0(entry->server, server) != 0)
continue;
- if (g_strcmp0(entry->interface, interface) == 0 &&
- g_strcmp0(entry->domain, domain) == 0 &&
- g_strcmp0(entry->server, server) == 0)
- return -EEXIST;
+ matches = g_slist_append(matches, entry);
}
+ if (matches != NULL)
+ remove_entries(matches);
+
return append_resolver(interface, domain, server, 0, 0);
}
const char *server, unsigned int lifetime)
{
GSList *list;
- unsigned int interval;
DBG("interface %s domain %s server %s lifetime %d",
interface, domain, server, lifetime);
- if (server == NULL && domain == NULL)
+ if (server == NULL)
return -EINVAL;
for (list = entry_list; list; list = list->next) {
struct entry_data *entry = list->data;
- if (entry->timeout == 0 ||
- g_strcmp0(entry->interface, interface) != 0 ||
- g_strcmp0(entry->domain, domain) != 0 ||
- g_strcmp0(entry->server, server) != 0)
+ if (!entry->timeout ||
+ g_strcmp0(entry->interface, interface) ||
+ g_strcmp0(entry->domain, domain) ||
+ g_strcmp0(entry->server, server))
continue;
g_source_remove(entry->timeout);
return 0;
}
- interval = lifetime * RESOLVER_LIFETIME_REFRESH_THRESHOLD;
-
- DBG("RDNSS start interface %s domain %s "
- "server %s lifetime threshold %d",
- interface, domain, server, interval);
-
- entry->timeout = g_timeout_add_seconds(interval,
- resolver_refresh_cb, entry);
+ entry->timeout = g_timeout_add_seconds(lifetime,
+ resolver_expire_cb, entry);
return 0;
}
DBG("interface %s domain %s server %s", interface, domain, server);
+ if (server == NULL)
+ return -EINVAL;
+
for (list = entry_list; list; list = list->next) {
struct entry_data *entry = list->data;
- if (g_strcmp0(entry->interface, interface) != 0)
+ if (interface != NULL &&
+ g_strcmp0(entry->interface, interface) != 0)
continue;
- if (g_strcmp0(entry->domain, domain) != 0)
+ if (domain != NULL && g_strcmp0(entry->domain, domain) != 0)
continue;
if (g_strcmp0(entry->server, server) != 0)
continue;
matches = g_slist_append(matches, entry);
- break;
}
if (matches == NULL)
}
/**
- * connman_resolver_flush:
+ * connman_resolver_append_public_server:
+ * @server: server address
*
- * Flush pending resolver requests
+ * Append public resolver server address to current list
*/
-void connman_resolver_flush(void)
+int connman_resolver_append_public_server(const char *server)
{
- if (dnsproxy_enabled == TRUE)
- __connman_dnsproxy_flush();
+ DBG("server %s", server);
- return;
+ return append_resolver(NULL, NULL, server, 0, RESOLVER_FLAG_PUBLIC);
}
-int __connman_resolver_redo_servers(const char *interface)
+/**
+ * connman_resolver_remove_public_server:
+ * @server: server address
+ *
+ * Remove public resolver server address to current list
+ */
+int connman_resolver_remove_public_server(const char *server)
{
- GSList *list;
-
- if (dnsproxy_enabled == FALSE)
- return 0;
-
- DBG("interface %s", interface);
-
- if (interface == NULL)
- return -EINVAL;
-
- for (list = entry_list; list; list = list->next) {
- struct entry_data *entry = list->data;
-
- if (entry->timeout == 0 ||
- g_strcmp0(entry->interface, interface) != 0)
- continue;
-
- /*
- * We remove the server, and then re-create so that it will
- * use proper source addresses when sending DNS queries.
- */
- __connman_dnsproxy_remove(entry->interface, entry->domain,
- entry->server);
- /*
- * Remove also the resolver timer for the old server entry.
- * A new timer will be set for the new server entry
- * when the next Router Advertisement message arrives
- * with RDNSS/DNSSL settings.
- */
- g_source_remove(entry->timeout);
-
- __connman_dnsproxy_append(entry->interface, entry->domain,
- entry->server);
- }
+ DBG("server %s", server);
- return 0;
+ return connman_resolver_remove(NULL, NULL, server);
}
-static void free_entry(gpointer data)
+/**
+ * connman_resolver_flush:
+ *
+ * Flush pending resolver requests
+ */
+void connman_resolver_flush(void)
{
- struct entry_data *entry = data;
- g_free(entry->interface);
- g_free(entry->domain);
- g_free(entry->server);
- g_free(entry);
-}
+ if (dnsproxy_enabled == TRUE)
+ __connman_dnsproxy_flush();
-static void free_resolvfile(gpointer data)
-{
- struct resolvfile_entry *entry = data;
- g_free(entry->interface);
- g_free(entry->domain);
- g_free(entry->server);
- g_free(entry);
+ return;
}
int __connman_resolver_init(connman_bool_t dnsproxy)
{
- int i;
- char **ns;
-
DBG("dnsproxy %d", dnsproxy);
if (dnsproxy == FALSE)
dnsproxy_enabled = TRUE;
- ns = connman_setting_get_string_list("FallbackNameservers");
- for (i = 0; ns != NULL && ns[i] != NULL; i += 1) {
- DBG("server %s", ns[i]);
- append_resolver(NULL, NULL, ns[i], 0, RESOLVER_FLAG_PUBLIC);
- }
-
return 0;
}
if (dnsproxy_enabled == TRUE)
__connman_dnsproxy_cleanup();
- else {
- GList *list;
- GSList *slist;
-
- for (list = resolvfile_list; list; list = g_list_next(list))
- free_resolvfile(list->data);
- g_list_free(resolvfile_list);
- resolvfile_list = NULL;
-
- for (slist = entry_list; slist; slist = g_slist_next(slist))
- free_entry(slist->data);
- g_slist_free(entry_list);
- entry_list = NULL;
- }
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
DBG("type %d block %d", type, block);
rfkill_type = convert_service_type(type);
+#if defined TIZEN_EXT
+ DBG("try to set rfkill block %d and type %d, but it's not permitted",
+ block, rfkill_type);
+ return 0;
+#endif
if (rfkill_type == NUM_RFKILL_TYPES)
return -EINVAL;
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
if (name == NULL)
return TRUE;
- if (__connman_device_isfiltered(name) == TRUE)
+ /* virtual interface from VMware */
+ if (g_str_has_prefix(name, "vmnet") == TRUE)
+ return TRUE;
+
+ /* virtual interface from VirtualBox */
+ if (g_str_has_prefix(name, "vboxnet") == TRUE)
+ return TRUE;
+
+ /* virtual interface from Virtual Machine Manager */
+ if (g_str_has_prefix(name, "virbr") == TRUE)
return TRUE;
return FALSE;
}
if (rtnl->newgateway) {
- const char *gateway =
- __connman_ipconfig_get_gateway_from_index(index,
- CONNMAN_IPCONFIG_TYPE_ALL);
+ const char *gateway = __connman_ipconfig_get_gateway_from_index(index);
if (gateway != NULL)
rtnl->newgateway(index, gateway);
case ARPHRD_LOOPBACK:
case ARPHDR_PHONET_PIPE:
case ARPHRD_NONE:
+#if defined TIZEN_EXT
+/*
+ * Description: SLP requires ARPHRD_PPP PPP type device
+ */
+ case ARPHRD_PPP:
+#endif
__connman_ipconfig_newlink(index, type, flags,
str, mtu, &stats);
break;
if (type == ARPHRD_ETHER)
read_uevent(interface);
+#if defined TIZEN_EXT
+ if (type == ARPHRD_PPP) {
+ interface->service_type = CONNMAN_SERVICE_TYPE_CELLULAR;
+ interface->device_type = CONNMAN_DEVICE_TYPE_CELLULAR;
+ }
+#endif
+
__connman_technology_add_interface(interface->service_type,
interface->index, interface->name, interface->ident);
}
case ARPHRD_ETHER:
case ARPHRD_LOOPBACK:
case ARPHRD_NONE:
+#if defined TIZEN_EXT
+/*
+ * Description: SLP requires ARPHRD_PPP PPP type device
+ */
+ case ARPHRD_PPP:
+ DBG("interface index(%d)", index);
+#endif
__connman_ipconfig_dellink(index, &stats);
break;
}
__connman_ipconfig_newaddr(index, family, label,
prefixlen, ip_string);
-
- if (family == AF_INET6) {
- /*
- * Re-create RDNSS configured servers if there are any
- * for this interface. This is done because we might
- * have now properly configured interface with proper
- * autoconfigured address.
- */
- char *interface = connman_inet_ifname(index);
-
- __connman_resolver_redo_servers(interface);
-
- g_free(interface);
- }
}
static void process_deladdr(unsigned char family, unsigned char prefixlen,
static void rtnl_newnduseropt(struct nlmsghdr *hdr)
{
struct nduseroptmsg *msg = (struct nduseroptmsg *) NLMSG_DATA(hdr);
- struct nd_opt_hdr *opt;
+ struct nd_opt_hdr *opt = (void *)&msg[1];
guint32 lifetime = -1;
const char **domains = NULL;
struct in6_addr *servers = NULL;
- int i, nr_servers = 0;
+ int nr_servers = 0;
int msglen = msg->nduseropt_opts_len;
char *interface;
- DBG("family %d index %d len %d type %d code %d",
- msg->nduseropt_family, msg->nduseropt_ifindex,
- msg->nduseropt_opts_len, msg->nduseropt_icmp_type,
- msg->nduseropt_icmp_code);
+ DBG("family %02x index %x len %04x type %02x code %02x",
+ msg->nduseropt_family, msg->nduseropt_ifindex,
+ msg->nduseropt_opts_len, msg->nduseropt_icmp_type,
+ msg->nduseropt_icmp_code);
if (msg->nduseropt_family != AF_INET6 ||
- msg->nduseropt_icmp_type != ND_ROUTER_ADVERT ||
- msg->nduseropt_icmp_code != 0)
+ msg->nduseropt_icmp_type != ND_ROUTER_ADVERT ||
+ msg->nduseropt_icmp_code != 0)
return;
interface = connman_inet_ifname(msg->nduseropt_ifindex);
return;
for (opt = (void *)&msg[1];
- msglen > 0;
- msglen -= opt->nd_opt_len * 8,
- opt = ((void *)opt) + opt->nd_opt_len*8) {
+ msglen >= 2 && msglen >= opt->nd_opt_len && opt->nd_opt_len;
+ msglen -= opt->nd_opt_len,
+ opt = ((void *)opt) + opt->nd_opt_len*8) {
- DBG("remaining %d nd opt type %d len %d\n",
- msglen, opt->nd_opt_type, opt->nd_opt_len);
-
- if (opt->nd_opt_type == 25) { /* ND_OPT_RDNSS */
- char buf[40];
+ DBG("nd opt type %d len %d\n",
+ opt->nd_opt_type, opt->nd_opt_len);
+ if (opt->nd_opt_type == 25)
servers = rtnl_nd_opt_rdnss(opt, &lifetime,
- &nr_servers);
- for (i = 0; i < nr_servers; i++) {
- if (!inet_ntop(AF_INET6, servers + i, buf,
- sizeof(buf)))
- continue;
+ &nr_servers);
+ else if (opt->nd_opt_type == 31)
+ domains = rtnl_nd_opt_dnssl(opt, &lifetime);
+ }
+
+ if (nr_servers) {
+ int i, j;
+ char buf[40];
+
+ for (i = 0; i < nr_servers; i++) {
+ if (!inet_ntop(AF_INET6, servers + i, buf, sizeof(buf)))
+ continue;
+ if (domains == NULL || domains[0] == NULL) {
connman_resolver_append_lifetime(interface,
NULL, buf, lifetime);
+ continue;
}
- } else if (opt->nd_opt_type == 31) { /* ND_OPT_DNSSL */
- g_free(domains);
-
- domains = rtnl_nd_opt_dnssl(opt, &lifetime);
- for (i = 0; domains != NULL && domains[i] != NULL; i++)
+ for (j = 0; domains[j]; j++)
connman_resolver_append_lifetime(interface,
- domains[i], NULL, lifetime);
+ domains[j],
+ buf, lifetime);
}
}
-
g_free(domains);
g_free(interface);
}
return "NEWLINK";
case RTM_DELLINK:
return "DELLINK";
- case RTM_GETADDR:
- return "GETADDR";
case RTM_NEWADDR:
return "NEWADDR";
case RTM_DELADDR:
if (!NLMSG_OK(hdr, len))
break;
- DBG("%s len %d type %d flags 0x%04x seq %d pid %d",
+ DBG("%s len %d type %d flags 0x%04x seq %d",
type2string(hdr->nlmsg_type),
hdr->nlmsg_len, hdr->nlmsg_type,
- hdr->nlmsg_flags, hdr->nlmsg_seq,
- hdr->nlmsg_pid);
+ hdr->nlmsg_flags, hdr->nlmsg_seq);
switch (hdr->nlmsg_type) {
case NLMSG_NOOP:
GIOCondition cond, gpointer data)
{
unsigned char buf[4096];
- struct sockaddr_nl nladdr;
- socklen_t addr_len = sizeof(nladdr);
- ssize_t status;
- int fd;
+ gsize len;
+ GIOStatus status;
if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
return FALSE;
memset(buf, 0, sizeof(buf));
- memset(&nladdr, 0, sizeof(nladdr));
- fd = g_io_channel_unix_get_fd(chan);
+ status = g_io_channel_read_chars(chan, (gchar *) buf,
+ sizeof(buf), &len, NULL);
- status = recvfrom(fd, buf, sizeof(buf), 0,
- (struct sockaddr *) &nladdr, &addr_len);
- if (status < 0) {
- if (errno == EINTR || errno == EAGAIN)
- return TRUE;
-
- return FALSE;
- }
-
- if (status == 0)
- return FALSE;
-
- if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
- DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
+ switch (status) {
+ case G_IO_STATUS_NORMAL:
+ break;
+ case G_IO_STATUS_AGAIN:
return TRUE;
+ default:
+ return FALSE;
}
- rtnl_message(buf, status);
+ rtnl_message(buf, len);
return TRUE;
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <string.h>
#include <netdb.h>
#include <gdbus.h>
-#include <ctype.h>
#include <connman/storage.h>
-#include <connman/setting.h>
#include "connman.h"
static GSequence *service_list = NULL;
static GHashTable *service_hash = NULL;
static GSList *counter_list = NULL;
-static unsigned int autoconnect_timeout = 0;
-static struct connman_service *current_default = NULL;
-static connman_bool_t services_dirty = FALSE;
struct connman_stats {
connman_bool_t valid;
char *passphrase;
char *agent_passphrase;
connman_bool_t roaming;
+ connman_bool_t login_required;
+ connman_bool_t network_created;
struct connman_ipconfig *ipconfig_ipv4;
struct connman_ipconfig *ipconfig_ipv6;
struct connman_network *network;
char **domains;
char *domainname;
char **timeservers;
- char **timeservers_config;
/* 802.1x settings from the config files */
char *eap;
char *identity;
char **excludes;
char *pac;
connman_bool_t wps;
- int online_check_count;
- connman_bool_t do_split_routing;
- connman_bool_t new_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.
+ */
+ gint user_initiated_pdn_connection_refcount;
+#endif
};
+#if defined TIZEN_EXT
+/*
+ * Public APIs to use user_initiated_pdn_connection_refcount
+ */
+void connman_service_user_initiated_pdn_connection_ref(
+ struct connman_service *service)
+{
+ g_atomic_int_inc(&service->user_initiated_pdn_connection_refcount);
+ DBG("User try to make a PDP connection with already referenced count: %d",
+ service->user_initiated_pdn_connection_refcount);
+}
+
+connman_bool_t connman_service_user_initiated_pdn_connection_unref_and_test(
+ struct connman_service *service)
+{
+ connman_bool_t test_zero = TRUE;
+
+ if (service->user_initiated_pdn_connection_refcount > 0)
+ test_zero = g_atomic_int_dec_and_test(&service->user_initiated_pdn_connection_refcount);
+
+ DBG("User try to disconnect existing PDP connection with already unreferenced count: %d",
+ service->user_initiated_pdn_connection_refcount);
+
+ return test_zero;
+}
+
+connman_bool_t connman_service_is_no_ref_user_initiated_pdn_connection(
+ struct connman_service *service)
+{
+ return g_atomic_int_compare_and_exchange(&service->user_initiated_pdn_connection_refcount,
+ 0, 0);
+}
+#endif
+
+static void append_path(gpointer value, gpointer user_data)
+{
+ struct connman_service *service = value;
+ DBusMessageIter *iter = user_data;
+
+ if (service->path == NULL || service->hidden == TRUE)
+ return;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
+ &service->path);
+}
+
+void __connman_service_list(DBusMessageIter *iter, void *user_data)
+{
+ if (service_list == NULL)
+ return;
+
+ g_sequence_foreach(service_list, append_path, iter);
+}
+
struct find_data {
const char *path;
struct connman_service *service;
return NULL;
}
-enum connman_service_type __connman_service_string2type(const char *str)
-{
- if (str == NULL)
- return CONNMAN_SERVICE_TYPE_UNKNOWN;
-
- if (strcmp(str, "ethernet") == 0)
- return CONNMAN_SERVICE_TYPE_ETHERNET;
- if (strcmp(str, "gadget") == 0)
- return CONNMAN_SERVICE_TYPE_GADGET;
- if (strcmp(str, "wifi") == 0)
- return CONNMAN_SERVICE_TYPE_WIFI;
- if (strcmp(str, "cellular") == 0)
- return CONNMAN_SERVICE_TYPE_CELLULAR;
- if (strcmp(str, "bluetooth") == 0)
- return CONNMAN_SERVICE_TYPE_BLUETOOTH;
- if (strcmp(str, "wimax") == 0)
- return CONNMAN_SERVICE_TYPE_WIMAX;
- if (strcmp(str, "vpn") == 0)
- return CONNMAN_SERVICE_TYPE_VPN;
- if (strcmp(str, "gps") == 0)
- return CONNMAN_SERVICE_TYPE_GPS;
- if (strcmp(str, "system") == 0)
- return CONNMAN_SERVICE_TYPE_SYSTEM;
-
- return CONNMAN_SERVICE_TYPE_UNKNOWN;
-}
-
static const char *security2string(enum connman_service_security security)
{
switch (security) {
case CONNMAN_SERVICE_SECURITY_WEP:
return "wep";
case CONNMAN_SERVICE_SECURITY_PSK:
- case CONNMAN_SERVICE_SECURITY_WPA:
- case CONNMAN_SERVICE_SECURITY_RSN:
return "psk";
case CONNMAN_SERVICE_SECURITY_8021X:
return "ieee8021x";
+ case CONNMAN_SERVICE_SECURITY_WPA:
+ return "wpa";
+ case CONNMAN_SERVICE_SECURITY_RSN:
+ return "rsn";
}
return NULL;
DBG("service %p", service);
keyfile = connman_storage_load_service(service->identifier);
- if (keyfile == NULL) {
- service->new_service = TRUE;
+ if (keyfile == NULL)
return -EIO;
- } else
- service->new_service = FALSE;
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_GPS:
- case CONNMAN_SERVICE_TYPE_GADGET:
- break;
case CONNMAN_SERVICE_TYPE_VPN:
- service->do_split_routing = g_key_file_get_boolean(keyfile,
- service->identifier, "SplitRouting", NULL);
+ case CONNMAN_SERVICE_TYPE_GADGET:
+#if defined TIZEN_EXT
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+#endif
break;
case CONNMAN_SERVICE_TYPE_WIFI:
if (service->name == NULL) {
case CONNMAN_SERVICE_TYPE_WIMAX:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+#if !defined TIZEN_EXT
case CONNMAN_SERVICE_TYPE_CELLULAR:
+#endif
service->favorite = g_key_file_get_boolean(keyfile,
service->identifier, "Favorite", NULL);
+ autoconnect = g_key_file_get_boolean(keyfile,
+ service->identifier, "AutoConnect", &error);
+ if (error == NULL)
+ service->autoconnect = autoconnect;
+ g_clear_error(&error);
+
str = g_key_file_get_string(keyfile,
service->identifier, "Failure", NULL);
if (str != NULL) {
service->error = string2error(str);
g_free(str);
}
- /* fall through */
-
- case CONNMAN_SERVICE_TYPE_ETHERNET:
- autoconnect = g_key_file_get_boolean(keyfile,
- service->identifier, "AutoConnect", &error);
- if (error == NULL)
- service->autoconnect = autoconnect;
- g_clear_error(&error);
break;
}
service->nameservers_config = NULL;
}
- service->timeservers_config = g_key_file_get_string_list(keyfile,
- service->identifier, "Timeservers", &length, NULL);
- if (service->timeservers_config != NULL && length == 0) {
- g_strfreev(service->timeservers_config);
- service->timeservers_config = NULL;
- }
-
service->domains = g_key_file_get_string_list(keyfile,
service->identifier, "Domains", &length, NULL);
if (service->domains != NULL && length == 0) {
service->pac = str;
}
- service->hidden_service = g_key_file_get_boolean(keyfile,
- service->identifier, "Hidden", NULL);
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
+ service->security == CONNMAN_SERVICE_SECURITY_8021X) {
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "EAP", NULL);
+ if (str != NULL) {
+ g_free(service->eap);
+ service->eap = str;
+ }
+
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "Phase2", NULL);
+ if (str != NULL) {
+ g_free(service->phase2);
+ service->phase2 = str;
+ }
+
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "Identity", NULL);
+ if (str != NULL) {
+ g_free(service->identity);
+ service->identity = str;
+ }
+
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "CACertFile", NULL);
+ if (str != NULL) {
+ g_free(service->ca_cert_file);
+ service->ca_cert_file = str;
+ }
+
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "ClientCertFile", NULL);
+ if (str != NULL) {
+ g_free(service->client_cert_file);
+ service->client_cert_file = str;
+ }
+
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "PrivateKeyFile", NULL);
+ if (str != NULL) {
+ g_free(service->private_key_file);
+ service->private_key_file = str;
+ }
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "PrivateKeyPassphrase", NULL);
+ if (str != NULL) {
+ g_free(service->private_key_passphrase);
+ service->private_key_passphrase = str;
+ }
+ }
+#endif
done:
g_key_file_free(keyfile);
const char *cst_str = NULL;
int err = 0;
- DBG("service %p new %d", service, service->new_service);
-
- if (service->new_service == TRUE)
- return -ESRCH;
+ DBG("service %p", service);
keyfile = __connman_storage_open_service(service->identifier);
if (keyfile == NULL)
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_GPS:
- case CONNMAN_SERVICE_TYPE_GADGET:
- break;
case CONNMAN_SERVICE_TYPE_VPN:
- g_key_file_set_boolean(keyfile, service->identifier,
- "SplitRouting", service->do_split_routing);
+ case CONNMAN_SERVICE_TYPE_GADGET:
break;
case CONNMAN_SERVICE_TYPE_WIFI:
if (service->network) {
g_key_file_set_boolean(keyfile, service->identifier,
"Favorite", service->favorite);
+ if (service->favorite == TRUE)
+ g_key_file_set_boolean(keyfile, service->identifier,
+ "AutoConnect", service->autoconnect);
+
if (service->state_ipv4 == CONNMAN_SERVICE_STATE_FAILURE ||
service->state_ipv6 == CONNMAN_SERVICE_STATE_FAILURE) {
const char *failure = error2string(service->error);
g_key_file_remove_key(keyfile, service->identifier,
"Failure", NULL);
}
- /* fall through */
-
- case CONNMAN_SERVICE_TYPE_ETHERNET:
- if (service->favorite == TRUE)
- g_key_file_set_boolean(keyfile, service->identifier,
- "AutoConnect", service->autoconnect);
break;
}
g_key_file_remove_key(keyfile, service->identifier,
"Nameservers", NULL);
- if (service->timeservers_config != NULL) {
- guint len = g_strv_length(service->timeservers_config);
-
- g_key_file_set_string_list(keyfile, service->identifier,
- "Timeservers",
- (const gchar **) service->timeservers_config, len);
- } else
- g_key_file_remove_key(keyfile, service->identifier,
- "Timeservers", NULL);
-
if (service->domains != NULL) {
guint len = g_strv_length(service->domains);
g_key_file_remove_key(keyfile, service->identifier,
"Proxy.URL", NULL);
- if (service->hidden_service == TRUE)
- g_key_file_set_boolean(keyfile, service->identifier, "Hidden",
- TRUE);
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
+ service->security == CONNMAN_SERVICE_SECURITY_8021X) {
+ if (service->eap != NULL && strlen(service->eap) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "EAP", service->eap);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "EAP", NULL);
+
+ if (service->phase2 != NULL && strlen(service->phase2) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "Phase2", service->phase2);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "Phase2", NULL);
- if (service->config_file != NULL && strlen(service->config_file) > 0)
- g_key_file_set_string(keyfile, service->identifier,
- "Config.file", service->config_file);
+ if (service->identity != NULL && strlen(service->identity) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "Identity", service->identity);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "Identity", NULL);
- if (service->config_entry != NULL &&
- strlen(service->config_entry) > 0)
- g_key_file_set_string(keyfile, service->identifier,
- "Config.ident", service->config_entry);
+ if (service->ca_cert_file != NULL && strlen(service->ca_cert_file) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "CACertFile", service->ca_cert_file);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "CACertFile", NULL);
+
+ if (service->client_cert_file != NULL && strlen(service->client_cert_file) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "ClientCertFile", service->client_cert_file);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "ClientCertFile", NULL);
+
+ if (service->private_key_file != NULL && strlen(service->private_key_file) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "PrivateKeyFile", service->private_key_file);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "PrivateKeyFile", NULL);
+ if (service->private_key_passphrase != NULL && strlen(service->private_key_passphrase) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "PrivateKeyPassphrase", service->private_key_passphrase);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "PrivateKeyPassphrase", NULL);
+ }
+#endif
done:
__connman_storage_save_service(keyfile, service->identifier);
return err;
}
-void __connman_service_save(struct connman_service *service)
+static guint changed_timeout = 0;
+
+static gboolean notify_services_changed(gpointer user_data)
{
- service_save(service);
+ changed_timeout = 0;
+
+ connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE, "Services",
+ DBUS_TYPE_OBJECT_PATH, __connman_service_list,
+ NULL);
+
+ return FALSE;
+}
+
+static void services_changed(gboolean delayed)
+{
+ DBG("");
+
+ if (changed_timeout > 0) {
+ g_source_remove(changed_timeout);
+ changed_timeout = 0;
+ }
+
+ if (__connman_connection_update_gateway() == TRUE) {
+ notify_services_changed(NULL);
+ return;
+ }
+
+ if (delayed == FALSE) {
+ notify_services_changed(NULL);
+ return;
+ }
+
+ changed_timeout = g_timeout_add_seconds(1, notify_services_changed,
+ NULL);
}
static enum connman_service_state combine_state(
return FALSE;
}
-static connman_bool_t is_idle_state(const struct connman_service *service,
- enum connman_service_state state)
-{
- switch (state) {
- case CONNMAN_SERVICE_STATE_UNKNOWN:
- case CONNMAN_SERVICE_STATE_ASSOCIATION:
- case CONNMAN_SERVICE_STATE_CONFIGURATION:
- case CONNMAN_SERVICE_STATE_READY:
- case CONNMAN_SERVICE_STATE_ONLINE:
- case CONNMAN_SERVICE_STATE_DISCONNECT:
- case CONNMAN_SERVICE_STATE_FAILURE:
- break;
- case CONNMAN_SERVICE_STATE_IDLE:
- return TRUE;
- }
-
- return FALSE;
-}
-
static connman_bool_t is_connecting(struct connman_service *service)
{
return is_connecting_state(service, service->state);
return is_connected_state(service, service->state);
}
-static const char *nameserver_get_ifname(struct connman_service *service)
-{
- const char *ifname;
-
- if (service->ipconfig_ipv4)
- ifname = __connman_ipconfig_get_ifname(service->ipconfig_ipv4);
- else if (service->ipconfig_ipv6)
- ifname = __connman_ipconfig_get_ifname(service->ipconfig_ipv6);
- else
- ifname = NULL;
-
- if (ifname == NULL)
- return NULL;
-
- switch (combine_state(service->state_ipv4, service->state_ipv6)) {
- case CONNMAN_SERVICE_STATE_UNKNOWN:
- case CONNMAN_SERVICE_STATE_IDLE:
- case CONNMAN_SERVICE_STATE_ASSOCIATION:
- case CONNMAN_SERVICE_STATE_CONFIGURATION:
- case CONNMAN_SERVICE_STATE_FAILURE:
- case CONNMAN_SERVICE_STATE_DISCONNECT:
- return NULL;
- case CONNMAN_SERVICE_STATE_READY:
- case CONNMAN_SERVICE_STATE_ONLINE:
- break;
- }
-
- return ifname;
-}
-
-static void remove_nameservers(struct connman_service *service,
- const char* interface, char **ns)
-{
- const char *ifname = interface;
- int i;
-
- if (ns == NULL)
- return;
-
- if (interface == NULL)
- ifname = nameserver_get_ifname(service);
-
- if (ifname == NULL)
- return;
-
- for (i = 0; ns[i] != NULL; i++)
- connman_resolver_remove(ifname, NULL, ns[i]);
-}
-
-static void remove_searchdomains(struct connman_service *service,
- const char *interface, char **sd)
-{
- const char *ifname = interface;
- int i;
-
- if (sd == NULL)
- return;
-
- if (interface == NULL)
- ifname = nameserver_get_ifname(service);
-
- if (ifname == NULL)
- return;
-
- for (i = 0; sd[i] != NULL; i++)
- connman_resolver_remove(ifname, sd[i], NULL);
-}
-
static void update_nameservers(struct connman_service *service)
{
const char *ifname;
if (service->ipconfig_ipv4)
- ifname = __connman_ipconfig_get_ifname(service->ipconfig_ipv4);
+ ifname = connman_ipconfig_get_ifname(service->ipconfig_ipv4);
else if (service->ipconfig_ipv6)
- ifname = __connman_ipconfig_get_ifname(service->ipconfig_ipv6);
+ ifname = connman_ipconfig_get_ifname(service->ipconfig_ipv6);
else
ifname = NULL;
if (service->nameservers_config != NULL) {
int i;
- remove_nameservers(service, ifname, service->nameservers);
-
- i = g_strv_length(service->nameservers_config);
- while (i != 0) {
- i--;
+ for (i = 0; service->nameservers_config[i] != NULL; i++) {
connman_resolver_append(ifname, NULL,
- service->nameservers_config[i]);
+ service->nameservers_config[i]);
}
} else if (service->nameservers != NULL) {
int i;
- i = g_strv_length(service->nameservers);
- while (i != 0) {
- i--;
+ for (i = 0; service->nameservers[i] != NULL; i++) {
connman_resolver_append(ifname, NULL,
- service->nameservers[i]);
+ service->nameservers[i]);
}
}
if (service->domains != NULL) {
- char *searchdomains[2] = {NULL, NULL};
int i;
- searchdomains[0] = service->domainname;
- remove_searchdomains(service, ifname, searchdomains);
-
- i = g_strv_length(service->domains);
- while (i != 0) {
- i--;
+ for (i = 0; service->domains[i]; i++)
connman_resolver_append(ifname, service->domains[i],
NULL);
- }
} else if (service->domainname != NULL)
connman_resolver_append(ifname, service->domainname, NULL);
update_nameservers(service);
}
-static void add_nameserver_route(int family, int index, char *nameserver,
- const char *gw)
-{
- switch (family) {
- case AF_INET:
- if (connman_inet_compare_subnet(index, nameserver) == TRUE)
- break;
-
- if (connman_inet_add_host_route(index, nameserver, gw) < 0)
- /* For P-t-P link the above route add will fail */
- connman_inet_add_host_route(index, nameserver, NULL);
- break;
-
- case AF_INET6:
- if (connman_inet_add_ipv6_host_route(index, nameserver,
- gw) < 0)
- connman_inet_add_ipv6_host_route(index, nameserver,
- NULL);
- break;
- }
-}
-
static void nameserver_add_routes(int index, char **nameservers,
const char *gw)
{
- int i, family;
+ int i, ret, family;
+ struct addrinfo hints;
+ struct addrinfo *addr;
for (i = 0; nameservers[i] != NULL; i++) {
- family = connman_inet_check_ipaddress(nameservers[i]);
- if (family < 0)
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_flags = AI_NUMERICHOST;
+ addr = NULL;
+
+ ret = getaddrinfo(nameservers[i], NULL, &hints, &addr);
+ if (ret == EAI_NONAME)
+ family = AF_INET; /* use the IPv4 as a default */
+ else if (ret != 0)
continue;
+ else
+ family = addr->ai_family;
+
+ if (family == AF_INET) {
+ if (connman_inet_compare_subnet(index,
+ nameservers[i]) != TRUE)
+ connman_inet_add_host_route(index,
+ nameservers[i], gw);
+ } else if (family == AF_INET6)
+ connman_inet_add_ipv6_host_route(index,
+ nameservers[i], gw);
- add_nameserver_route(family, index, nameservers[i], gw);
+ freeaddrinfo(addr);
}
}
-static void nameserver_del_routes(int index, char **nameservers,
- enum connman_ipconfig_type type)
+static void nameserver_del_routes(int index, char **nameservers)
{
- int i, family;
+ int i, ret, family;
+ struct addrinfo hints;
+ struct addrinfo *addr;
for (i = 0; nameservers[i] != NULL; i++) {
- family = connman_inet_check_ipaddress(nameservers[i]);
- if (family < 0)
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_flags = AI_NUMERICHOST;
+ addr = NULL;
+
+ ret = getaddrinfo(nameservers[i], NULL, &hints, &addr);
+ if (ret == EAI_NONAME)
+ family = AF_INET; /* use the IPv4 as a default */
+ else if (ret != 0)
continue;
+ else
+ family = addr->ai_family;
- switch (family) {
- case AF_INET:
- if (type != CONNMAN_IPCONFIG_TYPE_IPV6)
- connman_inet_del_host_route(index,
- nameservers[i]);
- break;
- case AF_INET6:
- if (type != CONNMAN_IPCONFIG_TYPE_IPV4)
- connman_inet_del_ipv6_host_route(index,
+ if (family == AF_INET)
+ connman_inet_del_host_route(index, nameservers[i]);
+ else if (family == AF_INET6)
+ connman_inet_del_ipv6_host_route(index,
nameservers[i]);
- break;
- }
+
+ freeaddrinfo(addr);
}
}
}
}
-void __connman_service_nameserver_del_routes(struct connman_service *service,
- enum connman_ipconfig_type type)
+void __connman_service_nameserver_del_routes(struct connman_service *service)
{
int index = -1;
index = connman_provider_get_index(service->provider);
if (service->nameservers_config != NULL)
- nameserver_del_routes(index, service->nameservers_config,
- type);
+ nameserver_del_routes(index, service->nameservers_config);
else if (service->nameservers != NULL)
- nameserver_del_routes(index, service->nameservers, type);
+ nameserver_del_routes(index, service->nameservers);
}
static struct connman_stats *stats_get(struct connman_service *service)
g_timer_reset(service->stats_roaming.timer);
}
-struct connman_service *__connman_service_get_default(void)
+static struct connman_service *get_default(void)
{
struct connman_service *service;
GSequenceIter *iter;
static void default_changed(void)
{
- struct connman_service *service = __connman_service_get_default();
+ struct connman_service *service = get_default();
- if (service == current_default)
- return;
+ __connman_notifier_default_changed(service);
+}
- __connman_service_timeserver_changed(current_default, NULL);
+const char *__connman_service_default(void)
+{
+ struct connman_service *service;
- current_default = service;
+ service = get_default();
+ if (service == NULL)
+ return "";
- __connman_notifier_default_changed(service);
+ return __connman_service_type2string(service->type);
}
static void state_changed(struct connman_service *service)
if (str == NULL)
return;
+#if defined TIZEN_EXT
+ const char *str_err = error2string(service->error);
+ if ((service->state == CONNMAN_SERVICE_STATE_FAILURE) && (str_err != NULL))
+ connman_dbus_service_property_changed_with_error_cause(service->path,
+ CONNMAN_SERVICE_INTERFACE, "State", DBUS_TYPE_STRING, &str,
+ "Error", DBUS_TYPE_STRING, &str_err);
+ else
+#endif
connman_dbus_property_changed_basic(service->path,
CONNMAN_SERVICE_INTERFACE, "State",
DBUS_TYPE_STRING, &str);
DBUS_TYPE_BOOLEAN, &service->autoconnect);
}
+static void passphrase_changed(struct connman_service *service)
+{
+ dbus_bool_t required;
+
+ switch (service->type) {
+ case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_WIMAX:
+ case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ case CONNMAN_SERVICE_TYPE_GPS:
+ case CONNMAN_SERVICE_TYPE_VPN:
+ case CONNMAN_SERVICE_TYPE_GADGET:
+ return;
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ required = FALSE;
+
+ switch (service->security) {
+ case CONNMAN_SERVICE_SECURITY_UNKNOWN:
+ case CONNMAN_SERVICE_SECURITY_NONE:
+ break;
+ case CONNMAN_SERVICE_SECURITY_WEP:
+ case CONNMAN_SERVICE_SECURITY_PSK:
+ case CONNMAN_SERVICE_SECURITY_WPA:
+ case CONNMAN_SERVICE_SECURITY_RSN:
+ if (service->passphrase == NULL)
+ required = TRUE;
+ break;
+ case CONNMAN_SERVICE_SECURITY_8021X:
+ break;
+ }
+ break;
+ }
+
+ connman_dbus_property_changed_basic(service->path,
+ CONNMAN_SERVICE_INTERFACE, "PassphraseRequired",
+ DBUS_TYPE_BOOLEAN, &required);
+}
+
+static void login_changed(struct connman_service *service)
+{
+ dbus_bool_t required = service->login_required;
+
+ if (service->path == NULL)
+ return;
+
+ connman_dbus_property_changed_basic(service->path,
+ CONNMAN_SERVICE_INTERFACE, "LoginRequired",
+ DBUS_TYPE_BOOLEAN, &required);
+}
+
static void append_security(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
iter);
}
-static void append_nameservers(DBusMessageIter *iter, char **servers)
+static void append_nameserver(DBusMessageIter *iter, char ***nameservers)
{
+ char **servers;
int i;
- DBG("%p", servers);
+ servers = *nameservers;
for (i = 0; servers[i] != NULL; i++) {
- DBG("servers[%d] %s", i, servers[i]);
dbus_message_iter_append_basic(iter,
DBUS_TYPE_STRING, &servers[i]);
}
return;
if (service->nameservers_config != NULL) {
- append_nameservers(iter, service->nameservers_config);
+ append_nameserver(iter, &service->nameservers_config);
return;
} else {
if (service->nameservers != NULL)
- append_nameservers(iter, service->nameservers);
+ append_nameserver(iter, &service->nameservers);
if (service->nameservers_auto != NULL)
- append_nameservers(iter, service->nameservers_auto);
+ append_nameserver(iter, &service->nameservers_auto);
}
}
static void append_dnsconfig(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
+ int i;
if (service->nameservers_config == NULL)
return;
- append_nameservers(iter, service->nameservers_config);
-}
-
-static void append_ts(DBusMessageIter *iter, void *user_data)
-{
- GSList *list = user_data;
-
- while (list != NULL) {
- char *timeserver = list->data;
-
- if (timeserver != NULL)
- dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
- ×erver);
-
- list = g_slist_next(list);
+ for (i = 0; service->nameservers_config[i]; i++) {
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING,
+ &service->nameservers_config[i]);
}
}
-static void append_tsconfig(DBusMessageIter *iter, void *user_data)
+static void append_domain(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
- int i;
- if (service->timeservers_config == NULL)
+ if (is_connected(service) == FALSE &&
+ is_connecting(service) == FALSE)
return;
- for (i = 0; service->timeservers_config[i]; i++) {
- dbus_message_iter_append_basic(iter,
- DBUS_TYPE_STRING,
- &service->timeservers_config[i]);
- }
+ if (service->domainname == NULL)
+ return;
+
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &service->domainname);
}
static void append_domainconfig(DBusMessageIter *iter, void *user_data)
DBUS_TYPE_STRING, &service->domains[i]);
}
-static void append_domain(DBusMessageIter *iter, void *user_data)
-{
- struct connman_service *service = user_data;
-
- if (is_connected(service) == FALSE &&
- is_connecting(service) == FALSE)
- return;
-
- if (service->domains != NULL)
- append_domainconfig(iter, user_data);
- else if (service->domainname != NULL)
- dbus_message_iter_append_basic(iter,
- DBUS_TYPE_STRING, &service->domainname);
-}
-
static void append_proxies(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
DBUS_TYPE_STRING, append_domainconfig, service);
}
+#if defined TIZEN_EXT
+static int __connman_service_dbus_update_default_info(int type, ...)
+{
+#define NETCONFIG_SERVICE "net.netconfig"
+#define NETCONFIG_NETWORK_STATE_INTERFACE NETCONFIG_SERVICE ".network"
+#define NETCONFIG_NETWORK_STATE_PATH "/net/netconfig/network"
+ DBusMessage *message;
+ DBusPendingCall *call;
+ dbus_bool_t ok;
+ va_list va;
+
+ message = dbus_message_new_method_call(NETCONFIG_SERVICE,
+ NETCONFIG_NETWORK_STATE_PATH,
+ NETCONFIG_NETWORK_STATE_INTERFACE, "UpdateDefaultConnectionInfo");
+
+ if (message == NULL)
+ return -ENOMEM;
+
+ va_start(va, type);
+ ok = dbus_message_append_args_valist(message, type, va);
+ va_end(va);
+
+ if (!ok)
+ return -ENOMEM;
+
+ if (dbus_connection_send_with_reply(connection, message, &call, 40000) == FALSE) {
+ connman_error("Failed to call %s.%s", NETCONFIG_NETWORK_STATE_INTERFACE,
+ "UpdateDefaultConnectionInfo");
+ dbus_message_unref(message);
+ return -EINVAL;
+ }
+
+ if (call == NULL) {
+ connman_error("D-Bus connection not available");
+ dbus_message_unref(message);
+ return -EINVAL;
+ }
+
+ dbus_message_unref(message);
+
+ return -EINPROGRESS;
+}
+
+static connman_bool_t __connman_service_is_internet_profile(
+ struct connman_service *cellular)
+{
+#define CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX CONNMAN_PATH "/service/cellular_"
+ DBG("Service path: %s", cellular->path);
+
+ const char internet_suffix[] = "_1";
+ char *suffix = NULL;
+
+ if (g_str_has_prefix(cellular->path, CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX) == TRUE) {
+ suffix = strrchr(cellular->path, '_');
+ if (strcmp(suffix, internet_suffix) == 0)
+ return TRUE;
+ }
+
+ DBG("Not Internet profile.");
+ return FALSE;
+}
+
+static struct connman_service *__connman_service_get_default(void)
+{
+ GSequenceIter *iter;
+ struct connman_service *default_service = NULL;
+
+ iter = g_sequence_get_begin_iter(service_list);
+
+ while (g_sequence_iter_is_end(iter) == FALSE) {
+ struct connman_service *service = g_sequence_get(iter);
+
+ DBG("service: %p %s %s %s", service, service->name,
+ state2string(service->state),
+ __connman_service_type2string(service->type));
+
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
+ is_connected(service) == TRUE)
+ return service;
+
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ if (__connman_service_is_internet_profile(service) == TRUE) {
+ if (default_service == NULL)
+ default_service = service;
+ else if (is_connected(default_service) == FALSE &&
+ is_connected(service) == TRUE)
+ default_service = service;
+ }
+
+ iter = g_sequence_iter_next(iter);
+ }
+
+ return default_service;
+}
+
+static void __connman_service_update_default_info(struct connman_service *service)
+{
+ struct connman_ipconfig *ip_config = NULL;
+ gchar *connection_type = NULL, *connection_state = NULL;
+ gchar *ip_addr = NULL, *proxy_addr = NULL;
+ gchar **proxy_list = NULL;
+
+ ip_config = __connman_service_get_ip4config(service);
+ if (ip_config == NULL)
+ return;
+
+ DBG("Update state %p %s %s", service, service->path, state2string(service->state));
+
+ ip_addr = g_strdup(__connman_ipconfig_get_local(ip_config));
+ if (ip_addr == NULL)
+ ip_addr = g_strdup("");
+
+ connection_type = g_strdup(
+ __connman_service_type2string(connman_service_get_type(service)));
+
+ connection_state = g_strdup(state2string(service->state));
+
+ proxy_list = connman_service_get_proxy_servers(service);
+ if (proxy_list != NULL)
+ proxy_addr = g_strdup(proxy_list[0]);
+ if (proxy_addr == NULL)
+ proxy_addr = g_strdup("");
+
+ __connman_service_dbus_update_default_info(
+ DBUS_TYPE_STRING, &connection_type, DBUS_TYPE_STRING, &connection_state,
+ DBUS_TYPE_STRING, &ip_addr, DBUS_TYPE_STRING, &proxy_addr, DBUS_TYPE_INVALID);
+
+ g_free(connection_type);
+ g_free(connection_state);
+ g_free(ip_addr);
+ g_free(proxy_addr);
+ g_strfreev(proxy_list);
+}
+
+static void __connman_service_update_default(struct connman_service *service)
+{
+ struct connman_service *default_service = NULL;
+
+ default_service = __connman_service_get_default();
+
+ DBG("service %p %s %s", service, service->path, state2string(service->state));
+ if (default_service != NULL)
+ DBG("default service %p %s %s", default_service, default_service->path,
+ state2string(default_service->state));
+ else
+ DBG("default service is NULL");
+
+ if (is_connected(service) == TRUE) {
+ if (service == default_service)
+ __connman_service_update_default_info(service);
+
+ return;
+ }
+
+ if (default_service == NULL) {
+ __connman_service_update_default_info(service);
+ return;
+ }
+
+ if (service != default_service) {
+ if (default_service->type == CONNMAN_SERVICE_TYPE_WIFI)
+ return;
+
+ if (is_connected(default_service) == TRUE)
+ __connman_service_update_default_info(default_service);
+ else
+ __connman_service_update_default_info(service);
+ } else
+ __connman_service_update_default_info(service);
+}
+#endif
+
static void proxy_changed(struct connman_service *service)
{
connman_dbus_property_changed_dict(service->path,
CONNMAN_SERVICE_INTERFACE, "Proxy",
append_proxy, service);
+#if defined TIZEN_EXT
+ DBG("");
+ if (is_connected(service) == TRUE)
+ __connman_service_update_default(service);
+#endif
}
static void proxy_configuration_changed(struct connman_service *service)
proxy_changed(service);
}
-static void timeservers_configuration_changed(struct connman_service *service)
-{
- connman_dbus_property_changed_array(service->path,
- CONNMAN_SERVICE_INTERFACE,
- "Timeservers.Configuration",
- DBUS_TYPE_STRING,
- append_tsconfig, service);
-}
-
static void link_changed(struct connman_service *service)
{
connman_dbus_property_changed_dict(service->path,
stats->data.time = stats->data_last.time + seconds;
}
+static char *wifi_build_group_name(const unsigned char *ssid,
+ unsigned int ssid_len,
+ const char *mode,
+ const char *security)
+{
+ GString *str;
+ unsigned int i;
+
+ /* the last 3 is for the 2 '_' and '\0' */
+ str = g_string_sized_new((ssid_len * 2) + strlen(mode)
+ + strlen(security) + 3);
+ if (str == NULL)
+ return NULL;
+
+ for (i = 0; i < ssid_len; i++)
+ g_string_append_printf(str, "%02x", ssid[i]);
+
+ g_string_append_printf(str, "_%s_%s", mode, security);
+
+ return g_string_free(str, FALSE);
+}
+
void __connman_service_notify(struct connman_service *service,
unsigned int rx_packets, unsigned int tx_packets,
unsigned int rx_bytes, unsigned int tx_bytes,
return TRUE;
}
+#if defined TIZEN_EXT
+static void append_wifi_ext_info(DBusMessageIter *dict,
+ struct connman_network *network)
+{
+ unsigned char bssid_buff[18] = {0,};
+ unsigned char *bssid_str = bssid_buff;
+ unsigned char *bssid;
+ unsigned int maxrate;
+ connman_uint16_t frequency;
+ const char *enc_mode;
+ const char *str;
+
+ 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((char *)bssid_str, 18, "%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);
+
+ str = connman_network_get_string(network, "WiFi.Security");
+
+ if (str != NULL && g_str_equal(str, "ieee8021x") == TRUE) {
+ str = connman_network_get_string(network, "WiFi.EAP");
+ if (str != NULL)
+ connman_dbus_dict_append_basic(dict, "EAP",
+ DBUS_TYPE_STRING, &str);
+
+ str = connman_network_get_string(network, "WiFi.Phase2");
+ if (str != NULL)
+ connman_dbus_dict_append_basic(dict, "Phase2",
+ DBUS_TYPE_STRING, &str);
+
+ str = connman_network_get_string(network, "WiFi.Identity");
+ if (str != NULL)
+ connman_dbus_dict_append_basic(dict, "Identity",
+ DBUS_TYPE_STRING, &str);
+
+ str = connman_network_get_string(network, "WiFi.Passphrase");
+ if (str != NULL)
+ connman_dbus_dict_append_basic(dict, "Password",
+ DBUS_TYPE_STRING, &str);
+
+ str = connman_network_get_string(network, "WiFi.CACertFile");
+ if (str != NULL)
+ connman_dbus_dict_append_basic(dict, "CACertFile",
+ DBUS_TYPE_STRING, &str);
+
+ str = connman_network_get_string(network, "WiFi.ClientCertFile");
+ if (str != NULL)
+ connman_dbus_dict_append_basic(dict, "ClientCertFile",
+ DBUS_TYPE_STRING, &str);
+
+ str = connman_network_get_string(network, "WiFi.PrivateKeyFile");
+ if (str != NULL)
+ connman_dbus_dict_append_basic(dict, "PrivateKeyFile",
+ DBUS_TYPE_STRING, &str);
+
+ str = connman_network_get_string(network, "WiFi.PrivateKeyPassphrase");
+ if (str != NULL)
+ connman_dbus_dict_append_basic(dict, "PrivateKeyPassphrase",
+ DBUS_TYPE_STRING, &str);
+ }
+}
+#endif
+
static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
struct connman_service *service)
{
+ dbus_bool_t required;
const char *str;
- GSList *list;
str = __connman_service_type2string(service->type);
if (str != NULL)
connman_dbus_dict_append_basic(dict, "Name",
DBUS_TYPE_STRING, &service->name);
+ connman_dbus_dict_append_basic(dict, "LoginRequired",
+ DBUS_TYPE_BOOLEAN, &service->login_required);
+
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
case CONNMAN_SERVICE_TYPE_SYSTEM:
append_ethernet, service);
break;
case CONNMAN_SERVICE_TYPE_WIFI:
+ if (service->passphrase != NULL && limited == FALSE)
+ connman_dbus_dict_append_basic(dict, "Passphrase",
+ DBUS_TYPE_STRING, &service->passphrase);
+
+ required = FALSE;
+
+ switch (service->security) {
+ case CONNMAN_SERVICE_SECURITY_UNKNOWN:
+ case CONNMAN_SERVICE_SECURITY_NONE:
+ break;
+ case CONNMAN_SERVICE_SECURITY_WEP:
+ case CONNMAN_SERVICE_SECURITY_PSK:
+ case CONNMAN_SERVICE_SECURITY_WPA:
+ case CONNMAN_SERVICE_SECURITY_RSN:
+ if (service->passphrase == NULL)
+ required = TRUE;
+ break;
+ case CONNMAN_SERVICE_SECURITY_8021X:
+ break;
+ }
+
+ connman_dbus_dict_append_basic(dict, "PassphraseRequired",
+ DBUS_TYPE_BOOLEAN, &required);
+
+#if defined TIZEN_EXT
+ if (service->network != NULL)
+ append_wifi_ext_info(dict, service->network);
+#endif
+
+ /* fall through */
case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_WIMAX:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
connman_dbus_dict_append_array(dict, "Nameservers.Configuration",
DBUS_TYPE_STRING, append_dnsconfig, service);
- if (service->state == CONNMAN_SERVICE_STATE_READY ||
- service->state == CONNMAN_SERVICE_STATE_ONLINE)
- list = __connman_timeserver_get_all(service);
- else
- list = NULL;
-
- connman_dbus_dict_append_array(dict, "Timeservers",
- DBUS_TYPE_STRING, append_ts, list);
-
- g_slist_free_full(list, g_free);
-
- connman_dbus_dict_append_array(dict, "Timeservers.Configuration",
- DBUS_TYPE_STRING, append_tsconfig, service);
-
connman_dbus_dict_append_array(dict, "Domains",
DBUS_TYPE_STRING, append_domain, service);
append_provider, service);
}
-static void append_struct_service(DBusMessageIter *iter,
- connman_dbus_append_cb_t function,
- struct connman_service *service)
+static void append_struct(gpointer value, gpointer user_data)
{
+ struct connman_service *service = value;
+ DBusMessageIter *iter = user_data;
DBusMessageIter entry, dict;
+ if (service->path == NULL || service->hidden == TRUE)
+ return;
+
dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &entry);
dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
&service->path);
connman_dbus_dict_open(&entry, &dict);
- if (function != NULL)
- function(&dict, service);
+ append_properties(&dict, TRUE, service);
connman_dbus_dict_close(&entry, &dict);
dbus_message_iter_close_container(iter, &entry);
}
-static void append_dict_properties(DBusMessageIter *dict, void *user_data)
-{
- struct connman_service *service = user_data;
-
- append_properties(dict, TRUE, service);
-}
-
-static void append_struct(gpointer value, gpointer user_data)
-{
- struct connman_service *service = value;
- DBusMessageIter *iter = user_data;
-
- if (service->path == NULL)
- return;
-
- append_struct_service(iter, append_dict_properties, service);
-}
-
void __connman_service_list_struct(DBusMessageIter *iter)
{
g_sequence_foreach(service_list, append_struct, iter);
}
-connman_bool_t __connman_service_is_hidden(struct connman_service *service)
-{
- return service->hidden;
-}
-
-connman_bool_t
-__connman_service_is_split_routing(struct connman_service *service)
-{
- return service->do_split_routing;
-}
-
int __connman_service_get_index(struct connman_service *service)
{
if (service == NULL)
return -1;
}
-void __connman_service_set_hidden(struct connman_service *service)
-{
- if (service == NULL || service->hidden == TRUE)
- return;
-
- service->hidden_service = TRUE;
-}
-
void __connman_service_set_domainname(struct connman_service *service,
const char *domainname)
{
- if (service == NULL || service->hidden == TRUE)
+ if (service == NULL)
return;
g_free(service->domainname);
return NULL;
if (service->nameservers_config != NULL)
- return g_strdupv(service->nameservers_config);
- else if (service->nameservers != NULL ||
- service->nameservers_auto != NULL) {
- int len = 0, len_auto = 0, i;
- char **nameservers;
-
- if (service->nameservers != NULL)
- len = g_strv_length(service->nameservers);
- if (service->nameservers_auto != NULL)
- len_auto = g_strv_length(service->nameservers_auto);
-
- nameservers = g_try_new0(char *, len + len_auto + 1);
- if (nameservers == NULL)
- return NULL;
-
- for (i = 0; i < len; i++)
- nameservers[i] = g_strdup(service->nameservers[i]);
-
- for (i = 0; i < len_auto; i++)
- nameservers[i + len] =
- g_strdup(service->nameservers_auto[i]);
-
- return nameservers;
- }
-
- return NULL;
-}
-
-char **connman_service_get_timeservers_config(struct connman_service *service)
-{
- if (service == NULL)
- return NULL;
-
- return service->timeservers_config;
-}
-
-char **connman_service_get_timeservers(struct connman_service *service)
-{
- if (service == NULL)
- return NULL;
-
- if (service->timeservers != NULL)
- return service->timeservers;
+ return service->nameservers_config;
+ else if (service->nameservers != NULL)
+ return service->nameservers;
return NULL;
}
void connman_service_set_proxy_method(struct connman_service *service,
enum connman_service_proxy_method method)
{
- if (service == NULL || service->hidden == TRUE)
+ if (service == NULL)
return;
service->proxy = method;
void __connman_service_set_proxy_autoconfig(struct connman_service *service,
const char *url)
{
- if (service == NULL || service->hidden == TRUE)
+ if (service == NULL)
return;
service->proxy = CONNMAN_SERVICE_PROXY_METHOD_AUTO;
return NULL;
}
+static void update_timeservers(struct connman_service *service)
+{
+ int i;
+
+ if (service->timeservers == NULL)
+ return;
+
+ switch (service->state) {
+ case CONNMAN_SERVICE_STATE_UNKNOWN:
+ case CONNMAN_SERVICE_STATE_IDLE:
+ case CONNMAN_SERVICE_STATE_ASSOCIATION:
+ case CONNMAN_SERVICE_STATE_CONFIGURATION:
+ return;
+ case CONNMAN_SERVICE_STATE_FAILURE:
+ case CONNMAN_SERVICE_STATE_DISCONNECT:
+ for (i = 0; service->timeservers[i] != NULL; i++)
+ connman_timeserver_remove(service->timeservers[i]);
+ return;
+ case CONNMAN_SERVICE_STATE_READY:
+ case CONNMAN_SERVICE_STATE_ONLINE:
+ break;
+ }
+
+ for (i = 0; service->timeservers[i] != NULL; i++)
+ connman_timeserver_append(service->timeservers[i]);
+}
+
int __connman_service_timeserver_append(struct connman_service *service,
const char *timeserver)
{
service->timeservers[len] = g_strdup(timeserver);
service->timeservers[len + 1] = NULL;
+ update_timeservers(service);
+
return 0;
}
const char *timeserver)
{
char **servers;
- int len, i, j, found = 0;
+ int len, i, j;
DBG("service %p timeserver %s", service, timeserver);
if (service->timeservers == NULL)
return 0;
- for (i = 0; service->timeservers != NULL &&
- service->timeservers[i] != NULL; i++)
- if (g_strcmp0(service->timeservers[i], timeserver) == 0) {
- found = 1;
- break;
- }
-
- if (found == 0)
- return 0;
-
len = g_strv_length(service->timeservers);
-
if (len == 1) {
+ if (g_strcmp0(service->timeservers[0], timeserver) != 0)
+ return 0;
+
g_strfreev(service->timeservers);
service->timeservers = NULL;
return 0;
}
- servers = g_try_new0(char *, len);
+ servers = g_try_new0(char *, len - 1);
if (servers == NULL)
return -ENOMEM;
for (i = 0, j = 0; i < len; i++) {
if (g_strcmp0(service->timeservers[i], timeserver) != 0) {
servers[j] = g_strdup(service->timeservers[i]);
- if (servers[j] == NULL)
- return -ENOMEM;
j++;
}
}
- servers[len - 1] = NULL;
+ servers[len - 2] = NULL;
g_strfreev(service->timeservers);
service->timeservers = servers;
- return 0;
-}
-
-void __connman_service_timeserver_changed(struct connman_service *service,
- GSList *ts_list)
-{
- if (service == NULL)
- return;
+ update_timeservers(service);
- connman_dbus_property_changed_array(service->path,
- CONNMAN_SERVICE_INTERFACE, "Timeservers",
- DBUS_TYPE_STRING, append_ts, ts_list);
+ return 0;
}
void __connman_service_set_pac(struct connman_service *service,
const char *pac)
{
- if (service->hidden == TRUE)
- return;
g_free(service->pac);
service->pac = g_strdup(pac);
proxy_changed(service);
}
+#if defined TIZEN_EXT
+/*
+ * Description: Telephony plug-in requires manual PROXY setting function
+ */
+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)
{
- if (service->immutable || service->hidden == TRUE)
+ if (service->immutable)
return;
g_free(service->identity);
void __connman_service_set_agent_identity(struct connman_service *service,
const char *agent_identity)
{
- if (service->hidden == TRUE)
- return;
g_free(service->agent_identity);
service->agent_identity = g_strdup(agent_identity);
service->agent_identity);
}
-static int check_passphrase(struct connman_service *service,
- enum connman_service_security security,
- const char *passphrase)
-{
- guint i;
- gsize length;
-
- if (passphrase == NULL) {
- /*
- * This will prevent __connman_service_set_passphrase() to
- * wipe the passphrase out in case of -ENOKEY error for a
- * favorite service. */
- if (service->favorite == TRUE)
- return 1;
- else
- return 0;
- }
-
- length = strlen(passphrase);
-
- switch (security) {
- case CONNMAN_SERVICE_SECURITY_PSK:
- case CONNMAN_SERVICE_SECURITY_WPA:
- case CONNMAN_SERVICE_SECURITY_RSN:
- /* A raw key is always 64 bytes length,
- * its content is in hex representation.
- * A PSK key must be between [8..63].
- */
- if (length == 64) {
- for (i = 0; i < 64; i++)
- if (!isxdigit((unsigned char)
- passphrase[i]))
- return -ENOKEY;
- } else if (length < 8 || length > 63)
- return -ENOKEY;
- break;
- case CONNMAN_SERVICE_SECURITY_WEP:
- /* length of WEP key is 10 or 26
- * length of WEP passphrase is 5 or 13
- */
- if (length == 10 || length == 26) {
- for (i = 0; i < length; i++)
- if (!isxdigit((unsigned char)
- passphrase[i]))
- return -ENOKEY;
- } else if (length != 5 && length != 13)
- return -ENOKEY;
- break;
- case CONNMAN_SERVICE_SECURITY_UNKNOWN:
- case CONNMAN_SERVICE_SECURITY_NONE:
- case CONNMAN_SERVICE_SECURITY_8021X:
- break;
- }
-
- return 0;
-}
-
-int __connman_service_set_passphrase(struct connman_service *service,
- const char *passphrase)
+void __connman_service_set_passphrase(struct connman_service *service,
+ const char* passphrase)
{
- int err = 0;
-
- if (service->immutable == TRUE || service->hidden == TRUE)
- return -EINVAL;
-
- err = check_passphrase(service, service->security, passphrase);
-
- if (err == 0) {
- g_free(service->passphrase);
- service->passphrase = g_strdup(passphrase);
+ if (service->immutable == TRUE)
+ return;
- if (service->network != NULL)
- connman_network_set_string(service->network,
- "WiFi.Passphrase",
- service->passphrase);
- service_save(service);
- }
+ g_free(service->passphrase);
+ service->passphrase = g_strdup(passphrase);
- return err;
-}
+ passphrase_changed(service);
-const char *__connman_service_get_passphrase(struct connman_service *service)
-{
- if (service == NULL)
- return NULL;
+ if (service->network != NULL)
+ connman_network_set_string(service->network,
+ "WiFi.Passphrase",
+ service->passphrase);
- return service->passphrase;
+ service_save(service);
}
void __connman_service_set_agent_passphrase(struct connman_service *service,
const char *agent_passphrase)
{
- if (service->hidden == TRUE)
- return;
g_free(service->agent_passphrase);
service->agent_passphrase = g_strdup(agent_passphrase);
dbus_message_iter_get_basic(&entry, &key);
dbus_message_iter_next(&entry);
- if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
+ if (dbus_message_iter_get_arg_type(&entry) !=
+ DBUS_TYPE_VARIANT)
goto error;
dbus_message_iter_recurse(&entry, &variant);
-
type = dbus_message_iter_get_arg_type(&variant);
if (g_str_equal(key, "Method") == TRUE) {
if (dbus_message_iter_init(msg, &iter) == FALSE)
return __connman_error_invalid_arguments(msg);
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- return __connman_error_invalid_arguments(msg);
-
dbus_message_iter_get_basic(&iter, &name);
dbus_message_iter_next(&iter);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
- return __connman_error_invalid_arguments(msg);
-
dbus_message_iter_recurse(&iter, &value);
type = dbus_message_iter_get_arg_type(&value);
autoconnect_changed(service);
service_save(service);
+ } else if (g_str_equal(name, "Passphrase") == TRUE) {
+ const char *passphrase;
+
+ if (type != DBUS_TYPE_STRING)
+ return __connman_error_invalid_arguments(msg);
+
+ if (service->immutable == TRUE)
+ return __connman_error_not_supported(msg);
+
+ dbus_message_iter_get_basic(&value, &passphrase);
+
+ __connman_service_set_passphrase(service, passphrase);
} else if (g_str_equal(name, "Nameservers.Configuration") == TRUE) {
DBusMessageIter entry;
GString *str;
return __connman_error_invalid_arguments(msg);
index = connman_network_get_index(service->network);
- gw = __connman_ipconfig_get_gateway_from_index(index,
- CONNMAN_IPCONFIG_TYPE_ALL);
+ gw = __connman_ipconfig_get_gateway_from_index(index);
if (gw && strlen(gw))
- __connman_service_nameserver_del_routes(service,
- CONNMAN_IPCONFIG_TYPE_ALL);
+ __connman_service_nameserver_del_routes(service);
dbus_message_iter_recurse(&value, &entry);
const char *val;
dbus_message_iter_get_basic(&entry, &val);
dbus_message_iter_next(&entry);
- if (connman_inet_check_ipaddress(val) > 0) {
- if (str->len > 0)
- g_string_append_printf(str, " %s", val);
- else
- g_string_append(str, val);
- }
+ if (str->len > 0)
+ g_string_append_printf(str, " %s", val);
+ else
+ g_string_append(str, val);
}
- remove_nameservers(service, NULL, service->nameservers_config);
g_strfreev(service->nameservers_config);
if (str->len > 0) {
dns_configuration_changed(service);
service_save(service);
- } else if (g_str_equal(name, "Timeservers.Configuration") == TRUE) {
- DBusMessageIter entry;
- GSList *list = NULL;
- int count = 0;
-
- if (type != DBUS_TYPE_ARRAY)
- return __connman_error_invalid_arguments(msg);
-
- dbus_message_iter_recurse(&value, &entry);
-
- while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
- const char *val;
- GSList *new_head;
-
- dbus_message_iter_get_basic(&entry, &val);
-
- new_head = __connman_timeserver_add_list(list, val);
- if (list != new_head) {
- count++;
- list = new_head;
- }
-
- dbus_message_iter_next(&entry);
- }
-
- g_strfreev(service->timeservers_config);
- service->timeservers_config = NULL;
-
- if (list != NULL) {
- service->timeservers_config = g_new0(char *, count+1);
-
- while (list != NULL) {
- count--;
- service->timeservers_config[count] = list->data;
- list = g_slist_delete_link(list, list);
- };
- }
-
- service_save(service);
- timeservers_configuration_changed(service);
-
- __connman_timeserver_sync(service);
} else if (g_str_equal(name, "Domains.Configuration") == TRUE) {
DBusMessageIter entry;
GString *str;
g_string_append(str, val);
}
- remove_searchdomains(service, NULL, service->domains);
g_strfreev(service->domains);
if (str->len > 0)
g_get_current_time(&service->modified);
service_save(service);
+ } else if (g_str_equal(name, "Passphrase") == TRUE) {
+ if (service->immutable == TRUE)
+ return __connman_error_not_supported(msg);
+
+ g_free(service->passphrase);
+ service->passphrase = NULL;
+
+ passphrase_changed(service);
+
+ service_save(service);
} else
return __connman_error_invalid_property(msg);
return FALSE;
}
-struct preferred_tech_data {
- GSequence *preferred_list;
- enum connman_service_type type;
-};
-
-static void preferred_tech_add_by_type(gpointer data, gpointer user_data)
-{
- struct connman_service *service = data;
- struct preferred_tech_data *tech_data = user_data;
-
- if (service->type == tech_data->type) {
- g_sequence_append(tech_data->preferred_list, service);
-
- DBG("type %d service %p %s", tech_data->type, service,
- service->name);
- }
-}
-
-static GSequence* preferred_tech_list_get(GSequence *list)
+void __connman_service_auto_connect(void)
{
- unsigned int *tech_array;
- struct preferred_tech_data tech_data;
- int i;
-
- tech_array = connman_setting_get_uint_list("PreferredTechnologies");
- if (tech_array == NULL)
- return NULL;
+ struct connman_service *service = NULL;
+ GSequenceIter *iter;
- tech_data.preferred_list = g_sequence_new(NULL);
+ DBG("");
- for (i = 0; tech_array[i] != 0; i += 1) {
- tech_data.type = tech_array[i];
- g_sequence_foreach(service_list, preferred_tech_add_by_type,
- &tech_data);
+ if (__connman_session_mode() == TRUE) {
+ DBG("Session mode enabled: auto connect disabled");
+ return;
}
- return tech_data.preferred_list;
-}
-
-static connman_bool_t auto_connect_service(GSequenceIter* iter,
- connman_bool_t preferred)
-{
- struct connman_service *service = NULL;
+ iter = g_sequence_get_begin_iter(service_list);
while (g_sequence_iter_is_end(iter) == FALSE) {
service = g_sequence_get(iter);
+#if defined TIZEN_EXT
+ DBG("service: %p %s %s %s, favorite(%d), ignore(%d)", service, service->name,
+ state2string(service->state),
+ __connman_service_type2string(service->type),
+ service->favorite, is_ignore(service));
+
+ /* Tizen takes Wi-Fi as the highest priority into consideration. */
+ if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
+ if (is_connecting(service) == TRUE || is_connected(service) == TRUE) {
+ service = NULL;
+ iter = g_sequence_iter_next(iter);
+ continue;
+ }
+#endif
if (service->pending != NULL)
- return TRUE;
+ return;
if (is_connecting(service) == TRUE)
- return TRUE;
+ return;
- if (service->favorite == FALSE) {
- if (preferred == TRUE)
- goto next_service;
- return FALSE;
- }
+ if (service->favorite == FALSE)
+ return;
- if (is_connected(service) == TRUE) {
- if (preferred == TRUE && service->state !=
- CONNMAN_SERVICE_STATE_ONLINE)
- goto next_service;
- return TRUE;
- }
+ if (is_connected(service) == TRUE)
+ return;
if (is_ignore(service) == FALSE && service->state ==
- CONNMAN_SERVICE_STATE_IDLE)
+ CONNMAN_SERVICE_STATE_IDLE)
break;
- next_service:
service = NULL;
iter = g_sequence_iter_next(iter);
}
if (service != NULL) {
-
- DBG("service %p %s %s", service, service->name,
- (preferred == TRUE)? "preferred": "auto");
-
service->userconnect = FALSE;
__connman_service_connect(service);
- return TRUE;
}
- return FALSE;
-}
-
-static gboolean run_auto_connect(gpointer data)
-{
- GSequenceIter *iter = NULL;
- GSequence *preferred_tech;
-
- autoconnect_timeout = 0;
-
- DBG("");
-
- preferred_tech = preferred_tech_list_get(service_list);
- if (preferred_tech != NULL)
- iter = g_sequence_get_begin_iter(preferred_tech);
-
- if (iter == NULL || auto_connect_service(iter, TRUE) == FALSE)
- iter = g_sequence_get_begin_iter(service_list);
-
- if (iter != NULL)
- auto_connect_service(iter, FALSE);
-
- if (preferred_tech != NULL)
- g_sequence_free(preferred_tech);
-
- return FALSE;
-}
-
-void __connman_service_auto_connect(void)
-{
- DBG("");
-
- if (__connman_session_mode() == TRUE) {
- DBG("Session mode enabled: auto connect disabled");
- return;
- }
-
- if (autoconnect_timeout != 0)
- return;
-
- autoconnect_timeout = g_timeout_add_seconds(0, run_auto_connect, NULL);
}
static void remove_timeout(struct connman_service *service)
}
}
-void __connman_service_reply_dbus_pending(DBusMessage *pending, int error)
+static void reply_pending(struct connman_service *service, int error)
{
- if (pending != NULL) {
+ remove_timeout(service);
+
+ if (service->pending != NULL) {
if (error > 0) {
DBusMessage *reply;
- reply = __connman_error_failed(pending, error);
+ reply = __connman_error_failed(service->pending,
+ error);
if (reply != NULL)
g_dbus_send_message(connection, reply);
} else {
- const char *sender, *path;
+ const char *sender;
- sender = dbus_message_get_interface(pending);
- path = dbus_message_get_path(pending);
+ sender = dbus_message_get_interface(service->pending);
- DBG("sender %s path %s", sender, path);
+ DBG("sender %s", sender);
if (g_strcmp0(sender, CONNMAN_MANAGER_INTERFACE) == 0)
- g_dbus_send_reply(connection, pending,
- DBUS_TYPE_OBJECT_PATH, &path,
+ g_dbus_send_reply(connection, service->pending,
+ DBUS_TYPE_OBJECT_PATH, &service->path,
DBUS_TYPE_INVALID);
else
- g_dbus_send_reply(connection, pending,
+ g_dbus_send_reply(connection, service->pending,
DBUS_TYPE_INVALID);
}
- dbus_message_unref(pending);
- }
-}
-
-static void reply_pending(struct connman_service *service, int error)
-{
- remove_timeout(service);
-
- if (service->pending != NULL) {
- __connman_service_reply_dbus_pending(service->pending, error);
+ dbus_message_unref(service->pending);
service->pending = NULL;
}
}
-static void check_pending_msg(struct connman_service *service)
-{
- if (service->pending == NULL)
- return;
-
- DBG("service %p pending msg %p already exists", service,
- service->pending);
- dbus_message_unref(service->pending);
-}
-
-void __connman_service_set_hidden_data(struct connman_service *service,
- gpointer user_data)
-{
- DBusMessage *pending = user_data;
-
- DBG("service %p pending %p", service, pending);
-
- if (pending == NULL)
- return;
-
- check_pending_msg(service);
-
- service->pending = pending;
-}
-
-void __connman_service_return_error(struct connman_service *service,
- int error, gpointer user_data)
-{
- DBG("service %p error %d user_data %p", service, error, user_data);
-
- __connman_service_set_hidden_data(service, user_data);
-
- reply_pending(service, error);
-}
-
static gboolean connect_timeout(gpointer user_data)
{
struct connman_service *service = user_data;
DBG("service %p", service);
+#if defined TIZEN_EXT
+ /*
+ * Description: TIZEN implements system global connection management.
+ */
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ connman_service_user_initiated_pdn_connection_ref(service);
+#endif
+
if (service->pending != NULL)
return __connman_error_in_progress(msg);
DBG("service %p", service);
+#if defined TIZEN_EXT
+ /*
+ * Description: TIZEN implements system global connection management.
+ */
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) {
+ if (connman_service_user_initiated_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;
if (err != -EINPROGRESS)
return __connman_error_failed(msg, -err);
+#if defined TIZEN_EXT
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+#else
return NULL;
+#endif
}
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
-gboolean __connman_service_remove(struct connman_service *service)
+static DBusMessage *remove_service(DBusConnection *conn,
+ DBusMessage *msg, void *user_data)
{
+ struct connman_service *service = user_data;
+
+ DBG("service %p", service);
+
if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET)
- return FALSE;
+ return __connman_error_not_supported(msg);
- if (service->immutable == TRUE || service->hidden == TRUE)
- return FALSE;
+ if (service->immutable == TRUE)
+ return __connman_error_not_supported(msg);
if (service->favorite == FALSE && service->state !=
CONNMAN_SERVICE_STATE_FAILURE)
- return FALSE;
+ return __connman_error_not_supported(msg);
set_reconnect_state(service, FALSE);
g_free(service->passphrase);
service->passphrase = NULL;
- g_free(service->agent_passphrase);
- service->agent_passphrase = NULL;
-
- g_free(service->identity);
- service->identity = NULL;
-
- g_free(service->agent_identity);
- service->agent_identity = NULL;
-
- g_free(service->eap);
- service->eap = NULL;
+ passphrase_changed(service);
set_idle(service);
__connman_service_set_favorite(service, FALSE);
-
service_save(service);
- return TRUE;
-}
-
-static DBusMessage *remove_service(DBusConnection *conn,
- DBusMessage *msg, void *user_data)
-{
- struct connman_service *service = user_data;
-
- DBG("service %p", service);
-
- if (__connman_service_remove(service) == FALSE)
- return __connman_error_not_supported(msg);
-
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
{
struct connman_service *def_service;
- def_service = __connman_service_get_default();
+ def_service = get_default();
if (def_service == NULL)
return;
def_service->state = CONNMAN_SERVICE_STATE_READY;
}
-static void switch_default_service(struct connman_service *default_service,
- struct connman_service *downgrade_service)
-{
- GSequenceIter *src, *dst;
-
- apply_relevant_default_downgrade(default_service);
- src = g_hash_table_lookup(service_hash, downgrade_service->identifier);
- dst = g_hash_table_lookup(service_hash, default_service->identifier);
- g_sequence_move(src, dst);
- downgrade_state(downgrade_service);
-}
-
static DBusMessage *move_service(DBusConnection *conn,
DBusMessage *msg, void *user_data,
gboolean before)
struct connman_service *service = user_data;
struct connman_service *target;
const char *path;
+ GSequenceIter *src, *dst;
enum connman_ipconfig_method target4, target6;
enum connman_ipconfig_method service4, service6;
return __connman_error_not_supported(msg);
target = find_service(path);
- if (target == NULL || target->favorite == FALSE || target == service)
+ if (target == NULL || target->favorite == FALSE || target == service ||
+ target->type == CONNMAN_SERVICE_TYPE_VPN)
return __connman_error_invalid_service(msg);
- if (target->type == CONNMAN_SERVICE_TYPE_VPN) {
- /*
- * We only allow VPN route splitting if there are
- * routes defined for a given VPN.
- */
- if (__connman_provider_check_routes(target->provider)
- == FALSE) {
- connman_info("Cannot move service. "
- "No routes defined for provider %s",
- __connman_provider_get_ident(target->provider));
- return __connman_error_invalid_service(msg);
- }
-
- target->do_split_routing = TRUE;
- } else
- target->do_split_routing = FALSE;
-
- service->do_split_routing = FALSE;
-
target4 = __connman_ipconfig_get_method(target->ipconfig_ipv4);
target6 = __connman_ipconfig_get_method(target->ipconfig_ipv6);
service4 = __connman_ipconfig_get_method(service->ipconfig_ipv4);
service6 = __connman_ipconfig_get_method(service->ipconfig_ipv6);
- DBG("target %s method %d/%d state %d/%d split %d", target->identifier,
- target4, target6, target->state_ipv4, target->state_ipv6,
- target->do_split_routing);
+ DBG("target %s method %d/%d state %d/%d", target->identifier,
+ target4, target6,
+ target->state_ipv4, target->state_ipv6);
DBG("service %s method %d/%d state %d/%d", service->identifier,
service4, service6,
g_get_current_time(&service->modified);
service_save(service);
- service_save(target);
+
+ src = g_hash_table_lookup(service_hash, service->identifier);
+ dst = g_hash_table_lookup(service_hash, target->identifier);
/*
* If the service which goes down is the default service and is
* the service which goes up, needs to recompute its state which
* is triggered via downgrading it - if relevant - to state ready.
*/
- if (before == TRUE)
- switch_default_service(target, service);
- else
- switch_default_service(service, target);
+ if (before == TRUE) {
+ apply_relevant_default_downgrade(target);
+ g_sequence_move(src, dst);
+ downgrade_state(service);
+ } else {
+ apply_relevant_default_downgrade(service);
+ g_sequence_move(dst, src);
+ downgrade_state(target);
+ }
- __connman_connection_update_gateway();
+ services_changed(FALSE);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
-static struct _services_notify {
- int id;
- GHashTable *add;
- GHashTable *remove;
-} *services_notify;
-
-static void service_append_added_foreach(gpointer data, gpointer user_data)
-{
- struct connman_service *service = data;
- DBusMessageIter *iter = user_data;
-
- if (service == NULL || service->path == NULL) {
- DBG("service %p or path is NULL", service);
- return;
- }
-
- if (g_hash_table_lookup(services_notify->add, service->path) != NULL) {
- DBG("new %s", service->path);
-
- append_struct(service, iter);
- g_hash_table_remove(services_notify->add, service->path);
- } else {
- DBG("changed %s", service->path);
-
- append_struct_service(iter, NULL, service);
- }
-}
-
-static void service_append_ordered(DBusMessageIter *iter, void *user_data)
-{
- if (service_list != NULL)
- g_sequence_foreach(service_list,
- service_append_added_foreach, iter);
-}
-
-static void append_removed(gpointer key, gpointer value, gpointer user_data)
-{
- char *objpath = key;
- DBusMessageIter *iter = user_data;
-
- DBG("removed %s", objpath);
- dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &objpath);
-}
-
-static gboolean service_send_changed(gpointer data)
-{
- DBusMessage *signal;
- DBusMessageIter iter, array;
-
- DBG("");
-
- signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
- CONNMAN_MANAGER_INTERFACE, "ServicesChanged");
- if (signal == NULL)
- return FALSE;
-
- __connman_dbus_append_objpath_dict_array(signal,
- service_append_ordered, NULL);
-
- dbus_message_iter_init_append(signal, &iter);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_OBJECT_PATH_AS_STRING, &array);
-
- g_hash_table_foreach(services_notify->remove, append_removed, &array);
-
- dbus_message_iter_close_container(&iter, &array);
-
- dbus_connection_send(connection, signal, NULL);
- dbus_message_unref(signal);
-
- g_hash_table_remove_all(services_notify->remove);
- g_hash_table_remove_all(services_notify->add);
-
- services_notify->id = 0;
- return FALSE;
-}
-
-static void service_schedule_changed(void)
-{
- if (services_notify->id != 0)
- return;
-
- services_notify->id = g_timeout_add(100, service_send_changed, NULL);
-}
-
-static void service_schedule_added(struct connman_service *service)
-{
- DBG("service %p", service);
-
- g_hash_table_remove(services_notify->remove, service->path);
- g_hash_table_replace(services_notify->add, service->path, service);
-
- service_schedule_changed();
-}
-
-static void service_schedule_removed(struct connman_service *service)
-{
- DBG("service %p %s", service, service->path);
-
- if (service == NULL || service->path == NULL) {
- DBG("service %p or path is NULL", service);
- return;
- }
-
- g_hash_table_remove(services_notify->add, service->path);
- g_hash_table_replace(services_notify->remove, g_strdup(service->path),
- NULL);
-
- service_schedule_changed();
-}
-
-static const GDBusMethodTable service_methods[] = {
- { GDBUS_DEPRECATED_METHOD("GetProperties",
- NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
- get_properties) },
- { GDBUS_METHOD("SetProperty",
- GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
- NULL, set_property) },
- { GDBUS_METHOD("ClearProperty",
- GDBUS_ARGS({ "name", "s" }), NULL,
- clear_property) },
- { GDBUS_ASYNC_METHOD("Connect", NULL, NULL,
- connect_service) },
- { GDBUS_METHOD("Disconnect", NULL, NULL,
- disconnect_service) },
- { GDBUS_METHOD("Remove", NULL, NULL, remove_service) },
- { GDBUS_METHOD("MoveBefore",
- GDBUS_ARGS({ "service", "o" }), NULL,
- move_before) },
- { GDBUS_METHOD("MoveAfter",
- GDBUS_ARGS({ "service", "o" }), NULL,
- move_after) },
- { GDBUS_METHOD("ResetCounters", NULL, NULL, reset_counters) },
+static GDBusMethodTable service_methods[] = {
+ { "GetProperties", "", "a{sv}", get_properties },
+ { "SetProperty", "sv", "", set_property },
+ { "ClearProperty", "s", "", clear_property },
+ { "Connect", "", "", connect_service,
+ G_DBUS_METHOD_FLAG_ASYNC },
+ { "Disconnect", "", "", disconnect_service },
+ { "Remove", "", "", remove_service },
+ { "MoveBefore", "o", "", move_before },
+ { "MoveAfter", "o", "", move_after },
+ { "ResetCounters", "", "", reset_counters },
{ },
};
-static const GDBusSignalTable service_signals[] = {
- { GDBUS_SIGNAL("PropertyChanged",
- GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
+static GDBusSignalTable service_signals[] = {
+ { "PropertyChanged", "sv" },
{ },
};
g_hash_table_remove(service_hash, service->identifier);
__connman_notifier_service_remove(service);
- service_schedule_removed(service);
stats_stop(service);
service->path = NULL;
if (path != NULL) {
- __connman_connection_update_gateway();
+ services_changed(FALSE);
g_dbus_unregister_interface(connection, path,
CONNMAN_SERVICE_INTERFACE);
g_hash_table_destroy(service->counter_table);
if (service->network != NULL) {
- __connman_network_disconnect(service->network);
- connman_network_unref(service->network);
- service->network = NULL;
+ if (service->network_created == TRUE)
+ connman_network_unref(service->network);
}
if (service->provider != NULL)
connman_provider_unref(service->provider);
if (service->ipconfig_ipv4 != NULL) {
- __connman_ipconfig_set_ops(service->ipconfig_ipv4, NULL);
- __connman_ipconfig_set_data(service->ipconfig_ipv4, NULL);
- __connman_ipconfig_unref(service->ipconfig_ipv4);
+ connman_ipconfig_set_ops(service->ipconfig_ipv4, NULL);
+ connman_ipconfig_set_data(service->ipconfig_ipv4, NULL);
+ connman_ipconfig_unref(service->ipconfig_ipv4);
service->ipconfig_ipv4 = NULL;
}
if (service->ipconfig_ipv6 != NULL) {
- __connman_ipconfig_set_ops(service->ipconfig_ipv6, NULL);
- __connman_ipconfig_set_data(service->ipconfig_ipv6, NULL);
- __connman_ipconfig_unref(service->ipconfig_ipv6);
+ connman_ipconfig_set_ops(service->ipconfig_ipv6, NULL);
+ connman_ipconfig_set_data(service->ipconfig_ipv6, NULL);
+ connman_ipconfig_unref(service->ipconfig_ipv6);
service->ipconfig_ipv6 = NULL;
}
- g_strfreev(service->timeservers);
- g_strfreev(service->timeservers_config);
g_strfreev(service->nameservers);
g_strfreev(service->nameservers_config);
g_strfreev(service->nameservers_auto);
g_free(service->private_key_file);
g_free(service->private_key_passphrase);
g_free(service->phase2);
- g_free(service->config_file);
- g_free(service->config_entry);
if (service->stats.timer != NULL)
g_timer_destroy(service->stats.timer);
g_free(service);
}
+/**
+ * __connman_service_put:
+ * @service: service structure
+ *
+ * Release service if no longer needed
+ */
+void __connman_service_put(struct connman_service *service)
+{
+ GSequenceIter *iter;
+
+ DBG("service %p", service);
+
+ if (__sync_fetch_and_sub(&service->refcount, 1) != 1)
+ return;
+
+ iter = g_hash_table_lookup(service_hash, service->identifier);
+ if (iter != NULL) {
+ reply_pending(service, ECONNABORTED);
+
+ __connman_service_disconnect(service);
+
+ g_sequence_remove(iter);
+ } else {
+ service_free(service);
+ }
+}
+
static void stats_init(struct connman_service *service)
{
/* home */
service->refcount = 1;
service->session_usage_count = 0;
+ service->network_created = FALSE;
+
service->type = CONNMAN_SERVICE_TYPE_UNKNOWN;
service->security = CONNMAN_SERVICE_SECURITY_UNKNOWN;
service->provider = NULL;
service->wps = FALSE;
+
+#if defined TIZEN_EXT
+ /*
+ * Description: TIZEN implements system global connection management.
+ */
+ g_atomic_int_set(&service->user_initiated_pdn_connection_refcount, 0);
+#endif
}
/**
*
* Increase reference counter of service
*/
-struct connman_service *
-connman_service_ref_debug(struct connman_service *service,
- const char *file, int line, const char *caller)
+struct connman_service *connman_service_ref(struct connman_service *service)
{
- DBG("%p ref %d by %s:%d:%s()", service, service->refcount + 1,
- file, line, caller);
+ DBG("%p", service);
__sync_fetch_and_add(&service->refcount, 1);
* connman_service_unref:
* @service: service structure
*
- * Decrease reference counter of service and release service if no
- * longer needed.
+ * Decrease reference counter of service
*/
-void connman_service_unref_debug(struct connman_service *service,
- const char *file, int line, const char *caller)
+void connman_service_unref(struct connman_service *service)
{
- GSequenceIter *iter;
-
- DBG("%p ref %d by %s:%d:%s()", service, service->refcount - 1,
- file, line, caller);
-
- if (__sync_fetch_and_sub(&service->refcount, 1) != 1)
- return;
-
- iter = g_hash_table_lookup(service_hash, service->identifier);
- if (iter != NULL) {
- reply_pending(service, ECONNABORTED);
-
- __connman_service_disconnect(service);
-
- g_sequence_remove(iter);
- } else {
- service_free(service);
- }
+ __connman_service_put(service);
}
static gint service_compare(gconstpointer a, gconstpointer b,
gboolean b_connected = is_connected(service_b);
if (a_connected == TRUE && b_connected == TRUE) {
+#if defined TIZEN_EXT
+ /* We prefer wifi on connected state */
+ if (service_a->type != service_b->type) {
+ if (service_a->type == CONNMAN_SERVICE_TYPE_WIFI)
+ return -1;
+ if (service_b->type == CONNMAN_SERVICE_TYPE_WIFI)
+ return 1;
+ }
+#endif
/* We prefer online over ready state */
if (state_a == CONNMAN_SERVICE_STATE_ONLINE)
return -1;
case CONNMAN_SERVICE_TYPE_VPN:
case CONNMAN_SERVICE_TYPE_GADGET:
break;
+#if defined TIZEN_EXT
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ return -1;
+ case CONNMAN_SERVICE_TYPE_WIMAX:
+ case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ return 1;
+#else
case CONNMAN_SERVICE_TYPE_WIFI:
return 1;
case CONNMAN_SERVICE_TYPE_WIMAX:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
return -1;
+#endif
}
}
if (service->type == CONNMAN_SERVICE_TYPE_VPN) {
if (service->ipconfig_ipv4)
- index = __connman_ipconfig_get_index(
+ index = connman_ipconfig_get_index(
service->ipconfig_ipv4);
else if (service->ipconfig_ipv6)
- index = __connman_ipconfig_get_index(
+ index = connman_ipconfig_get_index(
service->ipconfig_ipv6);
else
return NULL;
}
-connman_bool_t __connman_service_is_connected_state(struct connman_service *service,
- enum connman_ipconfig_type type)
-{
- if (service == NULL)
- return FALSE;
-
- switch (type) {
- case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
- break;
- case CONNMAN_IPCONFIG_TYPE_IPV4:
- return is_connected_state(service, service->state_ipv4);
- case CONNMAN_IPCONFIG_TYPE_IPV6:
- return is_connected_state(service, service->state_ipv6);
- }
-
- return FALSE;
-}
enum connman_service_security __connman_service_get_security(struct connman_service *service)
{
if (service == NULL)
return service->wps;
}
-void __connman_service_mark_dirty()
- {
- services_dirty = TRUE;
- }
-
/**
- * __connman_service_set_favorite_delayed:
+ * __connman_service_set_favorite:
* @service: service structure
* @favorite: favorite value
- * @delay_ordering: do not order service sequence
*
* Change the favorite setting of service
*/
-int __connman_service_set_favorite_delayed(struct connman_service *service,
- connman_bool_t favorite,
- gboolean delay_ordering)
+int __connman_service_set_favorite(struct connman_service *service,
+ connman_bool_t favorite)
{
GSequenceIter *iter;
- if (service->hidden == TRUE)
- return -EOPNOTSUPP;
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ return -EIO;
+#endif
iter = g_hash_table_lookup(service_hash, service->identifier);
if (iter == NULL)
return -ENOENT;
return -EALREADY;
service->favorite = favorite;
-
- if (delay_ordering == FALSE)
- service->order = __connman_service_get_order(service);
+ service->order = __connman_service_get_order(service);
favorite_changed(service);
- if (delay_ordering == FALSE) {
+ g_sequence_sort_changed(iter, service_compare, NULL);
- if (g_sequence_get_length(service_list) > 1) {
- g_sequence_sort_changed(iter, service_compare, NULL);
- service_schedule_changed();
+ services_changed(FALSE);
+
+#if defined TIZEN_EXT
+ {
+ struct connman_device *device = connman_network_get_device(service->network);
+
+ if (connman_device_get_type(device) == CONNMAN_DEVICE_TYPE_WIFI) {
+ if (service->favorite == TRUE)
+ connman_device_significant_wifi_profile_ref(device);
+ else
+ connman_device_significant_wifi_profile_unref_and_test(device);
}
- __connman_connection_update_gateway();
+ connman_device_save_significant_wifi_profile_refcount_to_storage(device);
}
-
+#endif
return 0;
}
-/**
- * __connman_service_set_favorite:
- * @service: service structure
- * @favorite: favorite value
- *
- * Change the favorite setting of service
- */
-int __connman_service_set_favorite(struct connman_service *service,
- connman_bool_t favorite)
-{
- return __connman_service_set_favorite_delayed(service, favorite,
- FALSE);
-}
-
int __connman_service_set_immutable(struct connman_service *service,
connman_bool_t immutable)
{
- if (service->hidden == TRUE)
- return -EOPNOTSUPP;
service->immutable = immutable;
immutable_changed(service);
void __connman_service_set_string(struct connman_service *service,
const char *key, const char *value)
{
- if (service->hidden == TRUE)
- return;
if (g_str_equal(key, "EAP") == TRUE) {
g_free(service->eap);
service->eap = g_strdup(value);
}
}
-void __connman_service_set_userconnect(struct connman_service *service,
- connman_bool_t userconnect)
-{
- if (service != NULL)
- service->userconnect = userconnect;
-}
-
static void service_complete(struct connman_service *service)
{
reply_pending(service, EIO);
if (retry == TRUE)
__connman_service_connect(service);
else {
- /* It is not relevant to stay on Failure state
- * when failing is due to wrong user input */
- service->state = CONNMAN_SERVICE_STATE_IDLE;
-
service_complete(service);
- __connman_connection_update_gateway();
- }
-}
-
-int __connman_service_add_passphrase(struct connman_service *service,
- const gchar *passphrase)
-{
- int err = 0;
-
- switch (service->security) {
- case CONNMAN_SERVICE_SECURITY_WEP:
- case CONNMAN_SERVICE_SECURITY_PSK:
- err = __connman_service_set_passphrase(service, passphrase);
- break;
- case CONNMAN_SERVICE_SECURITY_8021X:
- __connman_service_set_agent_passphrase(service,
- passphrase);
- break;
- case CONNMAN_SERVICE_SECURITY_UNKNOWN:
- case CONNMAN_SERVICE_SECURITY_NONE:
- case CONNMAN_SERVICE_SECURITY_WPA:
- case CONNMAN_SERVICE_SECURITY_RSN:
- DBG("service security '%s' (%d) not handled",
- security2string(service->security),
- service->security);
- break;
- }
-
- return err;
-}
-
-static int check_wpspin(struct connman_service *service, const char *wpspin)
-{
- int length;
- guint i;
-
- if (wpspin == NULL)
- return 0;
-
- length = strlen(wpspin);
-
- /* If 0, it will mean user wants to use PBC method */
- if (length == 0) {
- connman_network_set_string(service->network,
- "WiFi.PinWPS", NULL);
- return 0;
+ services_changed(FALSE);
+ __connman_device_request_scan(CONNMAN_DEVICE_TYPE_UNKNOWN);
}
-
- /* A WPS PIN is always 8 chars length,
- * its content is in digit representation.
- */
- if (length != 8)
- return -ENOKEY;
-
- for (i = 0; i < 8; i++)
- if (!isdigit((unsigned char) wpspin[i]))
- return -ENOKEY;
-
- connman_network_set_string(service->network, "WiFi.PinWPS", wpspin);
-
- return 0;
}
static void request_input_cb (struct connman_service *service,
- connman_bool_t values_received,
- const char *name, int name_len,
const char *identity, const char *passphrase,
- gboolean wps, const char *wpspin,
- const char *error, void *user_data)
+ void *user_data)
{
- struct connman_device *device;
- int err = 0;
-
DBG ("RequestInput return, %p", service);
- if (error != NULL) {
- DBG("error: %s", error);
-
- if (g_strcmp0(error,
- "net.connman.Agent.Error.Canceled") == 0) {
- err = -EINVAL;
-
- if (service->hidden == TRUE)
- __connman_service_return_error(service,
- ECANCELED, user_data);
- goto done;
- } else {
- if (service->hidden == TRUE)
- __connman_service_return_error(service,
- ETIMEDOUT, user_data);
- }
- }
-
- if (service->hidden == TRUE && name_len > 0 && name_len <= 32) {
- device = connman_network_get_device(service->network);
- err = __connman_device_request_hidden_scan(device,
- name, name_len,
- identity, passphrase,
- user_data);
- if (err < 0)
- __connman_service_return_error(service, -err,
- user_data);
- }
-
- if (values_received == FALSE || service->hidden == TRUE) {
- err = -EINVAL;
- goto done;
- }
-
- if (wps == TRUE && service->network != NULL) {
- err = check_wpspin(service, wpspin);
- if (err < 0)
- goto done;
-
- connman_network_set_bool(service->network, "WiFi.UseWPS", wps);
+ if (identity == NULL && passphrase == NULL && service->wps == FALSE) {
+ service_complete(service);
+ services_changed(FALSE);
+ __connman_device_request_scan(CONNMAN_DEVICE_TYPE_UNKNOWN);
+ return;
}
if (identity != NULL)
__connman_service_set_agent_identity(service, identity);
- if (passphrase != NULL)
- err = __connman_service_add_passphrase(service, passphrase);
-
- done:
- if (err >= 0) {
- /* We forget any previous error. */
- service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;
-
- __connman_service_connect(service);
-
- /* Never cache agent provided credentials */
- __connman_service_set_agent_identity(service, NULL);
- __connman_service_set_agent_passphrase(service, NULL);
- } else if (err == -ENOKEY) {
- __connman_service_indicate_error(service,
- CONNMAN_SERVICE_ERROR_INVALID_KEY);
- __connman_agent_report_error(service,
- error2string(service->error),
- report_error_cb, NULL);
- } else {
- /* It is not relevant to stay on Failure state
- * when failing is due to wrong user input */
- service->state = CONNMAN_SERVICE_STATE_IDLE;
-
- if (service->hidden == FALSE) {
- /*
- * If there was a real error when requesting
- * hidden scan, then that error is returned already
- * to the user somewhere above so do not try to
- * do this again.
- */
- __connman_service_return_error(service, -err,
- user_data);
+ if (passphrase != NULL) {
+ switch (service->security) {
+ case CONNMAN_SERVICE_SECURITY_WEP:
+ case CONNMAN_SERVICE_SECURITY_PSK:
+ __connman_service_set_passphrase(service, passphrase);
+ break;
+ case CONNMAN_SERVICE_SECURITY_8021X:
+ __connman_service_set_agent_passphrase(service,
+ passphrase);
+ break;
+ case CONNMAN_SERVICE_SECURITY_UNKNOWN:
+ case CONNMAN_SERVICE_SECURITY_NONE:
+ case CONNMAN_SERVICE_SECURITY_WPA:
+ case CONNMAN_SERVICE_SECURITY_RSN:
+ DBG("service security '%s' not handled",
+ security2string(service->security));
+ break;
}
-
- service_complete(service);
- __connman_connection_update_gateway();
}
+
+ __connman_service_connect(service);
+
+ /* Never cache agent provided credentials */
+ __connman_service_set_agent_identity(service, NULL);
+ __connman_service_set_agent_passphrase(service, NULL);
}
static void downgrade_connected_services(void)
}
}
-static int service_update_preferred_order(struct connman_service *default_service,
- struct connman_service *new_service,
- enum connman_service_state new_state)
+#if defined TIZEN_EXT
+static connman_bool_t __connman_service_can_drop_cellular(
+ struct connman_service *cellular)
{
- unsigned int *tech_array;
- int i;
+ if (cellular->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
+ is_connected(cellular) == TRUE)
+ if (connman_service_is_no_ref_user_initiated_pdn_connection(cellular) == TRUE)
+ return TRUE;
+ return FALSE;
+}
- if (default_service == NULL || default_service == new_service ||
- default_service->state != new_state )
- return 0;
+static void __connman_service_connect_default(void)
+{
+ static struct connman_device *connecting_device = NULL;
+ struct connman_service *default_service = NULL;
+ struct connman_device *default_device = NULL;
- tech_array = connman_setting_get_uint_list("PreferredTechnologies");
- if (tech_array != NULL) {
+ default_service = __connman_service_get_default();
- for (i = 0; tech_array[i] != 0; i += 1) {
- if (default_service->type == tech_array[i])
- return -EALREADY;
+ if (default_service != NULL) {
+ if (is_connecting(default_service) == FALSE &&
+ is_connected(default_service) == FALSE) {
- if (new_service->type == tech_array[i]) {
- switch_default_service(new_service,
- default_service);
- return 0;
- }
+ default_device = connman_network_get_device(
+ __connman_service_get_network(default_service));
+
+ DBG("connecting_device %p", connecting_device);
+
+ if (connecting_device == default_device)
+ return;
+
+ connecting_device = default_device;
+ default_service->userconnect = FALSE;
+
+ DBG("Connecting default service %p %s",
+ default_service, default_service->path);
+ DBG("Connecting device %p %s", connecting_device,
+ connman_device_get_string(connecting_device, "Name"));
+
+ __connman_service_connect(default_service);
+ } else if (is_connected(default_service) == TRUE) {
+ DBG("default service connected %s", default_service->path);
+ connecting_device = NULL;
}
- return -EAGAIN;
+ }
+}
+#endif
+
+static void service_single_connection(struct connman_service *allowed)
+{
+ GSequenceIter *iter;
+ GSList *services = NULL, *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);
+ }
+
+ DBG("Allowed %p %s", allowed, allowed->path);
+
+ for (list = services; list != NULL; list = list->next) {
+ struct connman_service *service = list->data;
+
+ DBG("Disconnecting %p %s", service, service->path);
+ __connman_service_disconnect(service);
}
- return -EALREADY;
+ g_slist_free(services);
}
static int service_indicate_state(struct connman_service *service)
{
enum connman_service_state old_state, new_state;
struct connman_service *def_service;
- int result;
GSequenceIter *iter;
if (service == NULL)
if (old_state == new_state)
return -EALREADY;
- def_service = __connman_service_get_default();
+ def_service = get_default();
if (new_state == CONNMAN_SERVICE_STATE_ONLINE) {
- result = service_update_preferred_order(def_service,
- service, new_state);
- if (result == -EALREADY)
- return result;
- if (result == -EAGAIN)
- __connman_service_auto_connect();
+ if (def_service != NULL && def_service != service &&
+ def_service->state == CONNMAN_SERVICE_STATE_ONLINE)
+ return -EALREADY;
}
- if (old_state == CONNMAN_SERVICE_STATE_ONLINE)
- __connman_notifier_leave_online(service->type);
-
service->state = new_state;
state_changed(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);
}
if (new_state == CONNMAN_SERVICE_STATE_CONFIGURATION) {
- if (service->new_service == FALSE &&
- __connman_stats_service_register(service) == 0) {
- /*
- * For new services the statistics are updated after
- * we have successfully connected.
- */
+ if (__connman_stats_service_register(service) == 0) {
__connman_stats_get(service, FALSE,
&service->stats.data);
__connman_stats_get(service, TRUE,
}
}
+ if (new_state == CONNMAN_SERVICE_STATE_ONLINE) {
+ if (service->login_required == TRUE) {
+ service->login_required = FALSE;
+ login_changed(service);
+ }
+
+ connman_timeserver_sync();
+ }
+
if (new_state == CONNMAN_SERVICE_STATE_IDLE) {
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
+ connman_network_get_bool(service->network,
+ "WiFi.UseWPS") == TRUE) {
+ connman_network_set_bool(service->network,
+ "WiFi.UseWPS", FALSE);
+ }
+
+ reply_pending(service, ECONNABORTED);
+ __connman_device_request_scan(service->type);
+
+ __connman_service_update_default(service);
+#endif
connman_bool_t reconnect;
reconnect = get_reconnect_state(service);
if (reconnect == TRUE)
__connman_service_auto_connect();
+
+ __connman_device_request_scan(CONNMAN_DEVICE_TYPE_UNKNOWN);
}
if (new_state == CONNMAN_SERVICE_STATE_READY) {
enum connman_ipconfig_method method;
- if (service->new_service == TRUE &&
- __connman_stats_service_register(service) == 0) {
- /*
- * This is normally done after configuring state
- * but for new service do this after we have connected
- * successfully.
- */
- __connman_stats_get(service, FALSE,
- &service->stats.data);
- __connman_stats_get(service, TRUE,
- &service->stats_roaming.data);
- }
-
- service->new_service = FALSE;
-
- service_update_preferred_order(def_service, service, new_state);
-
set_reconnect_state(service, TRUE);
__connman_service_set_favorite(service, TRUE);
__connman_ipconfig_disable_ipv6(
service->ipconfig_ipv6);
+#if defined TIZEN_EXT
+ __connman_service_update_default(service);
+#endif
+ if (connman_setting_get_bool("SingleConnection") == TRUE)
+ service_single_connection(service);
+
} else if (new_state == CONNMAN_SERVICE_STATE_DISCONNECT) {
- def_service = __connman_service_get_default();
+ def_service = get_default();
- if (__connman_notifier_is_connected() == FALSE &&
+ if (__connman_notifier_count_connected() == 0 &&
def_service != NULL &&
def_service->provider != NULL)
__connman_provider_disconnect(def_service->provider);
if (service->userconnect == TRUE &&
__connman_agent_report_error(service,
error2string(service->error),
- report_error_cb, NULL) == -EINPROGRESS)
+ report_error_cb, NULL) == -EIO)
return 0;
service_complete(service);
+
+ __connman_device_request_scan(CONNMAN_DEVICE_TYPE_UNKNOWN);
} else
service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;
+#if defined TIZEN_EXT
+ __connman_service_connect_default();
+#endif
iter = g_hash_table_lookup(service_hash, service->identifier);
- if (iter != NULL && g_sequence_get_length(service_list) > 1) {
+ if (iter != NULL)
g_sequence_sort_changed(iter, service_compare, NULL);
- service_schedule_changed();
- }
- __connman_connection_update_gateway();
+ services_changed(FALSE);
- if (new_state == CONNMAN_SERVICE_STATE_ONLINE) {
- __connman_notifier_enter_online(service->type);
+ if (new_state == CONNMAN_SERVICE_STATE_ONLINE)
default_changed();
- }
return 0;
}
service->error = error;
+#if defined TIZEN_EXT
+ if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY &&
+ service->favorite == FALSE)
+#else
if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY)
+#endif
__connman_service_set_passphrase(service, NULL);
__connman_service_ipconfig_indicate_state(service,
service->state_ipv4 = service->state_ipv6 =
CONNMAN_SERVICE_STATE_UNKNOWN;
- service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;
+ service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;;
if (service->favorite == TRUE)
set_reconnect_state(service, TRUE);
connected_networks_count, original_rp_filter);
}
-static gboolean redo_wispr(gpointer user_data)
-{
- struct connman_service *service = user_data;
-
- DBG("");
-
- __connman_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV6);
-
- return FALSE;
-}
-
-int __connman_service_online_check_failed(struct connman_service *service,
- enum connman_ipconfig_type type)
-{
- DBG("service %p type %d count %d", service, type,
- service->online_check_count);
-
- /* currently we only retry IPv6 stuff */
- if (type == CONNMAN_IPCONFIG_TYPE_IPV4 ||
- service->online_check_count != 1) {
- connman_warn("Online check failed for %p %s", service,
- service->name);
- return 0;
- }
-
- service->online_check_count = 0;
-
- /*
- * We set the timeout to 1 sec so that we have a chance to get
- * necessary IPv6 router advertisement messages that might have
- * DNS data etc.
- */
- g_timeout_add_seconds(1, redo_wispr, service);
-
- return EAGAIN;
-}
-
int __connman_service_ipconfig_indicate_state(struct connman_service *service,
enum connman_service_state new_state,
enum connman_ipconfig_type type)
if (ipconfig == NULL)
return -EINVAL;
+#if defined TIZEN_EXT
+ if (new_state == CONNMAN_SERVICE_STATE_FAILURE &&
+ service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
+ g_atomic_int_set(&service->user_initiated_pdn_connection_refcount, 0);
+#endif
/* Any change? */
if (old_state == new_state)
return -EALREADY;
if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
check_proxy_setup(service);
service_rp_filter(service, TRUE);
- } else {
- service->online_check_count = 1;
+ } else
__connman_wispr_start(service, type);
- }
break;
case CONNMAN_SERVICE_STATE_ONLINE:
break;
return ret;
}
+int __connman_service_request_login(struct connman_service *service)
+{
+ DBG("service %p", service);
+
+ if (service == NULL)
+ return -EINVAL;
+
+ service->login_required = TRUE;
+ login_changed(service);
+
+ return 0;
+}
+
static connman_bool_t prepare_network(struct connman_service *service)
{
enum connman_network_type type;
{
int err;
- if (service->hidden == TRUE)
- return -EPERM;
-
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
case CONNMAN_SERVICE_TYPE_SYSTEM:
if (service->network == NULL)
return -EOPNOTSUPP;
+#if defined TIZEN_EXT
+ if (service->wps == TRUE) {
+ connman_network_set_bool(service->network, "WiFi.UseWPS", TRUE);
+ break;
+ } else
+ return -ENOKEY;
+#else
if (service->wps == FALSE ||
connman_network_get_bool(
service->network,
"WiFi.UseWPS") == FALSE)
return -ENOKEY;
- } else if (service->error ==
- CONNMAN_SERVICE_ERROR_INVALID_KEY)
- return -ENOKEY;
+#endif
+ }
break;
case CONNMAN_SERVICE_SECURITY_8021X:
if (service->eap == NULL)
return -EINVAL;
+#if defined TIZEN_EXT
+ /*
+ * never request credentials if using EAP-TLS, EAP-SIM or EAP-AKA
+ * (EAP-TLS, EAP-SIM and EAP-AKA networks need to be fully provisioned)
+ */
+ if (g_str_equal(service->eap, "tls") == TRUE ||
+ g_str_equal(service->eap, "sim") == TRUE ||
+ g_str_equal(service->eap, "aka") == TRUE)
+ break;
+#else
/*
* never request credentials if using EAP-TLS
* (EAP-TLS networks need to be fully provisioned)
*/
if (g_str_equal(service->eap, "tls") == TRUE)
break;
+#endif
/*
* Return -ENOKEY if either identity or passphrase is
return -EINPROGRESS;
}
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_FAILURE,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_FAILURE,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+
if (service->network != NULL)
__connman_network_disconnect(service->network);
else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
__connman_provider_disconnect(service->provider);
if (service->userconnect == TRUE) {
- if (err == -ENOKEY || err == -EPERM) {
- DBusMessage *pending = NULL;
-
- /*
- * We steal the reply here. The idea is that the
- * connecting client will see the connection status
- * after the real hidden network is connected or
- * connection failed.
- */
- if (service->hidden == TRUE) {
- pending = service->pending;
- service->pending = NULL;
- }
-
- err = __connman_agent_request_passphrase_input(service,
- request_input_cb, pending);
- if (service->hidden == TRUE && err != -EINPROGRESS)
- service->pending = pending;
-
- return err;
+ if (err == -ENOKEY) {
+ if (__connman_agent_request_passphrase_input(service,
+ request_input_cb,
+ NULL) == -EIO)
+ return -EINPROGRESS;
}
+#if defined TIZEN_EXT
reply_pending(service, -err);
+#else
+ reply_pending(service, err);
+#endif
}
return err;
}
/**
+ * __connman_service_lookup:
+ * @pattern: search pattern
+ * @path: return object path
+ *
+ * Look up a service path from a search pattern
+ */
+int __connman_service_lookup(const char *pattern, const char **path)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+ struct connman_device *device;
+ const char *ifname;
+
+ g_hash_table_iter_init(&iter, service_hash);
+
+ while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ GSequenceIter *iter = value;
+ struct connman_service *service = g_sequence_get(iter);
+
+ if (g_strcmp0(service->identifier, pattern) == 0 ||
+ g_strcmp0(service->name, pattern) == 0) {
+ *path = (const char *) service->path;
+ return 0;
+ }
+
+ if (service->network == NULL)
+ continue;
+
+ device = connman_network_get_device(service->network);
+ if (device == NULL)
+ continue;
+
+ ifname = connman_device_get_string(device, "Interface");
+ if (ifname != NULL && g_strcmp0(ifname, pattern) == 0) {
+ *path = (const char *) service->path;
+ return 0;
+ }
+
+ }
+
+ return -ENXIO;
+}
+
+/**
* lookup_by_identifier:
* @identifier: service identifier
*
return NULL;
}
-struct provision_user_data {
+static struct connman_network *create_hidden_wifi(struct connman_device *device,
+ const char *ssid, const char *mode, const char *security,
+ const char *group)
+{
+ struct connman_network *network;
+ char *name;
+ int index;
+ unsigned int i, ssid_len;
+
+ ssid_len = strlen(ssid);
+ if (ssid_len < 1)
+ return NULL;
+
+ network = connman_network_create(group, CONNMAN_NETWORK_TYPE_WIFI);
+ if (network == NULL)
+ return NULL;
+
+ connman_network_set_blob(network, "WiFi.SSID",
+ (unsigned char *) ssid, ssid_len);
+
+ connman_network_set_string(network, "WiFi.Mode", mode);
+ connman_network_set_string(network, "WiFi.Security", security);
+
+ name = g_try_malloc0(ssid_len + 1);
+ if (name == NULL) {
+ connman_network_unref(network);
+ return NULL;
+ }
+
+ for (i = 0; i < ssid_len; i++) {
+ if (g_ascii_isprint(ssid[i]))
+ name[i] = ssid[i];
+ else
+ name[i] = ' ';
+ }
+
+ connman_network_set_name(network, name);
+
+ g_free(name);
+
+ index = connman_device_get_index(device);
+ connman_network_set_index(network, index);
+
+ if (connman_device_add_network(device, network) < 0) {
+ connman_network_unref(network);
+ return NULL;
+ }
+
+ connman_network_set_available(network, TRUE);
+
+ return network;
+}
+
+int __connman_service_create_and_connect(DBusMessage *msg)
+{
+ struct connman_service *service;
+ struct connman_network *network;
+ struct connman_device *device;
+ DBusMessageIter iter, array;
+ const char *mode = "managed", *security = "none", *group_security;
+ const char *type = NULL, *ssid = NULL, *passphrase = NULL;
+#if defined TIZEN_EXT
+ const char *eap_type = NULL, *eap_auth = NULL, *identity = NULL, *password = NULL;
+ const char *ca_cert_file = NULL, *client_cert_file = NULL;
+ const char *private_key_file = NULL, *private_key_password = NULL;
+#endif
+ connman_bool_t network_created = FALSE;
+ unsigned int ssid_len = 0;
const char *ident;
- int ret;
-};
+ char *name, *group;
+ int err;
+
+ dbus_message_iter_init(msg, &iter);
+ dbus_message_iter_recurse(&iter, &array);
+
+ while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry, value;
+ const char *key;
+
+ dbus_message_iter_recurse(&array, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &value);
+
+ switch (dbus_message_iter_get_arg_type(&value)) {
+ case DBUS_TYPE_STRING:
+ if (g_str_equal(key, "Type") == TRUE)
+ dbus_message_iter_get_basic(&value, &type);
+ else if (g_str_equal(key, "WiFi.Mode") == TRUE ||
+ g_str_equal(key, "Mode") == TRUE)
+ dbus_message_iter_get_basic(&value, &mode);
+ else if (g_str_equal(key, "WiFi.Security") == TRUE ||
+ g_str_equal(key, "Security") == TRUE)
+ dbus_message_iter_get_basic(&value, &security);
+ else if (g_str_equal(key, "WiFi.Passphrase") == TRUE ||
+ g_str_equal(key, "Passphrase") == TRUE)
+ dbus_message_iter_get_basic(&value, &passphrase);
+ else if (g_str_equal(key, "WiFi.SSID") == TRUE ||
+ g_str_equal(key, "SSID") == TRUE)
+ dbus_message_iter_get_basic(&value, &ssid);
+#if defined TIZEN_EXT
+ else if (g_str_equal(key, "WiFi.EAPType") == TRUE ||
+ g_str_equal(key, "EAPType") == TRUE)
+ dbus_message_iter_get_basic(&value, &eap_type);
+ else if (g_str_equal(key, "WiFi.EAPAuth") == TRUE ||
+ g_str_equal(key, "EAPAuth") == TRUE)
+ dbus_message_iter_get_basic(&value, &eap_auth);
+ else if (g_str_equal(key, "WiFi.Identity") == TRUE ||
+ g_str_equal(key, "Identity") == TRUE)
+ dbus_message_iter_get_basic(&value, &identity);
+ else if (g_str_equal(key, "WiFi.Password") == TRUE ||
+ g_str_equal(key, "Password") == TRUE)
+ dbus_message_iter_get_basic(&value, &password);
+ else if (g_str_equal(key, "WiFi.CACert") == TRUE ||
+ g_str_equal(key, "CACert") == TRUE)
+ dbus_message_iter_get_basic(&value, &ca_cert_file);
+ else if (g_str_equal(key, "WiFi.ClientCert") == TRUE ||
+ g_str_equal(key, "ClientCert") == TRUE)
+ dbus_message_iter_get_basic(&value, &client_cert_file);
+ else if (g_str_equal(key, "WiFi.PrivateKeyFile") == TRUE ||
+ g_str_equal(key, "PrivateKeyFile") == TRUE)
+ dbus_message_iter_get_basic(&value, &private_key_file);
+ else if (g_str_equal(key, "WiFi.PrivateKeyPassword") == TRUE ||
+ g_str_equal(key, "PrivateKeyPassword") == TRUE)
+ dbus_message_iter_get_basic(&value, &private_key_password);
+ break;
+#endif
+ }
+
+ dbus_message_iter_next(&array);
+ }
+
+ if (type == NULL)
+ return -EINVAL;
+
+ if (g_strcmp0(type, "wifi") != 0 || g_strcmp0(mode, "managed") != 0)
+ return -EOPNOTSUPP;
+
+ if (ssid == NULL)
+ return -EINVAL;
+
+ ssid_len = strlen(ssid);
+ if (ssid_len < 1)
+ return -EINVAL;
+
+ if (g_strcmp0(security, "none") != 0 &&
+ g_strcmp0(security, "wep") != 0 &&
+ g_strcmp0(security, "psk") != 0 &&
+ g_strcmp0(security, "wpa") != 0 &&
+ g_strcmp0(security, "rsn") != 0 &&
+ g_strcmp0(security, "ieee8021x") != 0)
+ return -EINVAL;
+
+ device = __connman_device_find_device(CONNMAN_SERVICE_TYPE_WIFI);
+ if (device == NULL)
+ return -EOPNOTSUPP;
+
+ ident = connman_device_get_ident(device);
+ if (ident == NULL)
+ return -EOPNOTSUPP;
+
+
+ if (!g_strcmp0(security, "wpa") ||
+ !g_strcmp0(security, "rsn"))
+ group_security = "psk";
+ else
+ group_security = security;
+
+ group = wifi_build_group_name((unsigned char *) ssid,
+ ssid_len, mode, group_security);
+ if (group == NULL)
+ return -EINVAL;
+
+ name = g_strdup_printf("%s_%s_%s", type, ident, group);
+
+ service = lookup_by_identifier(name);
+
+ if (service == NULL) {
+ network = create_hidden_wifi(device, ssid,
+ mode, security, group);
+ if (network != NULL) {
+ connman_network_set_group(network, group);
+ network_created = TRUE;
+ }
+
+ service = lookup_by_identifier(name);
+ }
+
+ g_free(name);
+ g_free(group);
+
+ if (service == NULL) {
+ err = -EOPNOTSUPP;
+ goto failed;
+ }
+
+ service->network_created = network_created;
+
+ if (is_connected(service) == TRUE) {
+ err = -EISCONN;
+ goto failed;
+ }
+
+ if (is_connecting(service) == TRUE) {
+ err = -EALREADY;
+ goto failed;
+ }
+
+ set_reconnect_state(service, FALSE);
+
+ __connman_device_disconnect(device);
+
+ if (passphrase != NULL) {
+ g_free(service->passphrase);
+ service->passphrase = g_strdup(passphrase);
+ }
+
+#if defined TIZEN_EXT
+ if (g_strcmp0(security, "ieee8021x") == 0) {
+ if (eap_type != NULL)
+ __connman_service_set_string(service, "EAP", eap_type);
+
+ if (eap_auth != NULL)
+ __connman_service_set_string(service, "Phase2", eap_auth);
+
+ if (identity != NULL)
+ __connman_service_set_string(service, "Identity", identity);
+
+ if (password != NULL)
+ __connman_service_set_string(service, "Passphrase", password);
+
+ if (ca_cert_file != NULL)
+ __connman_service_set_string(service, "CACertFile", ca_cert_file);
+
+ if (client_cert_file != NULL)
+ __connman_service_set_string(service, "ClientCertFile", client_cert_file);
+
+ if (private_key_file != NULL)
+ __connman_service_set_string(service, "PrivateKeyFile", private_key_file);
+
+ if (private_key_password != NULL)
+ __connman_service_set_string(service, "PrivateKeyPassphrase", private_key_password);
+ }
+#endif
+
+ service->userconnect = TRUE;
+
+ err = __connman_service_connect(service);
+ if (err < 0 && err != -EINPROGRESS)
+ goto failed;
+
+ service->pending = dbus_message_ref(msg);
+
+ return 0;
+
+failed:
+ if (service != NULL && service->network_created == TRUE) {
+ struct connman_network *network = service->network;
+
+ if (network != NULL) {
+ connman_network_set_available(network, FALSE);
+ __connman_device_cleanup_networks(device);
+ } else
+ __connman_service_put(service);
+ }
+
+ return err;
+}
static void provision_changed(gpointer value, gpointer user_data)
{
struct connman_service *service = value;
- struct provision_user_data *data = user_data;
- const char *path = data->ident;
- int ret;
+ char *path = user_data;
+
+ __connman_config_provision_service_ident(service, path);
+}
- ret = __connman_config_provision_service_ident(service, path,
- service->config_file, service->config_entry);
- if (ret > 0)
- data->ret = ret;
+void __connman_service_provision_changed(const char *ident)
+{
+ g_sequence_foreach(service_list, provision_changed, (void *)ident);
}
-int __connman_service_provision_changed(const char *ident)
+int __connman_service_provision(DBusMessage *msg)
{
- struct provision_user_data data = {
- .ident = ident,
- .ret = 0
- };
+ GKeyFile *keyfile = NULL;
+ const char *config_str = NULL;
+ char *group = NULL, *ident = NULL;
+ int err = 0;
+ struct connman_service *service;
+
+ DBG("");
+
+ dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &config_str,
+ DBUS_TYPE_INVALID);
- g_sequence_foreach(service_list, provision_changed, (void *)&data);
+ if (config_str == NULL || strlen(config_str) == 0)
+ return -EINVAL;
+
+ keyfile = g_key_file_new();
+
+ /* populate GKeyFile with config_str */
+ if (g_key_file_load_from_data(keyfile, config_str,
+ strlen(config_str), 0, NULL) == FALSE) {
+ err = -EINVAL;
+ goto done;
+ }
/*
- * Because the provision_changed() might have set some services
- * as favorite, we must sort the sequence now.
+ * read only one group of settings (only one service supported, no
+ * global settings)
*/
- if (services_dirty == TRUE) {
- services_dirty = FALSE;
-
- if (g_sequence_get_length(service_list) > 1) {
- g_sequence_sort(service_list, service_compare, NULL);
- service_schedule_changed();
- }
+ group = g_key_file_get_start_group(keyfile);
- __connman_connection_update_gateway();
+ if (group == NULL || g_str_has_prefix(group, "service_") == FALSE) {
+ err = -EINVAL;
+ goto done;
}
- return data.ret;
-}
+ err = __connman_config_load_service(keyfile, group, TRUE);
+ if (err < 0)
+ goto done;
-void __connman_service_set_config(struct connman_service *service,
- const char *file_id, const char *entry)
-{
- if (service == NULL)
- return;
+ ident = group + strlen("service_");
- g_free(service->config_file);
- service->config_file = g_strdup(file_id);
+ /* trigger service provisioning if service exists */
+ service = lookup_by_identifier(ident);
+ if (service != NULL)
+ __connman_config_provision_service(service);
+
+ g_dbus_send_reply(connection, msg, DBUS_TYPE_INVALID);
+
+done:
+ if (group != NULL)
+ g_free(group);
- g_free(service->config_entry);
- service->config_entry = g_strdup(entry);
+ if (keyfile != NULL)
+ g_key_file_free(keyfile);
+
+ return err;
}
/**
NULL, service, NULL);
iter = g_hash_table_lookup(service_hash, service->identifier);
- if (iter != NULL && g_sequence_get_length(service_list) > 1) {
+ if (iter != NULL)
g_sequence_sort_changed(iter, service_compare, NULL);
- service_schedule_changed();
- }
- __connman_connection_update_gateway();
+ services_changed(TRUE);
return 0;
}
static void service_up(struct connman_ipconfig *ipconfig)
{
- struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
+ struct connman_service *service = connman_ipconfig_get_data(ipconfig);
- DBG("%s up", __connman_ipconfig_get_ifname(ipconfig));
+ DBG("%s up", connman_ipconfig_get_ifname(ipconfig));
link_changed(service);
static void service_down(struct connman_ipconfig *ipconfig)
{
- DBG("%s down", __connman_ipconfig_get_ifname(ipconfig));
+ DBG("%s down", connman_ipconfig_get_ifname(ipconfig));
}
static void service_lower_up(struct connman_ipconfig *ipconfig)
{
- struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
+ struct connman_service *service = connman_ipconfig_get_data(ipconfig);
- DBG("%s lower up", __connman_ipconfig_get_ifname(ipconfig));
+ DBG("%s lower up", connman_ipconfig_get_ifname(ipconfig));
stats_start(service);
}
static void service_lower_down(struct connman_ipconfig *ipconfig)
{
- struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
+ struct connman_service *service = connman_ipconfig_get_data(ipconfig);
- DBG("%s lower down", __connman_ipconfig_get_ifname(ipconfig));
-
- if (is_idle_state(service, service->state_ipv4) == FALSE)
- __connman_ipconfig_disable(service->ipconfig_ipv4);
-
- if (is_idle_state(service, service->state_ipv6) == FALSE)
- __connman_ipconfig_disable(service->ipconfig_ipv6);
+ DBG("%s lower down", connman_ipconfig_get_ifname(ipconfig));
stats_stop(service);
service_save(service);
static void service_ip_bound(struct connman_ipconfig *ipconfig)
{
- struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
+ struct connman_service *service = connman_ipconfig_get_data(ipconfig);
enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
- DBG("%s ip bound", __connman_ipconfig_get_ifname(ipconfig));
+ DBG("%s ip bound", connman_ipconfig_get_ifname(ipconfig));
type = __connman_ipconfig_get_config_type(ipconfig);
method = __connman_ipconfig_get_method(ipconfig);
static void service_ip_release(struct connman_ipconfig *ipconfig)
{
- struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
+ struct connman_service *service = connman_ipconfig_get_data(ipconfig);
enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
- DBG("%s ip release", __connman_ipconfig_get_ifname(ipconfig));
+ DBG("%s ip release", connman_ipconfig_get_ifname(ipconfig));
type = __connman_ipconfig_get_config_type(ipconfig);
method = __connman_ipconfig_get_method(ipconfig);
static void setup_ip4config(struct connman_service *service, int index,
enum connman_ipconfig_method method)
{
- service->ipconfig_ipv4 = __connman_ipconfig_create(index,
+ service->ipconfig_ipv4 = connman_ipconfig_create(index,
CONNMAN_IPCONFIG_TYPE_IPV4);
if (service->ipconfig_ipv4 == NULL)
return;
- __connman_ipconfig_set_method(service->ipconfig_ipv4, method);
+ connman_ipconfig_set_method(service->ipconfig_ipv4, method);
- __connman_ipconfig_set_data(service->ipconfig_ipv4, service);
+ connman_ipconfig_set_data(service->ipconfig_ipv4, service);
- __connman_ipconfig_set_ops(service->ipconfig_ipv4, &service_ops);
+ connman_ipconfig_set_ops(service->ipconfig_ipv4, &service_ops);
}
static void setup_ip6config(struct connman_service *service, int index)
{
- service->ipconfig_ipv6 = __connman_ipconfig_create(index,
+ service->ipconfig_ipv6 = connman_ipconfig_create(index,
CONNMAN_IPCONFIG_TYPE_IPV6);
if (service->ipconfig_ipv6 == NULL)
return;
- __connman_ipconfig_set_data(service->ipconfig_ipv6, service);
+ connman_ipconfig_set_data(service->ipconfig_ipv6, service);
- __connman_ipconfig_set_ops(service->ipconfig_ipv6, &service_ops);
+ connman_ipconfig_set_ops(service->ipconfig_ipv6, &service_ops);
}
void __connman_service_read_ip4config(struct connman_service *service)
while (g_sequence_iter_is_end(iter) == FALSE) {
service = g_sequence_get(iter);
- if (__connman_ipconfig_get_index(service->ipconfig_ipv4)
+ if (connman_ipconfig_get_index(service->ipconfig_ipv4)
== index)
return service;
- if (__connman_ipconfig_get_index(service->ipconfig_ipv6)
+ if (connman_ipconfig_get_index(service->ipconfig_ipv6)
== index)
return service;
return NULL;
}
-struct connman_service *__connman_service_lookup_from_ident(const char *identifier)
-{
- return lookup_by_identifier(identifier);
-}
-
const char *__connman_service_get_ident(struct connman_service *service)
{
return service->identifier;
if (iter != NULL) {
if (g_sequence_iter_get_position(iter) == 0)
service->order = 1;
- else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
- service->do_split_routing == FALSE)
+ else if (service->type == CONNMAN_SERVICE_TYPE_VPN)
service->order = 10;
+#if defined TIZEN_EXT
+ else if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
+ service->order = 2;
+#endif
else
service->order = 0;
}
- DBG("service %p name %s order %d split %d", service, service->name,
- service->order, service->do_split_routing);
-
done:
return service->order;
}
-void __connman_service_update_ordering(void)
-{
- GSequenceIter *iter;
-
- iter = g_sequence_get_begin_iter(service_list);
- if (iter != NULL && g_sequence_get_length(service_list) > 1)
- g_sequence_sort_changed(iter, service_compare, NULL);
-}
-
static enum connman_service_type convert_network_type(struct connman_network *network)
{
enum connman_network_type type = connman_network_get_type(network);
service->wps = connman_network_get_bool(network, "WiFi.WPS");
if (service->strength > strength && service->network != NULL) {
- connman_network_unref(service->network);
- service->network = connman_network_ref(network);
+ service->network = network;
strength_changed(service);
}
if (service->network == NULL)
- service->network = connman_network_ref(network);
+ service->network = network;
iter = g_hash_table_lookup(service_hash, service->identifier);
- if (iter != NULL && g_sequence_get_length(service_list) > 1) {
+ if (iter != NULL)
g_sequence_sort_changed(iter, service_compare, NULL);
- service_schedule_changed();
- }
}
/**
struct connman_device *device;
const char *ident, *group;
char *name;
- unsigned int *auto_connect_types;
- int i, index;
+ int index;
DBG("network %p", network);
if (service->path != NULL) {
update_from_network(service, network);
- __connman_connection_update_gateway();
+ services_changed(TRUE);
return service;
}
service->type = convert_network_type(network);
- auto_connect_types = connman_setting_get_uint_list("DefaultAutoConnectTechnologies");
- service->autoconnect = FALSE;
- for (i = 0; auto_connect_types != NULL &&
- auto_connect_types[i] != 0; i++) {
- if (service->type == auto_connect_types[i]) {
- service->autoconnect = TRUE;
- break;
- }
- }
-
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_WIMAX:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_GPS:
case CONNMAN_SERVICE_TYPE_VPN:
case CONNMAN_SERVICE_TYPE_GADGET:
+ service->autoconnect = FALSE;
+ break;
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_CELLULAR:
- break;
- case CONNMAN_SERVICE_TYPE_ETHERNET:
- service->favorite = TRUE;
+ service->autoconnect = TRUE;
break;
}
}
__connman_notifier_service_add(service, service->name);
- service_schedule_added(service);
return service;
}
sorting:
if (need_sort == TRUE) {
iter = g_hash_table_lookup(service_hash, service->identifier);
- if (iter != NULL && g_sequence_get_length(service_list) > 1) {
+ if (iter != NULL)
g_sequence_sort_changed(iter, service_compare, NULL);
- service_schedule_changed();
- }
}
}
if (service == NULL)
return;
- service->ignore = TRUE;
-
__connman_connection_gateway_remove(service,
CONNMAN_IPCONFIG_TYPE_ALL);
+#if defined TIZEN_EXT
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_DISCONNECT,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
- connman_service_unref(service);
+ __connman_service_ipconfig_indicate_state(service,
+ CONNMAN_SERVICE_STATE_DISCONNECT,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+#endif
+
+ __connman_service_put(service);
}
/**
service->userconnect = TRUE;
service->state_ipv4 = service->state_ipv6 = CONNMAN_SERVICE_STATE_IDLE;
- service->state = combine_state(service->state_ipv4, service->state_ipv6);
str = connman_provider_get_string(provider, "Name");
if (str != NULL) {
service_register(service);
__connman_notifier_service_add(service, service->name);
- service_schedule_added(service);
return service;
}
-static void remove_unprovisioned_services()
-{
- gchar **services;
- GKeyFile *keyfile, *configkeyfile;
- char *file, *section;
- int i = 0;
-
- services = connman_storage_get_services();
- if (services == NULL)
- return;
-
- for (;services[i] != NULL; i++) {
- file = section = NULL;
- keyfile = configkeyfile = NULL;
-
- keyfile = connman_storage_load_service(services[i]);
- if (keyfile == NULL)
- continue;
-
- file = g_key_file_get_string(keyfile, services[i],
- "Config.file", NULL);
- if (file == NULL)
- goto next;
-
- section = g_key_file_get_string(keyfile, services[i],
- "Config.ident", NULL);
- if (section == NULL)
- goto next;
-
- configkeyfile = __connman_storage_load_config(file);
- if (configkeyfile == NULL) {
- /*
- * Config file is missing, remove the provisioned
- * service.
- */
- __connman_storage_remove_service(services[i]);
- goto next;
- }
-
- if (g_key_file_has_group(configkeyfile, section) == FALSE)
- /*
- * Config section is missing, remove the provisioned
- * service.
- */
- __connman_storage_remove_service(services[i]);
-
- next:
- if (keyfile != NULL)
- g_key_file_free(keyfile);
-
- if (configkeyfile != NULL)
- g_key_file_free(configkeyfile);
-
- g_free(section);
- g_free(file);
- }
-
- g_strfreev(services);
-}
-
int __connman_service_init(void)
{
DBG("");
service_list = g_sequence_new(service_free);
- services_notify = g_new0(struct _services_notify, 1);
- services_notify->remove = g_hash_table_new_full(g_str_hash,
- g_str_equal, g_free, NULL);
- services_notify->add = g_hash_table_new(g_str_hash, g_str_equal);
-
- remove_unprovisioned_services();
-
return 0;
}
DBG("");
- if (autoconnect_timeout != 0) {
- g_source_remove(autoconnect_timeout);
- autoconnect_timeout = 0;
- }
-
list = service_list;
service_list = NULL;
g_sequence_free(list);
g_slist_free(counter_list);
counter_list = NULL;
- if (services_notify->id != 0) {
- g_source_remove(services_notify->id);
- service_send_changed(NULL);
- g_hash_table_destroy(services_notify->remove);
- g_hash_table_destroy(services_notify->add);
- }
- g_free(services_notify);
-
dbus_connection_unref(connection);
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
* Copyright (C) 2011 BWM CarIT GmbH. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
CONNMAN_SESSION_REASON_PERIODIC = 4,
};
-enum connman_session_state {
- CONNMAN_SESSION_STATE_DISCONNECTED = 0,
- CONNMAN_SESSION_STATE_CONNECTED = 1,
- CONNMAN_SESSION_STATE_ONLINE = 2,
-};
-
-enum connman_session_type {
- CONNMAN_SESSION_TYPE_ANY = 0,
- CONNMAN_SESSION_TYPE_LOCAL = 1,
- CONNMAN_SESSION_TYPE_INTERNET = 2,
-};
-
enum connman_session_roaming_policy {
CONNMAN_SESSION_ROAMING_POLICY_UNKNOWN = 0,
CONNMAN_SESSION_ROAMING_POLICY_DEFAULT = 1,
};
struct session_info {
- enum connman_session_state state;
- enum connman_session_type type;
+ connman_bool_t online;
connman_bool_t priority;
GSList *allowed_bearers;
connman_bool_t avoid_handover;
guint notify_watch;
connman_bool_t append_all;
+ connman_bool_t info_dirty;
struct session_info *info;
struct session_info *info_last;
return NULL;
}
-static const char *state2string(enum connman_session_state state)
-{
- switch (state) {
- case CONNMAN_SESSION_STATE_DISCONNECTED:
- return "disconnected";
- case CONNMAN_SESSION_STATE_CONNECTED:
- return "connected";
- case CONNMAN_SESSION_STATE_ONLINE:
- return "online";
- }
-
- return NULL;
-}
-
-static const char *type2string(enum connman_session_type type)
-{
- switch (type) {
- case CONNMAN_SESSION_TYPE_ANY:
- return "";
- case CONNMAN_SESSION_TYPE_LOCAL:
- return "local";
- case CONNMAN_SESSION_TYPE_INTERNET:
- return "internet";
- }
-
- return NULL;
-}
-
-static enum connman_session_type string2type(const char *type)
-{
- if (g_strcmp0(type, "local") == 0)
- return CONNMAN_SESSION_TYPE_LOCAL;
- else if (g_strcmp0(type, "internet") == 0)
- return CONNMAN_SESSION_TYPE_INTERNET;
-
- return CONNMAN_SESSION_TYPE_ANY;
-}
-
static const char *roamingpolicy2string(enum connman_session_roaming_policy policy)
{
switch (policy) {
if (service == NULL)
return;
- if (__connman_service_is_connected_state(service,
- CONNMAN_IPCONFIG_TYPE_IPV4) == FALSE) {
- return;
- }
-
ipconfig_ipv4 = __connman_service_get_ip4config(service);
if (ipconfig_ipv4 == NULL)
return;
if (service == NULL)
return;
- if (__connman_service_is_connected_state(service,
- CONNMAN_IPCONFIG_TYPE_IPV6) == FALSE) {
- return;
- }
-
ipconfig_ipv4 = __connman_service_get_ip4config(service);
ipconfig_ipv6 = __connman_service_get_ip6config(service);
if (ipconfig_ipv6 == NULL)
const char *name, *ifname, *bearer;
if (session->append_all == TRUE ||
- info->state != info_last->state) {
- const char *state = state2string(info->state);
-
- connman_dbus_dict_append_basic(dict, "State",
- DBUS_TYPE_STRING,
- &state);
- info_last->state = info->state;
+ info->online != info_last->online) {
+ connman_dbus_dict_append_basic(dict, "Online",
+ DBUS_TYPE_BOOLEAN,
+ &info->online);
+ info_last->online = info->online;
}
if (session->append_all == TRUE ||
info_last->entry = info->entry;
}
- if (session->append_all == TRUE || info->type != info_last->type) {
- const char *type = type2string(info->type);
-
- connman_dbus_dict_append_basic(dict, "ConnectionType",
- DBUS_TYPE_STRING,
- &type);
- info_last->type = info->type;
- }
if (session->append_all == TRUE ||
info->priority != info_last->priority) {
}
session->append_all = FALSE;
-}
-
-static connman_bool_t is_type_matching_state(enum connman_session_state *state,
- enum connman_session_type type)
-{
- switch (type) {
- case CONNMAN_SESSION_TYPE_ANY:
- return TRUE;
- case CONNMAN_SESSION_TYPE_LOCAL:
- if (*state >= CONNMAN_SESSION_STATE_CONNECTED) {
- *state = CONNMAN_SESSION_STATE_CONNECTED;
- return TRUE;
- }
-
- break;
- case CONNMAN_SESSION_TYPE_INTERNET:
- if (*state == CONNMAN_SESSION_STATE_ONLINE)
- return TRUE;
- break;
- }
-
- return FALSE;
-}
-
-static connman_bool_t compute_notifiable_changes(struct connman_session *session)
-{
- struct session_info *info_last = session->info_last;
- struct session_info *info = session->info;
-
- if (session->append_all == TRUE)
- return TRUE;
-
- if (info->state != info_last->state)
- return TRUE;
-
- if (info->entry != info_last->entry &&
- info->state >= CONNMAN_SESSION_STATE_CONNECTED)
- return TRUE;
-
- if (info->periodic_connect != info_last->periodic_connect ||
- info->allowed_bearers != info_last->allowed_bearers ||
- info->avoid_handover != info_last->avoid_handover ||
- info->stay_connected != info_last->stay_connected ||
- info->roaming_policy != info_last->roaming_policy ||
- info->idle_timeout != info_last->idle_timeout ||
- info->priority != info_last->priority ||
- info->marker != info_last->marker ||
- info->ecall != info_last->ecall ||
- info->type != info_last->type)
- return TRUE;
-
- return FALSE;
+ session->info_dirty = FALSE;
}
static gboolean session_notify(gpointer user_data)
DBusMessage *msg;
DBusMessageIter array, dict;
- if (compute_notifiable_changes(session) == FALSE)
- return FALSE;
+ if (session->info_dirty == FALSE)
+ return 0;
DBG("session %p owner %s notify_path %s", session,
session->owner, session->notify_path);
g_free(session);
}
-static enum connman_session_state service_to_session_state(enum connman_service_state state)
+static connman_bool_t is_online(enum connman_service_state state)
{
switch (state) {
case CONNMAN_SERVICE_STATE_UNKNOWN:
case CONNMAN_SERVICE_STATE_CONFIGURATION:
case CONNMAN_SERVICE_STATE_DISCONNECT:
case CONNMAN_SERVICE_STATE_FAILURE:
- break;
case CONNMAN_SERVICE_STATE_READY:
- return CONNMAN_SESSION_STATE_CONNECTED;
- case CONNMAN_SERVICE_STATE_ONLINE:
- return CONNMAN_SESSION_STATE_ONLINE;
- }
-
- return CONNMAN_SESSION_STATE_DISCONNECTED;
-}
-
-static connman_bool_t is_connected(enum connman_service_state state)
-{
- switch (state) {
- case CONNMAN_SERVICE_STATE_UNKNOWN:
- case CONNMAN_SERVICE_STATE_IDLE:
- case CONNMAN_SERVICE_STATE_ASSOCIATION:
- case CONNMAN_SERVICE_STATE_CONFIGURATION:
- case CONNMAN_SERVICE_STATE_DISCONNECT:
- case CONNMAN_SERVICE_STATE_FAILURE:
break;
- case CONNMAN_SERVICE_STATE_READY:
case CONNMAN_SERVICE_STATE_ONLINE:
return TRUE;
}
break;
case CONNMAN_SERVICE_STATE_ASSOCIATION:
case CONNMAN_SERVICE_STATE_CONFIGURATION:
+ case CONNMAN_SERVICE_STATE_READY:
return TRUE;
case CONNMAN_SERVICE_STATE_DISCONNECT:
case CONNMAN_SERVICE_STATE_FAILURE:
- case CONNMAN_SERVICE_STATE_READY:
case CONNMAN_SERVICE_STATE_ONLINE:
break;
}
return FALSE;
}
-static void deselect_service(struct session_info *info)
+static connman_bool_t deselect_service(struct session_info *info)
{
struct service_entry *entry;
- connman_bool_t disconnect, connected;
+ connman_bool_t disconnect, online;
DBG("");
if (info->entry == NULL)
- return;
+ return FALSE;
disconnect = explicit_disconnect(info);
- connected = is_connecting(info->entry->state) == TRUE ||
- is_connected(info->entry->state) == TRUE;
+ online = is_connecting(info->entry->state) == TRUE ||
+ is_online(info->entry->state) == TRUE;
- info->state = CONNMAN_SESSION_STATE_DISCONNECTED;
+ info->online = FALSE;
info->entry->reason = CONNMAN_SESSION_REASON_UNKNOWN;
entry = info->entry;
info->entry = NULL;
- DBG("disconnect %d connected %d", disconnect, connected);
+ DBG("disconnect %d online %d", disconnect, online);
- if (disconnect == TRUE && connected == TRUE)
+ if (disconnect == TRUE && online == TRUE)
pending_timeout_add(0, call_disconnect, entry);
+
+ return TRUE;
}
static void deselect_and_disconnect(struct connman_session *session,
{
struct session_info *info = session->info;
- deselect_service(info);
+ session->info_dirty |= deselect_service(info);
info->reason = reason;
}
-static void select_connected_service(struct session_info *info,
+static connman_bool_t select_online_service(struct session_info *info,
struct service_entry *entry)
{
- enum connman_session_state state;
-
- state = service_to_session_state(entry->state);
- if (is_type_matching_state(&state, info->type) == FALSE)
- return;
-
- info->state = state;
+ info->online = TRUE;
info->entry = entry;
info->entry->reason = info->reason;
if (explicit_connect(info->reason) == FALSE)
- return;
+ return TRUE;
__connman_service_session_inc(info->entry->service);
+
+ return TRUE;
}
-static void select_offline_service(struct session_info *info,
+static connman_bool_t select_offline_service(struct session_info *info,
struct service_entry *entry)
{
if (explicit_connect(info->reason) == FALSE)
- return;
+ return FALSE;
- info->state = service_to_session_state(entry->state);
+ info->online = FALSE;
info->entry = entry;
info->entry->reason = info->reason;
__connman_service_session_inc(info->entry->service);
pending_timeout_add(0, call_connect, entry);
+
+ return TRUE;
}
-static void select_service(struct session_info *info,
+static connman_bool_t select_service(struct session_info *info,
struct service_entry *entry)
{
DBG("service %p", entry->service);
- if (is_connected(entry->state) == TRUE)
- select_connected_service(info, entry);
+ if (is_online(entry->state) == TRUE)
+ return select_online_service(info, entry);
else
- select_offline_service(info, entry);
+ return select_offline_service(info, entry);
}
static void select_and_connect(struct connman_session *session,
case CONNMAN_SERVICE_STATE_ONLINE:
case CONNMAN_SERVICE_STATE_IDLE:
case CONNMAN_SERVICE_STATE_DISCONNECT:
- select_service(info, entry);
+ session->info_dirty |=
+ select_service(info, entry);
return;
case CONNMAN_SERVICE_STATE_UNKNOWN:
case CONNMAN_SERVICE_STATE_FAILURE:
reason2string(info->reason));
if (info->entry != NULL) {
- enum connman_session_state state;
-
- state = service_to_session_state(info->entry->state);
-
- if (is_type_matching_state(&state, info->type) == TRUE)
- info->state = state;
+ info->online = is_online(info->entry->state);
+ if (info_last->online != info->online)
+ session->info_dirty = TRUE;
}
switch (trigger) {
g_sequence_free(service_list_last);
}
- if (info->type != info_last->type) {
- if (info->state >= CONNMAN_SESSION_STATE_CONNECTED &&
- is_type_matching_state(&info->state,
- info->type) == FALSE)
- deselect_and_disconnect(session, info->reason);
- }
-
- if (info->state == CONNMAN_SESSION_STATE_DISCONNECTED) {
+ if (info->online == FALSE) {
select_and_connect(session,
CONNMAN_SESSION_REASON_FREE_RIDE);
}
break;
case CONNMAN_SESSION_TRIGGER_CONNECT:
- if (info->state >= CONNMAN_SESSION_STATE_CONNECTED) {
+ if (info->online == TRUE) {
if (info->entry->reason == CONNMAN_SESSION_REASON_CONNECT)
break;
info->entry->reason = CONNMAN_SESSION_REASON_CONNECT;
break;
case CONNMAN_SESSION_TRIGGER_PERIODIC:
- if (info->state >= CONNMAN_SESSION_STATE_CONNECTED) {
+ if (info->online == TRUE) {
info->entry->reason = CONNMAN_SESSION_REASON_PERIODIC;
__connman_service_session_inc(info->entry->service);
break;
break;
case CONNMAN_SESSION_TRIGGER_SERVICE:
if (info->entry != NULL &&
- (is_connecting(info->entry->state) == TRUE ||
- is_connected(info->entry->state) == TRUE)) {
+ (is_connecting(info->entry->state) == TRUE ||
+ is_online(info->entry->state) == TRUE)) {
break;
}
break;
case CONNMAN_SESSION_TRIGGER_ECALL:
- if (info->state == CONNMAN_SESSION_STATE_DISCONNECTED &&
- info->entry != NULL &&
+ if (info->online == FALSE && info->entry != NULL &&
info->entry->service != NULL) {
deselect_and_disconnect(session, info->reason);
}
continue;
session_iter->info->ecall = info->ecall;
+ session_iter->info_dirty = TRUE;
session_changed(session_iter, CONNMAN_SESSION_TRIGGER_ECALL);
}
update_ecall_sessions(session);
+ session->info_dirty = TRUE;
return;
err:
{
struct connman_session *session = user_data;
struct session_info *info = session->info;
+ struct session_info *info_last = session->info_last;
DBusMessageIter iter, value;
const char *name;
- const char *val;
GSList *allowed_bearers;
DBG("session %p", session);
}
info->allowed_bearers = allowed_bearers;
+
+ session->info_dirty = TRUE;
} else {
goto err;
}
if (g_str_equal(name, "Priority") == TRUE) {
dbus_message_iter_get_basic(&value,
&info->priority);
+
+ if (info_last->priority != info->priority)
+ session->info_dirty = TRUE;
} else if (g_str_equal(name, "AvoidHandover") == TRUE) {
dbus_message_iter_get_basic(&value,
&info->avoid_handover);
+
+ if (info_last->avoid_handover != info->avoid_handover)
+ session->info_dirty = TRUE;
} else if (g_str_equal(name, "StayConnected") == TRUE) {
dbus_message_iter_get_basic(&value,
&info->stay_connected);
+
+ if (info_last->stay_connected != info->stay_connected)
+ session->info_dirty = TRUE;
} else if (g_str_equal(name, "EmergencyCall") == TRUE) {
dbus_message_iter_get_basic(&value,
&info->ecall);
if (g_str_equal(name, "PeriodicConnect") == TRUE) {
dbus_message_iter_get_basic(&value,
&info->periodic_connect);
+
+ if (info_last->periodic_connect != info->periodic_connect)
+ session->info_dirty = TRUE;
} else if (g_str_equal(name, "IdleTimeout") == TRUE) {
dbus_message_iter_get_basic(&value,
&info->idle_timeout);
+
+ if (info_last->idle_timeout != info->idle_timeout)
+ session->info_dirty = TRUE;
} else {
goto err;
}
break;
case DBUS_TYPE_STRING:
- if (g_str_equal(name, "ConnectionType") == TRUE) {
- dbus_message_iter_get_basic(&value, &val);
- info->type = string2type(val);
- } else if (g_str_equal(name, "RoamingPolicy") == TRUE) {
+ if (g_str_equal(name, "RoamingPolicy") == TRUE) {
+ const char *val;
dbus_message_iter_get_basic(&value, &val);
info->roaming_policy =
string2roamingpolicy(val);
+
+ if (info_last->roaming_policy != info->roaming_policy)
+ session->info_dirty = TRUE;
} else {
goto err;
}
goto err;
}
- session_changed(session, CONNMAN_SESSION_TRIGGER_SETTING);
+ if (session->info_dirty == TRUE)
+ session_changed(session, CONNMAN_SESSION_TRIGGER_SETTING);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
-static const GDBusMethodTable session_methods[] = {
- { GDBUS_METHOD("Destroy", NULL, NULL, destroy_session) },
- { GDBUS_METHOD("Connect", NULL, NULL, connect_session) },
- { GDBUS_METHOD("Disconnect", NULL, NULL,
- disconnect_session ) },
- { GDBUS_METHOD("Change",
- GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
- NULL, change_session) },
+static GDBusMethodTable session_methods[] = {
+ { "Destroy", "", "", destroy_session },
+ { "Connect", "", "", connect_session },
+ { "Disconnect", "", "", disconnect_session },
+ { "Change", "sv", "", change_session },
{ },
};
struct connman_session *session = NULL;
struct session_info *info, *info_last;
- enum connman_session_type type = CONNMAN_SESSION_TYPE_ANY;
connman_bool_t priority = FALSE, avoid_handover = FALSE;
connman_bool_t stay_connected = FALSE, ecall = FALSE;
enum connman_session_roaming_policy roaming_policy =
}
break;
case DBUS_TYPE_STRING:
- if (g_str_equal(key, "ConnectionType") == TRUE) {
- dbus_message_iter_get_basic(&value, &val);
- type = string2type(val);
- } else if (g_str_equal(key, "RoamingPolicy") == TRUE) {
+ if (g_str_equal(key, "RoamingPolicy") == TRUE) {
dbus_message_iter_get_basic(&value, &val);
roaming_policy = string2roamingpolicy(val);
} else {
g_dbus_add_disconnect_watch(connection, session->owner,
owner_disconnect, session, NULL);
- info->state = CONNMAN_SESSION_STATE_DISCONNECTED;
- info->type = type;
+ info->online = FALSE;
info->priority = priority;
info->avoid_handover = avoid_handover;
info->stay_connected = stay_connected;
update_ecall_sessions(session);
}
- info_last->state = info->state;
+ info_last->online = info->online;
info_last->priority = info->priority;
info_last->avoid_handover = info->avoid_handover;
info_last->stay_connected = info->stay_connected;
info_last->marker = info->marker;
info_last->allowed_bearers = info->allowed_bearers;
+ session->info_dirty = TRUE;
session->append_all = TRUE;
session_changed(session, CONNMAN_SESSION_TRIGGER_SETTING);
{
DBG("enable %d", enable);
- if (sessionmode != enable) {
- sessionmode = enable;
-
- connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
- CONNMAN_MANAGER_INTERFACE, "SessionMode",
- DBUS_TYPE_BOOLEAN, &sessionmode);
- }
+ sessionmode = enable;
if (sessionmode == TRUE)
__connman_service_disconnect_all();
session = value;
info = session->info;
- if (info->state == CONNMAN_SESSION_STATE_DISCONNECTED)
- continue;
-
if (info->entry != NULL && info->entry->service == service) {
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
ipconfig_ipv4_changed(session);
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
return keyfile;
}
-static int storage_save(GKeyFile *keyfile, char *pathname)
+static void storage_save(GKeyFile *keyfile, char *pathname)
{
gchar *data = NULL;
gsize length = 0;
GError *error = NULL;
- int ret = 0;
data = g_key_file_to_data(keyfile, &length, NULL);
if (!g_file_set_contents(pathname, data, length, &error)) {
DBG("Failed to store information: %s", error->message);
- g_error_free(error);
- ret = -EIO;
+ g_free(error);
}
g_free(data);
-
- return ret;
}
static void storage_delete(const char *pathname)
return keyfile;
}
-int __connman_storage_save_global(GKeyFile *keyfile)
+void __connman_storage_save_global(GKeyFile *keyfile)
{
gchar *pathname;
- int ret;
pathname = g_strdup_printf("%s/%s", STORAGEDIR, SETTINGS);
if(pathname == NULL)
- return -ENOMEM;
+ return;
- ret = storage_save(keyfile, pathname);
+ storage_save(keyfile, pathname);
g_free(pathname);
-
- return ret;
}
void __connman_storage_delete_global()
return keyfile;
}
+void __connman_storage_save_config(GKeyFile *keyfile, const char *ident)
+{
+ gchar *pathname;
+
+ pathname = g_strdup_printf("%s/%s.config", STORAGEDIR, ident);
+ if(pathname == NULL)
+ return;
+
+ storage_save(keyfile, pathname);
+}
+
+void __connman_storage_delete_config(const char *ident)
+{
+ gchar *pathname;
+
+ pathname = g_strdup_printf("%s/%s.config", STORAGEDIR, ident);
+ if(pathname == NULL)
+ return;
+
+ storage_delete(pathname);
+
+ g_free(pathname);
+}
+
GKeyFile *__connman_storage_open_service(const char *service_id)
{
gchar *pathname;
keyfile = storage_load(pathname);
g_free(pathname);
+ if (keyfile)
+ return keyfile;
+
+ pathname = g_strdup_printf("%s/%s", STORAGEDIR, DEFAULT);
+ if(pathname == NULL)
+ return NULL;
+
+ keyfile = storage_load(pathname);
+
+ g_free(pathname);
return keyfile;
}
-int __connman_storage_save_service(GKeyFile *keyfile, const char *service_id)
+void __connman_storage_save_service(GKeyFile *keyfile, const char *service_id)
{
- int ret = 0;
gchar *pathname, *dirname;
dirname = g_strdup_printf("%s/%s", STORAGEDIR, service_id);
if(dirname == NULL)
- return -ENOMEM;
+ return;
/* If the dir doesn't exist, create it */
if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) {
if(mkdir(dirname, MODE) < 0) {
if (errno != EEXIST) {
g_free(dirname);
- return -errno;
+ return;
}
}
}
g_free(dirname);
- ret = storage_save(keyfile, pathname);
-
- g_free(pathname);
-
- return ret;
-}
-
-static gboolean remove_file(const char *service_id, const char *file)
-{
- gchar *pathname;
- gboolean ret = FALSE;
-
- pathname = g_strdup_printf("%s/%s/%s", STORAGEDIR, service_id, file);
- if(pathname == NULL)
- return FALSE;
-
- if (g_file_test(pathname, G_FILE_TEST_EXISTS) == FALSE) {
- ret = TRUE;
- } else if (g_file_test(pathname, G_FILE_TEST_IS_REGULAR) == TRUE) {
- unlink(pathname);
- ret = TRUE;
- }
-
- g_free(pathname);
- return ret;
-}
-
-static gboolean remove_dir(const char *service_id)
-{
- gchar *pathname;
- gboolean ret = FALSE;
-
- pathname = g_strdup_printf("%s/%s", STORAGEDIR, service_id);
- if(pathname == NULL)
- return FALSE;
-
- if (g_file_test(pathname, G_FILE_TEST_EXISTS) == FALSE) {
- ret = TRUE;
- } else if (g_file_test(pathname, G_FILE_TEST_IS_DIR) == TRUE) {
- rmdir(pathname);
- ret = TRUE;
- }
+ storage_save(keyfile, pathname);
g_free(pathname);
- return ret;
-}
-
-gboolean __connman_storage_remove_service(const char *service_id)
-{
- gboolean removed;
-
- /* Remove service configuration file */
- removed = remove_file(service_id, SETTINGS);
- if (removed == FALSE)
- return FALSE;
-
- /* Remove the statistics file also */
- removed = remove_file(service_id, "data");
- if (removed == FALSE)
- return FALSE;
-
- removed = remove_dir(service_id);
- if (removed == FALSE)
- return FALSE;
-
- DBG("Removed service dir %s/%s", STORAGEDIR, service_id);
-
- return TRUE;
}
GKeyFile *__connman_storage_load_provider(const char *identifier)
g_free(pathname);
}
-gchar **__connman_storage_get_providers(void)
-{
- GSList *list = NULL;
- int num = 0, i = 0;
- struct dirent *d;
- gchar *str;
- DIR *dir;
- struct stat buf;
- int ret;
- char **providers;
- GSList *iter;
-
- dir = opendir(STORAGEDIR);
- if (dir == NULL)
- return NULL;
-
- while ((d = readdir(dir))) {
- if (strcmp(d->d_name, ".") == 0 ||
- strcmp(d->d_name, "..") == 0 ||
- strncmp(d->d_name, "provider_", 9) != 0)
- continue;
-
- if (d->d_type == DT_DIR) {
- str = g_strdup_printf("%s/%s/settings", STORAGEDIR,
- d->d_name);
- ret = stat(str, &buf);
- g_free(str);
- if (ret < 0)
- continue;
- list = g_slist_prepend(list, g_strdup(d->d_name));
- num += 1;
- }
- }
-
- closedir(dir);
-
- providers = g_try_new0(char *, num + 1);
- for (iter = list; iter != NULL; iter = g_slist_next(iter)) {
- if (providers != NULL)
- providers[i] = iter->data;
- else
- g_free(iter->data);
- i += 1;
- }
- g_slist_free(list);
-
- return providers;
-}
-
/*
* This function migrates keys from default.profile to settings file.
* This can be removed once the migration is over.
GKeyFile *keyfile_def = NULL;
GKeyFile *keyfile = NULL;
GError *error = NULL;
- connman_bool_t delete_old_config = TRUE;
- char **services, **keys, *value;
- int i, k, err;
connman_bool_t val;
- pathname = g_strdup_printf("%s/%s", STORAGEDIR, DEFAULT);
- if (pathname == NULL)
- return;
-
/* If setting file exists, migration has been done. */
keyfile = __connman_storage_load_global();
if (keyfile) {
g_key_file_free(keyfile);
- unlink(pathname);
- g_free(pathname);
return;
}
- /* If default.profile exists, create new settings file */
- keyfile_def = storage_load(pathname);
- if (keyfile_def == NULL)
- goto done;
+ pathname = g_strdup_printf("%s/%s", STORAGEDIR, DEFAULT);
+ if(pathname == NULL)
+ return;
- services = g_key_file_get_groups(keyfile_def, NULL);
- for (i = 0; services != NULL && services[i] != NULL; i++) {
- if (strncmp(services[i], "wifi_", 5) != 0 &&
- strncmp(services[i], "ethernet_", 9) != 0 &&
- strncmp(services[i], "cellular_", 9) != 0 &&
- strncmp(services[i], "bluetooth_", 10) != 0 &&
- strncmp(services[i], "wimax_", 6) != 0 &&
- strncmp(services[i], "vpn_", 4) != 0)
- continue;
+ /* Copy global settings from default.profile to settings. */
+ keyfile = g_key_file_new();
- keyfile = connman_storage_load_service(services[i]);
- if (keyfile != NULL) {
- g_key_file_free(keyfile);
- DBG("already exists %s", services[i]);
- continue;
- }
+ /* If default.profile doesn't exists, create settings with defaults. */
+ keyfile_def = storage_load(pathname);
+ if (keyfile_def == NULL) {
+ g_key_file_set_boolean(keyfile, "global",
+ "OfflineMode", FALSE);
- keyfile = g_key_file_new();
- if (keyfile == NULL) {
- connman_warn("Migrating %s failed", services[i]);
- delete_old_config = FALSE;
- continue;
- }
+ g_key_file_set_boolean(keyfile, "WiFi",
+ "Enable", FALSE);
- keys = g_key_file_get_keys(keyfile_def, services[i],
- NULL, NULL);
+ g_key_file_set_boolean(keyfile, "Bluetooth",
+ "Enable", FALSE);
- for (k = 0; keys != NULL && keys[k] != NULL; k++) {
- value = g_key_file_get_value(keyfile_def, services[i],
- keys[k], NULL);
- g_key_file_set_value(keyfile, services[i],
- keys[k], value);
- g_free(value);
- }
+ g_key_file_set_boolean(keyfile, "Wired",
+ "Enable", FALSE);
- if (keys != NULL && keys[0] != NULL) {
- err = __connman_storage_save_service(keyfile,
- services[i]);
- if (err >= 0)
- DBG("migrated %s", services[i]);
- else {
- connman_warn("Migrating %s failed %s",
- services[i], strerror(-err));
- delete_old_config = FALSE;
- }
- } else
- DBG("no keys in %s", services[i]);
+ g_key_file_set_boolean(keyfile, "3G",
+ "Enable", FALSE);
- g_strfreev(keys);
- g_key_file_free(keyfile);
- }
- g_strfreev(services);
+ g_key_file_set_boolean(keyfile, "WiMAX",
+ "Enable", FALSE);
- /* Copy global settings from default.profile to settings. */
- keyfile = g_key_file_new();
+ goto done;
+ }
+ /* offline mode */
val = g_key_file_get_boolean(keyfile_def, "global",
"OfflineMode", &error);
if (error != NULL) {
g_key_file_set_boolean(keyfile, "global",
"OfflineMode", val);
- /* Migrate Powered/Enable state key/value pairs from legacy
- * settings
- */
-
+ /* wifi */
val = g_key_file_get_boolean(keyfile_def, "WiFi",
"Enable", &error);
if (error != NULL) {
g_clear_error(&error);
- val = g_key_file_get_boolean(keyfile_def, "device_Wireless", "Powered", &error);
- if (error != NULL) {
- g_clear_error(&error);
- val = FALSE;
- }
+ val = FALSE;
}
g_key_file_set_boolean(keyfile, "WiFi",
"Enable", val);
+ /* bluetooth */
val = g_key_file_get_boolean(keyfile_def, "Bluetooth",
"Enable", &error);
if (error != NULL) {
g_clear_error(&error);
- val = g_key_file_get_boolean(keyfile_def, "device_Bluetooth", "Powered", &error);
- if (error != NULL) {
- g_clear_error(&error);
- val = FALSE;
- }
+ val = FALSE;
}
g_key_file_set_boolean(keyfile, "Bluetooth",
"Enable", val);
+ /* wired */
val = g_key_file_get_boolean(keyfile_def, "Wired",
"Enable", &error);
if (error != NULL) {
g_clear_error(&error);
- val = g_key_file_get_boolean(keyfile_def, "device_Ethernet", "Powered", &error);
- if (error != NULL) {
- g_clear_error(&error);
- val = FALSE;
- }
+ val = FALSE;
}
g_key_file_set_boolean(keyfile, "Wired",
"Enable", val);
- val = g_key_file_get_boolean(keyfile_def, "Cellular",
+ /* 3G */
+ val = g_key_file_get_boolean(keyfile_def, "3G",
"Enable", &error);
if (error != NULL) {
g_clear_error(&error);
- val = g_key_file_get_boolean(keyfile_def, "device_Cellular", "Powered", &error);
- if (error != NULL) {
- g_clear_error(&error);
- val = FALSE;
- }
+ val = FALSE;
}
- g_key_file_set_boolean(keyfile, "Cellular",
+ g_key_file_set_boolean(keyfile, "3G",
"Enable", val);
+ /* WiMAX */
val = g_key_file_get_boolean(keyfile_def, "WiMAX",
"Enable", &error);
if (error != NULL) {
g_clear_error(&error);
- val = g_key_file_get_boolean(keyfile_def, "device_WiMAX", "Powered", &error);
- if (error != NULL) {
- g_clear_error(&error);
- val = FALSE;
- }
+ val = FALSE;
}
g_key_file_set_boolean(keyfile, "WiMAX",
"Enable", val);
- if (__connman_storage_save_global(keyfile) < 0) {
- connman_warn("Migrating global config failed");
- delete_old_config = FALSE;
- }
+done:
+ __connman_storage_save_global(keyfile);
g_key_file_free(keyfile);
- g_key_file_free(keyfile_def);
+ if (keyfile_def)
+ g_key_file_free(keyfile_def);
- if (delete_old_config == TRUE) {
- DBG("migration done for %s", pathname);
- unlink(pathname);
- }
-done:
g_free(pathname);
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
notify->func = function;
notify->data = user_data;
- g_hash_table_replace(task->notify, g_strdup(member), notify);
+ g_hash_table_insert(task->notify, g_strdup(member), notify);
return 0;
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
static GSList *technology_list = NULL;
-/*
- * List of devices with no technology associated with them either because of
- * no compiled in support or the driver is not yet loaded.
-*/
-static GSList *techless_device_list = NULL;
-static GHashTable *rfkill_list;
-
static connman_bool_t global_offlinemode;
struct connman_rfkill {
connman_bool_t hardblock;
};
+enum connman_technology_state {
+ CONNMAN_TECHNOLOGY_STATE_UNKNOWN = 0,
+ CONNMAN_TECHNOLOGY_STATE_OFFLINE = 1,
+ CONNMAN_TECHNOLOGY_STATE_ENABLED = 2,
+ CONNMAN_TECHNOLOGY_STATE_CONNECTED = 3,
+};
+
struct connman_technology {
int refcount;
enum connman_service_type type;
+ enum connman_technology_state state;
char *path;
+ GHashTable *rfkill_list;
GSList *device_list;
int enabled;
char *regdom;
- connman_bool_t connected;
connman_bool_t tethering;
char *tethering_ident;
DBusMessage *pending_reply;
guint pending_timeout;
-
- GSList *scan_pending;
};
static GSList *driver_list = NULL;
return driver2->priority - driver1->priority;
}
-static void rfkill_check(gpointer key, gpointer value, gpointer user_data)
-{
- struct connman_rfkill *rfkill = value;
- enum connman_service_type type = GPOINTER_TO_INT(user_data);
-
- /* Calling _technology_rfkill_add will update the tech. */
- if (rfkill->type == type)
- __connman_technology_add_rfkill(rfkill->index, type,
- rfkill->softblock, rfkill->hardblock);
-}
-
/**
* connman_technology_driver_register:
* @driver: Technology driver definition
int connman_technology_driver_register(struct connman_technology_driver *driver)
{
GSList *list;
- struct connman_device *device;
- enum connman_service_type type;
+ struct connman_technology *technology;
- DBG("Registering %s driver", driver->name);
+ DBG("driver %p name %s", driver, driver->name);
driver_list = g_slist_insert_sorted(driver_list, driver,
compare_priority);
- if (techless_device_list == NULL)
- goto check_rfkill;
+ for (list = technology_list; list; list = list->next) {
+ technology = list->data;
- /*
- * Check for technology less devices if this driver
- * can service any of them.
- */
- for (list = techless_device_list; list; list = list->next) {
- device = list->data;
-
- type = __connman_device_get_service_type(device);
- if (type != driver->type)
+ if (technology->driver != NULL)
continue;
- techless_device_list = g_slist_remove(techless_device_list,
- device);
-
- __connman_technology_add_device(device);
+ if (technology->type == driver->type)
+ technology->driver = driver;
}
-check_rfkill:
- /* Check for orphaned rfkill switches. */
- g_hash_table_foreach(rfkill_list, rfkill_check,
- GINT_TO_POINTER(driver->type));
-
return 0;
}
GSList *list;
struct connman_technology *technology;
- DBG("Unregistering driver %p name %s", driver, driver->name);
+ DBG("driver %p name %s", driver, driver->name);
for (list = technology_list; list; list = list->next) {
technology = list->data;
technology->regdom = g_strdup(alpha2);
}
-static int set_regdom_by_device(struct connman_technology *technology,
- const char *alpha2)
+int connman_technology_set_regdom(const char *alpha2)
{
GSList *list;
- for (list = technology->device_list; list; list = list->next) {
- struct connman_device *device = list->data;
+ for (list = technology_list; list; list = list->next) {
+ struct connman_technology *technology = list->data;
+
+ if (technology->driver == NULL)
+ continue;
- if (connman_device_set_regdom(device, alpha2) != 0)
- return -ENOTSUP;
+ if (technology->driver->set_regdom)
+ technology->driver->set_regdom(technology, alpha2);
}
return 0;
}
-int connman_technology_set_regdom(const char *alpha2)
+static void free_rfkill(gpointer data)
+{
+ struct connman_rfkill *rfkill = data;
+
+ g_free(rfkill);
+}
+
+void __connman_technology_list(DBusMessageIter *iter, void *user_data)
{
GSList *list;
for (list = technology_list; list; list = list->next) {
struct connman_technology *technology = list->data;
- if (set_regdom_by_device(technology, alpha2) != 0) {
- if (technology->driver == NULL)
- continue;
+ if (technology->path == NULL)
+ continue;
- if (technology->driver->set_regdom != NULL)
- technology->driver->set_regdom(technology,
- alpha2);
- }
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
+ &technology->path);
}
+}
- return 0;
+static void technologies_changed(void)
+{
+ connman_dbus_property_changed_array(CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE, "Technologies",
+ DBUS_TYPE_OBJECT_PATH, __connman_technology_list, NULL);
}
-static void free_rfkill(gpointer data)
+static const char *state2string(enum connman_technology_state state)
{
- struct connman_rfkill *rfkill = data;
+ switch (state) {
+ case CONNMAN_TECHNOLOGY_STATE_UNKNOWN:
+ break;
+ case CONNMAN_TECHNOLOGY_STATE_OFFLINE:
+ return "offline";
+ case CONNMAN_TECHNOLOGY_STATE_ENABLED:
+ return "enabled";
+ case CONNMAN_TECHNOLOGY_STATE_CONNECTED:
+ return "connected";
+ }
- g_free(rfkill);
+ return NULL;
+}
+
+static void state_changed(struct connman_technology *technology)
+{
+ const char *str;
+
+ str = state2string(technology->state);
+ if (str == NULL)
+ return;
+
+ connman_dbus_property_changed_basic(technology->path,
+ CONNMAN_TECHNOLOGY_INTERFACE, "State",
+ DBUS_TYPE_STRING, &str);
}
static const char *get_name(enum connman_service_type type)
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
return "Bluetooth";
case CONNMAN_SERVICE_TYPE_CELLULAR:
- return "Cellular";
+ return "3G";
}
return NULL;
}
-static void save_state(struct connman_technology *technology)
+static void load_state(struct connman_technology *technology)
{
GKeyFile *keyfile;
gchar *identifier;
+ GError *error = NULL;
+ connman_bool_t enable;
DBG("technology %p", technology);
keyfile = __connman_storage_load_global();
- if (keyfile == NULL)
- keyfile = g_key_file_new();
+ /* Fallback on disabling technology if file not found. */
+ if (keyfile == NULL) {
+ technology->enable_persistent = FALSE;
+ return;
+ }
identifier = g_strdup_printf("%s", get_name(technology->type));
if (identifier == NULL)
goto done;
- g_key_file_set_boolean(keyfile, identifier, "Enable",
- technology->enable_persistent);
-
+ enable = g_key_file_get_boolean(keyfile, identifier, "Enable", &error);
+ if (error == NULL)
+ technology->enable_persistent = enable;
+ else {
+ technology->enable_persistent = FALSE;
+ g_clear_error(&error);
+ }
done:
g_free(identifier);
- __connman_storage_save_global(keyfile);
-
g_key_file_free(keyfile);
return;
}
-static void load_state(struct connman_technology *technology)
+static void save_state(struct connman_technology *technology)
{
GKeyFile *keyfile;
gchar *identifier;
- GError *error = NULL;
- connman_bool_t enable;
DBG("technology %p", technology);
keyfile = __connman_storage_load_global();
- /* Fallback on disabling technology if file not found. */
- if (keyfile == NULL) {
- if (technology->type == CONNMAN_SERVICE_TYPE_ETHERNET)
- /* We enable ethernet by default */
- technology->enable_persistent = TRUE;
- else
- technology->enable_persistent = FALSE;
- return;
- }
+ if (keyfile == NULL)
+ keyfile = g_key_file_new();
identifier = g_strdup_printf("%s", get_name(technology->type));
if (identifier == NULL)
goto done;
- enable = g_key_file_get_boolean(keyfile, identifier, "Enable", &error);
- if (error == NULL)
- technology->enable_persistent = enable;
- else {
- if (technology->type == CONNMAN_SERVICE_TYPE_ETHERNET)
- technology->enable_persistent = TRUE;
- else
- technology->enable_persistent = FALSE;
+ g_key_file_set_boolean(keyfile, identifier, "Enable",
+ technology->enable_persistent);
- save_state(technology);
- g_clear_error(&error);
- }
done:
g_free(identifier);
+ __connman_storage_save_global(keyfile);
+
g_key_file_free(keyfile);
return;
/* If there is a error, we enable offlinemode */
keyfile = __connman_storage_load_global();
if (keyfile == NULL)
- return FALSE;
+ return TRUE;
offlinemode = g_key_file_get_boolean(keyfile, "global",
"OfflineMode", &error);
if (error != NULL) {
- offlinemode = FALSE;
+ offlinemode = TRUE;
g_clear_error(&error);
}
return offlinemode;
}
-static void append_properties(DBusMessageIter *iter,
- struct connman_technology *technology)
+static DBusMessage *get_properties(DBusConnection *conn,
+ DBusMessage *message, void *user_data)
{
- DBusMessageIter dict;
+ struct connman_technology *technology = user_data;
+ DBusMessage *reply;
+ DBusMessageIter array, dict;
const char *str;
- connman_bool_t powered;
- connman_dbus_dict_open(iter, &dict);
+ reply = dbus_message_new_method_return(message);
+ if (reply == NULL)
+ return NULL;
+
+ dbus_message_iter_init_append(reply, &array);
+
+ connman_dbus_dict_open(&array, &dict);
+
+ str = state2string(technology->state);
+ if (str != NULL)
+ connman_dbus_dict_append_basic(&dict, "State",
+ DBUS_TYPE_STRING, &str);
str = get_name(technology->type);
if (str != NULL)
connman_dbus_dict_append_basic(&dict, "Type",
DBUS_TYPE_STRING, &str);
- __sync_synchronize();
- if (technology->enabled > 0)
- powered = TRUE;
- else
- powered = FALSE;
- connman_dbus_dict_append_basic(&dict, "Powered",
- DBUS_TYPE_BOOLEAN, &powered);
-
- connman_dbus_dict_append_basic(&dict, "Connected",
- DBUS_TYPE_BOOLEAN,
- &technology->connected);
-
connman_dbus_dict_append_basic(&dict, "Tethering",
DBUS_TYPE_BOOLEAN,
&technology->tethering);
DBUS_TYPE_STRING,
&technology->tethering_passphrase);
- connman_dbus_dict_close(iter, &dict);
-}
-
-static void technology_added_signal(struct connman_technology *technology)
-{
- DBusMessage *signal;
- DBusMessageIter iter;
-
- signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
- CONNMAN_MANAGER_INTERFACE, "TechnologyAdded");
- if (signal == NULL)
- return;
-
- dbus_message_iter_init_append(signal, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &technology->path);
- append_properties(&iter, technology);
-
- dbus_connection_send(connection, signal, NULL);
- dbus_message_unref(signal);
-}
-
-static void technology_removed_signal(struct connman_technology *technology)
-{
- g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
- CONNMAN_MANAGER_INTERFACE, "TechnologyRemoved",
- DBUS_TYPE_OBJECT_PATH, &technology->path,
- DBUS_TYPE_INVALID);
-}
-
-static DBusMessage *get_properties(DBusConnection *conn,
- DBusMessage *message, void *user_data)
-{
- struct connman_technology *technology = user_data;
- DBusMessage *reply;
- DBusMessageIter iter;
-
- reply = dbus_message_new_method_return(message);
- if (reply == NULL)
- return NULL;
-
- dbus_message_iter_init_append(reply, &iter);
- append_properties(&iter, technology);
+ connman_dbus_dict_close(&array, &dict);
return reply;
}
-void __connman_technology_list_struct(DBusMessageIter *array)
-{
- GSList *list;
- DBusMessageIter entry;
-
- for (list = technology_list; list; list = list->next) {
- struct connman_technology *technology = list->data;
-
- if (technology->path == NULL)
- continue;
-
- dbus_message_iter_open_container(array, DBUS_TYPE_STRUCT,
- NULL, &entry);
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
- &technology->path);
- append_properties(&entry, technology);
- dbus_message_iter_close_container(array, &entry);
- }
-}
-
-static gboolean technology_pending_reply(gpointer user_data)
-{
- struct connman_technology *technology = user_data;
- DBusMessage *reply;
-
- /* Power request timedout, send ETIMEDOUT. */
- if (technology->pending_reply != NULL) {
- reply = __connman_error_failed(technology->pending_reply, ETIMEDOUT);
- if (reply != NULL)
- g_dbus_send_message(connection, reply);
-
- dbus_message_unref(technology->pending_reply);
- technology->pending_reply = NULL;
- technology->pending_timeout = 0;
- }
-
- return FALSE;
-}
-
-static int technology_enable(struct connman_technology *technology,
- DBusMessage *msg)
-{
- GSList *list;
- int err = 0;
- int ret = -ENODEV;
- DBusMessage *reply;
-
- DBG("technology %p enable", technology);
-
- __sync_synchronize();
- if (technology->enabled > 0) {
- err = -EALREADY;
- goto done;
- }
-
- if (technology->pending_reply != NULL) {
- err = -EBUSY;
- goto done;
- }
-
- if (msg != NULL) {
- /*
- * This is a bit of a trick. When msg is not NULL it means
- * thats technology_enable was invoked from the manager API.
- * Hence we save the state here.
- */
- technology->enable_persistent = TRUE;
- save_state(technology);
- }
-
- __connman_rfkill_block(technology->type, FALSE);
-
- /*
- * An empty device list means that devices in the technology
- * were rfkill blocked. The unblock above will enable the devs.
- */
- if (technology->device_list == NULL) {
- ret = 0;
- goto done;
- }
-
- for (list = technology->device_list; list; list = list->next) {
- struct connman_device *device = list->data;
-
- err = __connman_device_enable(device);
- /*
- * err = 0 : Device was enabled right away.
- * If atleast one device gets enabled, we consider
- * the technology to be enabled.
- */
- if (err == 0)
- ret = 0;
- }
-
-done:
- if (ret == 0) {
- if (msg != NULL)
- g_dbus_send_reply(connection, msg, DBUS_TYPE_INVALID);
- return ret;
- }
-
- if (msg != NULL) {
- if (err == -EINPROGRESS) {
- technology->pending_reply = dbus_message_ref(msg);
- technology->pending_timeout = g_timeout_add_seconds(10,
- technology_pending_reply, technology);
- } else {
- if (err == -EALREADY)
- reply = __connman_error_already_enabled(msg);
- else
- reply = __connman_error_failed(msg, -err);
- if (reply != NULL)
- g_dbus_send_message(connection, reply);
- }
- }
-
- return err;
-}
-
-static int technology_disable(struct connman_technology *technology,
- DBusMessage *msg)
-{
- GSList *list;
- int err = 0;
- int ret = -ENODEV;
- DBusMessage *reply;
-
- DBG("technology %p disable", technology);
-
- __sync_synchronize();
- if (technology->enabled == 0) {
- err = -EALREADY;
- goto done;
- }
-
- if (technology->pending_reply != NULL) {
- err = -EBUSY;
- goto done;
- }
-
- if (technology->tethering == TRUE)
- set_tethering(technology, FALSE);
-
- if (msg != NULL) {
- technology->enable_persistent = FALSE;
- save_state(technology);
- }
-
- __connman_rfkill_block(technology->type, TRUE);
-
- for (list = technology->device_list; list; list = list->next) {
- struct connman_device *device = list->data;
-
- err = __connman_device_disable(device);
- if (err == 0)
- ret = 0;
- }
-
-done:
- if (ret == 0) {
- if (msg != NULL)
- g_dbus_send_reply(connection, msg, DBUS_TYPE_INVALID);
- return ret;
- }
-
- if (msg != NULL) {
- if (err == -EINPROGRESS) {
- technology->pending_reply = dbus_message_ref(msg);
- technology->pending_timeout = g_timeout_add_seconds(10,
- technology_pending_reply, technology);
- } else {
- if (err == -EALREADY)
- reply = __connman_error_already_disabled(msg);
- else
- reply = __connman_error_failed(msg, -err);
- if (reply != NULL)
- g_dbus_send_message(connection, reply);
- }
- }
-
- return err;
-}
-
static DBusMessage *set_property(DBusConnection *conn,
DBusMessage *msg, void *data)
{
if (dbus_message_iter_init(msg, &iter) == FALSE)
return __connman_error_invalid_arguments(msg);
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
- return __connman_error_invalid_arguments(msg);
-
dbus_message_iter_get_basic(&iter, &name);
dbus_message_iter_next(&iter);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
- return __connman_error_invalid_arguments(msg);
-
dbus_message_iter_recurse(&iter, &value);
type = dbus_message_iter_get_arg_type(&value);
dbus_message_iter_get_basic(&value, &tethering);
if (technology->tethering == tethering)
- return __connman_error_already_enabled(msg);
+ return __connman_error_in_progress(msg);
err = set_tethering(technology, tethering);
if (err < 0)
return __connman_error_failed(msg, -err);
- } else if (g_str_equal(name, "TetheringIdentifier") == TRUE) {
- const char *str;
-
- dbus_message_iter_get_basic(&value, &str);
-
- if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
- return __connman_error_not_supported(msg);
-
- if (strlen(str) < 1 || strlen(str) > 32)
- return __connman_error_invalid_arguments(msg);
-
- technology->tethering_ident = g_strdup(str);
- } else if (g_str_equal(name, "TetheringPassphrase") == TRUE) {
- const char *str;
-
- dbus_message_iter_get_basic(&value, &str);
-
- if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
- return __connman_error_not_supported(msg);
-
- if (strlen(str) < 8 || strlen(str) > 63)
- return __connman_error_passphrase_required(msg);
-
- technology->tethering_passphrase = g_strdup(str);
- } else if (g_str_equal(name, "Powered") == TRUE) {
- connman_bool_t enable;
-
- if (type != DBUS_TYPE_BOOLEAN)
- return __connman_error_invalid_arguments(msg);
-
- dbus_message_iter_get_basic(&value, &enable);
- if (enable == TRUE)
- technology_enable(technology, msg);
- else
- technology_disable(technology, msg);
-
- } else
- return __connman_error_invalid_property(msg);
-
- return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
-}
-
-static struct connman_technology *technology_find(enum connman_service_type type)
-{
- GSList *list;
-
- DBG("type %d", type);
-
- for (list = technology_list; list; list = list->next) {
- struct connman_technology *technology = list->data;
-
- if (technology->type == type)
- return technology;
- }
-
- return NULL;
-}
-
-static void reply_scan_pending(struct connman_technology *technology, int err)
-{
- DBusMessage *reply;
-
- DBG("technology %p err %d", technology, err);
-
- while (technology->scan_pending != NULL) {
- DBusMessage *msg = technology->scan_pending->data;
-
- DBG("reply to %s", dbus_message_get_sender(msg));
-
- if (err == 0)
- reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
- else
- reply = __connman_error_failed(msg, -err);
- g_dbus_send_message(connection, reply);
- dbus_message_unref(msg);
-
- technology->scan_pending =
- g_slist_delete_link(technology->scan_pending,
- technology->scan_pending);
- }
-}
-
-void __connman_technology_scan_started(struct connman_device *device)
-{
- DBG("device %p", device);
-}
-
-void __connman_technology_scan_stopped(struct connman_device *device)
-{
- int count = 0;
- struct connman_technology *technology;
- enum connman_service_type type;
- GSList *list;
-
- type = __connman_device_get_service_type(device);
- technology = technology_find(type);
-
- DBG("technology %p device %p", technology, device);
-
- if (technology == NULL)
- return;
-
- for (list = technology->device_list; list != NULL; list = list->next) {
- struct connman_device *other_device = list->data;
-
- if (device == other_device)
- continue;
-
- if (__connman_device_get_service_type(other_device) != type)
- continue;
-
- if (connman_device_get_scanning(other_device) == TRUE)
- count += 1;
- }
-
- if (count == 0)
- reply_scan_pending(technology, 0);
-}
-
-void __connman_technology_notify_regdom_by_device(struct connman_device *device,
- int result, const char *alpha2)
-{
- struct connman_technology *technology;
- enum connman_service_type type;
-
- type = __connman_device_get_service_type(device);
- technology = technology_find(type);
-
- if (technology == NULL)
- return;
-
- if (result < 0) {
- if (technology->driver != NULL &&
- technology->driver->set_regdom != NULL) {
- technology->driver->set_regdom(technology, alpha2);
- return;
- }
+ } else if (g_str_equal(name, "TetheringIdentifier") == TRUE) {
+ const char *str;
- alpha2 = NULL;
- }
+ dbus_message_iter_get_basic(&value, &str);
- connman_technology_regdom_notify(technology, alpha2);
-}
+ if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
+ return __connman_error_not_supported(msg);
-static DBusMessage *scan(DBusConnection *conn, DBusMessage *msg, void *data)
-{
- struct connman_technology *technology = data;
- int err;
+ technology->tethering_ident = g_strdup(str);
+ } else if (g_str_equal(name, "TetheringPassphrase") == TRUE) {
+ const char *str;
+
+ dbus_message_iter_get_basic(&value, &str);
- DBG ("technology %p request from %s", technology,
- dbus_message_get_sender(msg));
+ if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
+ return __connman_error_not_supported(msg);
- dbus_message_ref(msg);
- technology->scan_pending =
- g_slist_prepend(technology->scan_pending, msg);
+ if (strlen(str) < 8)
+ return __connman_error_invalid_arguments(msg);
- err = __connman_device_request_scan(technology->type);
- if (err < 0)
- reply_scan_pending(technology, err);
+ technology->tethering_passphrase = g_strdup(str);
+ } else
+ return __connman_error_invalid_property(msg);
- return NULL;
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
-static const GDBusMethodTable technology_methods[] = {
- { GDBUS_DEPRECATED_METHOD("GetProperties",
- NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
- get_properties) },
- { GDBUS_METHOD("SetProperty",
- GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
- NULL, set_property) },
- { GDBUS_ASYNC_METHOD("Scan", NULL, NULL, scan) },
+static GDBusMethodTable technology_methods[] = {
+ { "GetProperties", "", "a{sv}", get_properties },
+ { "SetProperty", "sv", "", set_property },
{ },
};
-static const GDBusSignalTable technology_signals[] = {
- { GDBUS_SIGNAL("PropertyChanged",
- GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
+static GDBusSignalTable technology_signals[] = {
+ { "PropertyChanged", "sv" },
{ },
};
+static struct connman_technology *technology_find(enum connman_service_type type)
+{
+ GSList *list;
+
+ DBG("type %d", type);
+
+ for (list = technology_list; list; list = list->next) {
+ struct connman_technology *technology = list->data;
+
+ if (technology->type == type)
+ return technology;
+ }
+
+ return NULL;
+}
+
static struct connman_technology *technology_get(enum connman_service_type type)
{
struct connman_technology *technology;
return NULL;
technology = technology_find(type);
- if (technology != NULL) {
- __sync_fetch_and_add(&technology->refcount, 1);
+ if (technology != NULL)
return technology;
- }
/* First check if we have a driver for this technology type */
for (list = driver_list; list; list = list->next) {
technology->path = g_strdup_printf("%s/technology/%s",
CONNMAN_PATH, str);
+ technology->rfkill_list = g_hash_table_new_full(g_int_hash, g_int_equal,
+ NULL, free_rfkill);
technology->device_list = NULL;
technology->pending_reply = NULL;
+ technology->state = CONNMAN_TECHNOLOGY_STATE_OFFLINE;
load_state(technology);
technology_list = g_slist_append(technology_list, technology);
- technology_added_signal(technology);
+ technologies_changed();
technology->driver = driver;
err = driver->probe(technology);
{
DBG("technology %p", technology);
- if (__sync_sub_and_fetch(&technology->refcount, 1) > 0)
+ if (__sync_fetch_and_sub(&technology->refcount, 1) != 1)
return;
- reply_scan_pending(technology, -EINTR);
-
if (technology->driver) {
technology->driver->remove(technology);
technology->driver = NULL;
technology_list = g_slist_remove(technology_list, technology);
- technology_removed_signal(technology);
+ technologies_changed();
g_dbus_unregister_interface(connection, technology->path,
CONNMAN_TECHNOLOGY_INTERFACE);
g_slist_free(technology->device_list);
+ g_hash_table_destroy(technology->rfkill_list);
g_free(technology->path);
g_free(technology->regdom);
break;
}
- connman_info("Adding interface %s [ %s ]", name,
+ connman_info("Create interface %s [ %s ]", name,
__connman_service_type2string(type));
- technology = technology_find(type);
+ technology = technology_get(type);
if (technology == NULL || technology->driver == NULL
|| technology->driver->add_interface == NULL)
if (technology->driver->remove_interface)
technology->driver->remove_interface(technology, index);
+
+ technology_put(technology);
}
int __connman_technology_add_device(struct connman_device *device)
DBG("device %p", device);
type = __connman_device_get_service_type(device);
+ __connman_notifier_register(type);
technology = technology_get(type);
- if (technology == NULL) {
- /*
- * Since no driver can be found for this device at the moment we
- * add it to the techless device list.
- */
- techless_device_list = g_slist_prepend(techless_device_list,
- device);
-
+ if (technology == NULL)
return -ENXIO;
- }
- if (technology->enable_persistent && !global_offlinemode) {
- int err = __connman_device_enable(device);
- /*
- * connman_technology_add_device() calls __connman_device_enable()
- * but since the device is already enabled, the calls does not
- * propagate through to connman_technology_enabled via
- * connman_device_set_powered.
- */
- if (err == -EALREADY)
- __connman_technology_enabled(type);
- }
+ if (technology->enable_persistent && !global_offlinemode)
+ __connman_device_enable(device);
/* if technology persistent state is offline */
if (!technology->enable_persistent)
__connman_device_disable(device);
DBG("device %p", device);
type = __connman_device_get_service_type(device);
+ __connman_notifier_unregister(type);
technology = technology_find(type);
- if (technology == NULL) {
- techless_device_list = g_slist_remove(techless_device_list,
- device);
+ if (technology == NULL)
return -ENXIO;
- }
technology->device_list = g_slist_remove(technology->device_list,
device);
- technology_put(technology);
+ if (technology->device_list == NULL) {
+ technology->state = CONNMAN_TECHNOLOGY_STATE_OFFLINE;
+ state_changed(technology);
+ }
return 0;
}
-static void powered_changed(struct connman_technology *technology)
+static gboolean technology_pending_reply(gpointer user_data)
{
- connman_bool_t powered;
+ struct connman_technology *technology = user_data;
+ DBusMessage *reply;
- __sync_synchronize();
- if (technology->enabled >0)
- powered = TRUE;
- else
- powered = FALSE;
+ /* Power request timedout, send ETIMEDOUT. */
+ if (technology->pending_reply != NULL) {
+ reply = __connman_error_failed(technology->pending_reply, ETIMEDOUT);
+ if (reply != NULL)
+ g_dbus_send_message(connection, reply);
- connman_dbus_property_changed_basic(technology->path,
- CONNMAN_TECHNOLOGY_INTERFACE, "Powered",
- DBUS_TYPE_BOOLEAN, &powered);
+ dbus_message_unref(technology->pending_reply);
+ technology->pending_reply = NULL;
+ technology->pending_timeout = 0;
+ }
+
+ return FALSE;
}
int __connman_technology_enabled(enum connman_service_type type)
if (technology == NULL)
return -ENXIO;
- if (__sync_fetch_and_add(&technology->enabled, 1) != 0)
- return -EALREADY;
-
- powered_changed(technology);
+ if (__sync_fetch_and_add(&technology->enabled, 1) == 0) {
+ __connman_notifier_enable(type);
+ technology->state = CONNMAN_TECHNOLOGY_STATE_ENABLED;
+ state_changed(technology);
+ }
if (technology->pending_reply != NULL) {
g_dbus_send_reply(connection, technology->pending_reply, DBUS_TYPE_INVALID);
return 0;
}
+int __connman_technology_enable(enum connman_service_type type, DBusMessage *msg)
+{
+ struct connman_technology *technology;
+ GSList *list;
+ int err = 0;
+ int ret = -ENODEV;
+ DBusMessage *reply;
+
+ DBG("type %d enable", type);
+
+ technology = technology_find(type);
+ if (technology == NULL) {
+ err = -ENXIO;
+ goto done;
+ }
+
+ if (technology->pending_reply != NULL) {
+ err = -EBUSY;
+ goto done;
+ }
+
+ if (msg != NULL) {
+ /*
+ * This is a bit of a trick. When msg is not NULL it means
+ * thats technology_enable was invoked from the manager API. Hence we save
+ * the state here.
+ */
+ technology->enable_persistent = TRUE;
+ save_state(technology);
+ }
+
+ __connman_rfkill_block(technology->type, FALSE);
+
+ /*
+ * An empty device list means that devices in the technology
+ * were rfkill blocked. The unblock above will enable the devs.
+ */
+ if (technology->device_list == NULL)
+ return 0;
+
+ for (list = technology->device_list; list; list = list->next) {
+ struct connman_device *device = list->data;
+
+ err = __connman_device_enable(device);
+ /*
+ * err = 0 : Device was enabled right away.
+ * If atleast one device gets enabled, we consider
+ * the technology to be enabled.
+ */
+ if (err == 0)
+ ret = 0;
+ }
+
+done:
+ if (ret == 0) {
+ if (msg != NULL)
+ g_dbus_send_reply(connection, msg, DBUS_TYPE_INVALID);
+ return ret;
+ }
+
+ if (msg != NULL) {
+ if (err == -EINPROGRESS) {
+ technology->pending_reply = dbus_message_ref(msg);
+ technology->pending_timeout = g_timeout_add_seconds(10,
+ technology_pending_reply, technology);
+ } else {
+ reply = __connman_error_failed(msg, -err);
+ if (reply != NULL)
+ g_dbus_send_message(connection, reply);
+ }
+ }
+
+ return err;
+}
+
int __connman_technology_disabled(enum connman_service_type type)
{
struct connman_technology *technology;
if (technology == NULL)
return -ENXIO;
- if (__sync_fetch_and_sub(&technology->enabled, 1) != 1)
- return -EINPROGRESS;
-
if (technology->pending_reply != NULL) {
g_dbus_send_reply(connection, technology->pending_reply, DBUS_TYPE_INVALID);
dbus_message_unref(technology->pending_reply);
technology->pending_timeout = 0;
}
- powered_changed(technology);
+ if (__sync_fetch_and_sub(&technology->enabled, 1) != 1)
+ return 0;
+
+ __connman_notifier_disable(type);
+ technology->state = CONNMAN_TECHNOLOGY_STATE_OFFLINE;
+ state_changed(technology);
return 0;
}
+int __connman_technology_disable(enum connman_service_type type, DBusMessage *msg)
+{
+ struct connman_technology *technology;
+ GSList *list;
+ int err = 0;
+ int ret = -ENODEV;
+ DBusMessage *reply;
+
+ DBG("type %d disable", type);
+
+ technology = technology_find(type);
+ if (technology == NULL) {
+ err = -ENXIO;
+ goto done;
+ }
+
+ if (technology->pending_reply != NULL) {
+ err = -EBUSY;
+ goto done;
+ }
+
+ if (technology->tethering == TRUE)
+ set_tethering(technology, FALSE);
+
+ if (msg != NULL) {
+ technology->enable_persistent = FALSE;
+ save_state(technology);
+ }
+
+ __connman_rfkill_block(technology->type, TRUE);
+
+ for (list = technology->device_list; list; list = list->next) {
+ struct connman_device *device = list->data;
+
+ err = __connman_device_disable(device);
+ if (err == 0)
+ ret = 0;
+ }
+
+done:
+ if (ret == 0) {
+ if (msg != NULL)
+ g_dbus_send_reply(connection, msg, DBUS_TYPE_INVALID);
+ return ret;
+ }
+
+ if (msg != NULL) {
+ if (err == -EINPROGRESS) {
+ technology->pending_reply = dbus_message_ref(msg);
+ technology->pending_timeout = g_timeout_add_seconds(10,
+ technology_pending_reply, technology);
+ } else {
+ reply = __connman_error_failed(msg, -err);
+ if (reply != NULL)
+ g_dbus_send_message(connection, reply);
+ }
+ }
+
+ return err;
+}
+
int __connman_technology_set_offlinemode(connman_bool_t offlinemode)
{
GSList *list;
struct connman_technology *technology = list->data;
if (offlinemode)
- err = technology_disable(technology, NULL);
+ err = __connman_technology_disable(technology->type, NULL);
if (!offlinemode && technology->enable_persistent)
- err = technology_enable(technology, NULL);
+ err = __connman_technology_enable(technology->type, NULL);
}
if (err == 0 || err == -EINPROGRESS || err == -EALREADY) {
return err;
}
-void __connman_technology_set_connected(enum connman_service_type type,
- connman_bool_t connected)
-{
- struct connman_technology *technology;
-
- technology = technology_find(type);
- if (technology == NULL)
- return;
-
- DBG("technology %p connected %d", technology, connected);
-
- technology->connected = connected;
-
- connman_dbus_property_changed_basic(technology->path,
- CONNMAN_TECHNOLOGY_INTERFACE, "Connected",
- DBUS_TYPE_BOOLEAN, &connected);
-}
-
int __connman_technology_add_rfkill(unsigned int index,
enum connman_service_type type,
connman_bool_t softblock,
DBG("index %u type %d soft %u hard %u", index, type,
softblock, hardblock);
- rfkill = g_hash_table_lookup(rfkill_list, &index);
- if (rfkill != NULL)
- goto done;
+ technology = technology_get(type);
+ if (technology == NULL)
+ return -ENXIO;
rfkill = g_try_new0(struct connman_rfkill, 1);
if (rfkill == NULL)
return -ENOMEM;
+ __connman_notifier_register(type);
+
rfkill->index = index;
rfkill->type = type;
rfkill->softblock = softblock;
rfkill->hardblock = hardblock;
- g_hash_table_insert(rfkill_list, &rfkill->index, rfkill);
-
-done:
- technology = technology_get(type);
- /* If there is no driver for this type, ignore it. */
- if (technology == NULL)
- return -ENXIO;
+ g_hash_table_replace(technology->rfkill_list, &rfkill->index, rfkill);
if (hardblock) {
DBG("%s is switched off.", get_name(type));
DBG("index %u soft %u hard %u", index, softblock, hardblock);
- rfkill = g_hash_table_lookup(rfkill_list, &index);
+ technology = technology_find(type);
+ if (technology == NULL)
+ return -ENXIO;
+
+ rfkill = g_hash_table_lookup(technology->rfkill_list, &index);
if (rfkill == NULL)
return -ENXIO;
return 0;
}
- technology = technology_find(type);
- /* If there is no driver for this type, ignore it. */
- if (technology == NULL)
- return -ENXIO;
-
if (!global_offlinemode) {
if (technology->enable_persistent && softblock)
return __connman_rfkill_block(type, FALSE);
DBG("index %u", index);
- rfkill = g_hash_table_lookup(rfkill_list, &index);
- if (rfkill == NULL)
- return -ENXIO;
-
- g_hash_table_remove(rfkill_list, &index);
-
technology = technology_find(type);
if (technology == NULL)
return -ENXIO;
+ rfkill = g_hash_table_lookup(technology->rfkill_list, &index);
+ if (rfkill == NULL)
+ return -ENXIO;
+
+ g_hash_table_remove(technology->rfkill_list, &index);
+
technology_put(technology);
return 0;
connection = connman_dbus_get_connection();
- rfkill_list = g_hash_table_new_full(g_int_hash, g_int_equal,
- NULL, free_rfkill);
-
global_offlinemode = connman_technology_load_offlinemode();
- /* This will create settings file if it is missing */
- connman_technology_save_offlinemode();
-
return 0;
}
{
DBG("");
- g_hash_table_destroy(rfkill_list);
-
dbus_connection_unref(connection);
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
* Copyright (C) 2011 ProFUSION embedded systems
*
* This program is free software; you can redistribute it and/or modify
#define BRIDGE_PROC_DIR "/proc/sys/net/bridge"
#define BRIDGE_NAME "tether"
+#define BRIDGE_IP "192.168.218.1"
+#define BRIDGE_BCAST "192.168.218.255"
+#define BRIDGE_SUBNET "255.255.255.0"
+#define BRIDGE_IP_START "192.168.218.100"
+#define BRIDGE_IP_END "192.168.218.200"
#define BRIDGE_DNS "8.8.8.8"
#define DEFAULT_MTU 1500
+#define PRIVATE_NETWORK_IP "192.168.219.1"
+#define PRIVATE_NETWORK_PEER_IP "192.168.219.2"
+#define PRIVATE_NETWORK_NETMASK "255.255.255.0"
#define PRIVATE_NETWORK_PRIMARY_DNS BRIDGE_DNS
#define PRIVATE_NETWORK_SECONDARY_DNS "8.8.4.4"
+static char *default_interface = NULL;
static volatile int tethering_enabled;
static GDHCPServer *tethering_dhcp_server = NULL;
-static struct connman_ippool *dhcp_ippool = NULL;
static DBusConnection *connection;
static GHashTable *pn_hash;
char *interface;
int index;
guint iface_watch;
- struct connman_ippool *pool;
+ const char *server_ip;
+ const char *peer_ip;
const char *primary_dns;
const char *secondary_dns;
};
g_dhcp_server_unref(server);
}
-static void tethering_restart(struct connman_ippool *pool, void *user_data)
+static int set_forward_delay(const char *name, unsigned int delay)
{
- __connman_tethering_set_disabled();
- __connman_tethering_set_enabled();
+ FILE *f;
+ char *forward_delay_path;
+
+ forward_delay_path =
+ g_strdup_printf("/sys/class/net/%s/bridge/forward_delay", name);
+
+ if (forward_delay_path == NULL)
+ return -ENOMEM;
+
+ f = fopen(forward_delay_path, "r+");
+
+ g_free(forward_delay_path);
+
+ if (f == NULL)
+ return -errno;
+
+ fprintf(f, "%d", delay);
+
+ fclose(f);
+
+ return 0;
}
-void __connman_tethering_set_enabled(void)
+static int create_bridge(const char *name)
+{
+ int sk, err;
+
+ DBG("name %s", name);
+
+ sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ if (sk < 0)
+ return -EOPNOTSUPP;
+
+ if (ioctl(sk, SIOCBRADDBR, name) == -1) {
+ err = -errno;
+ if (err != -EEXIST)
+ return -EOPNOTSUPP;
+ }
+
+ err = set_forward_delay(name, 0);
+
+ if (err < 0)
+ ioctl(sk, SIOCBRDELBR, name);
+
+ close(sk);
+
+ return err;
+}
+
+static int remove_bridge(const char *name)
+{
+ int sk, err;
+
+ DBG("name %s", name);
+
+ sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ if (sk < 0)
+ return -EOPNOTSUPP;
+
+ err = ioctl(sk, SIOCBRDELBR, name);
+
+ close(sk);
+
+ if (err < 0)
+ return -EOPNOTSUPP;
+
+ return 0;
+}
+
+static int enable_bridge(const char *name)
+{
+ int err, index;
+
+ index = connman_inet_ifindex(name);
+ if (index < 0)
+ return index;
+
+ err = __connman_inet_modify_address(RTM_NEWADDR,
+ NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
+ BRIDGE_IP, NULL, 24, BRIDGE_BCAST);
+ if (err < 0)
+ return err;
+
+ return connman_inet_ifup(index);
+}
+
+static int disable_bridge(const char *name)
{
int index;
+
+ index = connman_inet_ifindex(name);
+ if (index < 0)
+ return index;
+
+ return connman_inet_ifdown(index);
+}
+
+static int enable_ip_forward(connman_bool_t enable)
+{
+
+ FILE *f;
+
+ f = fopen("/proc/sys/net/ipv4/ip_forward", "r+");
+ if (f == NULL)
+ return -errno;
+
+ if (enable == TRUE)
+ fprintf(f, "1");
+ else
+ fprintf(f, "0");
+
+ fclose(f);
+
+ return 0;
+}
+
+static int enable_nat(const char *interface)
+{
+ int err;
+
+ if (interface == NULL)
+ return 0;
+
+ /* Enable IPv4 forwarding */
+ err = enable_ip_forward(TRUE);
+ if (err < 0)
+ return err;
+
+ /* POSTROUTING flush */
+ err = __connman_iptables_command("-t nat -F POSTROUTING");
+ if (err < 0)
+ return err;
+
+ /* Enable masquerading */
+ err = __connman_iptables_command("-t nat -A POSTROUTING "
+ "-o %s -j MASQUERADE", interface);
+ if (err < 0)
+ return err;
+
+ return __connman_iptables_commit("nat");
+}
+
+static void disable_nat(const char *interface)
+{
+ int err;
+
+ /* Disable IPv4 forwarding */
+ enable_ip_forward(FALSE);
+
+ /* POSTROUTING flush */
+ err = __connman_iptables_command("-t nat -F POSTROUTING");
+ if (err < 0)
+ return;
+
+ __connman_iptables_commit("nat");
+}
+
+void __connman_tethering_set_enabled(void)
+{
int err;
- const char *gateway;
- const char *broadcast;
- const char *subnet_mask;
- const char *start_ip;
- const char *end_ip;
const char *dns;
- unsigned char prefixlen;
DBG("enabled %d", tethering_enabled + 1);
if (__sync_fetch_and_add(&tethering_enabled, 1) != 0)
return;
- err = __connman_bridge_create(BRIDGE_NAME);
+ err = create_bridge(BRIDGE_NAME);
if (err < 0)
return;
- index = connman_inet_ifindex(BRIDGE_NAME);
- dhcp_ippool = __connman_ippool_create(index, 2, 252,
- tethering_restart, NULL);
- if (dhcp_ippool == NULL) {
- connman_error("Fail to create IP pool");
- return;
- }
-
- gateway = __connman_ippool_get_gateway(dhcp_ippool);
- broadcast = __connman_ippool_get_broadcast(dhcp_ippool);
- subnet_mask = __connman_ippool_get_subnet_mask(dhcp_ippool);
- start_ip = __connman_ippool_get_start_ip(dhcp_ippool);
- end_ip = __connman_ippool_get_end_ip(dhcp_ippool);
-
- err = __connman_bridge_enable(BRIDGE_NAME, gateway, broadcast);
+ err = enable_bridge(BRIDGE_NAME);
if (err < 0 && err != -EALREADY) {
- __connman_bridge_remove(BRIDGE_NAME);
+ remove_bridge(BRIDGE_NAME);
return;
}
- dns = gateway;
+ dns = BRIDGE_IP;
if (__connman_dnsproxy_add_listener(BRIDGE_NAME) < 0) {
connman_error("Can't add listener %s to DNS proxy",
BRIDGE_NAME);
dns = BRIDGE_DNS;
}
- tethering_dhcp_server = dhcp_server_start(BRIDGE_NAME,
- gateway, subnet_mask,
- start_ip, end_ip,
- 24 * 3600, dns);
+ tethering_dhcp_server =
+ dhcp_server_start(BRIDGE_NAME,
+ BRIDGE_IP, BRIDGE_SUBNET,
+ BRIDGE_IP_START, BRIDGE_IP_END,
+ 24 * 3600, dns);
if (tethering_dhcp_server == NULL) {
- __connman_bridge_disable(BRIDGE_NAME);
- __connman_bridge_remove(BRIDGE_NAME);
+ disable_bridge(BRIDGE_NAME);
+ remove_bridge(BRIDGE_NAME);
return;
}
- prefixlen =
- __connman_ipconfig_netmask_prefix_len(subnet_mask);
- __connman_nat_enable(BRIDGE_NAME, start_ip, prefixlen);
+ enable_nat(default_interface);
DBG("tethering started");
}
if (__sync_fetch_and_sub(&tethering_enabled, 1) != 1)
return;
- __connman_nat_disable(BRIDGE_NAME);
+ disable_nat(default_interface);
dhcp_server_stop(tethering_dhcp_server);
tethering_dhcp_server = NULL;
- __connman_bridge_disable(BRIDGE_NAME);
+ disable_bridge(BRIDGE_NAME);
- __connman_ippool_unref(dhcp_ippool);
-
- __connman_bridge_remove(BRIDGE_NAME);
+ remove_bridge(BRIDGE_NAME);
DBG("tethering stopped");
}
+void __connman_tethering_update_interface(const char *interface)
+{
+ DBG("interface %s", interface);
+
+ g_free(default_interface);
+
+ if (interface == NULL) {
+ disable_nat(interface);
+ default_interface = NULL;
+
+ return;
+ }
+
+ default_interface = g_strdup(interface);
+
+ __sync_synchronize();
+ if (tethering_enabled == 0)
+ return;
+
+ enable_nat(interface);
+}
+
static void setup_tun_interface(unsigned int flags, unsigned change,
void *data)
{
struct connman_private_network *pn = data;
unsigned char prefixlen;
DBusMessageIter array, dict;
- const char *server_ip;
- const char *peer_ip;
- const char *subnet_mask;
int err;
DBG("index %d flags %d change %d", pn->index, flags, change);
if (flags & IFF_UP)
return;
- subnet_mask = __connman_ippool_get_subnet_mask(pn->pool);
- server_ip = __connman_ippool_get_start_ip(pn->pool);
- peer_ip = __connman_ippool_get_end_ip(pn->pool);
prefixlen =
- __connman_ipconfig_netmask_prefix_len(subnet_mask);
+ __connman_ipconfig_netmask_prefix_len(PRIVATE_NETWORK_NETMASK);
if ((__connman_inet_modify_address(RTM_NEWADDR,
NLM_F_REPLACE | NLM_F_ACK, pn->index, AF_INET,
- server_ip, peer_ip, prefixlen, NULL)) < 0) {
+ pn->server_ip, pn->peer_ip,
+ prefixlen, NULL)) < 0) {
DBG("address setting failed");
return;
}
connman_inet_ifup(pn->index);
- err = __connman_nat_enable(BRIDGE_NAME, server_ip, prefixlen);
+ err = enable_nat(default_interface);
if (err < 0) {
- connman_error("failed to enable NAT");
+ connman_error("failed to enable NAT on %s", default_interface);
goto error;
}
connman_dbus_dict_open(&array, &dict);
connman_dbus_dict_append_basic(&dict, "ServerIPv4",
- DBUS_TYPE_STRING, &server_ip);
+ DBUS_TYPE_STRING, &pn->server_ip);
connman_dbus_dict_append_basic(&dict, "PeerIPv4",
- DBUS_TYPE_STRING, &peer_ip);
+ DBUS_TYPE_STRING, &pn->peer_ip);
connman_dbus_dict_append_basic(&dict, "PrimaryDNS",
DBUS_TYPE_STRING, &pn->primary_dns);
connman_dbus_dict_append_basic(&dict, "SecondaryDNS",
{
struct connman_private_network *pn = user_data;
- __connman_nat_disable(BRIDGE_NAME);
+ disable_nat(default_interface);
connman_rtnl_remove_watch(pn->iface_watch);
- __connman_ippool_unref(pn->pool);
if (pn->watch > 0) {
g_dbus_remove_watch(connection, pn->watch);
g_hash_table_remove(pn_hash, pn->path);
}
-static void ippool_disconnect(struct connman_ippool *pool, void *user_data)
-{
- struct connman_private_network *pn = user_data;
-
- DBG("block used externally");
-
- g_hash_table_remove(pn_hash, pn->path);
-}
-
int __connman_private_network_request(DBusMessage *msg, const char *owner)
{
struct connman_private_network *pn;
pn->fd = fd;
pn->interface = iface;
pn->index = index;
- pn->pool = __connman_ippool_create(pn->index, 1, 1, ippool_disconnect, pn);
- if (pn->pool == NULL) {
- errno = -ENOMEM;
- goto error;
- }
-
+ pn->server_ip = PRIVATE_NETWORK_IP;
+ pn->peer_ip = PRIVATE_NETWORK_PEER_IP;
pn->primary_dns = PRIVATE_NETWORK_PRIMARY_DNS;
pn->secondary_dns = PRIVATE_NETWORK_SECONDARY_DNS;
if (tethering_enabled == 0) {
if (tethering_dhcp_server)
dhcp_server_stop(tethering_dhcp_server);
- __connman_bridge_disable(BRIDGE_NAME);
- __connman_bridge_remove(BRIDGE_NAME);
- __connman_nat_disable(BRIDGE_NAME);
+ disable_bridge(BRIDGE_NAME);
+ remove_bridge(BRIDGE_NAME);
}
if (connection == NULL)
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <errno.h>
#include <glib.h>
-#include <stdlib.h>
-#include <gweb/gresolv.h>
-#include <netdb.h>
#include "connman.h"
-static GSList *ts_list = NULL;
+static GSList *driver_list = NULL;
+static GHashTable *server_hash = NULL;
-static GResolv *resolv = NULL;
-static int resolv_id = 0;
-
-static void resolv_debug(const char *str, void *data)
-{
- connman_info("%s: %s\n", (const char *) data, str);
-}
-static void save_timeservers(char **servers)
-{
- GKeyFile *keyfile;
- int cnt;
-
- keyfile = __connman_storage_load_global();
- if (keyfile == NULL)
- keyfile = g_key_file_new();
-
- for (cnt = 0; servers != NULL && servers[cnt] != NULL; cnt++);
-
- g_key_file_set_string_list(keyfile, "global", "Timeservers",
- (const gchar **)servers, cnt);
-
- __connman_storage_save_global(keyfile);
-
- g_key_file_free(keyfile);
-
- return;
-}
-
-static char **load_timeservers()
+static gint compare_priority(gconstpointer a, gconstpointer b)
{
- GKeyFile *keyfile;
- char **servers = NULL;
-
- keyfile = __connman_storage_load_global();
- if (keyfile == NULL)
- return NULL;
-
- servers = g_key_file_get_string_list(keyfile, "global",
- "Timeservers", NULL, NULL);
+ const struct connman_timeserver_driver *driver1 = a;
+ const struct connman_timeserver_driver *driver2 = b;
- g_key_file_free(keyfile);
-
- return servers;
+ return driver2->priority - driver1->priority;
}
-static void resolv_result(GResolvResultStatus status, char **results, gpointer user_data)
-{
- int i;
-
- DBG("status %d", status);
-
- if (status == G_RESOLV_RESULT_STATUS_SUCCESS) {
- if (results != NULL) {
- for (i = 0; results[i]; i++)
- DBG("result: %s", results[i]);
-
- __connman_ntp_start(results[0]);
-
- return;
- }
- }
-
- /* If resolving fails, move to the next server */
- __connman_timeserver_sync_next();
-}
-
-/*
- * Once the timeserver list (ts_list) is created, we start querying the
- * servers one by one. If resolving fails on one of them, we move to the
- * next one. The user can enter either an IP address or a URL for the
- * timeserver. We only resolve the urls. Once we have a IP for the NTP
- * server, we start querying it for time corrections.
+/**
+ * connman_timeserver_driver_register:
+ * @driver: timeserver driver definition
+ *
+ * Register a new timeserver driver
+ *
+ * Returns: %0 on success
*/
-void __connman_timeserver_sync_next()
-{
- char *server;
-
- __connman_ntp_stop();
-
- /* Get the 1st server in the list */
- if (ts_list == NULL)
- return;
-
- server = ts_list->data;
-
- ts_list = g_slist_delete_link(ts_list, ts_list);
-
- /* if its a IP , directly query it. */
- if (connman_inet_check_ipaddress(server) > 0) {
- DBG("Using timeservers %s", server);
-
- __connman_ntp_start(server);
-
- g_free(server);
- return;
- }
-
- DBG("Resolving server %s", server);
-
- resolv_id = g_resolv_lookup_hostname(resolv, server,
- resolv_result, NULL);
-
- g_free(server);
-
- return;
-}
-
-GSList *__connman_timeserver_add_list(GSList *server_list,
- const char *timeserver)
+int connman_timeserver_driver_register(struct connman_timeserver_driver *driver)
{
- GSList *list = server_list;
+ DBG("driver %p name %s", driver, driver->name);
- if (timeserver == NULL)
- return server_list;
+ driver_list = g_slist_insert_sorted(driver_list, driver,
+ compare_priority);
- while (list != NULL) {
- char *existing_server = list->data;
- if (strcmp(timeserver, existing_server) == 0)
- return server_list;
- list = g_slist_next(list);
- }
- return g_slist_prepend(server_list, g_strdup(timeserver));
+ return 0;
}
-/*
- * __connman_timeserver_get_all function creates the timeserver
- * list which will be used to determine NTP server for time corrections.
- * The service settings take priority over the global timeservers.
+/**
+ * connman_timeserver_driver_unregister:
+ * @driver: timeserver driver definition
+ *
+ * Remove a previously registered timeserver driver
*/
-GSList *__connman_timeserver_get_all(struct connman_service *service)
+void connman_timeserver_driver_unregister(struct connman_timeserver_driver *driver)
{
- GSList *list = NULL;
- struct connman_network *network;
- char **timeservers;
- char **service_ts;
- char **service_ts_config;
- const char *service_gw;
- char **fallback_ts;
- int index, i;
-
- service_ts_config = connman_service_get_timeservers_config(service);
-
- /* First add Service Timeservers.Configuration to the list */
- for (i = 0; service_ts_config != NULL && service_ts_config[i] != NULL;
- i++)
- list = __connman_timeserver_add_list(list,
- service_ts_config[i]);
-
- service_ts = connman_service_get_timeservers(service);
-
- /* First add Service Timeservers via DHCP to the list */
- for (i = 0; service_ts != NULL && service_ts[i] != NULL; i++)
- list = __connman_timeserver_add_list(list, service_ts[i]);
-
- network = __connman_service_get_network(service);
- if (network != NULL) {
- index = connman_network_get_index(network);
- service_gw = __connman_ipconfig_get_gateway_from_index(index,
- CONNMAN_IPCONFIG_TYPE_ALL);
-
- /* Then add Service Gateway to the list */
- if (service_gw != NULL)
- list = __connman_timeserver_add_list(list, service_gw);
- }
-
- /* Then add Global Timeservers to the list */
- timeservers = load_timeservers();
+ DBG("driver %p name %s", driver, driver->name);
- for (i = 0; timeservers != NULL && timeservers[i] != NULL; i++)
- list = __connman_timeserver_add_list(list, timeservers[i]);
-
- g_strfreev(timeservers);
-
- fallback_ts = connman_setting_get_string_list("FallbackTimeservers");
-
- /* Lastly add the fallback servers */
- for (i = 0; fallback_ts != NULL && fallback_ts[i] != NULL; i++)
- list = __connman_timeserver_add_list(list, fallback_ts[i]);
-
- return g_slist_reverse(list);
+ driver_list = g_slist_remove(driver_list, driver);
}
-/*
- * This function must be called everytime the default service changes, the
- * service timeserver(s) or gatway changes or the global timeserver(s) changes.
+/**
+ * connman_timeserver_append:
+ * @server: server address
+ *
+ * Append time server server address to current list
*/
-int __connman_timeserver_sync(struct connman_service *default_service)
+int connman_timeserver_append(const char *server)
{
- struct connman_service *service;
+ GSList *list;
- if (default_service != NULL)
- service = default_service;
- else
- service = __connman_service_get_default();
+ DBG("server %s", server);
- if (service == NULL)
+ if (server == NULL)
return -EINVAL;
- if (resolv == NULL)
+ /* This server is already handled by a driver */
+ if (g_hash_table_lookup(server_hash, server))
return 0;
- /*
- * Before we start creating the new timeserver list we must stop
- * any ongoing ntp query and server resolution.
- */
-
- __connman_ntp_stop();
-
- if (resolv_id > 0)
- g_resolv_cancel_lookup(resolv, resolv_id);
- g_slist_free_full(ts_list, g_free);
+ for (list = driver_list; list; list = list->next) {
+ struct connman_timeserver_driver *driver = list->data;
+ char *new_server;
- ts_list = __connman_timeserver_get_all(service);
+ if (driver->append == NULL)
+ continue;
- __connman_service_timeserver_changed(service, ts_list);
+ new_server = g_strdup(server);
+ if (new_server == NULL)
+ return -ENOMEM;
- if (ts_list == NULL) {
- DBG("No timeservers set.");
- return 0;
+ if (driver->append(server) == 0) {
+ g_hash_table_insert(server_hash, new_server, driver);
+ return 0;
+ } else {
+ g_free(new_server);
+ }
}
- __connman_timeserver_sync_next();
-
- return 0;
+ return -ENOENT;
}
-static int timeserver_start(struct connman_service *service)
+/**
+ * connman_timeserver_remove:
+ * @server: server address
+ *
+ * Remover time server server address from current list
+ */
+int connman_timeserver_remove(const char *server)
{
- char **nameservers;
- int i;
+ struct connman_timeserver_driver *driver;
- DBG("service %p", service);
+ DBG("server %s", server);
- i = __connman_service_get_index(service);
- if (i < 0)
+ if (server == NULL)
return -EINVAL;
- nameservers = connman_service_get_nameservers(service);
- if (nameservers == NULL)
+ driver = g_hash_table_lookup(server_hash, server);
+ if (driver == NULL)
return -EINVAL;
- /* Stop an already ongoing resolution, if there is one */
- if (resolv != NULL && resolv_id > 0)
- g_resolv_cancel_lookup(resolv, resolv_id);
+ g_hash_table_remove(server_hash, server);
- /* get rid of the old resolver */
- if (resolv != NULL) {
- g_resolv_unref(resolv);
- resolv = NULL;
- }
+ if (driver->remove == NULL)
+ return -ENOENT;
- resolv = g_resolv_new(i);
- if (resolv == NULL) {
- g_strfreev(nameservers);
- return -ENOMEM;
- }
-
- if (getenv("CONNMAN_RESOLV_DEBUG"))
- g_resolv_set_debug(resolv, resolv_debug, "RESOLV");
-
- for (i = 0; nameservers[i] != NULL; i++)
- g_resolv_add_nameserver(resolv, nameservers[i], 53, 0);
-
- g_strfreev(nameservers);
-
- return __connman_timeserver_sync(service);
+ return driver->remove(server);
}
-static void timeserver_stop()
+void connman_timeserver_sync(void)
{
- DBG(" ");
-
- if (resolv != NULL) {
- g_resolv_unref(resolv);
- resolv = NULL;
- }
+ GSList *list;
- g_slist_free_full(ts_list, g_free);
-
- ts_list = NULL;
-
- __connman_ntp_stop();
-}
-
-int __connman_timeserver_system_set(char **servers)
-{
- save_timeservers(servers);
-
- __connman_timeserver_sync(NULL);
-
- return 0;
-}
+ DBG("");
-char **__connman_timeserver_system_get()
-{
- char **servers;
+ for (list = driver_list; list; list = list->next) {
+ struct connman_timeserver_driver *driver = list->data;
- servers = load_timeservers();
- return servers;
-}
+ if (driver->sync == NULL)
+ continue;
-static void default_changed(struct connman_service *default_service)
-{
- if (default_service != NULL)
- timeserver_start(default_service);
- else
- timeserver_stop();
+ driver->sync();
+ }
}
-static struct connman_notifier timeserver_notifier = {
- .name = "timeserver",
- .default_changed = default_changed,
-};
-
int __connman_timeserver_init(void)
{
DBG("");
- connman_notifier_register(×erver_notifier);
+ server_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
return 0;
}
{
DBG("");
- connman_notifier_unregister(×erver_notifier);
+ g_hash_table_destroy(server_hash);
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
CONNMAN_WISPR_RESULT_FAILED = 3,
};
-struct wispr_route {
- char *address;
- int if_index;
-};
-
struct connman_wispr_portal_context {
struct connman_service *service;
enum connman_ipconfig_type type;
const char *status_url;
- char *redirect_url;
-
/* WISPr specific */
GWebParser *wispr_parser;
struct connman_wispr_message wispr_msg;
char *wispr_formdata;
enum connman_wispr_result wispr_result;
-
- GSList *route_list;
};
struct connman_wispr_portal {
msg->location_name = NULL;
}
-static void free_wispr_routes(struct connman_wispr_portal_context *wp_context)
-{
- while (wp_context->route_list != NULL) {
- struct wispr_route *route = wp_context->route_list->data;
-
- DBG("free route to %s if %d type %d", route->address,
- route->if_index, wp_context->type);
-
- switch(wp_context->type) {
- case CONNMAN_IPCONFIG_TYPE_IPV4:
- connman_inet_del_host_route(route->if_index,
- route->address);
- break;
- case CONNMAN_IPCONFIG_TYPE_IPV6:
- connman_inet_del_ipv6_host_route(route->if_index,
- route->address);
- break;
- case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
- break;
- }
-
- g_free(route->address);
- g_free(route);
-
- wp_context->route_list =
- g_slist_delete_link(wp_context->route_list,
- wp_context->route_list);
- }
-}
-
static void free_connman_wispr_portal_context(struct connman_wispr_portal_context *wp_context)
{
- DBG("context %p", wp_context);
+ DBG("");
if (wp_context == NULL)
return;
g_web_unref(wp_context->web);
- g_free(wp_context->redirect_url);
-
g_web_parser_unref(wp_context->wispr_parser);
connman_wispr_message_init(&wp_context->wispr_msg);
g_free(wp_context->wispr_password);
g_free(wp_context->wispr_formdata);
- free_wispr_routes(wp_context);
-
g_free(wp_context);
}
result = g_markup_parse_context_parse(parser_context,
str, strlen(str), NULL);
if (result == TRUE)
- g_markup_parse_context_end_parse(parser_context, NULL);
+ result = g_markup_parse_context_end_parse(parser_context, NULL);
g_markup_parse_context_free(parser_context);
}
wp_context->type);
}
-static gboolean wispr_route_request(const char *address, int ai_family,
- int if_index, gpointer user_data)
-{
- int result = -1;
- struct connman_wispr_portal_context *wp_context = user_data;
- const char *gateway;
- struct wispr_route *route;
-
- gateway = __connman_ipconfig_get_gateway_from_index(if_index,
- wp_context->type);
-
- DBG("address %s if %d gw %s", address, if_index, gateway);
-
- if (gateway == NULL)
- return FALSE;
-
- route = g_try_new0(struct wispr_route, 1);
- if (route == 0) {
- DBG("could not create struct");
- return FALSE;
- }
-
- switch(wp_context->type) {
- case CONNMAN_IPCONFIG_TYPE_IPV4:
- result = connman_inet_add_host_route(if_index, address,
- gateway);
- break;
- case CONNMAN_IPCONFIG_TYPE_IPV6:
- result = connman_inet_add_ipv6_host_route(if_index, address,
- gateway);
- break;
- case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
- break;
- }
-
- if (result < 0) {
- g_free(route);
- return FALSE;
- }
-
- route->address = g_strdup(address);
- route->if_index = if_index;
- wp_context->route_list = g_slist_prepend(wp_context->route_list, route);
-
- return TRUE;
-}
-
static void wispr_portal_request_portal(struct connman_wispr_portal_context *wp_context)
{
DBG("");
wp_context->request_id = g_web_request_get(wp_context->web,
wp_context->status_url,
- wispr_portal_web_result,
- wispr_route_request,
- wp_context);
+ wispr_portal_web_result, wp_context);
if (wp_context->request_id == 0)
wispr_portal_error(wp_context);
return FALSE;
}
-static void wispr_portal_browser_reply_cb(struct connman_service *service,
- connman_bool_t authentication_done,
- const char *error, void *user_data)
-{
- struct connman_wispr_portal_context *wp_context = user_data;
-
- DBG("");
-
- if (service == NULL || wp_context == NULL)
- return;
-
- if (authentication_done == FALSE) {
- wispr_portal_error(wp_context);
- free_wispr_routes(wp_context);
- return;
- }
-
- /* Restarting the test */
- __connman_wispr_start(service, wp_context->type);
-}
-
static void wispr_portal_request_wispr_login(struct connman_service *service,
- connman_bool_t success,
- const char *ssid, int ssid_len,
const char *username, const char *password,
- gboolean wps, const char *wpspin,
- const char *error, void *user_data)
+ void *user_data)
{
struct connman_wispr_portal_context *wp_context = user_data;
DBG("");
- if (error != NULL && g_strcmp0(error,
- "net.connman.Agent.Error.LaunchBrowser") == 0) {
- __connman_agent_request_browser(service,
- wispr_portal_browser_reply_cb,
- wp_context->redirect_url, wp_context);
- return;
- }
-
g_free(wp_context->wispr_username);
wp_context->wispr_username = g_strdup(username);
wp_context->wispr_result = CONNMAN_WISPR_RESULT_LOGIN;
+ __connman_service_request_login(wp_context->service);
+
if (__connman_agent_request_login_input(wp_context->service,
wispr_portal_request_wispr_login,
- wp_context) != -EINPROGRESS)
+ wp_context) != -EIO)
wispr_portal_error(wp_context);
break;
&str) == TRUE)
portal_manage_status(result, wp_context);
else
- __connman_agent_request_browser(wp_context->service,
- wispr_portal_browser_reply_cb,
- wp_context->redirect_url, wp_context);
+ __connman_service_request_login(wp_context->service);
break;
case 302:
- if (g_web_supports_tls() == FALSE ||
- g_web_result_get_header(result, "Location",
- &redirect) == FALSE) {
- __connman_agent_request_browser(wp_context->service,
- wispr_portal_browser_reply_cb,
- wp_context->status_url, wp_context);
+ if (g_web_result_get_header(result, "Location",
+ &redirect) == FALSE)
break;
- }
DBG("Redirect URL: %s", redirect);
- wp_context->redirect_url = g_strdup(redirect);
-
wp_context->request_id = g_web_request_get(wp_context->web,
- redirect, wispr_portal_web_result,
- wispr_route_request, wp_context);
+ redirect, wispr_portal_web_result, wp_context);
goto done;
- case 400:
case 404:
- if (__connman_service_online_check_failed(wp_context->service,
- wp_context->type) == 0)
- wispr_portal_error(wp_context);
+ wispr_portal_error(wp_context);
break;
default:
break;
}
- free_wispr_routes(wp_context);
wp_context->request_id = 0;
done:
wp_context->wispr_msg.message_type = -1;
wp_context->token = 0;
+ if (proxy == NULL)
+ proxy = getenv("http_proxy");
+
+ if (getenv("CONNMAN_WEB_DEBUG"))
+ g_web_set_debug(wp_context->web, web_debug, "WEB");
+
if (proxy != NULL && g_strcmp0(proxy, "DIRECT") != 0)
g_web_set_proxy(wp_context->web, proxy);
wispr_portal_request_portal(wp_context);
}
-static gboolean no_proxy_callback(gpointer user_data)
-{
- struct connman_wispr_portal_context *wp_context = user_data;
-
- proxy_callback("DIRECT", wp_context);
-
- return FALSE;
-}
-
static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)
{
- enum connman_service_proxy_method proxy_method;
enum connman_service_type service_type;
char *interface = NULL;
- char **nameservers = NULL;
int if_index;
int err = 0;
- int i;
DBG("wispr/portal context %p", wp_context);
DBG("service %p", wp_context->service);
DBG("interface %s", interface);
if_index = connman_inet_ifindex(interface);
- if (if_index < 0) {
- DBG("Could not get ifindex");
- err = -EINVAL;
- goto done;
- }
-
- nameservers = connman_service_get_nameservers(wp_context->service);
- if (nameservers == NULL) {
- DBG("Could not get nameservers");
- err = -EINVAL;
- goto done;
- }
+ if (if_index < 0)
+ return -EINVAL;
wp_context->web = g_web_new(if_index);
if (wp_context->web == NULL) {
- DBG("Could not set up GWeb");
err = -ENOMEM;
goto done;
}
- if (getenv("CONNMAN_WEB_DEBUG"))
- g_web_set_debug(wp_context->web, web_debug, "WEB");
-
if (wp_context->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
g_web_set_address_family(wp_context->web, AF_INET);
wp_context->status_url = STATUS_URL_IPV4;
wp_context->status_url = STATUS_URL_IPV6;
}
- for (i = 0; nameservers[i] != NULL; i++)
- g_web_add_nameserver(wp_context->web, nameservers[i]);
-
- proxy_method = connman_service_get_proxy_method(wp_context->service);
-
- if (proxy_method != CONNMAN_SERVICE_PROXY_METHOD_DIRECT) {
- wp_context->token = connman_proxy_lookup(interface,
- wp_context->status_url,
- wp_context->service,
- proxy_callback, wp_context);
-
- if (wp_context->token == 0)
- err = -EINVAL;
- } else {
- g_timeout_add_seconds(0, no_proxy_callback, wp_context);
- }
+ wp_context->token = connman_proxy_lookup(interface,
+ wp_context->status_url,
+ wp_context->service,
+ proxy_callback, wp_context);
+ if (wp_context->token == 0)
+ err = -EINVAL;
done:
- g_strfreev(nameservers);
-
g_free(interface);
return err;
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
return -EINVAL;
wpad = g_try_new0(struct connman_wpad, 1);
- if (wpad == NULL) {
- g_strfreev(nameservers);
+ if (wpad == NULL)
return -ENOMEM;
- }
wpad->service = service;
wpad->resolv = g_resolv_new(index);
if (wpad->resolv == NULL) {
- g_strfreev(nameservers);
g_free(wpad);
return -ENOMEM;
}
for (i = 0; nameservers[i] != NULL; i++)
g_resolv_add_nameserver(wpad->resolv, nameservers[i], 53, 0);
- g_strfreev(nameservers);
-
wpad->hostname = g_strdup_printf("wpad.%s", domainname);
DBG("hostname %s", wpad->hostname);
--- /dev/null
+#!/usr/bin/python
+
+import sys
+import dbus
+
+if (len(sys.argv) < 2):
+ print "Usage: %s <ssid> [passphrase] [security]" % (sys.argv[0])
+ sys.exit(1)
+
+bus = dbus.SystemBus()
+
+manager = dbus.Interface(bus.get_object("net.connman", "/"),
+ "net.connman.Manager")
+
+print "Attempting to connect service %s" % (sys.argv[1])
+
+if len(sys.argv) > 2:
+ if len(sys.argv) > 3:
+ security = sys.argv[3]
+ else:
+ security = "rsn"
+ passphrase = sys.argv[2]
+else:
+ security = "none"
+ passphrase = ""
+
+path = manager.ConnectService(({ "Type": "wifi", "Mode": "managed",
+ "SSID": sys.argv[1],
+ "Security": security,
+ "Passphrase": passphrase }),
+ timeout=60000);
+print "Service path is %s" %(path)
if (len(sys.argv) < 2):
print "Usage: %s type" % (sys.argv[0])
- sys.exit(1)
bus = dbus.SystemBus()
else:
return None
-technologies = manager.GetTechnologies()
-tech = None
+properties = manager.GetProperties()
-for path,_ in technologies:
- tech = technology_disable_tethering(path, sys.argv[1])
- if tech != None:
- break;
+for key in properties.keys():
+ if key in ["Technologies"]:
+ for path in properties[key]:
+ tech = technology_disable_tethering(path, sys.argv[1])
+ if tech != None:
+ break;
if tech == None:
print "Failed to disable %s tethering" % (sys.argv[1])
import sys
import dbus
-if (len(sys.argv) >= 2 and len(sys.argv) < 4 and sys.argv[1] == "wifi"):
+if (len(sys.argv) < 4 and sys.argv[1] == "wifi"):
print "Usage: %s wifi [SSID] [passphrase]" % (sys.argv[0])
sys.exit(1)
elif (len(sys.argv) < 2):
print "Usage: %s type" % (sys.argv[0])
- sys.exit(1)
bus = dbus.SystemBus()
else:
return None
-technologies = manager.GetTechnologies()
-tech = None
+properties = manager.GetProperties()
-for path,_ in technologies:
- if (len(sys.argv) == 4):
- tech = technology_enable_tethering(path,
+for key in properties.keys():
+ if key in ["Technologies"]:
+ for path in properties[key]:
+ if (len(sys.argv) == 4):
+ tech = technology_enable_tethering(path,
sys.argv[1], sys.argv[2], sys.argv[3])
- else:
- tech = technology_enable_tethering(path, sys.argv[1], "", "")
+ else:
+ tech = technology_enable_tethering(path,
+ sys.argv[1], "", "")
- if tech != None:
- break;
+ if tech != None:
+ break;
if tech == None:
print "Failed to enable %s tethering" % (sys.argv[1])
--- /dev/null
+#!/usr/bin/python
+
+import sys
+import dbus
+
+if (len(sys.argv) < 2):
+ print "Usage: %s <pattern>" % (sys.argv[0])
+ sys.exit(1)
+
+bus = dbus.SystemBus()
+
+manager = dbus.Interface(bus.get_object('net.connman', '/'),
+ 'net.connman.Manager')
+
+path = manager.LookupService(sys.argv[1])
+
+print "Service is %s" % (path)
--- /dev/null
+#!/usr/bin/python
+
+import dbus
+
+bus = dbus.SystemBus()
+
+manager = dbus.Interface(bus.get_object("net.connman", "/"),
+ "net.connman.Manager")
+
+properties = manager.GetProperties()
+
+active = properties["ActiveProfile"]
+
+for path in properties["Profiles"]:
+ if (active == path):
+ print "[ %s ] <== active" % (path)
+ else:
+ print "[ %s ]" % (path)
+
+ profile = dbus.Interface(bus.get_object("net.connman", path),
+ "net.connman.Profile")
+
+ properties = profile.GetProperties()
+ for key in properties.keys():
+ if key in ["Services"]:
+ list = ""
+ for path in properties["Services"]:
+ val = str(path)
+ list = list + val[val.rfind("/") + 1:] + " "
+ print " Services = [ %s]" % (list)
+ else:
+ print " %s = %s" % (key, properties[key])
+
+ print
manager = dbus.Interface(bus.get_object("net.connman", "/"),
"net.connman.Manager")
-for path, properties in manager.GetServices():
+properties = manager.GetProperties()
+
+for path in properties["Services"]:
service = dbus.Interface(bus.get_object("net.connman", path),
"net.connman.Service")
- identifier = path[path.rfind("/") + 1:]
- print "[ %s ]" % (identifier)
+
+ properties = service.GetProperties()
+
+ print "[ %s ]" % (path)
for key in properties.keys():
if key in ["IPv4", "IPv4.Configuration",
"Ethernet", "Provider"]:
val = extract_values(properties[key])
elif key in ["Nameservers", "Nameservers.Configuration",
- "Domains", "Domains.Configuration",
- "Timeservers", "Timeservers.Configuration",
- "Security"]:
+ "Domains", "Domains.Configuration",
+ "Security"]:
val = extract_list(properties[key])
elif key in ["Favorite", "Immutable", "AutoConnect",
"LoginRequired", "PassphraseRequired"]:
val = int(value)
elif name in ["IPv4", "IPv6", "Ethernet", "Proxy" ]:
val = extract_values(value)
- elif name in ["Services", "Technologies",
- "Nameservers", "Domains", "Timeservers"]:
+ elif name in ["Nameservers", "Domains", "Services",
+ "Update", "Technologies", "AvailableTechnologies",
+ "EnabledTechnologies", "ConnectedTechnologies" ]:
val = extract_list(value)
else:
val = str(value)
--- /dev/null
+#!/usr/bin/python
+
+import gobject
+
+import dbus
+import dbus.mainloop.glib
+
+def property_changed(name, value):
+ if name in ["Profiles", "Services", "Technologies"]:
+ val = "["
+ for i in value:
+ val = val + " " + i[i.rfind("/") + 1:]
+ val = val + " ]"
+ elif name in ["AvailableTechnologies", "EnabledTechnologies",
+ "ConnectedTechnologies",
+ "AvailableDebugs", "EnabledDebugs"]:
+ val = "["
+ for i in value:
+ val = val + " " + i
+ val = val + " ]"
+ elif name in ["Strength", "Priority"]:
+ val = int(value)
+ else:
+ val = str(value)
+ print "%s = %s" % (name, val)
+
+if __name__ == '__main__':
+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+ bus = dbus.SystemBus()
+
+ bus.add_signal_receiver(property_changed,
+ bus_name="net.connman",
+ dbus_interface="net.connman.Manager",
+ signal_name = "PropertyChanged")
+
+ mainloop = gobject.MainLoop()
+ mainloop.run()
def property_changed(name, value, path):
service = path[path.rfind("/") + 1:]
- if name in ["Services"]:
+ if name in ["Profiles", "Services", "Technologies"]:
val = "["
for i in value:
val = val + " " + i[i.rfind("/") + 1:]
val = val + " ]"
elif name in ["IPv4", "IPv4.Configuration",
"IPv6", "IPv6.Configuration",
- "Proxy", "Proxy.Configuration", "Ethernet", "Provider"]:
+ "Proxy", "Proxy.Configuration", "Ethernet"]:
val = extract_values(value)
elif name in ["Nameservers", "Nameservers.Configuration",
- "Domains", "Domains.Configuration",
- "Timeservers", "Timeservers.Configuration", "Security"]:
+ "Domains", "Domains.Configuration"
+ "Security"]:
val = extract_list(value)
elif name in ["Strength", "Priority"]:
val = int(value)
val = str(value)
print "[%s] %s = %s" % (service, name, val)
-def services_changed(services, removed):
- for i in services:
- service = i[0][i[0].rfind("/") + 1:]
- print "[%s] changed" % (service)
- for n in i[1].keys():
- property_changed(n, i[1][n], i[0])
- for i in removed:
- service = i[i.rfind("/") + 1:]
- print "[%s] removed" % (service)
-
-def technology_added(path, properties):
- technology = path[path.rfind("/") + 1:]
- print "[%s] added" % (technology)
- for n in properties.keys():
- property_changed(n, properties[n], technology)
-
-def technology_removed(path):
- technology = path[path.rfind("/") + 1:]
- print "[%s] removed" % (technology)
-
if __name__ == '__main__':
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus.add_signal_receiver(property_changed,
bus_name="net.connman",
- dbus_interface="net.connman.Manager",
- signal_name="PropertyChanged",
- path_keyword="path")
-
- bus.add_signal_receiver(services_changed,
- bus_name="net.connman",
- dbus_interface="net.connman.Manager",
- signal_name="ServicesChanged")
-
- bus.add_signal_receiver(property_changed,
- bus_name="net.connman",
dbus_interface="net.connman.Service",
- signal_name="PropertyChanged",
- path_keyword="path")
-
- bus.add_signal_receiver(technology_added,
- bus_name="net.connman",
- dbus_interface="net.connman.Manager",
- signal_name="TechnologyAdded")
-
- bus.add_signal_receiver(technology_removed,
- bus_name="net.connman",
- dbus_interface="net.connman.Manager",
- signal_name="TechnologyRemoved")
-
- bus.add_signal_receiver(property_changed,
- bus_name="net.connman",
- dbus_interface="net.connman.Technology",
- signal_name="PropertyChanged",
+ signal_name = "PropertyChanged",
path_keyword="path")
mainloop = gobject.MainLoop()
--- /dev/null
+#!/usr/bin/python
+
+import sys
+import dbus
+
+if (len(sys.argv) < 3):
+ print "Usage: %s <ssid> [key=value] ..." % (sys.argv[0])
+ sys.exit(1)
+
+bus = dbus.SystemBus()
+
+manager = dbus.Interface(bus.get_object("net.connman", "/"),
+ "net.connman.Manager")
+
+config = unicode("", "utf-8")
+config += "[service_%s]\n" %(sys.argv[1])
+
+for arg in sys.argv:
+ keyval = arg.split("=", 1)
+ if (len(keyval) >= 2):
+ config += arg
+ config += '\n'
+
+config = config.rstrip()
+
+manager.ProvisionService(config);
+
+print "Sent configuration:\n%s" %(config)
--- /dev/null
+#!/usr/bin/python
+
+import sys
+import dbus
+
+if (len(sys.argv) < 3):
+ print "Usage: %s <address> <netmask | prefix length> <gateway> [version]" % (sys.argv[0])
+ sys.exit(1)
+
+bus = dbus.SystemBus()
+
+manager = dbus.Interface(bus.get_object('net.connman', "/"),
+ 'net.connman.Manager')
+
+properties = manager.GetProperties()
+
+for path in properties["Services"]:
+ service = dbus.Interface(bus.get_object('net.connman', path),
+ 'net.connman.Service')
+
+ properties = service.GetProperties()
+
+
+
+ if (len(sys.argv) == 5 and sys.argv[4] == "ipv6"):
+ ipv = 6
+ else:
+ ipv = 4
+
+ print "Setting IPv%d address %s for %s" % (ipv, sys.argv[1], path)
+
+ if (ipv == 4):
+ service.SetProperty("IPv4.Configuration",
+ { "Method": "manual",
+ "Address": sys.argv[1],
+ "Netmask": sys.argv[2],
+ "Gateway": sys.argv[3]})
+ else:
+ service.SetProperty("IPv6.Configuration",
+ { "Method": "manual",
+ "Address": sys.argv[1],
+ "PrefixLength": sys.argv[2],
+ "Gateway": sys.argv[3]})
+
+ print
import sys
import dbus
-def make_variant(string):
- return dbus.String(string, variant_level=1)
-
def print_usage():
print "Usage: %s <service> [off|dhcp|manual <address> [netmask] [gateway]]" % (sys.argv[0])
print "Setting method %s for %s" % (sys.argv[2], sys.argv[1])
-ipv4_configuration = { "Method": make_variant(sys.argv[2]) }
+ipv4_configuration = { "Method": sys.argv[2] }
if (len(sys.argv) > 3):
- ipv4_configuration["Address"] = make_variant(sys.argv[3])
+ ipv4_configuration["Address"] = sys.argv[3]
if (len(sys.argv) > 4):
- ipv4_configuration["Netmask"] = make_variant(sys.argv[4])
+ ipv4_configuration["Netmask"] = sys.argv[4]
if (len(sys.argv) > 5):
- ipv4_configuration["Gateway"] = make_variant(sys.argv[5])
+ ipv4_configuration["Gateway"] = sys.argv[5]
service.SetProperty("IPv4.Configuration", ipv4_configuration)
print "New IPv4.Configuration: ", ipv4_configuration
import sys
import dbus
-def make_variant(string):
- return dbus.String(string, variant_level=1)
-
def print_usage():
print "Usage: %s <service> off|manual|auto [<address> [prefixlen] [gateway]] [<privacy>]" % (sys.argv[0])
print "Setting method %s for %s" % (sys.argv[2], sys.argv[1])
-ipv6_configuration = { "Method": make_variant(sys.argv[2])}
+ipv6_configuration = { "Method": sys.argv[2] }
if sys.argv[2] == "auto":
if (len(sys.argv) > 3):
- ipv6_configuration["Privacy"] = make_variant(sys.argv[3])
+ ipv6_configuration["Privacy"] = sys.argv[3]
else:
if (len(sys.argv) > 3):
- ipv6_configuration["Address"] = make_variant(sys.argv[3])
+ ipv6_configuration["Address"] = sys.argv[3]
if (len(sys.argv) > 4):
- ipv6_configuration["PrefixLength"] = make_variant(sys.argv[4])
+ ipv6_configuration["PrefixLength"] = sys.argv[4]
if (len(sys.argv) > 5):
- ipv6_configuration["Gateway"] = make_variant(sys.argv[5])
+ ipv6_configuration["Gateway"] = sys.argv[5]
service.SetProperty("IPv6.Configuration", ipv6_configuration)
print "New IPv6.Configuration: ", ipv6_configuration
+++ /dev/null
-#!/usr/bin/python
-
-import sys
-import dbus
-
-if (len(sys.argv) < 2):
- print "Usage: %s <service> [timeserver*]" % (sys.argv[0])
- sys.exit(1)
-
-bus = dbus.SystemBus()
-path = "/net/connman/service/" + sys.argv[1]
-service = dbus.Interface(bus.get_object('net.connman', path),
- 'net.connman.Service')
-
-properties = service.GetProperties()
-
-print "Setting timeserver to %s" % (sys.argv[2:])
-
-service.SetProperty("Timeservers.Configuration",
- dbus.Array(sys.argv[2:], signature=dbus.Signature('s')))
manager = dbus.Interface(bus.get_object("net.connman", "/"),
"net.connman.Manager")
-technologies = manager.GetTechnologies()
+properties = manager.GetProperties()
-for path, properties in technologies:
+for path in properties["Technologies"]:
object = dbus.Interface(bus.get_object("net.connman", path),
"org.freedesktop.DBus.Introspectable")
class Canceled(dbus.DBusException):
_dbus_error_name = "net.connman.Error.Canceled"
-class LaunchBrowser(dbus.DBusException):
- _dbus_error_name = "net.connman.Agent.Error.LaunchBrowser"
-
class Agent(dbus.service.Object):
- name = None
- ssid = None
identity = None
passphrase = None
wpspin = None
response = {}
if not self.identity and not self.passphrase and not self.wpspin:
- print "Service credentials requested, type cancel to cancel"
args = raw_input('Answer: ')
for arg in args.split():
- if arg.startswith("cancel"):
- response["Error"] = arg
if arg.startswith("Identity="):
identity = arg.replace("Identity=", "", 1)
response["Identity"] = identity
response = {}
if not self.username and not self.password:
- print "User login requested, type cancel to cancel"
- print "or browser to login through the browser by yourself."
args = raw_input('Answer: ')
for arg in args.split():
- if arg.startswith("cancel") or arg.startswith("browser"):
- response["Error"] = arg
if arg.startswith("Username="):
username = arg.replace("Username=", "", 1)
response["Username"] = username
return response
- def input_hidden(self):
- response = {}
-
- if not self.name and not self.ssid:
- args = raw_input('Answer ')
-
- for arg in args.split():
- if arg.startswith("Name="):
- name = arg.replace("Name=", "", 1)
- response["Name"] = name
- break
- if arg.startswith("SSID="):
- ssid = arg.replace("SSID", "", 1)
- response["SSID"] = ssid
- break
- else:
- if self.name:
- response["Name"] = self.name
- if self.ssid:
- response["SSID"] = self.ssid
-
- return response
-
@dbus.service.method("net.connman.Agent",
in_signature='oa{sv}',
out_signature='a{sv}')
def RequestInput(self, path, fields):
print "RequestInput (%s,%s)" % (path, fields)
- response = {}
+ response = None
- if fields.has_key("Name"):
- response.update(self.input_hidden())
if fields.has_key("Passphrase"):
- response.update(self.input_passphrase())
- if fields.has_key("Username"):
- response.update(self.input_username())
-
- if response.has_key("Error"):
- if response["Error"] == "cancel":
- raise Canceled("canceled")
- return
- if response["Error"] == "browser":
- raise LaunchBrowser("launch browser")
- return
+ response = self.input_passphrase()
+ elif fields.has_key("Username"):
+ response = self.input_username()
+ else:
+ print "No method to answer the input request"
print "returning (%s)" % (response)
@dbus.service.method("net.connman.Agent",
in_signature='os',
out_signature='')
- def RequestBrowser(self, path, url):
- print "RequestBrowser (%s,%s)" % (path, url)
-
- print "Please login through the given url in a browser"
- print "Then press enter to accept or some text to cancel"
-
- args = raw_input('> ')
-
- if len(args) > 0:
- raise Canceled("canceled")
-
- return
-
- @dbus.service.method("net.connman.Agent",
- in_signature='os',
- out_signature='')
def ReportError(self, path, error):
print "ReportError %s, %s" % (path, error)
retry = raw_input("Retry service (yes/no): ")
def print_usage():
print "Usage:"
- print "For hidden service:"
- print "%s Name=<hidden service name> [SSID=<hidden ssid>]" % (sys.argv[0])
print "For EAP/WPA input:"
print "%s Identity=<identity> Passphrase=<passphrase> WPS=<wpspin>" % (sys.argv[0])
print "For WISPr login input:"
if len(sys.argv) >= 2:
for arg in sys.argv[1:]:
- if arg.startswith("Name="):
- object.name = arg.replace("Name=", "", 1)
- elif arg.startswith("SSID="):
- object.ssid = arg.replace("SSID=", "", 1)
- elif arg.startswith("Identity="):
+ if arg.startswith("Identity="):
object.identity = arg.replace("Identity=", "", 1)
elif arg.startswith("Passphrase="):
object.passphrase = arg.replace("Passphrase=", "", 1)
print ""
print " state"
print " services"
+ print " passphrase <service> [passphrase]"
print " autoconnect <service> [autoconnect]"
print " connect <service>"
print " disconnect <service>"
print " remove <service>"
print ""
- print " scan <type>"
+ print " scan [type]"
print " enable <type>"
print " disable <type>"
print " offlinemode [on|off]"
sys.exit(1)
def print_services(services):
- for path, properties in services:
+ for path in services:
+ service = dbus.Interface(bus.get_object("net.connman", path),
+ "net.connman.Service")
+
+ properties = service.GetProperties()
+
identifier = path[path.rfind("/") + 1:]
- state = " "
- autoconnect = " "
if properties["Favorite"] == dbus.Boolean(1):
favorite = "*"
-
- if properties["AutoConnect"] == dbus.Boolean(1):
- autoconnect = " A"
- else:
- autoconnect = " "
-
- if properties["State"] == "ready":
- state = "R"
- elif properties["State"] == "online":
- state = "O"
else:
favorite = " "
else:
name = "{" + properties["Type"] + "}"
- print "%s%s%s %-26s { %s }" % (favorite, autoconnect, state,
- name, identifier)
+ print "%s %-26s { %s }" % (favorite, name, identifier)
if sys.argv[1] == "state":
properties = manager.GetProperties()
print "System is %s" % (properties["State"])
elif sys.argv[1] in ["services", "list", "show"]:
- print_services(manager.GetServices())
+ properties = manager.GetProperties()
+
+ print_services(properties["Services"])
+
+elif sys.argv[1] in ["passphrase", "pass"]:
+ if (len(sys.argv) < 3):
+ print "Need at least service parameter"
+ sys.exit(1)
+
+ path = "/net/connman/service/" + sys.argv[2]
+
+ service = dbus.Interface(bus.get_object("net.connman", path),
+ "net.connman.Service")
+
+ if (len(sys.argv) > 3):
+ passphrase = sys.argv[3]
+
+ service.SetProperty("Passphrase", passphrase);
+
+ print "Passphrase %s set for %s" % (passphrase, sys.argv[2])
+ else:
+ properties = service.GetProperties()
+
+ if "Name" in properties.keys():
+ name = properties["Name"]
+ else:
+ name = "{" + properties["Type"] + "}"
+
+ if "Passphrase" in properties.keys():
+ passphrase = properties["Passphrase"]
+ else:
+ passphrase = "not set"
+
+ print "Passphrase for %s is %s" % (name, passphrase)
elif sys.argv[1] in ["autoconnect", "autoconn"]:
if (len(sys.argv) < 3):
elif sys.argv[1] == "scan":
if len(sys.argv) > 2:
- path = "/net/connman/technology/" + sys.argv[2]
- technology = dbus.Interface(bus.get_object("net.connman", path),
- "net.connman.Technology")
- technology.Scan()
+ manager.RequestScan(sys.argv[2])
+ else:
+ manager.RequestScan("")
elif sys.argv[1] == "enable":
if len(sys.argv) > 2:
- path = "/net/connman/technology/" + sys.argv[2]
- technology = dbus.Interface(bus.get_object("net.connman", path),
- "net.connman.Technology")
- technology.SetProperty("Powered", True)
+ manager.EnableTechnology(sys.argv[2])
+ else:
+ manager.EnableTechnology("")
elif sys.argv[1] == "disable":
if len(sys.argv) > 2:
- path = "/net/connman/technology/" + sys.argv[2]
- technology = dbus.Interface(bus.get_object("net.connman", path),
- "net.connman.Technology")
- technology.SetProperty("Powered", False)
+ manager.DisableTechnology(sys.argv[2])
+ else:
+ manager.DisableTechnology("")
elif sys.argv[1] in ["offlinemode", "flightmode"]:
if len(sys.argv) > 2:
properties = manager.GetProperties()
+def print_properties(key, value):
+ if key == "Profiles":
+ interface = "net.connman.Profile"
+ elif key == "Services":
+ interface = "net.connman.Service"
+ elif key == "Technologies":
+ interface = "net.connman.Technology"
+ else:
+ return
+
+ print "%s" % (key)
+ for path in value:
+ print " %s" % (path)
+ obj = dbus.Interface(bus.get_object("net.connman", path),
+ interface)
+
+ properties = obj.GetProperties()
+
+ for key in properties.keys():
+ if key in ["Services", "Technologies"]:
+ continue
+
+ elif key in ["Powered", "Scanning", "Connected",
+ "Available", "Remember", "Default",
+ "Favorite", "Immutable", "AutoConnect",
+ "LoginRequired",
+ "PassphraseRequired"]:
+ if properties[key] == dbus.Boolean(1):
+ val = "true"
+ else:
+ val = "false"
+
+ elif key in ["IPv4", "IPv4.Configuration",
+ "IPv6", "IPv6.Configuration",
+ "Proxy", "Proxy.Configuration",
+ "Ethernet", "Provider"]:
+ val = extract_values(properties[key])
+
+ elif key in ["Nameservers", "Nameservers.Configuration",
+ "Domains", "Domains.Configuration",
+ "Security"]:
+ val = extract_list(properties[key])
+
+ elif key in ["Strength", "Priority"]:
+ val = int(properties[key])
+
+ elif key in ["Tethering"]:
+ if properties[key] == dbus.Boolean(1):
+ val = "true"
+ else:
+ val = "false"
+ else:
+ val = str(properties[key])
+
+ print " %s = %s" % (key, val)
+
+ if "Services" in properties.keys():
+ list = ""
+ for path in properties["Services"]:
+ val = str(path)
+ list = list + val[val.rfind("/") + 1:] + " "
+ print " Services = [ %s]" % (list)
+
+
for key in properties.keys():
- if key in ["OfflineMode", "SessionMode"]:
+ if key in ["Profiles", "Services", "Technologies"]:
+ print_properties(key, properties[key])
+ elif key in ["AvailableTechnologies", "EnabledTechnologies",
+ "ConnectedTechnologies",
+ "AvailableDebugs", "EnabledDebugs"]:
+ print "%s" % (key)
+ list = ""
+ for val in properties[key]:
+ list = list + val + " "
+ print " [ %s]" % (list)
+ elif key in ["OfflineMode", "Tethering"]:
print "%s" % (key)
if properties[key] == dbus.Boolean(1):
print " true"
else:
print " false"
+ elif key in ["DefaultTechnology"]:
+ print "%s" % (key)
+ if properties[key] == "":
+ print " <none>"
+ else:
+ print " %s" % (properties[key])
else:
print "%s" % (key)
print " %s" % (properties[key])
-
-print ("Services")
-services = manager.GetServices()
-
-for (path, properties) in services:
- print " %s" % (path)
- for key in properties.keys():
- if key in ["Available", "Remember", "Default",
- "Favorite", "Immutable", "AutoConnect",
- "LoginRequired",
- "PassphraseRequired"]:
- if properties[key] == dbus.Boolean(1):
- val = "true"
- else:
- val = "false"
-
- elif key in ["IPv4", "IPv4.Configuration",
- "IPv6", "IPv6.Configuration",
- "Proxy", "Proxy.Configuration",
- "Ethernet", "Provider"]:
- val = extract_values(properties[key])
-
- elif key in ["Nameservers", "Nameservers.Configuration",
- "Domains", "Domains.Configuration",
- "Security"]:
- val = extract_list(properties[key])
-
- elif key in ["Strength", "Priority"]:
- val = int(properties[key])
-
- else:
- val = str(properties[key])
-
- print " %s = %s" % (key, val)
-
-print ("Technologies")
-technologies = manager.GetTechnologies()
-
-for (path, properties) in technologies:
- print " %s" % (path)
- for key in properties.keys():
-
- if key in ["Connected", "Powered", "Tethering"]:
- if properties[key] == dbus.Boolean(1):
- val = "true"
- else:
- val = "false"
- else:
- val = properties[key]
-
- print " %s = %s" % (key, val)
bus.watch_name_owner('net.connman', self.connman_name_owner_changed)
except dbus.DBusException:
traceback.print_exc()
+ exit(1)
def connman_name_owner_changed(self, proxy):
try:
except dbus.DBusException:
traceback.print_exc()
+ exit(1)
def release(self, session_name):
s = self.find_session(session_name)
del self.sessions[session_name]
def type_convert(self, key, value):
- if key in [ "AllowedBearers" ]:
+ if key in [ "AllowedBearers", "RoamingPolicy" ]:
return value
- elif key in [ "RoamingPolicy", "ConnectionType" ]:
- if len(value) > 0:
- return value[0]
elif key in [ "Priority", "AvoidHandover",
"StayConnected", "EmergencyCall" ]:
flag = str(value[0]).strip().lower()
print e.get_dbus_message()
return
traceback.print_exc()
+ exit(1)
@dbus.service.method("com.example.TestSession",
in_signature='', out_signature='')
self.release(session_name)
except dbus.DBusException:
traceback.print_exc()
+ exit(1)
@dbus.service.method("com.example.TestSession",
in_signature='', out_signature='')
print e.get_dbus_message()
return
traceback.print_exc()
+ exit(1)
@dbus.service.method("com.example.TestSession",
in_signature='', out_signature='')
print e.get_dbus_message()
return
traceback.print_exc()
+ exit(1)
@dbus.service.method("com.example.TestSession",
in_signature='', out_signature='')
print e.get_dbus_message()
return
traceback.print_exc()
+ exit(1)
@dbus.service.method("com.example.TestSession",
in_signature='', out_signature='')
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
--- /dev/null
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/sendfile.h>
+#include <sys/socket.h>
+#include <linux/if_alg.h>
+
+static void build_hash(int sk, int fd, size_t size, const char *pathname)
+{
+ unsigned char hash[20];
+ ssize_t written, length;
+ int i;
+
+ written = sendfile(sk, fd, NULL, size);
+ if (written < 0)
+ perror("Failed to write data");
+
+ printf("send %zd bytes\n", written);
+
+ length = recv(sk, hash, sizeof(hash), 0);
+ if (length < 0)
+ perror("Failed to read data");
+
+ printf("recv %zd bytes\n", length);
+
+ for (i = 0; i < length; i++)
+ printf("%02x", hash[i]);
+ printf(" %s\n", pathname);
+}
+
+static int create_hash(int sk, const char *pathname)
+{
+ struct stat st;
+ int fd;
+
+ fd = open(pathname, O_RDONLY | O_CLOEXEC);
+ if (fd < 0)
+ return -1;
+
+ if (fstat(fd, &st) < 0) {
+ close(fd);
+ return -1;
+ }
+
+ build_hash(sk, fd, st.st_size, pathname);
+
+ close(fd);
+
+ return 0;
+}
+
+static int create_socket(void)
+{
+ struct sockaddr_alg salg = {
+ .salg_family = AF_ALG,
+ .salg_type = "hash",
+ .salg_name = "sha1",
+ };
+ int sk, nsk;
+
+ sk = socket(PF_ALG, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
+ if (sk < 0) {
+ perror("Failed to create socket");
+ return -1;
+ }
+
+ if (bind(sk, (struct sockaddr *) &salg, sizeof(salg)) < 0) {
+ perror("Failed to bind socket");
+ close(sk);
+ return -1;
+ }
+
+ nsk = accept(sk, NULL, 0);
+ if (nsk < 0) {
+ perror("Failed to accept socket");
+ close(sk);
+ return -1;
+ }
+
+ close(sk);
+
+ return nsk;
+}
+
+int main(int argc, char *argv[])
+{
+ int sk;
+
+ if (argc < 2) {
+ fprintf(stderr, "Missing argument\n");
+ return 1;
+ }
+
+ sk = create_socket();
+ if (sk < 0)
+ return 1;
+
+ create_hash(sk, argv[1]);
+
+ close(sk);
+
+ return 0;
+}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
/*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2011 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
if (new_entry == NULL)
return -EINVAL;
- if (builtin == -1)
- chain_head = chain_head->next;
-
- ret = connman_add_entry(table, new_entry, chain_head, builtin);
+ ret = connman_add_entry(table, new_entry, chain_head->next, builtin);
if (ret < 0)
g_free(new_entry);
return TRUE;
}
-static GList *find_existing_rule(struct connman_iptables *table,
+static int connman_iptables_delete_rule(struct connman_iptables *table,
struct ipt_ip *ip, char *chain_name,
char *target_name, struct xtables_target *xt_t,
struct xtables_match *xt_m,
struct xt_entry_match *xt_e_m = NULL;
struct connman_iptables_entry *entry;
struct ipt_entry *entry_test;
- int builtin;
+ int builtin, removed;
+
+ removed = 0;
chain_head = find_chain_head(table, chain_name);
if (chain_head == NULL)
- return NULL;
+ return -EINVAL;
chain_tail = find_chain_tail(table, chain_name);
if (chain_tail == NULL)
- return NULL;
+ return -EINVAL;
if (!xt_t && !xt_m)
- return NULL;
+ return -EINVAL;
entry_test = new_rule(ip, target_name, xt_t, xt_rm);
if (entry_test == NULL)
- return NULL;
+ return -EINVAL;
if (xt_t != NULL)
xt_e_t = ipt_get_target(entry_test);
else
list = chain_head->next;
- for (; list != chain_tail->prev; list = list->next) {
+ for (entry = NULL; list != chain_tail->prev; list = list->next) {
struct connman_iptables_entry *tmp;
struct ipt_entry *tmp_e;
continue;
}
+ entry = tmp;
break;
}
- g_free(entry_test);
-
- if (list != chain_tail->prev)
- return list;
-
- return NULL;
-}
-
-static int connman_iptables_delete_rule(struct connman_iptables *table,
- struct ipt_ip *ip, char *chain_name,
- char *target_name, struct xtables_target *xt_t,
- struct xtables_match *xt_m,
- struct xtables_rule_match *xt_rm)
-{
- struct connman_iptables_entry *entry;
- GList *chain_tail, *list;
- int builtin, removed;
-
- removed = 0;
-
- chain_tail = find_chain_tail(table, chain_name);
- if (chain_tail == NULL)
- return -EINVAL;
-
- list = find_existing_rule(table, ip, chain_name, target_name,
- xt_t, xt_m, xt_rm);
- if (list == NULL)
- return -EINVAL;
-
- entry = list->data;
-
- if (entry == NULL)
+ if (entry == NULL) {
+ g_free(entry_test);
return -EINVAL;
-
- builtin = entry->builtin;
+ }
/* We have deleted a rule,
* all references should be bumped accordingly */
return 0;
}
-static int connman_iptables_compare_rule(struct connman_iptables *table,
- struct ipt_ip *ip, char *chain_name,
- char *target_name, struct xtables_target *xt_t,
- struct xtables_match *xt_m,
- struct xtables_rule_match *xt_rm)
-{
- struct connman_iptables_entry *entry;
- GList *found;
-
- found = find_existing_rule(table, ip, chain_name, target_name,
- xt_t, xt_m, xt_rm);
- if (found == NULL)
- return -EINVAL;
-
- entry = found->data;
- if (entry == NULL)
- return -EINVAL;
-
- return 0;
-}
-
-
static int connman_iptables_change_policy(struct connman_iptables *table,
char *chain_name, char *policy)
{
static struct option connman_iptables_opts[] = {
{.name = "append", .has_arg = 1, .val = 'A'},
- {.name = "compare", .has_arg = 1, .val = 'C'},
{.name = "delete", .has_arg = 1, .val = 'D'},
{.name = "flush-chain", .has_arg = 1, .val = 'F'},
{.name = "insert", .has_arg = 1, .val = 'I'},
return xt_m;
}
-static int parse_ip_and_mask(const char *str, struct in_addr *ip, struct in_addr *mask)
-{
- char **tokens;
- uint32_t prefixlength;
- uint32_t tmp;
- int err;
-
- tokens = g_strsplit(str, "/", 2);
- if (tokens == NULL)
- return -1;
-
- if (!inet_pton(AF_INET, tokens[0], ip)) {
- err = -1;
- goto out;
- }
-
- if (tokens[1] != NULL) {
- prefixlength = strtol(tokens[1], NULL, 10);
- if (prefixlength > 31) {
- err = -1;
- goto out;
- }
-
- tmp = ~(0xffffffff >> prefixlength);
- } else {
- tmp = 0xffffffff;
- }
-
- mask->s_addr = htonl(tmp);
- ip->s_addr = ip->s_addr & mask->s_addr;
- err = 0;
-out:
- g_strfreev(tokens);
-
- return err;
-}
-
int main(int argc, char *argv[])
{
struct connman_iptables *table;
char *table_name, *chain, *new_chain, *match_name, *target_name;
char *delete_chain, *flush_chain, *policy;
int c, in_len, out_len;
- gboolean dump, invert, delete, insert, delete_rule, compare_rule;
+ gboolean dump, invert, delete, insert, delete_rule;
+ struct in_addr src, dst;
xtables_init_all(&connman_iptables_globals, NFPROTO_IPV4);
delete = FALSE;
insert = FALSE;
delete_rule = FALSE;
- compare_rule = FALSE;
- chain = new_chain = match_name = target_name = NULL;
+ table_name = chain = new_chain = match_name = target_name = NULL;
delete_chain = flush_chain = policy = NULL;
memset(&ip, 0, sizeof(struct ipt_ip));
table = NULL;
/* extension's options will generate false-positives errors */
opterr = 0;
- while ((c = getopt_long(argc, argv,
- "-A:C:D:F:I:L::N:P:X:d:i:j:m:o:s:t:",
+ while ((c = getopt_long(argc, argv, "-A:D:F:I:L::N:P:X:d:i:j:m:o:s:t:",
connman_iptables_globals.opts, NULL)) != -1) {
switch (c) {
case 'A':
- /* It is either -A, -C, -D or -I at once */
- if (chain)
- goto out;
-
- chain = optarg;
- break;
-
- case 'C':
- /* It is either -A, -C, -D or -I at once */
+ /* It is either -A, -D or -I at once */
if (chain)
goto out;
chain = optarg;
- compare_rule = TRUE;
break;
case 'D':
- /* It is either -A, -C, -D or -I at once */
+ /* It is either -A, -D or -I at once */
if (chain)
goto out;
break;
case 'I':
- /* It is either -A, -C, -D or -I at once */
+ /* It is either -A, -D or -I at once */
if (chain)
goto out;
break;
case 'd':
- if (!parse_ip_and_mask(optarg, &ip.dst, &ip.dmsk))
+ if (!inet_pton(AF_INET, optarg, &dst))
break;
+ ip.dst = dst;
+ inet_pton(AF_INET, "255.255.255.255", &ip.dmsk);
+
if (invert)
ip.invflags |= IPT_INV_DSTIP;
-
break;
case 'i':
break;
case 's':
- if (!parse_ip_and_mask(optarg, &ip.src, &ip.smsk))
+ if (!inet_pton(AF_INET, optarg, &src))
break;
+ ip.src = src;
+ inet_pton(AF_INET, "255.255.255.255", &ip.smsk);
+
if (invert)
ip.invflags |= IPT_INV_SRCIP;
goto commit;
}
- if (compare_rule == TRUE) {
- int ret;
-
- ret = connman_iptables_compare_rule(table, &ip,
- chain, target_name, xt_t, xt_m, xt_rm);
-
- if (ret == 0)
- printf("Rule exists.\n");
- else
- printf("Rule does not exist.\n");
-
- goto out;
- }
-
if (delete_rule == TRUE) {
printf("Deleting %s to %s (match %s)\n", target_name,
chain, match_name);
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2011 Intel Corporation. All rights reserved.
* Copyright (C) 2011 ProFUSION embedded systems
*
* This program is free software; you can redistribute it and/or modify
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
}
}
+ buf += 2 + (count * 4);
+ len -= 2 + (count * 4);
}
static void bss_rates(DBusMessageIter *iter, void *user_data)
const char *path = NULL;
int err;
- if (error != NULL)
+ if (error != NULL) {
+ err = -EIO;
goto create;
+ }
dbus_message_iter_get_basic(iter, &path);
if (path == NULL) {
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
timer = g_timer_new();
- if (g_web_request_get(web, argv[1], web_result, NULL, NULL) == 0) {
+ if (g_web_request_get(web, argv[1], web_result, NULL) == 0) {
fprintf(stderr, "Failed to start request\n");
return 1;
}
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <string.h>
#include <signal.h>
#include <termios.h>
-#include <netdb.h>
#include <gweb/gweb.h>
result = g_markup_parse_context_parse(context, str, strlen(str), NULL);
if (result == TRUE)
- g_markup_parse_context_end_parse(context, NULL);
+ result = g_markup_parse_context_end_parse(context, NULL);
g_markup_parse_context_free(context);
}
return FALSE;
}
-static gboolean wispr_route(const char *addr, int ai_family, int if_index,
- gpointer user_data)
-{
- char *family = "unknown";
-
- if (ai_family == AF_INET)
- family = "IPv4";
- else if (ai_family == AF_INET6)
- family = "IPv6";
-
- printf("Route request: %s %s index %d\n", family, addr, if_index);
-
- if (ai_family != AF_INET && ai_family != AF_INET6)
- return FALSE;
-
- return TRUE;
-}
-
static gboolean wispr_result(GWebResult *result, gpointer user_data)
{
struct wispr_session *wispr = user_data;
printf("\n");
wispr->request = g_web_request_get(wispr->web, redirect,
- wispr_result, wispr_route, wispr);
+ wispr_result, wispr);
return FALSE;
}
printf("\n");
wispr->request = g_web_request_get(wispr->web, redirect,
- wispr_result, NULL, wispr);
+ wispr_result, wispr);
return FALSE;
}
parser_callback, &wispr);
wispr.request = g_web_request_get(wispr.web, option_url,
- wispr_result, wispr_route, &wispr);
+ wispr_result, &wispr);
if (wispr.request == 0) {
fprintf(stderr, "Failed to start request\n");
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include "test-connman.h"
-static enum connman_session_state string2state(const char *state)
-{
- if (g_strcmp0(state, "connected") == 0)
- return CONNMAN_SESSION_STATE_CONNECTED;
- if (g_strcmp0(state, "online") == 0)
- return CONNMAN_SESSION_STATE_ONLINE;
-
- return CONNMAN_SESSION_STATE_DISCONNECTED;
-}
-
-static enum connman_session_state string2type(const char *type)
-{
- if (g_strcmp0(type, "local") == 0)
- return CONNMAN_SESSION_TYPE_LOCAL;
- if (g_strcmp0(type, "internet") == 0)
- return CONNMAN_SESSION_TYPE_INTERNET;
-
- return CONNMAN_SESSION_TYPE_ANY;
-}
-
static const char *roamingpolicy2string(enum connman_session_roaming_policy policy)
{
switch (policy) {
}
break;
case DBUS_TYPE_BOOLEAN:
- if (g_str_equal(key, "Priority") == TRUE) {
+ if (g_str_equal(key, "Online") == TRUE) {
+ dbus_message_iter_get_basic(&value,
+ &info->online);
+ } else if (g_str_equal(key, "Priority") == TRUE) {
dbus_message_iter_get_basic(&value,
&info->priority);
}
break;
case DBUS_TYPE_STRING:
- if (g_str_equal(key, "State") == TRUE) {
- const char *val;
- dbus_message_iter_get_basic(&value, &val);
-
- info->state = string2state(val);
- } else if (g_str_equal(key, "Bearer") == TRUE) {
+ if (g_str_equal(key, "Bearer") == TRUE) {
const char *val;
dbus_message_iter_get_basic(&value, &val);
info->interface = g_strdup(val);
- } else if (g_str_equal(key, "ConnectionType")
- == TRUE) {
- const char *val;
- dbus_message_iter_get_basic(&value, &val);
-
- info->type = string2type(val);
} else {
g_assert(FALSE);
return __connman_error_invalid_arguments(msg);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
-static const GDBusMethodTable notify_methods[] = {
- { GDBUS_METHOD("Release", NULL, NULL, notify_release) },
- { GDBUS_METHOD("Update",
- GDBUS_ARGS({ "settings", "a{sv}" }), NULL,
- notify_update) },
+static GDBusMethodTable notify_methods[] = {
+ { "Release", "", "", notify_release },
+ { "Update", "a{sv}", "", notify_update },
{ },
};
*
* Connection Manager
*
- * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
typedef void (* notify_cb) (struct test_session *session);
-enum connman_session_state {
- CONNMAN_SESSION_STATE_DISCONNECTED = 0,
- CONNMAN_SESSION_STATE_CONNECTED = 1,
- CONNMAN_SESSION_STATE_ONLINE = 2,
-};
-
-enum connman_session_type {
- CONNMAN_SESSION_TYPE_ANY = 0,
- CONNMAN_SESSION_TYPE_LOCAL = 1,
- CONNMAN_SESSION_TYPE_INTERNET = 2,
-};
-
enum connman_session_roaming_policy {
CONNMAN_SESSION_ROAMING_POLICY_UNKNOWN = 0,
CONNMAN_SESSION_ROAMING_POLICY_DEFAULT = 1,
struct test_session_info {
char *bearer;
- enum connman_session_state state;
- enum connman_session_type type;
+ connman_bool_t online;
char *name;
/* ipv4, ipv6 dicts */
GSList *allowed_bearers;
+++ /dev/null
-/*
- *
- * Connection Manager
- *
- * Copyright (C) 2012 BWM CarIT GmbH. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-
-#include "../src/connman.h"
-
-/* #define DEBUG */
-#ifdef DEBUG
-#include <stdio.h>
-
-#define LOG(fmt, arg...) do { \
- fprintf(stdout, "%s:%s() " fmt "\n", \
- __FILE__, __func__ , ## arg); \
-} while (0)
-#else
-#define LOG(fmt, arg...)
-#endif
-
-static void test_ippool_basic0(void)
-{
- struct connman_ippool *pool;
- int i;
-
- __connman_ippool_init();
-
- pool = __connman_ippool_create(23, 1, 500, NULL, NULL);
- g_assert(pool == NULL);
-
- for (i = 0; i < 100000; i++) {
- pool = __connman_ippool_create(23, 1, 20, NULL, NULL);
- g_assert(pool);
-
- __connman_ippool_unref(pool);
- }
-
- __connman_ippool_cleanup();
-}
-
-static void test_ippool_basic1(void)
-{
- struct connman_ippool *pool;
- const char *gateway;
- const char *broadcast;
- const char *subnet_mask;
- const char *start_ip;
- const char *end_ip;
- int i;
-
- __connman_ippool_init();
-
- /* Test the IP range */
- for (i = 1; i < 254; i++) {
- pool = __connman_ippool_create(23, 1, i, NULL, NULL);
- g_assert(pool);
-
- gateway = __connman_ippool_get_gateway(pool);
- broadcast = __connman_ippool_get_broadcast(pool);
- subnet_mask = __connman_ippool_get_subnet_mask(pool);
- start_ip = __connman_ippool_get_start_ip(pool);
- end_ip = __connman_ippool_get_end_ip(pool);
-
- g_assert(gateway);
- g_assert(broadcast);
- g_assert(subnet_mask);
- g_assert(start_ip);
- g_assert(end_ip);
-
- LOG("\n\tIP range %s --> %s\n"
- "\tgateway %s broadcast %s mask %s", start_ip, end_ip,
- gateway, broadcast, subnet_mask);
-
- __connman_ippool_unref(pool);
- }
-
- __connman_ippool_cleanup();
-}
-
-static void test_ippool_exhaust0(void)
-{
- struct connman_ippool *pool;
- const char *gateway;
- const char *broadcast;
- const char *subnet_mask;
- const char *start_ip;
- const char *end_ip;
- GSList *list = NULL, *it;
- int i = 0;
-
- __connman_ippool_init();
-
- /* Allocate all possible pools */
-
- /*
- * Number of addresses
- * 24-bit block 10.0.0.0 – 10.255.255.255 16,777,216
- * 20-bit block 172.16.0.0 – 172.31.255.255 1,048,576
- * 16-bit block 192.168.0.0 – 192.168.255.255 65,536
- *
- * Total 17,891,328
- *
- * Total numbers of 256 blocks: 69,888
- */
-
- while (TRUE) {
- pool = __connman_ippool_create(23, 1, 100, NULL, NULL);
- if (pool == NULL)
- break;
- i += 1;
- g_assert(i < 69888);
-
- list = g_slist_prepend(list, pool);
-
- gateway = __connman_ippool_get_gateway(pool);
- broadcast = __connman_ippool_get_broadcast(pool);
- subnet_mask = __connman_ippool_get_subnet_mask(pool);
- start_ip = __connman_ippool_get_start_ip(pool);
- end_ip = __connman_ippool_get_end_ip(pool);
-
- g_assert(gateway);
- g_assert(broadcast);
- g_assert(subnet_mask);
- g_assert(start_ip);
- g_assert(end_ip);
- }
-
- LOG("Number of blocks %d", i);
-
- for (it = list; it != NULL; it = it->next) {
- pool = it->data;
-
- __connman_ippool_unref(pool);
- }
-
- g_slist_free(list);
-
- __connman_ippool_cleanup();
-}
-
-static void collision_cb(struct connman_ippool *pool, void *user_data)
-{
- int *flag = user_data;
-
- LOG("collision detected");
-
- g_assert(*flag == 0);
- g_assert(pool);
-
- *flag = 1;
-}
-
-static void test_ippool_collision0(void)
-{
- struct connman_ippool *pool;
- const char *gateway;
- const char *broadcast;
- const char *subnet_mask;
- const char *start_ip;
- const char *end_ip;
- int flag;
-
- __connman_ippool_init();
-
- /* Test the IP range collision */
-
- flag = 0;
- pool = __connman_ippool_create(23, 1, 100, collision_cb, &flag);
- g_assert(pool);
-
- gateway = __connman_ippool_get_gateway(pool);
- broadcast = __connman_ippool_get_broadcast(pool);
- subnet_mask = __connman_ippool_get_subnet_mask(pool);
- start_ip = __connman_ippool_get_start_ip(pool);
- end_ip = __connman_ippool_get_end_ip(pool);
-
- g_assert(gateway);
- g_assert(broadcast);
- g_assert(subnet_mask);
- g_assert(start_ip);
- g_assert(end_ip);
-
- LOG("\n\tIP range %s --> %s\n"
- "\tgateway %s broadcast %s mask %s", start_ip, end_ip,
- gateway, broadcast, subnet_mask);
-
- __connman_ippool_newaddr(23, start_ip, 24);
-
- g_assert(flag == 0);
-
- __connman_ippool_newaddr(42, start_ip, 16);
-
- g_assert(flag == 1);
-
- __connman_ippool_unref(pool);
-
- flag = 0;
-
- pool = __connman_ippool_create(23, 1, 100, collision_cb, &flag);
- g_assert(pool);
-
- gateway = __connman_ippool_get_gateway(pool);
- broadcast = __connman_ippool_get_broadcast(pool);
- subnet_mask = __connman_ippool_get_subnet_mask(pool);
- start_ip = __connman_ippool_get_start_ip(pool);
- end_ip = __connman_ippool_get_end_ip(pool);
-
- g_assert(gateway);
- g_assert(broadcast);
- g_assert(subnet_mask);
- g_assert(start_ip);
- g_assert(end_ip);
-
- LOG("\n\tIP range %s --> %s\n"
- "\tgateway %s broadcast %s mask %s", start_ip, end_ip,
- gateway, broadcast, subnet_mask);
-
- __connman_ippool_newaddr(45, start_ip, 22);
-
- g_assert(flag == 1);
-
- __connman_ippool_unref(pool);
-
- __connman_ippool_cleanup();
-}
-
-int main(int argc, char *argv[])
-{
- g_test_init(&argc, &argv, NULL);
-
- g_test_add_func("/basic0", test_ippool_basic0);
- g_test_add_func("/basic1", test_ippool_basic1);
- g_test_add_func("/exhaust0", test_ippool_exhaust0);
- g_test_add_func("/collision0", test_ippool_collision0);
-
- return g_test_run();
-}
+++ /dev/null
-/*
- *
- * Connection Manager
- *
- * Copyright (C) 2012 BWM CarIT GmbH. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-
-#include "../src/connman.h"
-
-/* #define DEBUG */
-#ifdef DEBUG
-#include <stdio.h>
-
-#define LOG(fmt, arg...) do { \
- fprintf(stdout, "%s:%s() " fmt "\n", \
- __FILE__, __func__ , ## arg); \
-} while (0)
-#else
-#define LOG(fmt, arg...)
-#endif
-
-struct connman_notifier *nat_notifier;
-
-struct connman_service {
- char *dummy;
-};
-
-char *connman_service_get_interface(struct connman_service *service)
-{
- return "eth0";
-}
-
-int connman_notifier_register(struct connman_notifier *notifier)
-{
- nat_notifier = notifier;
-
- return 0;
-}
-
-void connman_notifier_unregister(struct connman_notifier *notifier)
-{
- nat_notifier = NULL;
-}
-
-
-static void test_iptables_basic0(void)
-{
- int err;
-
- err = __connman_iptables_command("-C INPUT -i session-bridge -j ACCEPT");
- g_assert(err != 0);
- err = __connman_iptables_commit("filter");
- g_assert(err == 0);
-
- err = __connman_iptables_command("-I INPUT -i session-bridge -j ACCEPT");
- g_assert(err == 0);
- err = __connman_iptables_commit("filter");
- g_assert(err == 0);
-
- err = __connman_iptables_command("-C INPUT -i session-bridge -j ACCEPT");
- g_assert(err == 0);
- err = __connman_iptables_commit("filter");
- g_assert(err == 0);
-
- err = __connman_iptables_command("-D INPUT -i session-bridge -j ACCEPT");
- g_assert(err == 0);
- err = __connman_iptables_commit("filter");
- g_assert(err == 0);
-
- err = __connman_iptables_command("-C INPUT -i session-bridge -j ACCEPT");
- g_assert(err != 0);
- err = __connman_iptables_commit("filter");
- g_assert(err == 0);
-}
-
-static void test_nat_basic0(void)
-{
- int err;
-
- err = __connman_nat_enable("bridge", "192.168.2.1", 24);
- g_assert(err == 0);
-
- /* test that table is empty */
- err = __connman_iptables_command("-t nat -C POSTROUTING "
- "-s 192.168.2.1/24 -o eth0 -j MASQUERADE");
- g_assert(err != 0);
- err = __connman_iptables_commit("nat");
- g_assert(err == 0);
-
-
- __connman_nat_disable("bridge");
-}
-
-static void test_nat_basic1(void)
-{
- struct connman_service *service;
- int err;
-
- service = g_try_new0(struct connman_service, 1);
- g_assert(service);
-
- nat_notifier->default_changed(service);
-
- err = __connman_nat_enable("bridge", "192.168.2.1", 24);
- g_assert(err == 0);
-
- /* test that table is not empty */
- err = __connman_iptables_command("-t nat -C POSTROUTING "
- "-s 192.168.2.1/24 -o eth0 -j MASQUERADE");
- g_assert(err == 0);
- err = __connman_iptables_commit("nat");
- g_assert(err == 0);
-
- __connman_nat_disable("bridge");
-
- /* test that table is empty again */
- err = __connman_iptables_command("-t nat -C POSTROUTING "
- "-s 192.168.2.1/24 -o eth0 -j MASQUERADE");
- g_assert(err != 0);
- err = __connman_iptables_commit("nat");
- g_assert(err == 0);
-}
-
-int main(int argc, char *argv[])
-{
- int err;
-
- g_test_init(&argc, &argv, NULL);
-
- __connman_log_init(argv[0], "*", FALSE);
- __connman_iptables_init();
- __connman_nat_init();
-
- g_test_add_func("/iptables/basic0", test_iptables_basic0);
- g_test_add_func("/nat/basic0", test_nat_basic0);
- g_test_add_func("/nat/basic1", test_nat_basic1);
-
- err = g_test_run();
-
- __connman_nat_cleanup();
- __connman_iptables_cleanup();
- __connman_log_cleanup();
-
- return err;
-}
static void test_session_connect_notify(struct test_session *session)
{
- LOG("session %p state %d", session, session->info->state);
+ LOG("session %p online %d", session, session->info->online);
- if (session->info->state == CONNMAN_SESSION_STATE_DISCONNECTED)
+ if (session->info->online != TRUE)
return;
util_session_cleanup(session);
static void test_session_disconnect_notify(struct test_session *session)
{
- LOG("session %p state %d", session, session->info->state);
+ LOG("session %p online %d", session, session->info->online);
- if (session->info->state >= CONNMAN_SESSION_STATE_CONNECTED)
+ if (session->info->online != FALSE)
return;
util_session_cleanup(session);
enum test_session_state next_state = state;
DBusMessage *msg;
- LOG("state %d session %p %s state %d", state, session,
- session->notify_path, session->info->state);
+ LOG("state %d session %p %s online %d", state, session,
+ session->notify_path, session->info->online);
switch (state) {
case TEST_SESSION_STATE_0:
- if (session->info->state == CONNMAN_SESSION_STATE_DISCONNECTED)
+ if (session->info->online == FALSE)
next_state = TEST_SESSION_STATE_1;
break;
case TEST_SESSION_STATE_1:
- if (session->info->state >= CONNMAN_SESSION_STATE_CONNECTED)
+ if (session->info->online == TRUE)
next_state = TEST_SESSION_STATE_2;
break;
case TEST_SESSION_STATE_2:
- if (session->info->state == CONNMAN_SESSION_STATE_DISCONNECTED)
+ if (session->info->online == FALSE)
next_state = TEST_SESSION_STATE_3;
default:
break;
enum test_session_state next_state = state;
DBusMessage *msg;
- LOG("state %d session %p %s state %d", state, session,
- session->notify_path, session->info->state);
+ LOG("state %d session %p %s online %d", state, session,
+ session->notify_path, session->info->online);
switch (state) {
case TEST_SESSION_STATE_0:
- if (session0->info->state == CONNMAN_SESSION_STATE_DISCONNECTED
- && session1->info->state ==
- CONNMAN_SESSION_STATE_DISCONNECTED) {
+ if (session0->info->online == FALSE &&
+ session1->info->online == FALSE) {
next_state = TEST_SESSION_STATE_1;
}
break;
case TEST_SESSION_STATE_1:
- if (session0->info->state >= CONNMAN_SESSION_STATE_CONNECTED &&
- session1->info->state >=
- CONNMAN_SESSION_STATE_CONNECTED) {
+ if (session0->info->online == TRUE &&
+ session1->info->online == TRUE) {
next_state = TEST_SESSION_STATE_2;
}
break;
case TEST_SESSION_STATE_2:
- if (session0->info->state == CONNMAN_SESSION_STATE_DISCONNECTED
- && session1->info->state ==
- CONNMAN_SESSION_STATE_DISCONNECTED) {
+ if (session0->info->online == FALSE &&
+ session1->info->online == FALSE) {
next_state = TEST_SESSION_STATE_3;
}
connman_died,
NULL, NULL);
fix->manager_watch = g_dbus_add_signal_watch(fix->main_connection,
- CONNMAN_SERVICE, NULL,
+ NULL, NULL,
CONNMAN_MANAGER_INTERFACE,
PROPERTY_CHANGED,
handle_manager_changed,