diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..65fdc6a8e --- /dev/null +++ b/.gitignore @@ -0,0 +1,77 @@ +*.o +*.a +*.lo +*.la +.deps +.libs +.dirstamp +Makefile +Makefile.in +aclocal.m4 +config.guess +config.h +config.h.in +config.log +config.status +config.sub +configure +depcomp +compile +install-sh +libtool +ltmain.sh +missing +stamp-h1 +autom4te.cache + +connman.pc +include/connman +include/version.h +src/builtin.h +src/connmand +src/connman.conf +src/connman.service +src/*-connman.rules +plugins/connman.policy +scripts/connman +scripts/openconnect-script +scripts/openvpn-script +client/connmanctl +tools/wispr +tools/dhcp-test +tools/dhcp-server-test +tools/addr-test +tools/tap-test +tools/web-test +tools/wpad-test +tools/resolv-test +tools/polkit-test +tools/iptables-test +tools/iptables-unit +tools/dnsproxy-test +tools/supplicant-test +tools/dbus-test +tools/stats-tool +tools/stats-ringbuffer-dump +tools/private-network-test +tools/session-test +unit/test-ippool +unit/test-nat +unit/test-pbkdf2-sha1 +unit/test-prf-sha1 + +doc/*.bak +doc/*.stamp +doc/connman.* +!doc/connman.8 +!doc/connman.conf.5 +doc/connman-*.txt +doc/*.sgml +doc/version.xml +doc/xml +doc/html + +vpn/builtin.h +vpn/connman-vpnd +vpn/connman-vpn.service +vpn/net.connman.vpn.service diff --git a/.mailmap b/.mailmap new file mode 100644 index 000000000..93fae5996 --- /dev/null +++ b/.mailmap @@ -0,0 +1,4 @@ +Luiz Augusto von Dentz +Leena Gunda +Flávio Ceolin +Daniel Wagner diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..4eb89e751 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,54 @@ +Marcel Holtmann +Inaky Perez-Gonzalez +Samuel Ortiz +Joshua Lock +Richard Purdie +Gustavo Sverzut Barbieri +Martin Xu +Sam Leffler +Daniel Wagner +Forest Bond +Kalle Valo +Fabien Marotte +Pekka Pessi +Tomasz Bursztyka +Cristiano Fernandes +Joey Lee +Leena Gunda +Patrik Flykt +David Woodhouse +Gustavo Padovan +Julien Massot +Jukka Rissanen +Grant Erickson +Guillaume Lucas +Henri Bragge +Alok Barsode +Sébastien Bianti +Yu A Wang +Thierry Boureille +Paolo Pellegrino +Bertrand Aygon +Jeff Zheng +Philippe Nunes +Danny Jeongseok Seo +Flávio Ceolin +Arjan van de Ven +Daniel Mack +Guillaume Zajac +Manfred Kober +Mario Domenech Goulart +Otavio Salvador +Tim Sander +Adrien Bustany +Henrique Dante de Almeida +Lucas De Marchi +Elena Tebesoi +Mikel Astiz +Paulo Pizarro +Ross Burton +Tudor Marcu +Ceara Chewning +Johannes Berg +Justin Maggard +Yann E. Morin diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..6d45519c8 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 000000000..a1340afcc --- /dev/null +++ b/ChangeLog @@ -0,0 +1,878 @@ +ver 1.15: + Fix issue with missing cleanup for IPv4-LL handling. + Fix issue with missing property update for domain names. + Fix issue with scanning for all stored hidden WiFi networks. + Fix issue with time server polling for non-default service. + Fix issue with persistent storage of time configuration. + +ver 1.14: + Fix issue with WiFi scanning race condition and power cycle. + Add support for configuring allowed tethering technologies. + Add support for persistent tethering configurations. + Add support for DHCPv6 max retransmission duration option. + Add support for DHCPv6 elapsed time option. + Add support for DHCPv6 confirm messages. + +ver 1.13: + Fix issue with auto-scanning of known hidden SSIDs. + Fix issue with not correctly terminated auto-scanning. + Fix issue with missing enforcing of immutable services. + Fix issue with missing handling of multiple connection attempts. + Fix issue with missing WISPr restart after nameserver change. + Fix issue with missing provisioning for IP address method. + Fix issue with missing IP configuration signal on disconnect. + Fix issue with DNS proxy and memory leaks on request timeouts. + Fix issue with DNS proxy and handling partial TCP messages. + Fix issue with DNS proxy and handling of EDNS0 buffers. + Fix issue with DNS proxy and handling of IPv6 loopback. + Fix issue with DNS proxy listening on all interfaces. + Fix issue with CDMA network creation. + +ver 1.12: + Fix issue with overwriting gateway address. + Fix issue with missing IP address validation. + Fix issue with parsing of IPv6 configuration settings. + Fix issue with DHCP server address stored in host order. + Fix issue with resolver query failures and pending results. + Fix issue with wrongly reported max scan SSID parameter. + Fix issue with handling errors from WiFi fast scanning. + Add support for WiFi provisioning via NFC. + Add support for VPN daemon provisioning. + Add support for Ethernet provisioning. + +ver 1.11: + Fix issue with agent reference counting imbalance. + Fix issue with handling max number of SSID for scanning. + Fix issue with missing notification of online state changes. + Fix issue with not properly triggering auto-connect behavior. + Fix issue with disabling IPv6 in lower up interface states. + Fix issue with spurious error messages for interface handling. + Fix issue with wrong answer count in DNS responses. + Fix issue with crash in DNS lookup function. + Add support for BlueZ 5.x network interfaces. + Remove deprecated WiMAX support. + +ver 1.10: + Fix issue with not skipping service if settings loading fails. + Fix issue with not clearing address before starting DHCP. + Fix issue with not handling removal of GPRS context. + Fix issue with not closing UDP socket on error condition. + Fix issue with race condition when removing WiFi device. + Add support for separate VPN daemon. + +ver 1.9: + Fix issue with WISPr portal context handling. + Fix issue with DNS lookup from wrong queue. + Fix issue with DNS data reception after disconnect. + Fix issue with missing DNS host part length checking. + Fix issue with RFKILL and technology interaction. + Fix issue with tethering and disabled technologies. + Add support for single connected technology setting. + +ver 1.8: + Fix issue with NTP transmit time calculation. + Fix issue with WiFi Tethering and newer kernels. + Fix issue with Netlink messages from Wireless Extensions. + Fix issue with IPv6 nameserver refresh beeing applied to IPv4. + Fix issue with overwriting DNS proxy address information. + Fix issue with missing handling of RFKILL hard blocking. + Add support for disabling internal backtrace functionality. + +ver 1.7: + Fix issue with IPv4 address removal when setting interface down. + Fix issue with wrong error when setting tethering support option. + Fix issue with errors reported twice via agent to the client. + Fix issue with missing serialization of agent callbacks. + Add initial version of command line client tool. + +ver 1.6: + Fix issue with Bluetooth networking support. + Fix issue with technology enabling method returns. + Fix issue with wrong IP address for fixed configurations. + Fix issue with IP address setting when interface is down. + Fix issue with handling duplicate hidden WiFi networks. + Fix issue with missing scanning for hidden WiFi networks. + Fix issue with missing update of service properties. + Fix issue with missing clearing of service errors. + Add manual pages for daemon and configuration file. + +ver 1.5: + Fix issue with detecting Bluetooth networks when powered off. + Fix issue with connection attempts of non-favorite services. + Fix issue with connection attempts of disabled IP configurations. + Fix issue with missing auto-connection after changing IP method. + Fix issue with setting service state when changing IPv4 method. + Fix issue with IPv6 usage and static/manual configuration. + Add support for configuration option to disable hostname updates. + Add support for storing WiFi Tethering identifier and passphrase. + Add support for signaling changes of error property. + +ver 1.4: + Fix issue with WiFi scanning in Tethering mode. + Fix issue with WISPr operation and disconnects. + Fix issue with DHCP client and restart behavior. + Fix issue with DNS resolving and failing IPv6 records. + Fix issue with incorrect NTP leap-not-in-sync flag. + Fix issue with incorrect NTP transmit time value. + Fix issue with failing NTP server due to routing. + Fix issue with missing gateway change notification. + Fix issue with stale network interfaces at startup. + Fix issue with pending method reply and agent errors. + Add support for providing previous WPS PIN to agent. + Add support for WPA supplicant based auto-scanning. + Add support for per device regulatory domain setting. + Add support for provisioning hidden WiFi networks. + +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: + Fix multiple issues with service connection states. + Fix multiple issues with technology handling. + Fix issue with DHCP file descriptor leakage. + Fix issue with open access points and WPS. + Fix issue with handling of cellular devices. + Fix issue with DNS proxy hostname resolving. + Add support for PPTP and L2TP VPN tunneling. + Add support for organized settings storage. + Add support for WiFi fast connect handling. + Add support for better WiFi error handling. + Add support for integrated WISPr handling. + +ver 0.77: + Fix issue with iptables API breakage. + Fix issue with agent input handling. + Fix issue with empty cellular operator name. + Fix issue with reference counting for network objects. + Fix issue with missing D-Bus signals for proxy changes. + Fix issue with group identifier and hidden WiFi networks. + Fix issue with setting wrong gateway for PPP connections. + Fix issue with mismatch of stored IP configuration settings. + Fix issue with not stopping DHCP for IPv4 configuration. + Add support for remembering last IP address from DHCP. + Add support for EAP-GTC authentication method. + +ver 0.76: + Fix issue with loopback interface setup. + Fix issue with /etc/localtime being a symlink. + Fix issue with not handling dummy network devices. + Fix issue with not provisioning existing services. + Fix issue with running WPAD on IPv6 connections. + Fix issue with client certificate for TTLS/PEAP. + Remove internal element infrastructure. + +ver 0.75: + Fix issue with 3G connect timeout handling. + Fix issue with WiFi raw key PSK handling. + Fix issue with DHCP renewal timeout handling. + Fix issue with DHCP and empty nameserver list. + Add support for unit testing. + +ver 0.74: + Fix issue with race condition in ready/online handling. + Fix issue with DHCP release callback handling. + Fix multiple issues with session API handling. + Add support for using DNS proxy for Tethering. + Add support for Private Network API. + Add support for Clock API. + +ver 0.73: + Update support for session API handling. + Add support for more advanced roaming policies. + Add support for EAP identity and passphrase queries. + Add support for IPv6 handling with cellular bearer. + Add support for main configuration file. + Remove deprecated profile interface. + +ver 0.72: + Fix issue with overwriting DNS servers from DHCP. + Fix issue with DHCP renewal with same configuration. + Fix issue with multiple memory leaks. + Add support for 6to4 tunneling. + +ver 0.71: + Fix issue with not storing IPv6 privacy settings. + Fix issue with storing fixed and manual IP settings. + Fix issue with service state when PAN connection fails. + Fix issue with tethering and WiFi bridge handling. + Fix issue with autonomously activated contexts. + Fix issue with nameserver array for PACrunner. + Fix issue with network information memory leak. + Fix issue with double-free in statistics handling. + Fix issue with handling malformed profiles. + Fix issue with pending DHCP client requests. + Add initial support for TI shared transport handling. + +ver 0.70: + Add support for reporting invalid WiFi passphrases. + Add support for IPv6 privacy extension. + Add support for IPv6 advanced features. + Add support for IPv6 nameserver settings. + Remove deprecated APN service settings. + +ver 0.69: + Fix issue with not handling DNS proxy failures gracefully. + Fix issue with double free in statistics handling. + Fix issue with early tethering bridge creation. + Add support for tethering property per technology. + Add support for initial WiFi tethering feature. + Add support for using PACrunner as proxy driver. + Add support for WPS as part of the security property. + +ver 0.68: + Fix issue with wrong name of PolicyKit configuration file. + Fix issue with inconsistency of WiFi scan states. + Fix issue with missing auto-reconnect and oFono. + Add support for vpnc based private networks. + Add support for WiFi Protected Setup handling. + Remove legacy WiFi plugin. + +ver 0.67: + Fix issue with oFono plugin and multiple online calls. + Fix issue with checking for AutoConnect service property. + Remove deprecated MCC and MNC service properties. + +ver 0.66: + Fix multiple set of memory leaks. + Fix issue with WPA supplicant phase2 values. + Fix issue with WiFi access points after kill/restart. + Fix issue with correct PACrunner configuration loading. + Add support for loading provision files at runtime. + Add support for setting proxy auto-configuration. + Add support for IPv6 auto-configured addresses. + +ver 0.65: + Use new WiFi plugin by default. + Fix issue with handling already powered devices. + Fix issue with handling proxy PAC option from DHCP. + Add support for handling regulatory domain settings. + Add support for handling IPv6 router advertisements. + Add support for handling IPv6 nameservers. + Add support for handling multiple search domains. + Add support for handling oFono modem lockdown. + Add support for handling IPv6 DNS connections. + Add support for IPv4 Link-Local negotiation. + Add support for USB CDC Tethering functionality. + +ver 0.64: + Update service name to net.connman domain. + Fix issue with disabling a technology twice. + Fix issue with using wrong string for Proxy.Method. + Fix issue with TCP connection lookup and DNS proxy. + Fix issue with TCP receive busy waits and DNS proxy. + Fix various issues with WPA Supplicant interaction. + Add support for chunk encoding to HTTP client. + Add support for internal HTTP client for portal detection. + Add support for internal DHCP server setup. + Add support for internal NAT and IP forwarding setup. + Add support for Bluetooth Tethering functionality. + Remove deprecated device and network D-Bus interfaces. + Remove support for dhclient plugin. + +ver 0.63: + Change to use nl80211/cfg80211 WiFi management by default. + Fix various issues with new WPA Supplicant interface. + Fix issue with not connecting failed networks at boot. + Fix issue with properly tracking RFKILL blocked state. + Fix issue with missing signals for IPv4/IPv6 gateway details. + Add support for using RTNL for setting IPv4/IPv6 details. + Add support for using PHONET_PIPE GPRS interfaces. + Add support for setting manual proxy configurations. + Add support for exporting proxy configurations to PACrunner. + Add support for combined home and roaming statistics. + Add support for OpenVPN connections. + Remove dependency on udev. + +ver 0.62: + Fix crash with non-existent or extra DHCP result options. + Fix crash when doing PEAP/TTLS authentication. + Fix issue with handling multiple data counters. + Fix issue with Bluetooth adapters without address. + Fix issue with multiple scanning attempts after disconnects. + Fix issue with VPN services when switching into offline mode. + Add support for storing statistics information in separate files. + Add support for verification of configuration file parameters. + Add support for handling time server values from DHCP. + Add support for allowing DNS over TCP within the DNS proxy. + Add support for loading proxy configurations into PACrunner. + Add support for WiFi plugin using new WPA Supplicant D-Bus API. + Add support for requesting passphrases via agents. + Remove default support for EDNS0 option. + +ver 0.61: + Add support for using the internal DHCP client by default. + Add support for latest PolicyKit framework. + Add support for new oFono D-Bus interfaces. + +ver 0.60: + Fix issue with missing reset of proxy settings. + Fix issue with missing Ethernet property changed signal. + Fix issue with offline operation on already blocked devices. + Fix issue with offline mode and device powered changes. + Fix issue with portal detection and DHCP renewals. + Fix issue with connection attempts for removed networks. + Fix issue with stale pointers of networks. + +ver 0.59: + Fix issue with D-Bus object paths of VPN providers. + +ver 0.58: + Fix various issues around offline mode. + Fix various issues with VPN nameserver handling. + Add support for home/roaming network statistics. + Add support for EAP-TTLS WiFi configuration. + Add support for creating backtraces. + +ver 0.57: + Fix missing default profile creation. + Fix missing service integration of VPN providers. + Fix missing export of PAC information retrieved from DHCP. + Fix issue with detection of new Bluetooth devices. + Fix issue with offline mode handling. + Fix issue with device power handling. + +ver 0.56: + Fix issues with offline mode handling. + Fix service integration with VPN providers. + Add internal asynchronous resolver library. + Add internal DHCP client library. + Add support for using internal DHCP client. + Add support for WPAD proxy auto-configuration. + Add support for static IPv6 configuration. + Add support for DHCP provided domain names. + Add initial support for on-demand connections. + Remove uDHCP and resolvconf plugins. + +ver 0.55: + Fix issue with 3G roaming status indication. + Fix issue with using -H option with dhclient. + Fix issue with loading WiFi SSID details for scanning. + Add support for setting host routes for DNS servers. + Add support for more detailed statistics counters. + Add support for internal DHCP client library. + +ver 0.54: + Fix issue with root requests and EDNS0 OPT records. + Fix issue with default gateway when route deletion fails. + Fix issue with group identifiers for cellular networks. + Fix issue with fixed IP settings from cellular networks. + Fix issue with nameserver settings and manual configuration. + Add support for cellular network name changes. + Add support for cellular signal strength changes. + Add support for actively scanning for hidden networks. + Add support for ASCII based WEP keys. + Add support for NTP timeserver updates. + Add support for PPP default route settings. + +ver 0.53: + Fix issue with supplicant and device scanning state cleaning. + Fix issue with Bluetooth PAN networks stay in connected state. + Fix issue with reference counting and connected state. + Fix issue with technology disabling on device removal. + Fix issue with two default gateways when using VPN. + Fix issue with static IPv4 configuration and signals. + Add support for splitting DHCP provided nameserver results. + Add support multiple nameservers in /etc/resolv.conf. + Add support for setting manual DNS server configuration. + Add support for exporting IPv4 gateway information. + Add support for newer versions of oFono API. + +ver 0.52: + Fix issue with new "connected" states. + Fix issue with hidden networks and PSK. + Fix issue with DHCP and Bluetooth PAN. + Fix issue when disconnecting PAN networks. + Add support for application sessions. + Add plugin for hh2serial GPS support. + +ver 0.51: + Fix issue with missing device power toggling. + Fix issue with D-Bus object path on device removal. + Add support for WiFi portal detection. + Add support for configuring static gateways. + Remove unneeded plugin for Option HSO support. + Remove unneeded plugin for Ericsson MBM support. + +ver 0.50: + Fix configuration loading for unknown services. + Fix IP method setting of Ethernet plugin. + +ver 0.49: + Fix issue with WiFi power changes. + Fix issue with Bluetooth device startup. + Fix issue with host route settings for VPN. + Fix issue with processing of RFKILL events. + Fix some WPA Enterprise privacy issues. + Add support for basic Ethernet information. + Add support for static IP settings. + +ver 0.48: + Fix signal strength calculation when quality is not provided. + Fix issues with wpa_supplicant state tracking. + Fix faulty removal of IP address from interface. + Fix permissions of newly created /etc/resolv.conf file. + Fix DNS proxy handling when in offline mode. + Add support for EDNS0 resolver option. + Add workaround for large EDNS0 queries. + Add workaround for DHCP startup failures with WiFi networks. + Add support for handling hostnames and domainnames. + Add support for IPv4 configuration via service interface. + Add support for fixed and manual IPv4 configuration. + Add support for default service changed notifier. + Add support for clearing failure state via service removal. + Add support for OpenConnect VPN connections. + Add support for IEEE 802.1x WiFi networks. + Add support for roaming between WPA and WPA2 networks. + Add various generic D-Bus helpers and use them. + Remove special handling of Ethernet devices. + +ver 0.47: + Fix segmentation fault on resolver shutdown. + Fix issue with adding nameserver that doesn't exist. + Fix issue when no broadcast address is given. + Fix issue with missing property changed signal. + Add checks for invalid supplicant state transitions. + Add initial version of oFono GPRS support. + Add support for dynamic debug framework. + +ver 0.46: + Fix reconnect issue when power off or disabling the device. + Remove problematic retry on failure code path. + +ver 0.45: + Fix crash with connect timeout and second connect attempt. + Fix reconnect issues after suspend or roaming attempt. + +ver 0.44: + Fix command line options for device filtering. + Fix issue with network reference in MBM support. + Fix handling when losing network access in MBM plugin. + Fix broken libiWmxSDK callback parameter handling. + Add work around Intel WiMAX SDK API breakage. + +ver 0.43: + Fix issue with missing scanning after power up. + Fix issue with udev versus /dev/rfkill event processing. + Fix issue with powered down device on connection attempt. + Add support for multiple connection attempts. + Add support for tracking the operation state. + Add full support for Ericsson MBM cellular devices. + +ver 0.42: + Fix issue with switching between hidden WiFi networks. + Fix issue with missing scanning after disconnect. + Fix issue with not triggering auto-connect in some cases. + +ver 0.41: + Fix race condition with WiFi devices and RFKILL. + Fix issue with WiFi connect/disconnect and some drivers. + Fix issue with WEP encryption and staging drivers. + Fix issue with wrong setup of loopback interfaces. + +ver 0.40: + Fix issue with wrong setting of initial AutoConnect value. + Fix issue with IP configuration and loopback devices. + Fix issue with build system and include directory. + Fix wrong variable for dhclient-script location. + Fix disconnect race condition with Bluetooth service. + Add support for ignoring bonding Ethernet interfaces. + +ver 0.39: + Fix file permissions for profile storage. + Fix service resorting when they are in different states. + Fix support for handling Bluetooth PAN devices. + Add support for AutoConnect property of services. + Add support for creating, modifying and removing profiles. + Add support for fully flexible task handling framework. + Add support for more generic RTNL handling and notifications. + Add support for full non-recursive build. + +ver 0.38: + Fix broken check for security modes. + Fix requirement of inotify when loopback support is disabled. + +ver 0.37: + Fix missing update of signal strength from scan results. + Fix error handling in case when passphrase is required. + Add support for PassphraseRequired property. + Add missing check for WiFi security modes. + +ver 0.36: + Fix missing reset of network reference when disconnecting. + Fix wrong variable reference when sending technology replies. + Fix wrong identifiers of D-Bus error names. + +ver 0.35: + Fix missing auto-connect trigger on Ethernet device removal. + Fix availability listing for devices without attached drivers. + Fix signals for connected and default technologies. + Fix notification to use service types instead of device types. + Fix potential pending scan result reply messages after removal. + Add support for blocking enable and disable technology changes. + +ver 0.34: + Fix setup of udev context before loading any plugins. + Fix rearming the scan trigger if a device got disabled. + Fix device power state changes tracking with RFKILL notifications. + Fix wrong usage of device types instead of service types. + Fix connect method to handle non-WiFi services. + +ver 0.33: + Add support for RFKILL changes of the WiFi subsystem. + Fix state value of Network Manager compatibility support. + +ver 0.32: + Fix broken device unregistration on removal. + Fix WiMAX device detection handling. + +ver 0.31: + Fix missing enforcement of offline mode for new devices. + Add support for persistent storage of offline mode. + Add support for persistent storage of device power state. + Remove deprecated and unused network storage callbacks. + +ver 0.30: + Fix issue where hidden network could show up in service list. + Fix issue with asynchronous notification of scan requests. + Fix message reference leak when adding interface fails. + Fix problem when removing network during inactive state. + Remove broken and unused callback for joining networks. + Remove deprecated device and network interface methods. + Remove test scripts for deprecated interface methods. + +ver 0.29: + Fix missing signal emission for offline mode changes. + Fix signal emission for changes in technology properties. + Rename Technologies property to AvailableTechnologies. + +ver 0.28: + Fix another reference counting imbalance when adding networks. + Revert supplicant change to always reset scanning after results. + +ver 0.27: + Fix missing disarming of the connection timeout. + Fix handling of multiple supplicant disconnect attempts. + Fix simultaneous connects from different technologies limitation. + +ver 0.26: + Fix broken handling of auto-connect logic. + Fix handling of out-of-range access points. + Fix support for connecting to hidden networks. + Fix reference counting for networks with same SSID. + Fix issue with WiFi interfaces not getting switched off. + Fix problems with delayed service list updates. + Fix disconnect/abort of connection attempts. + +ver 0.25: + Fix showing of WiFi networks with less than 25% signal strength. + Fix potential segmentation fault with network passphrases. + +ver 0.24: + Fix handling of initial device powered state. + Fix missing Powered property changed signals. + Fix canceling of a network connection attempt. + Fix stalled configuration issue with supplicant. + Fix detection of association errors from supplicant. + Fix issue with wrong scanning state information. + Fix hidden SSID detection routines. + Fix visible Ethernet services even without carrier. + Add global method call to request scanning. + Add support for global technologies list. + Add support for delaying service list updates. + Update the overall D-Bus API documentation. + +ver 0.23: + Fix dhclient probe/remove race condition. + Fix handling of disconnected services during auto-connect. + Add support for proper group name of hidden networks. + Add support for storing SSID details of hidden networks. + +ver 0.22: + Fix wrong auto-connect procedure after user connection. + Fix invalid update of already connected network. + Fix idle state handling after disconnecting device. + Fix disconnect race condition in WiFi supplicant. + Fix WiFi signal strength reporting. + +ver 0.21: + Add udev based network device detection. + Add support for global auto-connect feature. + Add support for basic service drag and drop. + Fix missing passphrase cleanup on service removal. + Fix potential duplicate network creation. + Fix handling of WEP shared keys. + +ver 0.20: + Add plugin for Intel WiMAX SDK support. + Add special handling for default vendor SSIDs. + Add support for default gateway in different network. + Add support for automatic switching of default gateway. + Add support for asynchronous handling of Powered property. + Add support for connecting/disconnecting Ethernet services. + Add support for more detailed error states of services. + Add support for clearing error state via ClearProperty. + Fix error code for invalid or unknown properties. + Fix various timeout handling issues. + Remove Policy and Priority device and network properties. + +ver 0.19: + Add hidden networks to the service list. + Add support for storing the service name. + Fix service list sorting for connected services. + Fix missing cancel command when operation times out. + Fix various issues with service favorite handling. + Remove Available and Remember network properties. + +ver 0.18: + Add support for asynchronous service connect method. + Fix broken storage of service favorite details. + +ver 0.17: + Add AT chat library implementation. + Fix service lookup for WiFi and WiMAX devices. + Fix service state signal emission and error handling. + Fix storing and loading of configured passphrases for services. + +ver 0.16: + Update Intel OSPM support to latest specification. + Add initial support for new service interface. + Add support for builtin plugins. + Add extra warning if no nameserver is defined. + Add error reporting for state and storage directory creation. + Add error message for network and device storing failures + Fix stale entry in gateway list after connection changes. + Fix handling of DHCP results with no nameserver. + Fix infinite loop for service lookup. + Fix various format string warnings. + +ver 0.15: + Detect VMware network interface and ignore them. + Fix setting of scan_ssid for hidden networks. + Fix empty network name property. + +ver 0.14: + Add support for detecting DHCP failures. + Add support for joining hidden WiFi networks. + Add support for device and network address property. + Add support for default /etc/resolv.conf generation. + Fix issue with wrong address setting for loopback. + Fix detection of WiFi access point changes. + Fix crash with blob properties. + +ver 0.13: + Add support for notification infrastructure. + Add fully dynamic property storage capabilities. + Fix broken loading of last network on bootup. + Fix crash when unplugging WiFi devices. + Rename OSPM plugin to Intel OSPM plugin. + Rename WiMAX plugin to Intel WiMAX SDK plugin. + +ver 0.12: + Fix connection state change handling. + Fix network list enumeration. + Fix broken driver matching for devices. + Fix issue with network identifier lookup. + +ver 0.11: + Add plugin priority handling. + Add network type for WiMAX. + Fix network protocol selection for Bluetooth PAN. + Fix parameters for Bluetooth PAN disconnect method. + +ver 0.10: + Fix races with connection signals. + Fix automatic switching of default connection. + +ver 0.9: + Rename FlightMode to OfflineMode. + Add static IPv4 setting support for Ethernet devices. + Add extra options to exclude devices and plugins. + Add support for toggling debug output. + Add support for ScanInterval property. + Fix handling of disconnect commands from applications. + Fix detection of networks that are out of range. + Fix setting network remember status. + Fix argument type checking of properties. + +ver 0.8: + Add Device and Network property to connection interface. + Add option to disable installation of data files. + Add command line option to show version number. + Fix signal emission for network changes. + +ver 0.7: + Add basic support for flight mode. + Add support for multiple storage drivers. + Add support for RTNL newlink watch API. + Add support for different security privileges. + Add support for device and network priorities. + Add functions for setting network properties. + Fix issue with listing devices without a driver. + Fix issue with WiFi scanning indication. + Fix detection of WiFi security changes. + Update WiFi driver to use new network helpers. + Install different D-Bus configuration for PolicyKit. + +ver 0.6: + Add CONNMAN_API_SUBJECT_TO_CHANGE definition. + Add detailed configuration options. + Add various D-Bus helper functions. + Add generic device driver infrastructure. + Add generic network driver infrastructure. + Add property for WiFi network mode. + Add property for network interface name. + Add property for global connection policy. + Add support for verbose compiler warnings. + Add support for device detection via udev. + Add support for systems with udhcpc. + Add support for Bluetooth PAN networks. + Fix WiFi issue with DHCP restart after handshake. + Fix exported symbols list creation. + Remove deprecated and unused plugins. + +ver 0.5: + Add support for handling Bluetooth adapters. + Add support for activating wpa_supplicant on demand. + Add Device property to network objects. + Add Scanning property to device objects. + Fix Name property of device objects. + Fix WiFi SSID to object path conversion. + Fix duplicate wireless scan results. + Fix built issue with libudev and uClibc. + Fix issues with element registration failures. + +ver 0.4: + Add DNS proxy resolver plugin. + Add support for default connections. + Add support for gateway change notifications. + Add signal strength property for connections. + Add property for connection type. + Fix issue with carrier detection. + Fix broken resolvconf plugin. + +ver 0.3: + Add support for automatically connecting known networks. + Add improved framework for handling resolver details. + Add generic signal strength property. + Fix bridge and WiMAX device detection. + Fix network listing for Ethernet devices. + +ver 0.2: + Add support for indicating network changes. + Add support for signal strength property. + Add support for unique device names. + Fix broken device enumeration. + Fix issue with device removal callback. + Fix issue with wpa_supplicant disconnecting. + Fix D-Bus access policy configuration. + +ver 0.1: + Initial public release. diff --git a/HACKING b/HACKING new file mode 100644 index 000000000..05fb69c67 --- /dev/null +++ b/HACKING @@ -0,0 +1,144 @@ +Hacking on Connection Manager +***************************** + + +Build tools requirements +======================== + +When building and testing directly from the repository it is important to +have at least automake version 1.10 or later installed. All modern +distributions should default to the latest version, but it seems that +Debian's default is still an earlier version: + + Check version + # dpkg -l '*automake*' + + Install new version + # apt-get install automake1.10 + # update-alternatives --config automake + + +Working with the source code repository +======================================= + +The repository contains two extra scripts that accomplish the bootstrap +process. One is called "bootstrap" which is the basic scripts that uses the +autotools scripts to create the needed files for building and installing. +It makes sure to call the right programs depending on the usage of shared or +static libraries or translations etc. + +The second program is called "bootstrap-configure". This program will make +sure to properly clean the repository, call the "bootstrap" script and then +call configure with proper settings for development. It will use the best +options and pass them over to configure. These options normally include +the enabling the maintainer mode and the debugging features. + +So while in a normal source project the call "./configure ..." is used to +configure the project with its settings like prefix and extra options. In +case of bare repositories call "./bootstrap-configure" and it will bootstrap +the repository and calls configure with all the correct options to make +development easier. + +In case of preparing for a release with "make distcheck", don't use +bootstrap-configure since it could export development specific settings. + +So the normal steps to checkout, build and install such a repository is +like this: + + Checkout repository + # git clone git://git.kernel.org/pub/scm/network/connman/connman.git + # cd connman + + Configure and build + # ./bootstrap-configure + # make + + Check installation + # make install DESTDIR=$PWD/x + # find x + # rm -rf x + + Check distribution + # make distcheck + + Final installation + # sudo make install + + Remove autogenerated files + # make maintainer-clean + + +Running from within the source code repository +============================================== + +When using "./configure --enable-maintainer-mode" the automake scripts will +use the plugins directly from within the repository. This removes the need +to use "make install" when testing "connmand". The "bootstrap-configure" +automatically includes this option. + + Run daemon in foreground with debugging + # sudo ./src/connmand -n -d 'plugins/*' + +The debugging option -d takes an argument. This argument can be a comma +separated list of file names like 'plugins/wifi.c,plugins/ethernet.c' to +enable debugs in these files. Simple glob style pattern matching is +supported in this list. + +For production installations or distribution packaging it is important that +the "--enable-maintainer-mode" option is NOT used. + +Some times it is important to restrict the available interfaces. For example +in cases where testing happens over a network connection. The "-i" command +line switch allows to specify a glob pattern for the interface names. + + Run daemon for wireless interfaces + # sudo ./src/connmand -n -i wlan* + + +Debugging the D-Bus interface during runtime +============================================ + +Running the daemon with debugging information in the foreground is quite +verbose and sometimes not really helpful. The "monitor-connman" script +allows to monitor "PropertyChanged" D-Bus signals from various interfaces. + +Every "PropertyChanged" signal will generate a line of output. Some of them +can get very complex. The first detail inside "{ ... }" is the interface +name (without its service name prefix). The second detail inside "[ ... ]" +is the object path. And after that it is followed by a key and value of +the property that changed. + + +Generating source code documentation +==================================== + +The source code is annotated using the gtk-doc style documentation. This +allows an easy way of generating API documentation. The "bootstrap-configure" +script will use the "--enable-gtk-doc" configure to enable the generation of +the documentation. + +To make the gtk-doc process work, the gtk-doc tools need to be installed. +Every distribution should provide a package for this, but the naming of the +package might be different: + + Debian + # apt-get install gtk-doc-tools + + Ubuntu + # apt-get install gtk-doc-utils + + Fedora + # yum install gtk-doc + +In case "bootstrap-configure" is not used, the manual steps for generating +the documentation files are like this: + + Configuring the repository + # ./configure --enable-gtk-doc + + Generate the documentation + # cd doc && make + + View documentation + # firefox doc/html/index.html + diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..56b077d6a --- /dev/null +++ b/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PREFIX', the package will +use PREFIX as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..f05b75528 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,428 @@ + +AM_MAKEFLAGS = --no-print-directory + +includedir = @includedir@/connman + +include_HEADERS = include/types.h include/log.h include/plugin.h \ + include/notifier.h include/service.h \ + include/resolver.h include/ipconfig.h \ + include/device.h include/network.h include/inet.h \ + include/storage.h include/provision.h \ + include/session.h include/ipaddress.h include/agent.h \ + include/inotify.h + +nodist_include_HEADERS = include/version.h + +noinst_HEADERS = include/rtnl.h include/task.h \ + include/dbus.h include/option.h \ + include/provider.h include/vpn-dbus.h \ + include/utsname.h include/timeserver.h include/proxy.h \ + include/technology.h include/setting.h + +local_headers = $(foreach file,$(include_HEADERS) $(nodist_include_HEADERS) \ + $(noinst_HEADERS), include/connman/$(notdir $(file))) + + +gdbus_sources = gdbus/gdbus.h gdbus/mainloop.c gdbus/watch.c \ + gdbus/object.c gdbus/client.c gdbus/polkit.c + +gdhcp_sources = gdhcp/gdhcp.h gdhcp/common.h gdhcp/common.c gdhcp/client.c \ + gdhcp/server.c gdhcp/ipv4ll.h gdhcp/ipv4ll.c gdhcp/unaligned.h + +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 + +if DATAFILES + +if NMCOMPAT +nmcompat_conf = plugins/connman-nmcompat.conf +endif + +dbusconfdir = @DBUS_CONFDIR@ + +dbusconf_DATA = src/connman.conf $(nmcompat_conf) + +if VPN +dbusconf_DATA += vpn/connman-vpn-dbus.conf +dbusservicedir = @DBUS_DATADIR@ +dbusservice_DATA = vpn/net.connman.vpn.service +endif + +if SYSTEMD +systemdunitdir = @SYSTEMD_UNITDIR@ + +systemdunit_DATA = src/connman.service + +if VPN +systemdunit_DATA += vpn/connman-vpn.service +endif +endif +endif + +plugin_LTLIBRARIES = + +plugin_objects = + +builtin_modules = +builtin_sources = +builtin_libadd = +builtin_cflags = + +noinst_PROGRAMS = + +unit_objects = + +MANUAL_PAGES = + +sbin_PROGRAMS = src/connmand + +src_connmand_SOURCES = $(gdbus_sources) $(gdhcp_sources) $(gweb_sources) \ + $(builtin_sources) src/connman.ver \ + src/main.c src/connman.h src/log.c \ + src/error.c src/plugin.c src/task.c \ + src/device.c src/network.c src/connection.c \ + src/manager.c src/service.c \ + src/clock.c src/timezone.c src/agent-connman.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/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/ipaddress.c \ + src/inotify.c src/firewall.c + +src_connmand_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ \ + @XTABLES_LIBS@ @GNUTLS_LIBS@ -lresolv -ldl -lrt + +src_connmand_LDFLAGS = -Wl,--export-dynamic \ + -Wl,--version-script=$(srcdir)/src/connman.ver + +if VPN +vpn_plugin_LTLIBRARIES = + +vpn_plugin_objects = + +builtin_vpn_modules = +builtin_vpn_sources = +builtin_vpn_libadd = +builtin_vpn_cflags = + +sbin_PROGRAMS += vpn/connman-vpnd + +vpn_connman_vpnd_SOURCES = $(gdbus_sources) $(builtin_vpn_sources) \ + $(gweb_sources) vpn/vpn.ver vpn/main.c vpn/vpn.h \ + src/log.c src/error.c src/plugin.c src/task.c \ + vpn/vpn-manager.c vpn/vpn-provider.c \ + vpn/vpn-provider.h vpn/vpn-rtnl.h \ + vpn/vpn-ipconfig.c src/inet.c vpn/vpn-rtnl.c \ + src/dbus.c src/storage.c src/ipaddress.c src/agent.c \ + vpn/vpn-agent.c vpn/vpn-agent.h src/inotify.c \ + vpn/vpn-config.c + +vpn_connman_vpnd_LDADD = $(builtin_vpn_libadd) @GLIB_LIBS@ @DBUS_LIBS@ \ + @GNUTLS_LIBS@ -lresolv -ldl + +vpn_connman_vpnd_LDFLAGS = -Wl,--export-dynamic \ + -Wl,--version-script=$(srcdir)/vpn/vpn.ver +endif + +BUILT_SOURCES = $(local_headers) src/builtin.h + +if VPN +BUILT_SOURCES += vpn/builtin.h +endif + +CLEANFILES = src/connman.conf $(BUILT_SOURCES) + +statedir = $(localstatedir)/run/connman + +if VPN +vpn_plugindir = $(libdir)/connman/plugins-vpn +endif + +plugindir = $(libdir)/connman/plugins + +scriptdir = $(libdir)/connman/scripts + +storagedir = $(localstatedir)/lib/connman +vpn_storagedir = $(localstatedir)/lib/connman-vpn + +configdir = ${sysconfdir}/connman + +if MAINTAINER_MODE +if VPN +build_vpn_plugindir = $(abs_top_srcdir)/vpn/plugins/.libs +endif +build_plugindir = $(abs_top_srcdir)/plugins/.libs +build_scriptdir = $(abs_top_srcdir)/scripts +else +build_plugindir = $(plugindir) +build_scriptdir = $(scriptdir) +if VPN +build_vpn_plugindir = $(vpn_plugindir) +endif +endif + +AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \ + @GNUTLS_CFLAGS@ $(builtin_cflags) \ + -DCONNMAN_PLUGIN_BUILTIN \ + -DSTATEDIR=\""$(statedir)"\" \ + -DPLUGINDIR=\""$(build_plugindir)"\" \ + -DSCRIPTDIR=\""$(build_scriptdir)"\" \ + -DSTORAGEDIR=\""$(storagedir)\"" \ + -DVPN_STORAGEDIR=\""$(vpn_storagedir)\"" \ + -DCONFIGDIR=\""$(configdir)\"" + +if VPN +AM_CPPFLAGS = -I$(builddir)/include -I$(srcdir)/gdbus +else +AM_CPPFLAGS = -I$(builddir)/include -I$(builddir)/src -I$(srcdir)/gdbus +endif + +src_connmand_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \ + @GNUTLS_CFLAGS@ $(builtin_cflags) \ + -DCONNMAN_PLUGIN_BUILTIN \ + -DSTATEDIR=\""$(statedir)"\" \ + -DPLUGINDIR=\""$(build_plugindir)"\" \ + -DSCRIPTDIR=\""$(build_scriptdir)"\" \ + -DSTORAGEDIR=\""$(storagedir)\"" \ + -DVPN_STORAGEDIR=\""$(vpn_storagedir)\"" \ + -DCONFIGDIR=\""$(configdir)\"" \ + -I$(builddir)/src + +EXTRA_DIST = src/genbuiltin src/connman-dbus.conf src/connman-polkit.conf \ + plugins/connman-nmcompat.conf + +if VPN +vpn_connman_vpnd_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ \ + $(builtin_vpn_cflags) \ + -DCONNMAN_PLUGIN_BUILTIN \ + -DSTATEDIR=\""$(statedir)"\" \ + -DPLUGINDIR=\""$(build_vpn_plugindir)"\" \ + -DSCRIPTDIR=\""$(build_scriptdir)"\" \ + -DSTORAGEDIR=\""$(storagedir)\"" \ + -DVPN_STORAGEDIR=\""$(vpn_storagedir)\"" \ + -DCONFIGDIR=\""$(configdir)\"" \ + -I$(builddir)/vpn + +endif + +EXTRA_DIST += vpn/vpn-dbus.conf vpn/vpn-polkit.conf + +script_DATA = +script_PROGRAMS = +script_LTLIBRARIES = + +include Makefile.plugins + +if CLIENT +noinst_PROGRAMS += client/connmanctl + +noinst_MANUAL_PAGES = doc/connmanctl.1 + +client_connmanctl_SOURCES = $(gdbus_sources) \ + client/dbus_helpers.h client/dbus_helpers.c \ + client/services.h client/services.c \ + client/commands.h client/commands.c \ + client/input.h client/input.c \ + client/agent.h client/agent.c \ + client/main.c + +client_connmanctl_LDADD = @DBUS_LIBS@ @GLIB_LIBS@ -lreadline -ldl +endif + +noinst_PROGRAMS += unit/test-pbkdf2-sha1 unit/test-prf-sha1 unit/test-ippool + +unit_test_pbkdf2_sha1_SOURCES = unit/test-pbkdf2-sha1.c \ + src/shared/sha1.h src/shared/sha1.c +unit_test_pbkdf2_sha1_LDADD = @GLIB_LIBS@ + +unit_test_prf_sha1_SOURCES = unit/test-prf-sha1.c \ + src/shared/sha1.h src/shared/sha1.c +unit_test_prf_sha1_LDADD = @GLIB_LIBS@ + +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 + +TESTS = unit/test-pbkdf2-sha1 unit/test-prf-sha1 unit/test-ippool + +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 \ + 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 \ + tools/session-test tools/iptables-unit \ + tools/dnsproxy-test + +tools_supplicant_test_SOURCES = $(gdbus_sources) tools/supplicant-test.c \ + tools/supplicant-dbus.h tools/supplicant-dbus.c \ + tools/supplicant.h tools/supplicant.c +tools_supplicant_test_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ + +tools_web_test_SOURCES = $(gweb_sources) tools/web-test.c +tools_web_test_LDADD = @GLIB_LIBS@ @GNUTLS_LIBS@ -lresolv + +tools_resolv_test_SOURCES = gweb/gresolv.h gweb/gresolv.c tools/resolv-test.c +tools_resolv_test_LDADD = @GLIB_LIBS@ -lresolv + +tools_wpad_test_SOURCES = gweb/gresolv.h gweb/gresolv.c tools/wpad-test.c +tools_wpad_test_LDADD = @GLIB_LIBS@ -lresolv + +tools_stats_tool_LDADD = @GLIB_LIBS@ + +tools_dhcp_test_SOURCES = $(gdhcp_sources) tools/dhcp-test.c +tools_dhcp_test_LDADD = @GLIB_LIBS@ + +tools_dhcp_server_test_SOURCES = $(gdhcp_sources) tools/dhcp-server-test.c +tools_dhcp_server_test_LDADD = @GLIB_LIBS@ + +tools_dbus_test_SOURCES = $(gdbus_sources) tools/dbus-test.c +tools_dbus_test_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ + +tools_polkit_test_LDADD = @DBUS_LIBS@ + +tools_iptables_test_SOURCES = src/log.c src/iptables.c tools/iptables-test.c +tools_iptables_test_LDADD = @GLIB_LIBS@ @XTABLES_LIBS@ -ldl + +tools_private_network_test_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ + +tools_session_test_SOURCES = $(gdbus_sources) src/log.c src/dbus.c \ + tools/session-test.c tools/session-utils.c tools/manager-api.c \ + tools/session-api.c tools/session-test.h +tools_session_test_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ -ldl + +tools_iptables_unit_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \ + -DIPTABLES_SAVE=\""${IPTABLES_SAVE}"\" +tools_iptables_unit_SOURCES = $(gdbus_sources) src/log.c \ + src/iptables.c src/firewall.c src/nat.c tools/iptables-unit.c +tools_iptables_unit_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ @XTABLES_LIBS@ -ldl + +tools_dnsproxy_test_SOURCES = tools/dnsproxy-test.c +tools_dnsproxy_test_LDADD = @GLIB_LIBS@ + +endif + +test_scripts = test/get-state test/list-services \ + test/monitor-services test/test-clock \ + test/simple-agent test/show-introspection test/test-compat \ + test/test-manager test/test-connman test/monitor-connman \ + test/connect-provider test/remove-provider \ + test/test-counter test/set-ipv4-method test/set-ipv6-method \ + 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-new-supplicant test/service-move-before \ + test/set-global-timeservers test/get-global-timeservers \ + test/set-nameservers test/set-domains test/set-timeservers \ + test/set-clock + +test_scripts += test/vpn-connect test/vpn-disconnect test/vpn-get \ + test/monitor-vpn test/vpn-property + +if TEST +testdir = $(pkglibdir)/test +test_SCRIPTS = $(test_scripts) +endif + +EXTRA_DIST += $(test_scripts) + +EXTRA_DIST += doc/overview-api.txt doc/behavior-api.txt \ + doc/ipconfig-api.txt doc/plugin-api.txt \ + 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 \ + doc/vpn-connection-api.txt \ + doc/vpn-manager-api.txt doc/vpn-overview.txt + +EXTRA_DIST += src/main.conf + +MANUAL_PAGES += doc/connman.8 doc/connman.conf.5 + +dist_man_MANS = $(MANUAL_PAGES) + +pkgconfigdir = $(libdir)/pkgconfig + +pkgconfig_DATA = connman.pc + +DISTCHECK_CONFIGURE_FLAGS = --disable-gtk-doc \ + --disable-datafiles \ + --enable-hh2serial-gps \ + --enable-openconnect \ + --enable-openvpn \ + --enable-vpnc \ + --enable-session-policy-local \ + --enable-nmcompat \ + --enable-polkit + +DISTCLEANFILES = $(pkgconfig_DATA) + +MAINTAINERCLEANFILES = Makefile.in \ + aclocal.m4 configure config.h.in config.sub config.guess \ + ltmain.sh depcomp compile missing install-sh mkinstalldirs + + +src/builtin.h: src/genbuiltin $(builtin_sources) + $(AM_V_GEN)$(srcdir)/src/genbuiltin $(builtin_modules) > $@ + +vpn/builtin.h: src/genbuiltin $(builtin_vpn_sources) + $(AM_V_GEN)$(srcdir)/src/genbuiltin $(builtin_vpn_modules) > $@ + +src/connman.conf: src/connman-dbus.conf src/connman-polkit.conf +if POLKIT + $(AM_V_GEN)cp $(srcdir)/src/connman-polkit.conf $@ +else + $(AM_V_GEN)cp $(srcdir)/src/connman-dbus.conf $@ +endif + +if VPN +vpn/connman-vpn-dbus.conf: vpn/vpn-dbus.conf vpn/vpn-polkit.conf +if POLKIT + $(AM_V_GEN)cp $(srcdir)/vpn/vpn-polkit.conf $@ +else + $(AM_V_GEN)cp $(srcdir)/vpn/vpn-dbus.conf $@ +endif +endif + +if SELINUX +if VPN +EXTRA_DIST += connman-task.pp +CLEANFILES += connman-task.pp +endif + +connman-task.pp: vpn/connman-task.te + make -f /usr/share/selinux/devel/Makefile +endif + +EXTRA_DIST += vpn/connman-task.te + +include/connman/version.h: include/version.h + $(AM_V_at)$(MKDIR_P) include/connman + $(AM_V_GEN)$(LN_S) $(abs_top_builddir)/$< $@ + +include/connman/%.h: $(abs_top_srcdir)/include/%.h + $(AM_V_at)$(MKDIR_P) include/connman + $(AM_V_GEN)$(LN_S) $< $@ + +clean-local: + @$(RM) -rf include/connman diff --git a/Makefile.plugins b/Makefile.plugins new file mode 100644 index 000000000..ce5089d67 --- /dev/null +++ b/Makefile.plugins @@ -0,0 +1,263 @@ + +plugin_cflags = -fvisibility=hidden -I$(srcdir)/gdbus \ + @DBUS_CFLAGS@ @GLIB_CFLAGS@ +plugin_ldflags = -no-undefined -module -avoid-version + +script_cflags = -fvisibility=hidden -I$(srcdir)/gdbus \ + @DBUS_CFLAGS@ + +if LOOPBACK +builtin_modules += loopback +builtin_sources += plugins/loopback.c +endif + +if ETHERNET +builtin_modules += ethernet +builtin_sources += plugins/ethernet.c +endif + +gsupplicant_sources = gsupplicant/gsupplicant.h gsupplicant/dbus.h \ + gsupplicant/supplicant.c gsupplicant/dbus.c + +if WIFI +builtin_modules += wifi +builtin_sources += plugins/wifi.c $(gsupplicant_sources) +endif + +if BLUETOOTH +builtin_modules += bluetooth_legacy +builtin_sources += plugins/bluetooth_legacy.c +builtin_modules += bluetooth +builtin_sources += plugins/bluetooth.c +endif + +if HH2SERIAL_GPS +if HH2SERIAL_GPS_BUILTIN +builtin_modules += hh2serial_gps +builtin_sources += plugins/hh2serial-gps.c +else +plugin_LTLIBRARIES += plugins/hh2serial-gps.la +plugin_objects += $(plugins_hh2serial_gps_la_OBJECTS) +plugins_hh2serial_gps_la_CFLAGS = $(plugin_cflags) +plugins_hh2serial_gps_la_LDFLAGS = $(plugin_ldflags) +endif +endif + +if OFONO +builtin_modules += ofono +builtin_sources += plugins/mcc.h plugins/ofono.c +endif + +if DUNDEE +builtin_modules += dundee +builtin_sources += plugins/dundee.c +endif + +if VPN +builtin_modules += vpn +builtin_sources += plugins/vpn.c + +if OPENCONNECT +if OPENCONNECT_BUILTIN +builtin_vpn_modules += openconnect +builtin_vpn_sources += vpn/plugins/openconnect.c +builtin_vpn_source = vpn/plugins/vpn.c vpn/plugins/vpn.h +builtin_vpn_cflags += -DOPENCONNECT=\"@OPENCONNECT@\" +else +vpn_plugin_LTLIBRARIES += vpn/plugins/openconnect.la +vpn_plugin_objects += $(plugins_openconnect_la_OBJECTS) +vpn_plugins_openconnect_la_SOURCES = vpn/plugins/vpn.h vpn/plugins/vpn.c \ + vpn/plugins/openconnect.c +vpn_plugins_openconnect_la_CFLAGS = $(plugin_cflags) \ + -DOPENCONNECT=\"@OPENCONNECT@\" \ + -DSTATEDIR=\""$(statedir)"\" \ + -DSCRIPTDIR=\""$(build_scriptdir)"\" +vpn_plugins_openconnect_la_LDFLAGS = $(plugin_ldflags) +endif +endif + +if OPENVPN +if OPENVPN_BUILTIN +builtin_vpn_modules += openvpn +builtin_vpn_sources += vpn/plugins/openvpn.c +builtin_vpn_source = vpn/plugins/vpn.c vpn/plugins/vpn.h +builtin_vpn_cflags += -DOPENVPN=\"@OPENVPN@\" +else +vpn_plugin_LTLIBRARIES += vpn/plugins/openvpn.la +vpn_plugin_objects += $(plugins_openvpn_la_OBJECTS) +vpn_plugins_openvpn_la_SOURCES = vpn/plugins/vpn.h vpn/plugins/vpn.c \ + vpn/plugins/openvpn.c +vpn_plugins_openvpn_la_CFLAGS = $(plugin_cflags) -DOPENVPN=\"@OPENVPN@\" \ + -DSTATEDIR=\""$(statedir)"\" \ + -DSCRIPTDIR=\""$(build_scriptdir)"\" +vpn_plugins_openvpn_la_LDFLAGS = $(plugin_ldflags) +endif +endif + +if VPNC +if VPNC_BUILTIN +builtin_vpn_modules += vpnc +builtin_vpn_sources += vpn/plugins/vpnc.c +builtin_vpn_source = vpn/plugins/vpn.c vpn/plugins/vpn.h +builtin_vpn_cflags += -DVPNC=\"@VPNC@\" +else +vpn_plugin_LTLIBRARIES += vpn/plugins/vpnc.la +vpn_plugin_objects += $(plugins_vpnc_la_OBJECTS) +vpn_plugins_vpnc_la_SOURCES = vpn/plugins/vpn.h vpn/plugins/vpn.c \ + vpn/plugins/vpnc.c +vpn_plugins_vpnc_la_CFLAGS = $(plugin_cflags) -DVPNC=\"@VPNC@\" \ + -DSTATEDIR=\""$(statedir)"\" \ + -DSCRIPTDIR=\""$(build_scriptdir)"\" +vpn_plugins_vpnc_la_LDFLAGS = $(plugin_ldflags) +endif +endif + +if L2TP +if L2TP_BUILTIN +builtin_vpn_modules += l2tp +builtin_vpn_sources += vpn/plugins/l2tp.c +builtin_vpn_source = vpn/plugins/vpn.c vpn/plugins/vpn.h +builtin_vpn_cflags += -DL2TP=\"@L2TP@\" +else +vpn_plugin_LTLIBRARIES += vpn/plugins/l2tp.la +vpn_plugin_objects += $(plugins_l2tp_la_OBJECTS) +vpn_plugins_l2tp_la_SOURCES = vpn/plugins/vpn.h vpn/plugins/vpn.c \ + vpn/plugins/l2tp.c +vpn_plugins_l2tp_la_CFLAGS = $(plugin_cflags) -DL2TP=\"@L2TP@\" \ + -DSTATEDIR=\""$(statedir)"\" \ + -DSCRIPTDIR=\""$(build_scriptdir)"\" +vpn_plugins_l2tp_la_LDFLAGS = $(plugin_ldflags) +endif +endif + +if PPTP +if PPTP_BUILTIN +builtin_vpn_modules += pptp +builtin_vpn_sources += vpn/plugins/pptp.c +builtin_vpn_source = vpn/plugins/vpn.c vpn/plugins/vpn.h +builtin_vpn_cflags += -DPPPD=\"@PPPD@\" -DPPTP=\"@PPTP@\" +else +vpn_plugin_LTLIBRARIES += vpn/plugins/pptp.la +vpn_plugin_objects += $(plugins_pptp_la_OBJECTS) +vpn_plugins_pptp_la_SOURCES = vpn/plugins/vpn.h vpn/plugins/vpn.c \ + vpn/plugins/pptp.c +vpn_plugins_pptp_la_CFLAGS = $(plugin_cflags) -DPPPD=\"@PPPD@\" \ + -DPPTP=\"@PPTP@\" \ + -DSTATEDIR=\""$(statedir)"\" \ + -DSCRIPTDIR=\""$(build_scriptdir)"\" +vpn_plugins_pptp_la_LDFLAGS = $(plugin_ldflags) +endif +endif + +if PPTP +script_LTLIBRARIES += scripts/libppp-plugin.la +scripts_libppp_plugin_la_LDFLAGS = $(script_cflags) @DBUS_CFLAGS@ +scripts_libppp_plugin_la_LIBADD = @DBUS_LIBS@ +else +if L2TP +script_LTLIBRARIES += scripts/libppp-plugin.la +scripts_libppp_plugin_la_LDFLAGS = $(script_cflags) @DBUS_CFLAGS@ +scripts_libppp_plugin_la_LIBADD = @DBUS_LIBS@ +endif +endif + +if VPN +builtin_vpn_sources += $(builtin_vpn_source) +endif +endif + +if PACRUNNER +builtin_modules += pacrunner +builtin_sources += plugins/pacrunner.c +endif + +if POLKIT +builtin_modules += polkit +builtin_sources += plugins/polkit.c + +if DATAFILES +policydir = @POLKIT_DATADIR@ + +policy_DATA = plugins/net.connman.policy + +if VPN +policy_DATA += vpn/net.connman.vpn.policy +endif +endif +endif + +if IOSPM +plugin_LTLIBRARIES += plugins/iospm.la +plugin_objects += $(plugins_iospm_la_OBJECTS) +plugins_iospm_la_CFLAGS = $(plugin_cflags) +plugins_iospm_la_LDFLAGS = $(plugin_ldflags) +endif + +if OPENCONNECT +script_PROGRAMS += scripts/openconnect-script + +scripts_openconnect_script_LDADD = @DBUS_LIBS@ +else +if VPNC +script_PROGRAMS += scripts/openconnect-script + +scripts_openconnect_script_LDADD = @DBUS_LIBS@ +endif +endif + +if OPENVPN +script_PROGRAMS += scripts/openvpn-script + +scripts_openvpn_script_LDADD = @DBUS_LIBS@ +endif + +if NMCOMPAT +builtin_modules += nmcompat +builtin_sources += plugins/nmcompat.c +endif + +if TIST +if TIST_BUILTIN +builtin_modules += tist +builtin_sources += plugins/tist.c +else +plugin_LTLIBRARIES += plugins/tist.la +plugin_objects += $(plugins_tist_la_OBJECTS) +plugins_tist_la_CFLAGS = $(plugin_cflags) +plugins_tist_la_LDFLAGS = $(plugin_ldflags) +endif +endif + +if SESSION_POLICY_LOCAL +if SESSION_POLICY_LOCAL_BUILTIN +builtin_modules += session_policy_local +builtin_sources += plugins/session_policy_local.c +else +plugin_LTLIBRARIES += plugins/session_policy_local.la +plugin_objects += $(plugins_session_policy_local_la_OBJECTS) +plugins_session_policy_local_la_CFLAGS = $(plugin_cflags) \ + -DSTORAGEDIR=\""$(storagedir)\"" +plugins_session_policy_local_la_LDFLAGS = $(plugin_ldflags) +endif +endif + +if NEARD +builtin_modules += neard +builtin_sources += plugins/neard.c +endif + +EXTRA_DIST += plugins/polkit.policy + +plugins/net.connman.policy: plugins/polkit.policy +if POLKIT + $(AM_V_GEN)cp $< $@ +endif + +EXTRA_DIST += vpn/vpn-polkit.policy + +if VPN +vpn/net.connman.vpn.policy: vpn/vpn-polkit.policy +if POLKIT + $(AM_V_GEN)cp $< $@ +endif +endif diff --git a/NEWS b/NEWS new file mode 100644 index 000000000..e69de29bb diff --git a/README b/README new file mode 100644 index 000000000..161c53527 --- /dev/null +++ b/README @@ -0,0 +1,326 @@ +Connection Manager +****************** + +Copyright (C) 2007-2012 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) + +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) + +Also plugins with additional features are available: + - Loopback interface setup + - PACrunner proxy handling + - PolicyKit authorization support + +Note that when ConnMan starts, it clears all network interfaces that are +going to be used. If this is not desired, network interfaces can be ignored +either by setting NetworkInterfaceBlacklist in the main.conf config file or +by using the -I command line option. + + +Compilation and installation +============================ + +In order to compile Connection Manager you need following software packages: + - GCC compiler + - GLib library + - D-Bus library + - IP-Tables library + - GnuTLS library (optional) + - PolicyKit (optional) + - readline (command line client) + +To configure run: + ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var + +Configure automatically searches for all required components and packages. + +To compile and install 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 + + 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. + + 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. + + --disable-ofono + + Disable support for cellular 2G/3G/4G devices + + 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. + + --disable-dundee + + Disable support for Bluetooth DUN devices + + 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. + + 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. + + --disable-pacrunner + + 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. + + 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. + + --disable-loopback + + Disable 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. + + --enable-polkit + + Enable support for PolicyKit authorization + + 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. + + --disable-client + + Disable support for the command line client + + By default the command line client is enabled and uses the + readline library. For specific systems where ConnMan is + configured by other means, the command line client can be + disabled and the dependency on readline is removed. + + --enable-selinux + + Enable support for compiling SElinux type enforcement rules + + The TE rules are needed if host environment is in enforcing + mode. Without this option, the VPN client process cannot + send notification to connman-vpnd via net.connman.Task + interface. The compiled connman-task.pp module needs to + also installed using this command + # semodule -i connman-task.pp + in order to enable the dbus access. + + +Activating debugging +==================== + +One can activate debugging prints in ConnMan using -d command line option. +If the -d option has no parameters, then debugging is activated for all +source code files. If the -d option has parameters, they tell which source +code files have debugging activated. One can use wild cards in file names. +Example: + -d Activate all normal debug prints + -d src/service.c This prints debugging info from src/service.c + file only + -d src/network.c:src/ipconfig.c + This activates debug prints in src/network.c + and src/ipconfig.c files. + -d 'src/n*.c' This would activate debug print from all the C source + files starting with letter 'n' in src directory. + Note the quotation marks around option, that is to + prevent shell expansion. + -d '*/n*.c:*/i*.c' Activate debug prints for all C source files starting + with letters 'n' or 'i' in any sub-directory. + +Some components of ConnMan have environment variable activated debug prints. +If the environment variable is set, then corresponding component will print +some extra debugging information. +Following environment variables can be used: + CONNMAN_DHCP_DEBUG DHCPv4 related debug information + CONNMAN_DHCPV6_DEBUG DHCPv6 related debug information + CONNMAN_IPTABLES_DEBUG Extra information when iptables is used + CONNMAN_RESOLV_DEBUG Name resolver debug prints. These debug prints + are used when ConnMan resolves host names for + its own use. + Note that the DNS proxy debug prints do not + use this environment variable. For that, one + can use "-d src/dnsproxy.c" command line option. + CONNMAN_SUPPLICANT_DEBUG Debugging prints for communication between + connmand and wpa_supplicant processes. + CONNMAN_WEB_DEBUG Debug information when ConnMan does Internet + connectivity check in Wispr and 6to4 components. + +Example: + CONNMAN_WEB_DEBUG=1 src/connmand -n + + +Kernel configuration +==================== + +In order to support tethering, the following kernel configuration options +need to be enabled either as modules (m) or builtin (y): + +CONFIG_BRIDGE +CONFIG_IP_NF_TARGET_MASQUERADE + +In order to enable CONFIG_IP_NF_TARGET_MASQUERADE, the following options need +to be enabled also as modules (m) or builtin (y): + +CONFIG_NETFILTER +CONFIG_NF_CONNTRACK_IPV4 +CONFIG_NF_NAT_IPV4 + + +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 + +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. + +and finally: + +CONFIG_AUTOSCAN_EXPONENTIAL=y + +This will enable the exact same function as bgscan but while being +disconnected. + +It is recommended to use wpa_supplicant 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 diff --git a/TODO b/TODO new file mode 100644 index 000000000..2ed6a489f --- /dev/null +++ b/TODO @@ -0,0 +1,225 @@ +Background +========== + +- Priority scale: High, Medium and Low + +- Complexity scale: C1, C2, C4 and C8. + The complexity scale is exponential, with complexity 1 being the + lowest complexity. Complexity is a function of both task 'complexity' + and task 'scope'. + + +Core +==== + +- Session API implementation + + Priority: High + Complexity: C4 + Owner: Daniel Wagner + Owner: Patrik Flykt + + The session API should provide a connection abstraction in order to + prioritize applications network accesses, prevent or allow network + and bearer roaming, or provide applications with a way to request + for periodic network connections. On-demand connections will be + implemented through this API as well. + See http://www.mail-archive.com/connman@connman.net/msg01653.html + + +- Personal firewall + + Priority: Low + Complexity: C8 + Owner: Tomasz Bursztyka + + Discuss and implement a basic and safe firewalling strategy into + Connman. Provide a D-Bus API for personal firewalling. + + +- PACRunner extensions + + Priority: Low + Complexity: C4 + + Support more URI schemes, support multiple connections, tighter + security integration. + + +- Check logging produced by connman_info() + + Priority: Medium + Complexity: C1 + + Check that logging produced by connman_info() contains meaningful messages + and get rid of the unnecessary ones. + + +- Support for multiple agents + + Priority: Medium + Complexity: C2 + + Allow to register multiple agents. Each unique system bus name owner + however is only allowed to register one agent. + + The selection of which agents is used should be matched by bus name + owner if possible or first come first serve. A graceful fallback to + the next agent should be also used in case of malfunctional agents. + +- Remove --nobacktrace option + + Priority: Medium + Complexity: C1 + When: 2.0 + + Remove the --nobacktrace option or change it to --backtrace depending on the + level of systemd integration or other factors. + + +- Clean up type definitions + + Priority: Medium + Complexity: C1 + + Go through variable types and use the following: + * bool from instead of connman_bool_t and gboolean, in the + latter case in those places it makes sense + + +- Clean up data structure usage + + Priority: Medium + Complexity: C4 + + Use hash tables, queues and lists in the code. Replace GSequences with + simpler structures. At the same time do a check on the currently used + data structures and see if something can be simplified. + + +- Unit tests for DHCP, DNS and HTTP + + Priority: Medium + Complexity: C4 + + Create unit tests for these components starting with DHCP. Use gtest + from GLib for this task similarly to what has been done for OBEX in Bluez + and oFono in general. + + +- DHCPv6 DECLINE message support + + Priority: Medium + Complexity: C2 + + +WiFi +==== + +- Clean up WiFi data structure usage + + Priority: Medium + Complexity: C2 + + Struct wifi_data is passed as a pointer in some of the wifi plugin + callbacks. For example removing a WiFi USB stick causes RTNL and + wpa_supplicant to call the wifi plugin at the same time causing the + freeing of the wifi data structure. Fix up the code to have proper + reference counting or other handling in place for the shared wifi data + and the members in the data structure. + + +- EAP-AKA/SIM + + Priority: Medium + Complexity: C2 + Owner: Samuel Ortiz + + This EAP is needed for SIM card based network authentication. + ConnMan here plays a minor role: Once wpa_supplicant is set up for + starting and EAP-AKA/SIM authentication, it will talk to a SIM card + through its pcsc-lite API. + + +- EAP-FAST + + Priority: Low + Complexity: C1 + + +- WiFi p2p + + Priority: Medium + Complexity: C2 + + +- Removing wpa_supplicant 0.7.x legacy support + + Priority: Low + Complexity: C1 + Owner: Tomasz Bursztyka + + 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 +========= + +- Remove Bluez 4.x support + + Priority: Low + Complexity: C1 + + Remove plugins/bluetooth-legacy.c support in about 6 month (July 2013) or + when Bluez 4.x usage becomes minimal. + +Cellular +======== + + +VPN +=== + +- IPsec + + Priority: Medium + Complexity: C4 + Owner: Jukka Rissanen + +- L2TP & PPTP compatibility prefix removal + + Priority: Medium + Complexity: C1 + When: connman 2.0 + + The VPN config file provisioning patchset contains code that makes + PPP options to be marked by "PPPD." prefix. The code supports also + old "L2TP." and "PPTP." prefix for PPP options. Remove the compatibility + code and only allow "PPPD." prefix for PPP options. + + +Tools +===== + +- Add Session mode, VPN and Clock API support to connmanctl command line tool + + Priority: Low + Complexity: C2 + + The connmanctl command line tool should support Session mode and VPN + Agent with a set of suitable commands used in both interactive and + non-interactive mode. Also add support for Clock API. + + +User Interface +============== + +- GNOME3 UI + + Priority: Low + Complexity: C4 + Owner: Alok Barsode + + A GNOME3 shell user interface would make it easier for mainstream distros + users to use ConnMan. diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 000000000..0a59871d8 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,61 @@ +AC_DEFUN([AC_PROG_CC_PIE], [ + AC_CACHE_CHECK([whether ${CC-cc} accepts -fPIE], ac_cv_prog_cc_pie, [ + echo 'void f(){}' > conftest.c + if test -z "`${CC-cc} -fPIE -pie -c conftest.c 2>&1`"; then + ac_cv_prog_cc_pie=yes + else + ac_cv_prog_cc_pie=no + fi + rm -rf conftest* + ]) +]) + +AC_DEFUN([COMPILER_FLAGS], [ + if (test "${CFLAGS}" = ""); then + CFLAGS="-Wall -O2 -D_FORTIFY_SOURCE=2" + fi + if (test "$USE_MAINTAINER_MODE" = "yes"); then + CFLAGS+=" -Werror -Wextra" + CFLAGS+=" -Wno-unused-parameter" + CFLAGS+=" -Wno-missing-field-initializers" + CFLAGS+=" -Wdeclaration-after-statement" + CFLAGS+=" -Wmissing-declarations" + CFLAGS+=" -Wredundant-decls" + CFLAGS+=" -Wcast-align" + CFLAGS="$CFLAGS -DG_DISABLE_DEPRECATED" + fi +]) + +AC_DEFUN([GTK_DOC_CHECK], +[ + AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first + AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first + dnl for overriding the documentation installation directory + AC_ARG_WITH([html-dir], + AS_HELP_STRING([--with-html-dir=PATH], [path to installed docs]),, + [with_html_dir='${datadir}/gtk-doc/html']) + HTML_DIR="$with_html_dir" + AC_SUBST([HTML_DIR]) + + dnl enable/disable documentation building + AC_ARG_ENABLE([gtk-doc], + AS_HELP_STRING([--enable-gtk-doc], + [use gtk-doc to build documentation [[default=no]]]),, + [enable_gtk_doc=no]) + + if test x$enable_gtk_doc = xyes; then + ifelse([$1],[], + [PKG_CHECK_EXISTS([gtk-doc],, + AC_MSG_ERROR([gtk-doc not installed and --enable-gtk-doc requested]))], + [PKG_CHECK_EXISTS([gtk-doc >= $1],, + AC_MSG_ERROR([You need to have gtk-doc >= $1 installed to build gtk-doc]))]) + fi + + AC_MSG_CHECKING([whether to build gtk-doc documentation]) + AC_MSG_RESULT($enable_gtk_doc) + + AC_PATH_PROGS(GTKDOC_CHECK,gtkdoc-check,) + + AM_CONDITIONAL([ENABLE_GTK_DOC], [test x$enable_gtk_doc = xyes]) + AM_CONDITIONAL([GTK_DOC_USE_LIBTOOL], [test -n "$LIBTOOL"]) +]) diff --git a/bootstrap b/bootstrap new file mode 100755 index 000000000..0dd71d917 --- /dev/null +++ b/bootstrap @@ -0,0 +1,7 @@ +#!/bin/sh + +aclocal && \ + autoheader && \ + libtoolize --automake --copy --force && \ + automake --add-missing --copy && \ + autoconf diff --git a/bootstrap-configure b/bootstrap-configure new file mode 100755 index 000000000..0741bcdac --- /dev/null +++ b/bootstrap-configure @@ -0,0 +1,24 @@ +#!/bin/sh + +if [ -f config.status ]; then + make maintainer-clean +fi + +if [ ! -f doc/gtk-doc.make ]; then + gtkdocize --copy --docdir doc +fi + +./bootstrap && \ + ./configure --enable-maintainer-mode \ + --enable-debug \ + --prefix=/usr \ + --mandir=/usr/share/man \ + --localstatedir=/var \ + --sysconfdir=/etc \ + --disable-datafiles \ + --enable-openconnect=builtin \ + --enable-openvpn=builtin \ + --enable-vpnc=builtin \ + --enable-session-policy-local=builtin \ + --enable-nmcompat \ + --enable-polkit $* diff --git a/client/agent.c b/client/agent.c new file mode 100644 index 000000000..5fe695fb3 --- /dev/null +++ b/client/agent.c @@ -0,0 +1,529 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2013 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "input.h" +#include "dbus_helpers.h" +#include "agent.h" + +static bool agent_registered = false; +static DBusMessage *agent_message = NULL; +static struct { + DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter dict; +} agent_reply = { }; + +#define AGENT_INTERFACE "net.connman.Agent" + +static void request_input_ssid_return(char *input); +static void request_input_passphrase_return(char *input); +static void request_input_string_return(char *input); + +static int confirm_input(char *input) +{ + int i; + + if (input == NULL) + return -1; + + for (i = 0; input[i] != '\0'; i++) + if (isspace(input[i]) == 0) + break; + + if (strcasecmp(&input[i], "yes") == 0 || + strcasecmp(&input[i], "y") == 0) + return 1; + + if (strcasecmp(&input[i], "no") == 0 || + strcasecmp(&input[i], "n") == 0) + return 0; + + return -1; +} + +static char *strip_path(char *path) +{ + char *name = strrchr(path, '/'); + if (name != NULL) + name++; + else + name = path; + + return name; +} + +static char *agent_path(void) +{ + static char *path = NULL; + + if (path == NULL) + path = g_strdup_printf("/net/connman/connmanctl%d", getpid()); + + return path; +} + +static void pending_message_remove() +{ + if (agent_message != NULL) { + dbus_message_unref(agent_message); + agent_message = NULL; + } + + if (agent_reply.reply != NULL) { + dbus_message_unref(agent_reply.reply); + agent_reply.reply = NULL; + } +} + +static void pending_command_complete(char *message) +{ + __connmanctl_save_rl(); + + fprintf(stdout, "%s", message); + + __connmanctl_redraw_rl(); + + if (__connmanctl_is_interactive() == true) + __connmanctl_command_mode(); + else + __connmanctl_agent_mode("", NULL); +} + +static DBusMessage *agent_release(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + g_dbus_unregister_interface(connection, agent_path(), AGENT_INTERFACE); + agent_registered = false; + + pending_message_remove(); + pending_command_complete("Agent unregistered by ConnMan\n"); + + if (__connmanctl_is_interactive() == false) + __connmanctl_quit(); + + return dbus_message_new_method_return(message); +} + +static DBusMessage *agent_cancel(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + pending_message_remove(); + pending_command_complete("Agent request cancelled by ConnMan\n"); + + return dbus_message_new_method_return(message); +} + +static DBusConnection *agent_connection = NULL; + +static void request_browser_return(char *input) +{ + switch (confirm_input(input)) { + case 1: + g_dbus_send_reply(agent_connection, agent_message, + DBUS_TYPE_INVALID); + break; + case 0: + g_dbus_send_error(agent_connection, agent_message, + "net.connman.Agent.Error.Canceled", NULL); + break; + default: + return; + } + + pending_message_remove(); + pending_command_complete(""); +} + +static DBusMessage *agent_request_browser(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + DBusMessageIter iter; + char *service, *url; + + dbus_message_iter_init(message, &iter); + + dbus_message_iter_get_basic(&iter, &service); + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &url); + + __connmanctl_save_rl(); + fprintf(stdout, "Agent RequestBrowser %s\n", strip_path(service)); + fprintf(stdout, " %s\n", url); + __connmanctl_redraw_rl(); + + agent_connection = connection; + agent_message = dbus_message_ref(message); + __connmanctl_agent_mode("Connected (yes/no)? ", + request_browser_return); + + return NULL; +} + +static void report_error_return(char *input) +{ + switch (confirm_input(input)) { + case 1: + g_dbus_send_error(agent_connection, agent_message, + "net.connman.Agent.Error.Retry", NULL); + break; + case 0: + g_dbus_send_reply(agent_connection, agent_message, + DBUS_TYPE_INVALID); + break; + default: + return; + } + + pending_message_remove(); + pending_command_complete(""); +} + +static DBusMessage *agent_report_error(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + DBusMessageIter iter; + char *path, *service, *error; + + dbus_message_iter_init(message, &iter); + + dbus_message_iter_get_basic(&iter, &path); + service = strip_path(path); + + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &error); + + __connmanctl_save_rl(); + fprintf(stdout, "Agent ReportError %s\n", service); + fprintf(stdout, " %s\n", error); + __connmanctl_redraw_rl(); + + agent_connection = connection; + agent_message = dbus_message_ref(message); + __connmanctl_agent_mode("Retry (yes/no)? ", report_error_return); + + return NULL; +} + +enum requestinput { + SSID = 0, + IDENTITY = 1, + PASSPHRASE = 2, + WPS = 3, + WISPR_USERNAME = 4, + WISPR_PASSPHRASE = 5, + REQUEST_INPUT_MAX = 6, +}; + +static struct { + const char *attribute; + bool requested; + char *prompt; + connmanctl_input_func_t *func; +} agent_input[] = { + { "Name", false, "Hidden SSID name? ", request_input_ssid_return }, + { "Identity", false, "EAP username? ", request_input_string_return }, + { "Passphrase", false, "Passphrase? ", + request_input_passphrase_return }, + { "WPS", false, "WPS PIN (empty line for pushbutton)? " , + request_input_string_return }, + { "Username", false, "WISPr username? ", request_input_string_return }, + { "Password", false, "WISPr password? ", request_input_string_return }, + { }, +}; + +static void request_input_next(void) +{ + int i; + + for (i = 0; agent_input[i].attribute != NULL; i++) { + if (agent_input[i].requested == true) { + if(agent_input[i].func != NULL) + __connmanctl_agent_mode(agent_input[i].prompt, + agent_input[i].func); + else + agent_input[i].requested = false; + return; + } + } + + dbus_message_iter_close_container(&agent_reply.iter, + &agent_reply.dict); + + g_dbus_send_message(agent_connection, agent_reply.reply); + agent_reply.reply = NULL; + + pending_message_remove(); + pending_command_complete(""); +} + +static void request_input_append(const char *attribute, char *value) +{ + __connmanctl_dbus_append_dict_entry(&agent_reply.dict, attribute, + DBUS_TYPE_STRING, &value); +} + +static void request_input_ssid_return(char *input) +{ + int len = 0; + + if (input != NULL) + len = strlen(input); + + if (len > 0 && len <= 32) { + agent_input[SSID].requested = false; + request_input_append(agent_input[SSID].attribute, input); + + request_input_next(); + } +} + +static void request_input_passphrase_return(char *input) +{ + /* TBD passphrase length checking */ + + if (input != NULL && strlen(input) > 0) { + agent_input[PASSPHRASE].requested = false; + request_input_append(agent_input[PASSPHRASE].attribute, input); + + agent_input[WPS].requested = false; + + request_input_next(); + } +} + +static void request_input_string_return(char *input) +{ + int i; + + for (i = 0; agent_input[i].attribute != NULL; i++) { + if (agent_input[i].requested == true) { + request_input_append(agent_input[i].attribute, input); + agent_input[i].requested = false; + break; + } + } + + request_input_next(); +} + +static DBusMessage *agent_request_input(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + DBusMessageIter iter, dict, entry, variant; + char *service, *str, *field; + DBusMessageIter dict_entry, field_entry, field_value; + char *argument, *value, *attr_type; + + int i; + + dbus_message_iter_init(message, &iter); + + dbus_message_iter_get_basic(&iter, &str); + service = strip_path(str); + + dbus_message_iter_next(&iter); + dbus_message_iter_recurse(&iter, &dict); + + __connmanctl_save_rl(); + fprintf(stdout, "Agent RequestInput %s\n", service); + __connmanctl_dbus_print(&dict, " ", " = ", "\n"); + fprintf(stdout, "\n"); + __connmanctl_redraw_rl(); + + dbus_message_iter_recurse(&iter, &dict); + + while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) { + + dbus_message_iter_recurse(&dict, &entry); + + dbus_message_iter_get_basic(&entry, &field); + + dbus_message_iter_next(&entry); + + dbus_message_iter_recurse(&entry, &variant); + dbus_message_iter_recurse(&variant, &dict_entry); + + while (dbus_message_iter_get_arg_type(&dict_entry) + == DBUS_TYPE_DICT_ENTRY) { + dbus_message_iter_recurse(&dict_entry, &field_entry); + + dbus_message_iter_get_basic(&field_entry, &argument); + + dbus_message_iter_next(&field_entry); + + dbus_message_iter_recurse(&field_entry, &field_value); + + dbus_message_iter_get_basic(&field_value, &value); + + if (strcmp(argument, "Type") == 0) + attr_type = g_strdup(value); + + dbus_message_iter_next(&dict_entry); + } + + for (i = 0; agent_input[i].attribute != NULL; i++) { + if (strcmp(field, agent_input[i].attribute) == 0) { + agent_input[i].requested = true; + break; + } + } + + g_free(attr_type); + attr_type = NULL; + + dbus_message_iter_next(&dict); + } + + agent_connection = connection; + agent_reply.reply = dbus_message_new_method_return(message); + dbus_message_iter_init_append(agent_reply.reply, &agent_reply.iter); + + dbus_message_iter_open_container(&agent_reply.iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &agent_reply.dict); + + request_input_next(); + + return NULL; +} + +static const GDBusMethodTable agent_methods[] = { + { GDBUS_METHOD("Release", NULL, NULL, agent_release) }, + { GDBUS_METHOD("Cancel", NULL, NULL, agent_cancel) }, + { GDBUS_ASYNC_METHOD("RequestBrowser", + GDBUS_ARGS({ "service", "o" }, + { "url", "s" }), + NULL, agent_request_browser) }, + { GDBUS_ASYNC_METHOD("ReportError", + GDBUS_ARGS({ "service", "o" }, + { "error", "s" }), + NULL, agent_report_error) }, + { GDBUS_ASYNC_METHOD("RequestInput", + GDBUS_ARGS({ "service", "o" }, + { "fields", "a{sv}" }), + GDBUS_ARGS({ "fields", "a{sv}" }), + agent_request_input) }, + { }, +}; + +static int agent_register_return(DBusMessageIter *iter, const char *error, + void *user_data) +{ + DBusConnection *connection = user_data; + + if (error != NULL) { + g_dbus_unregister_interface(connection, agent_path(), + AGENT_INTERFACE); + fprintf(stderr, "Error registering Agent: %s\n", error); + return 0; + } + + agent_registered = true; + fprintf(stdout, "Agent registered\n"); + + return -EINPROGRESS; +} + +int __connmanctl_agent_register(DBusConnection *connection) +{ + char *path = agent_path(); + int result; + + if (agent_registered == true) { + fprintf(stderr, "Agent already registered\n"); + return -EALREADY; + } + + if (g_dbus_register_interface(connection, path, + AGENT_INTERFACE, agent_methods, + NULL, NULL, connection, + NULL) == FALSE) { + fprintf(stderr, "Error: Failed to register Agent callbacks\n"); + return 0; + } + + result = __connmanctl_dbus_method_call(connection, "/", + "net.connman.Manager", "RegisterAgent", + agent_register_return, connection, + DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); + + if (result != -EINPROGRESS) { + g_dbus_unregister_interface(connection, agent_path(), + AGENT_INTERFACE); + + fprintf(stderr, "Error: Failed to register Agent\n"); + } + + return result; +} + +static int agent_unregister_return(DBusMessageIter *iter, const char *error, + void *user_data) +{ + if (error != NULL) { + fprintf(stderr, "Error unregistering Agent: %s\n", error); + return 0; + } + + agent_registered = false; + fprintf(stdout, "Agent unregistered\n"); + + return 0; +} + +int __connmanctl_agent_unregister(DBusConnection *connection) +{ + char *path = agent_path(); + int result; + + if (agent_registered == false) { + fprintf(stderr, "Agent not registered\n"); + return -EALREADY; + } + + g_dbus_unregister_interface(connection, agent_path(), AGENT_INTERFACE); + + result = __connmanctl_dbus_method_call(connection, "/", + "net.connman.Manager", "UnregisterAgent", + agent_unregister_return, NULL, + DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); + + if (result != -EINPROGRESS) + fprintf(stderr, "Error: Failed to unregister Agent\n"); + + return result; +} diff --git a/client/agent.h b/client/agent.h new file mode 100644 index 000000000..d6eaac9e6 --- /dev/null +++ b/client/agent.h @@ -0,0 +1,39 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2013 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 + * + */ + +#ifndef __CONNMANCTL_AGENT_H +#define __CONNMANCTL_AGENT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int __connmanctl_agent_register(DBusConnection *connection); +int __connmanctl_agent_unregister(DBusConnection *connection); + +#ifdef __cplusplus +} +#endif + +#endif /* __CONNMANCTL_AGENT_H */ diff --git a/client/commands.c b/client/commands.c new file mode 100644 index 000000000..1a87c5395 --- /dev/null +++ b/client/commands.c @@ -0,0 +1,1383 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2012-2013 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "dbus_helpers.h" +#include "input.h" +#include "services.h" +#include "commands.h" +#include "agent.h" + +static DBusConnection *connection; + +struct connman_option { + const char *name; + const char val; + const char *desc; +}; + +static char *ipv4[] = { + "Method", + "Address", + "Netmask", + "Gateway", + NULL +}; + +static char *ipv6[] = { + "Method", + "Address", + "PrefixLength", + "Gateway", + NULL +}; + +static int cmd_help(char *args[], int num, struct connman_option *options); + +static bool check_dbus_name(const char *name) +{ + /* + * Valid dbus chars should be [A-Z][a-z][0-9]_ + * and should not start with number. + */ + unsigned int i; + + if (name == NULL || name[0] == '\0' || (name[0] >= '0' && + name[0] <= '9')) + return false; + + for (i = 0; name[i] != '\0'; i++) + if (!((name[i] >= 'A' && name[i] <= 'Z') || + (name[i] >= 'a' && name[i] <= 'z') || + (name[i] >= '0' && name[i] <= '9') || + name[i] == '_')) + return false; + + return true; +} + +static int parse_boolean(char *arg) +{ + if (arg == NULL) + return -1; + + if (strcasecmp(arg, "no") == 0 || + strcasecmp(arg, "false") == 0 || + strcasecmp(arg, "off" ) == 0 || + strcasecmp(arg, "disable" ) == 0 || + strcasecmp(arg, "n") == 0 || + strcasecmp(arg, "f") == 0 || + strcasecmp(arg, "0") == 0) + return 0; + + if (strcasecmp(arg, "yes") == 0 || + strcasecmp(arg, "true") == 0 || + strcasecmp(arg, "on") == 0 || + strcasecmp(arg, "enable" ) == 0 || + strcasecmp(arg, "y") == 0 || + strcasecmp(arg, "t") == 0 || + strcasecmp(arg, "1") == 0) + return 1; + + return -1; +} + +static int parse_args(char *arg, struct connman_option *options) +{ + int i; + + if (arg == NULL) + return -1; + + for (i = 0; options[i].name != NULL; i++) { + if (strcmp(options[i].name, arg) == 0 || + (strncmp(arg, "--", 2) == 0 && + strcmp(&arg[2], options[i].name) == 0)) + return options[i].val; + } + + return '?'; +} + +static int enable_return(DBusMessageIter *iter, const char *error, + void *user_data) +{ + char *tech = user_data; + char *str; + + str = strrchr(tech, '/'); + if (str != NULL) + str++; + else + str = tech; + + if (error == NULL) { + fprintf(stdout, "Enabled %s\n", str); + } else + fprintf(stderr, "Error %s: %s\n", str, error); + + g_free(user_data); + + return 0; +} + +static int cmd_enable(char *args[], int num, struct connman_option *options) +{ + char *tech; + dbus_bool_t b = TRUE; + + if (num > 2) + return -E2BIG; + + if (num < 2) + return -EINVAL; + + if (check_dbus_name(args[1]) == false) + return -EINVAL; + + if (strcmp(args[1], "offlinemode") == 0) { + tech = g_strdup(args[1]); + return __connmanctl_dbus_set_property(connection, "/", + "net.connman.Manager", enable_return, tech, + "OfflineMode", DBUS_TYPE_BOOLEAN, &b); + } + + tech = g_strdup_printf("/net/connman/technology/%s", args[1]); + return __connmanctl_dbus_set_property(connection, tech, + "net.connman.Technology", enable_return, tech, + "Powered", DBUS_TYPE_BOOLEAN, &b); +} + +static int disable_return(DBusMessageIter *iter, const char *error, + void *user_data) +{ + char *tech = user_data; + char *str; + + str = strrchr(tech, '/'); + if (str != NULL) + str++; + else + str = tech; + + if (error == NULL) { + fprintf(stdout, "Disabled %s\n", str); + } else + fprintf(stderr, "Error %s: %s\n", str, error); + + g_free(user_data); + + return 0; +} + +static int cmd_disable(char *args[], int num, struct connman_option *options) +{ + char *tech; + dbus_bool_t b = FALSE; + + if (num > 2) + return -E2BIG; + + if (num < 2) + return -EINVAL; + + if (check_dbus_name(args[1]) == false) + return -EINVAL; + + if (strcmp(args[1], "offlinemode") == 0) { + tech = g_strdup(args[1]); + return __connmanctl_dbus_set_property(connection, "/", + "net.connman.Manager", disable_return, tech, + "OfflineMode", DBUS_TYPE_BOOLEAN, &b); + } + + tech = g_strdup_printf("/net/connman/technology/%s", args[1]); + return __connmanctl_dbus_set_property(connection, tech, + "net.connman.Technology", disable_return, tech, + "Powered", DBUS_TYPE_BOOLEAN, &b); +} + +static int state_print(DBusMessageIter *iter, const char *error, + void *user_data) +{ + DBusMessageIter entry; + + if (error != NULL) { + fprintf(stderr, "Error: %s", error); + return 0; + } + + dbus_message_iter_recurse(iter, &entry); + __connmanctl_dbus_print(&entry, " ", " = ", "\n"); + fprintf(stdout, "\n"); + + return 0; +} + +static int cmd_state(char *args[], int num, struct connman_option *options) +{ + if (num > 1) + return -E2BIG; + + return __connmanctl_dbus_method_call(connection, "/", + "net.connman.Manager", "GetProperties", + state_print, NULL, DBUS_TYPE_INVALID); +} + +static int services_list(DBusMessageIter *iter, const char *error, + void *user_data) +{ + if (error == NULL) { + __connmanctl_services_list(iter); + fprintf(stdout, "\n"); + } else { + fprintf(stderr, "Error: %s\n", error); + } + + return 0; +} + +static int services_properties(DBusMessageIter *iter, const char *error, + void *user_data) +{ + char *path = user_data; + char *str; + DBusMessageIter dict; + + if (error == NULL) { + fprintf(stdout, "%s\n", path); + + dbus_message_iter_recurse(iter, &dict); + __connmanctl_dbus_print(&dict, " ", " = ", "\n"); + + fprintf(stdout, "\n"); + + } else { + str = strrchr(path, '/'); + if (str != NULL) + str++; + else + str = path; + + fprintf(stderr, "Error %s: %s\n", str, error); + } + + g_free(user_data); + + return 0; +} + +static int cmd_services(char *args[], int num, struct connman_option *options) +{ + char *service_name = NULL; + char *path; + int c; + + if (num > 3) + return -E2BIG; + + c = parse_args(args[1], options); + switch (c) { + case -1: + break; + case 'p': + if (num < 3) + return -EINVAL; + service_name = args[2]; + break; + default: + if (num > 2) + return -E2BIG; + service_name = args[1]; + break; + } + + if (service_name == NULL) { + return __connmanctl_dbus_method_call(connection, "/", + "net.connman.Manager", "GetServices", + services_list, NULL, DBUS_TYPE_INVALID); + } + + if (check_dbus_name(service_name) == false) + return -EINVAL; + + path = g_strdup_printf("/net/connman/service/%s", service_name); + return __connmanctl_dbus_method_call(connection, path, + "net.connman.Service", "GetProperties", + services_properties, path, DBUS_TYPE_INVALID); +} + +static int technology_print(DBusMessageIter *iter, const char *error, + void *user_data) +{ + DBusMessageIter array; + + if (error != NULL) { + fprintf(stderr, "Error: %s\n", error); + return 0; + } + + dbus_message_iter_recurse(iter, &array); + while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) { + DBusMessageIter entry, dict; + const char *path; + + dbus_message_iter_recurse(&array, &entry); + dbus_message_iter_get_basic(&entry, &path); + fprintf(stdout, "%s\n", path); + + dbus_message_iter_next(&entry); + + dbus_message_iter_recurse(&entry, &dict); + __connmanctl_dbus_print(&dict, " ", " = ", "\n"); + fprintf(stdout, "\n"); + + dbus_message_iter_next(&array); + } + + return 0; +} + +static int cmd_technologies(char *args[], int num, + struct connman_option *options) +{ + if (num > 1) + return -E2BIG; + + return __connmanctl_dbus_method_call(connection, "/", + "net.connman.Manager", "GetTechnologies", + technology_print, NULL, DBUS_TYPE_INVALID); +} + +struct tether_enable { + char *path; + dbus_bool_t enable; +}; + +static int tether_set_return(DBusMessageIter *iter, const char *error, + void *user_data) +{ + struct tether_enable *tether = user_data; + char *str; + + str = strrchr(tether->path, '/'); + if (str != NULL) + str++; + else + str = tether->path; + + if (error == NULL) { + fprintf(stdout, "%s tethering for %s\n", + tether->enable == TRUE ? "Enabled": "Disabled", + str); + } else + fprintf(stderr, "Error %s %s tethering: %s\n", + tether->enable == TRUE ? + "enabling": "disabling", str, error); + + g_free(tether->path); + g_free(user_data); + + return 0; +} + +static int tether_set(char *technology, int set_tethering) +{ + struct tether_enable *tether = g_new(struct tether_enable, 1); + + switch(set_tethering) { + case 1: + tether->enable = TRUE; + break; + case 0: + tether->enable = FALSE; + break; + default: + g_free(tether); + return 0; + } + + tether->path = g_strdup_printf("/net/connman/technology/%s", + technology); + + return __connmanctl_dbus_set_property(connection, tether->path, + "net.connman.Technology", tether_set_return, + tether, "Tethering", DBUS_TYPE_BOOLEAN, + &tether->enable); +} + +struct tether_properties { + int ssid_result; + int passphrase_result; + int set_tethering; +}; + +static int tether_update(struct tether_properties *tether) +{ + printf("%d %d %d\n", tether->ssid_result, tether->passphrase_result, + tether->set_tethering); + + if (tether->ssid_result == 0 && tether->passphrase_result == 0) + return tether_set("wifi", tether->set_tethering); + + if (tether->ssid_result != -EINPROGRESS && + tether->passphrase_result != -EINPROGRESS) { + g_free(tether); + return 0; + } + + return -EINPROGRESS; +} + +static int tether_set_ssid_return(DBusMessageIter *iter, const char *error, + void *user_data) +{ + struct tether_properties *tether = user_data; + + if (error == NULL) { + fprintf(stdout, "Wifi SSID set\n"); + tether->ssid_result = 0; + } else { + fprintf(stderr, "Error setting wifi SSID: %s\n", error); + tether->ssid_result = -EINVAL; + } + + return tether_update(tether); +} + +static int tether_set_passphrase_return(DBusMessageIter *iter, + const char *error, void *user_data) +{ + struct tether_properties *tether = user_data; + + if (error == NULL) { + fprintf(stdout, "Wifi passphrase set\n"); + tether->passphrase_result = 0; + } else { + fprintf(stderr, "Error setting wifi passphrase: %s\n", error); + tether->passphrase_result = -EINVAL; + } + + return tether_update(tether); +} + +static int tether_set_ssid(char *ssid, char *passphrase, int set_tethering) +{ + struct tether_properties *tether = g_new(struct tether_properties, 1); + + tether->set_tethering = set_tethering; + + tether->ssid_result = __connmanctl_dbus_set_property(connection, + "/net/connman/technology/wifi", + "net.connman.Technology", + tether_set_ssid_return, tether, + "TetheringIdentifier", DBUS_TYPE_STRING, &ssid); + + tether->passphrase_result =__connmanctl_dbus_set_property(connection, + "/net/connman/technology/wifi", + "net.connman.Technology", + tether_set_passphrase_return, tether, + "TetheringPassphrase", DBUS_TYPE_STRING, &passphrase); + + if (tether->ssid_result != -EINPROGRESS && + tether->passphrase_result != -EINPROGRESS) { + g_free(tether); + return -ENXIO; + } + + return -EINPROGRESS; +} + +static int cmd_tether(char *args[], int num, struct connman_option *options) +{ + char *ssid, *passphrase; + int set_tethering; + + if (num < 3) + return -EINVAL; + + passphrase = args[num - 1]; + ssid = args[num - 2]; + + set_tethering = parse_boolean(args[2]); + + if (strcmp(args[1], "wifi") == 0) { + + if (num > 5) + return -E2BIG; + + if (num == 5 && set_tethering == -1) + return -EINVAL; + + if (num == 4) + set_tethering = -1; + + if (num > 3) + return tether_set_ssid(ssid, passphrase, set_tethering); + } + + if (num > 3) + return -E2BIG; + + if (set_tethering == -1) + return -EINVAL; + + if (check_dbus_name(args[1]) == false) + return -EINVAL; + + return tether_set(args[1], set_tethering); +} + +static int scan_return(DBusMessageIter *iter, const char *error, + void *user_data) +{ + char *path = user_data; + + if (error == NULL) { + char *str = strrchr(path, '/'); + str++; + fprintf(stdout, "Scan completed for %s\n", str); + } else + fprintf(stderr, "Error %s: %s\n", path, error); + + g_free(user_data); + + return 0; +} + +static int cmd_scan(char *args[], int num, struct connman_option *options) +{ + char *path; + + if (num > 2) + return -E2BIG; + + if (num < 2) + return -EINVAL; + + if (check_dbus_name(args[1]) == false) + return -EINVAL; + + path = g_strdup_printf("/net/connman/technology/%s", args[1]); + return __connmanctl_dbus_method_call(connection, path, + "net.connman.Technology", "Scan", + scan_return, path, DBUS_TYPE_INVALID); +} + +static int connect_return(DBusMessageIter *iter, const char *error, + void *user_data) +{ + char *path = user_data; + + if (error == NULL) { + char *str = strrchr(path, '/'); + str++; + fprintf(stdout, "Connected %s\n", str); + } else + fprintf(stderr, "Error %s: %s\n", path, error); + + g_free(user_data); + + return 0; +} + +static int cmd_connect(char *args[], int num, struct connman_option *options) +{ + char *path; + + if (num > 2) + return -E2BIG; + + if (num < 2) + return -EINVAL; + + if (check_dbus_name(args[1]) == false) + return -EINVAL; + + path = g_strdup_printf("/net/connman/service/%s", args[1]); + return __connmanctl_dbus_method_call(connection, path, + "net.connman.Service", "Connect", + connect_return, path, DBUS_TYPE_INVALID); +} + +static int disconnect_return(DBusMessageIter *iter, const char *error, + void *user_data) +{ + char *path = user_data; + + if (error == NULL) { + char *str = strrchr(path, '/'); + str++; + fprintf(stdout, "Disconnected %s\n", str); + } else + fprintf(stderr, "Error %s: %s\n", path, error); + + g_free(user_data); + + return 0; +} + +static int cmd_disconnect(char *args[], int num, struct connman_option *options) +{ + char *path; + + if (num > 2) + return -E2BIG; + + if (num < 2) + return -EINVAL; + + if (check_dbus_name(args[1]) == false) + return -EINVAL; + + path = g_strdup_printf("/net/connman/service/%s", args[1]); + return __connmanctl_dbus_method_call(connection, path, + "net.connman.Service", "Disconnect", + disconnect_return, path, DBUS_TYPE_INVALID); +} + +static int config_return(DBusMessageIter *iter, const char *error, + void *user_data) +{ + char *service_name = user_data; + + if (error != NULL) + fprintf(stderr, "Error %s: %s\n", service_name, error); + + g_free(user_data); + + return 0; +} + +struct config_append { + char **opts; + int values; +}; + +static void config_append_ipv4(DBusMessageIter *iter, + void *user_data) +{ + struct config_append *append = user_data; + char **opts = append->opts; + int i = 0; + + if (opts == NULL) + return; + + while (opts[i] != NULL && ipv4[i] != NULL) { + __connmanctl_dbus_append_dict_entry(iter, ipv4[i], + DBUS_TYPE_STRING, &opts[i]); + i++; + } + + append->values = i; +} + +static void config_append_ipv6(DBusMessageIter *iter, void *user_data) +{ + struct config_append *append = user_data; + char **opts = append->opts; + + if (opts == NULL) + return; + + append->values = 1; + + if (g_strcmp0(opts[0], "auto") == 0) { + char *str; + + switch (parse_boolean(opts[1])) { + case 0: + append->values = 2; + + str = "disabled"; + __connmanctl_dbus_append_dict_entry(iter, "Privacy", + DBUS_TYPE_STRING, &str); + break; + + case 1: + append->values = 2; + + str = "enabled"; + __connmanctl_dbus_append_dict_entry(iter, "Privacy", + DBUS_TYPE_STRING, &str); + break; + + default: + if (opts[1] != NULL) { + append->values = 2; + + if (g_strcmp0(opts[1], "prefered") != 0 && + g_strcmp0(opts[1], + "preferred") != 0) { + fprintf(stderr, "Error %s: %s\n", + opts[1], + strerror(EINVAL)); + return; + } + + str = "prefered"; + __connmanctl_dbus_append_dict_entry(iter, + "Privacy", DBUS_TYPE_STRING, + &str); + } + break; + } + } else if (g_strcmp0(opts[0], "manual") == 0) { + int i = 1; + + while (opts[i] != NULL && ipv6[i] != NULL) { + if (i == 2) { + int value = atoi(opts[i]); + __connmanctl_dbus_append_dict_entry(iter, + ipv6[i], DBUS_TYPE_BYTE, + &value); + } else { + __connmanctl_dbus_append_dict_entry(iter, + ipv6[i], DBUS_TYPE_STRING, + &opts[i]); + } + i++; + } + + append->values = i; + + } else if (g_strcmp0(opts[0], "off") != 0) { + fprintf(stderr, "Error %s: %s\n", opts[0], strerror(-EINVAL)); + + return; + } + + __connmanctl_dbus_append_dict_entry(iter, "Method", DBUS_TYPE_STRING, + &opts[0]); +} + +static void config_append_str(DBusMessageIter *iter, void *user_data) +{ + struct config_append *append = user_data; + char **opts = append->opts; + int i = 0; + + if (opts == NULL) + return; + + while (opts[i] != NULL) { + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, + &opts[i]); + i++; + } + + append->values = i; +} + +static void append_servers(DBusMessageIter *iter, void *user_data) +{ + struct config_append *append = user_data; + char **opts = append->opts; + int i = 1; + + if (opts == NULL) + return; + + while (opts[i] != NULL && g_strcmp0(opts[i], "--excludes") != 0) { + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, + &opts[i]); + i++; + } + + append->values = i; +} + +static void append_excludes(DBusMessageIter *iter, void *user_data) +{ + struct config_append *append = user_data; + char **opts = append->opts; + int i = append->values; + + if (opts == NULL || opts[i] == NULL || + g_strcmp0(opts[i], "--excludes") != 0) + return; + + i++; + while (opts[i] != NULL) { + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, + &opts[i]); + i++; + } + + append->values = i; +} + +static void config_append_proxy(DBusMessageIter *iter, void *user_data) +{ + struct config_append *append = user_data; + char **opts = append->opts; + + if (opts == NULL) + return; + + if (g_strcmp0(opts[0], "manual") == 0) { + __connmanctl_dbus_append_dict_string_array(iter, "Servers", + append_servers, append); + + __connmanctl_dbus_append_dict_string_array(iter, "Excludes", + append_excludes, append); + + } else if (g_strcmp0(opts[0], "auto") == 0) { + if (opts[1] != NULL) { + __connmanctl_dbus_append_dict_entry(iter, "URL", + DBUS_TYPE_STRING, &opts[1]); + append->values++; + } + + } else if (g_strcmp0(opts[0], "direct") != 0) + return; + + __connmanctl_dbus_append_dict_entry(iter, "Method",DBUS_TYPE_STRING, + &opts[0]); + + append->values++; +} + +static int cmd_config(char *args[], int num, struct connman_option *options) +{ + int result = 0, res = 0, index = 2, oldindex = 0; + int c; + char *service_name, *path; + char **opt_start; + dbus_bool_t val; + struct config_append append; + + service_name = args[1]; + if (service_name == NULL) + return -EINVAL; + + if (check_dbus_name(service_name) == false) + return -EINVAL; + + while (index < num && args[index] != NULL) { + c = parse_args(args[index], options); + opt_start = &args[index + 1]; + append.opts = opt_start; + append.values = 0; + + res = 0; + + oldindex = index; + path = g_strdup_printf("/net/connman/service/%s", service_name); + + switch (c) { + case 'a': + switch (parse_boolean(*opt_start)) { + case 1: + val = TRUE; + break; + case 0: + val = FALSE; + break; + default: + res = -EINVAL; + break; + } + + index++; + + if (res == 0) { + res = __connmanctl_dbus_set_property(connection, + path, "net.connman.Service", + config_return, + g_strdup(service_name), + "AutoConnect", + DBUS_TYPE_BOOLEAN, &val); + } + break; + case 'i': + res = __connmanctl_dbus_set_property_dict(connection, + path, "net.connman.Service", + config_return, g_strdup(service_name), + "IPv4.Configuration", DBUS_TYPE_STRING, + config_append_ipv4, &append); + index += append.values; + break; + + case 'v': + res = __connmanctl_dbus_set_property_dict(connection, + path, "net.connman.Service", + config_return, g_strdup(service_name), + "IPv6.Configuration", DBUS_TYPE_STRING, + config_append_ipv6, &append); + index += append.values; + break; + + case 'n': + res = __connmanctl_dbus_set_property_array(connection, + path, "net.connman.Service", + config_return, g_strdup(service_name), + "Nameservers.Configuration", + DBUS_TYPE_STRING, config_append_str, + &append); + index += append.values; + break; + + case 't': + res = __connmanctl_dbus_set_property_array(connection, + path, "net.connman.Service", + config_return, g_strdup(service_name), + "Timeservers.Configuration", + DBUS_TYPE_STRING, config_append_str, + &append); + index += append.values; + break; + + case 'd': + res = __connmanctl_dbus_set_property_array(connection, + path, "net.connman.Service", + config_return, g_strdup(service_name), + "Domains.Configuration", + DBUS_TYPE_STRING, config_append_str, + &append); + index += append.values; + break; + + case 'x': + res = __connmanctl_dbus_set_property_dict(connection, + path, "net.connman.Service", + config_return, g_strdup(service_name), + "Proxy.Configuration", + DBUS_TYPE_STRING, config_append_proxy, + &append); + index += append.values; + break; + case 'r': + res = __connmanctl_dbus_method_call(connection, + path, "net.connman.Service", "Remove", + config_return, g_strdup(service_name), + DBUS_TYPE_INVALID); + break; + default: + res = -EINVAL; + break; + } + + g_free(path); + + if (res < 0) { + if (res == -EINPROGRESS) + result = -EINPROGRESS; + else + printf("Error '%s': %s\n", args[oldindex], + strerror(-res)); + } else + index += res; + + index++; + } + + return result; +} + +static DBusHandlerResult monitor_changed(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + DBusMessageIter iter; + const char *interface, *path; + + interface = dbus_message_get_interface(message); + if (strncmp(interface, "net.connman.", 12) != 0) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + interface = strrchr(interface, '.'); + if (interface != NULL && *interface != '\0') + interface++; + + path = strrchr(dbus_message_get_path(message), '/'); + if (path != NULL && *path != '\0') + path++; + + __connmanctl_save_rl(); + + if (dbus_message_is_signal(message, "net.connman.Manager", + "ServicesChanged") == TRUE) { + + fprintf(stdout, "%-12s %-20s = {\n", interface, + "ServicesChanged"); + dbus_message_iter_init(message, &iter); + __connmanctl_services_list(&iter); + fprintf(stdout, "\n}\n"); + + __connmanctl_redraw_rl(); + + return DBUS_HANDLER_RESULT_HANDLED; + } + + if (dbus_message_is_signal(message, "net.connman.Manager", + "TechnologyAdded") == TRUE) + path = "TechnologyAdded"; + + if (dbus_message_is_signal(message, "net.connman.Manager", + "TechnologyRemoved") == TRUE) + path = "TechnologyRemoved"; + + fprintf(stdout, "%-12s %-20s ", interface, path); + dbus_message_iter_init(message, &iter); + + __connmanctl_dbus_print(&iter, "", " = ", " = "); + fprintf(stdout, "\n"); + + __connmanctl_redraw_rl(); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static bool monitor_s = false; +static bool monitor_t = false; +static bool monitor_m = false; + +static void monitor_add(char *interface) +{ + char *rule; + DBusError err; + + if (monitor_s == false && monitor_t == false && monitor_m == false) + dbus_connection_add_filter(connection, monitor_changed, + NULL, NULL); + + if (g_strcmp0(interface, "Service") == 0) { + if (monitor_s == true) + return; + monitor_s = true; + } else if (g_strcmp0(interface, "Technology") == 0) { + if (monitor_t == true) + return; + monitor_t = true; + } else if (g_strcmp0(interface, "Manager") == 0) { + if (monitor_m == true) + return; + monitor_m = true; + } else + return; + + dbus_error_init(&err); + rule = g_strdup_printf("type='signal',interface='net.connman.%s'", + interface); + dbus_bus_add_match(connection, rule, &err); + g_free(rule); + + if (dbus_error_is_set(&err)) + fprintf(stderr, "Error: %s\n", err.message); +} + +static void monitor_del(char *interface) +{ + char *rule; + + if (g_strcmp0(interface, "Service") == 0) { + if (monitor_s == false) + return; + monitor_s = false; + } else if (g_strcmp0(interface, "Technology") == 0) { + if (monitor_t == false) + return; + monitor_t = false; + } else if (g_strcmp0(interface, "Manager") == 0) { + if (monitor_m == false) + return; + monitor_m = false; + } else + return; + + rule = g_strdup_printf("type='signal',interface='net.connman.%s'", + interface); + dbus_bus_remove_match(connection, rule, NULL); + g_free(rule); + + if (monitor_s == false && monitor_t == false && monitor_m == false) + dbus_connection_remove_filter(connection, monitor_changed, + NULL); +} + +static int cmd_monitor(char *args[], int num, struct connman_option *options) +{ + bool add = true; + int c; + + if (num > 3) + return -E2BIG; + + if (num == 3) { + switch (parse_boolean(args[2])) { + case 0: + add = false; + break; + + default: + break; + } + } + + c = parse_args(args[1], options); + switch (c) { + case -1: + monitor_add("Service"); + monitor_add("Technology"); + monitor_add("Manager"); + break; + + case 's': + if (add == true) + monitor_add("Service"); + else + monitor_del("Service"); + break; + + case 'c': + if (add == true) + monitor_add("Technology"); + else + monitor_del("Technology"); + break; + + case 'm': + if (add == true) + monitor_add("Manager"); + else + monitor_del("Manager"); + break; + + default: + switch(parse_boolean(args[1])) { + case 0: + monitor_del("Service"); + monitor_del("Technology"); + monitor_del("Manager"); + break; + + case 1: + monitor_add("Service"); + monitor_add("Technology"); + monitor_add("Manager"); + break; + + default: + return -EINVAL; + } + } + + if (add == true) + return -EINPROGRESS; + + return 0; +} + +static int cmd_agent(char *args[], int num, struct connman_option *options) +{ + if (num > 2) + return -E2BIG; + + if (num < 2) + return -EINVAL; + + switch(parse_boolean(args[1])) { + case 0: + __connmanctl_agent_unregister(connection); + break; + + case 1: + if (__connmanctl_agent_register(connection) == -EINPROGRESS) + return -EINPROGRESS; + + break; + + default: + return -EINVAL; + break; + } + + return 0; +} + +static int cmd_exit(char *args[], int num, struct connman_option *options) +{ + return 1; +} + +static struct connman_option service_options[] = { + {"properties", 'p', "[] (obsolete)"}, + { NULL, } +}; + +static struct connman_option config_options[] = { + {"nameservers", 'n', " [] []"}, + {"timeservers", 't', " [] [...]"}, + {"domains", 'd', " [] [...]"}, + {"ipv6", 'v', "off|auto [enable|disable|prefered]|\n" + "\t\t\tmanual
"}, + {"proxy", 'x', "direct|auto |manual [] [...]\n" + "\t\t\t[exclude [] [...]]"}, + {"autoconnect", 'a', "yes|no"}, + {"ipv4", 'i', "off|dhcp|manual
"}, + {"remove", 'r', " Remove service"}, + { NULL, } +}; + +static struct connman_option monitor_options[] = { + {"services", 's', "[off] Monitor only services"}, + {"tech", 'c', "[off] Monitor only technologies"}, + {"manager", 'm', "[off] Monitor only manager interface"}, + { NULL, } +}; + +static const struct { + const char *cmd; + const char *argument; + struct connman_option *options; + int (*func) (char *args[], int num, struct connman_option *options); + const char *desc; +} cmd_table[] = { + { "state", NULL, NULL, cmd_state, + "Shows if the system is online or offline" }, + { "technologies", NULL, NULL, cmd_technologies, + "Display technologies" }, + { "enable", "|offline", NULL, cmd_enable, + "Enables given technology or offline mode" }, + { "disable", "|offline", NULL, cmd_disable, + "Disables given technology or offline mode"}, + { "tether", " on|off\n" + " wifi [on|off] ", + NULL, cmd_tether, + "Enable, disable tethering, set SSID and passphrase for wifi" }, + { "services", "[]", service_options, cmd_services, + "Display services" }, + { "scan", "", NULL, cmd_scan, + "Scans for new services for given technology" }, + { "connect", "", NULL, cmd_connect, + "Connect a given service" }, + { "disconnect", "", NULL, cmd_disconnect, + "Disconnect a given service" }, + { "config", "", config_options, cmd_config, + "Set service configuration options" }, + { "monitor", "[off]", monitor_options, cmd_monitor, + "Monitor signals from interfaces" }, + { "agent", "on|off", NULL, cmd_agent, + "Agent mode" }, + { "help", NULL, NULL, cmd_help, + "Show help" }, + { "exit", NULL, NULL, cmd_exit, + "Exit" }, + { "quit", NULL, NULL, cmd_exit, + "Quit" }, + { NULL, }, +}; + +static int cmd_help(char *args[], int num, struct connman_option *options) +{ + bool interactive = __connmanctl_is_interactive(); + int i, j; + + if (interactive == false) + fprintf(stdout, "Usage: connmanctl [[command] [args]]\n"); + + for (i = 0; cmd_table[i].cmd != NULL; i++) { + const char *cmd = cmd_table[i].cmd; + const char *argument = cmd_table[i].argument; + const char *desc = cmd_table[i].desc; + + printf("%-12s%-22s%s\n", cmd != NULL? cmd: "", + argument != NULL? argument: "", + desc != NULL? desc: ""); + + if (cmd_table[i].options != NULL) { + for (j = 0; cmd_table[i].options[j].name != NULL; + j++) { + const char *options_desc = + cmd_table[i].options[j].desc != NULL ? + cmd_table[i].options[j].desc: ""; + + printf(" --%-12s%s\n", + cmd_table[i].options[j].name, + options_desc); + } + } + } + + if (interactive == false) + fprintf(stdout, "\nNote: arguments and output are considered " + "EXPERIMENTAL for now.\n"); + + return 0; +} + +int __connmanctl_commands(DBusConnection *dbus_conn, char *argv[], int argc) +{ + int i, result; + + connection = dbus_conn; + + for (i = 0; cmd_table[i].cmd != NULL; i++) { + if (g_strcmp0(cmd_table[i].cmd, argv[0]) == 0 && + cmd_table[i].func != NULL) { + result = cmd_table[i].func(argv, argc, + cmd_table[i].options); + if (result < 0 && result != -EINPROGRESS) + fprintf(stderr, "Error '%s': %s\n", argv[0], + strerror(-result)); + return result; + } + } + + fprintf(stderr, "Error '%s': Unknown command\n", argv[0]); + return -EINVAL; +} + +char *__connmanctl_lookup_command(const char *text, int state) +{ + static int i = 0; + static int len = 0; + + if (state == 0) { + i = 0; + len = strlen(text); + } + + while (cmd_table[i].cmd != NULL) { + const char *command = cmd_table[i].cmd; + + i++; + + if (strncmp(text, command, len) == 0) + return strdup(command); + } + + return NULL; +} diff --git a/client/commands.h b/client/commands.h new file mode 100644 index 000000000..6ae9029b2 --- /dev/null +++ b/client/commands.h @@ -0,0 +1,26 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2013 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 + * + */ + +#include + +int __connmanctl_commands(DBusConnection *connection, char *argv[], int argc); +char *__connmanctl_lookup_command(const char *text, int state); diff --git a/client/dbus_helpers.c b/client/dbus_helpers.c new file mode 100644 index 000000000..a3e084336 --- /dev/null +++ b/client/dbus_helpers.c @@ -0,0 +1,378 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2013 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 + * + */ + +#include +#include +#include + +#include "input.h" +#include "dbus_helpers.h" + +#define TIMEOUT 60000 + +void __connmanctl_dbus_print(DBusMessageIter *iter, const char *pre, + const char *dict, const char *sep) +{ + int arg_type; + dbus_bool_t b; + unsigned char c; + unsigned int i; + double d; + + char *str; + DBusMessageIter entry; + + if (pre == NULL) + pre = ""; + + while ((arg_type = dbus_message_iter_get_arg_type(iter)) + != DBUS_TYPE_INVALID) { + + fprintf(stdout, "%s", pre); + + switch (arg_type) { + case DBUS_TYPE_STRUCT: + fprintf(stdout, "{ "); + dbus_message_iter_recurse(iter, &entry); + __connmanctl_dbus_print(&entry, "", "=", " "); + fprintf(stdout, " }"); + break; + + case DBUS_TYPE_ARRAY: + fprintf(stdout, "[ "); + + dbus_message_iter_recurse(iter, &entry); + __connmanctl_dbus_print(&entry, "", "=", ", "); + + fprintf(stdout, " ]"); + break; + + case DBUS_TYPE_DICT_ENTRY: + + dbus_message_iter_recurse(iter, &entry); + __connmanctl_dbus_print(&entry, "", dict, dict); + break; + + case DBUS_TYPE_STRING: + case DBUS_TYPE_OBJECT_PATH: + dbus_message_iter_get_basic(iter, &str); + fprintf(stdout, "%s", str); + break; + + case DBUS_TYPE_VARIANT: + dbus_message_iter_recurse(iter, &entry); + __connmanctl_dbus_print(&entry, pre, dict, sep); + break; + + case DBUS_TYPE_BOOLEAN: + dbus_message_iter_get_basic(iter, &b); + if (b == FALSE) + fprintf(stdout, "False"); + else + fprintf(stdout, "True"); + break; + + case DBUS_TYPE_BYTE: + dbus_message_iter_get_basic(iter, &c); + fprintf(stdout, "%d", c); + break; + + case DBUS_TYPE_UINT16: + case DBUS_TYPE_UINT32: + dbus_message_iter_get_basic(iter, &i); + fprintf(stdout, "%d", i); + break; + + case DBUS_TYPE_DOUBLE: + dbus_message_iter_get_basic(iter, &d); + fprintf(stdout, "%f", d); + break; + + default: + fprintf(stdout, "", arg_type); + break; + } + + if (dbus_message_iter_has_next(iter) == TRUE) + fprintf(stdout, "%s", sep); + + dbus_message_iter_next(iter); + } +} + +struct dbus_callback { + connmanctl_dbus_method_return_func_t cb; + void *user_data; +}; + +static void dbus_method_reply(DBusPendingCall *call, void *user_data) +{ + struct dbus_callback *callback = user_data; + int res = 0; + DBusMessage *reply; + DBusMessageIter iter; + + __connmanctl_save_rl(); + + reply = dbus_pending_call_steal_reply(call); + if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { + DBusError err; + + dbus_error_init(&err); + dbus_set_error_from_message(&err, reply); + + callback->cb(NULL, err.message, callback->user_data); + + dbus_error_free(&err); + goto end; + } + + dbus_message_iter_init(reply, &iter); + res = callback->cb(&iter, NULL, callback->user_data); + +end: + __connmanctl_redraw_rl(); + if (__connmanctl_is_interactive() == false && res != -EINPROGRESS) + __connmanctl_quit(); + + g_free(callback); + dbus_message_unref(reply); +} + +static int send_method_call(DBusConnection *connection, + DBusMessage *message, connmanctl_dbus_method_return_func_t cb, + void *user_data) +{ + int res = -ENXIO; + DBusPendingCall *call; + struct dbus_callback *callback; + + if (dbus_connection_send_with_reply(connection, message, &call, + TIMEOUT) == FALSE) + goto end; + + if (call == NULL) + goto end; + + if (cb != NULL) { + callback = g_new0(struct dbus_callback, 1); + callback->cb = cb; + callback->user_data = user_data; + dbus_pending_call_set_notify(call, dbus_method_reply, + callback, NULL); + res = -EINPROGRESS; + } + +end: + dbus_message_unref(message); + return res; +} + +static int append_variant(DBusMessageIter *iter, const char *property, + int type, void *value) +{ + DBusMessageIter variant; + char *type_str; + + switch(type) { + case DBUS_TYPE_BOOLEAN: + type_str = DBUS_TYPE_BOOLEAN_AS_STRING; + break; + case DBUS_TYPE_BYTE: + type_str = DBUS_TYPE_BYTE_AS_STRING; + break; + case DBUS_TYPE_STRING: + type_str = DBUS_TYPE_STRING_AS_STRING; + break; + default: + return -EOPNOTSUPP; + } + + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &property); + dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, type_str, + &variant); + dbus_message_iter_append_basic(&variant, type, value); + dbus_message_iter_close_container(iter, &variant); + + return 0; +} + +int __connmanctl_dbus_method_call(DBusConnection *connection, const char *path, + const char *interface, const char *method, + connmanctl_dbus_method_return_func_t cb, void *user_data, + int arg1, ...) +{ + DBusMessage *message; + va_list args; + + message = dbus_message_new_method_call("net.connman", path, + interface, method); + + if (message == NULL) + return -ENOMEM; + + va_start(args, arg1); + dbus_message_append_args_valist(message, arg1, args); + va_end(args); + + return send_method_call(connection, message, cb, user_data); +} + +int __connmanctl_dbus_set_property(DBusConnection *connection, + const char *path, const char *interface, + connmanctl_dbus_method_return_func_t cb, void * user_data, + const char *property, int type, void *value) +{ + DBusMessage *message; + DBusMessageIter iter; + + message = dbus_message_new_method_call("net.connman", path, + interface, "SetProperty"); + + if (message == NULL) + return -ENOMEM; + + dbus_message_iter_init_append(message, &iter); + + if (append_variant(&iter, property, type, value) < 0) { + dbus_message_unref(message); + return -EINVAL; + } + + return send_method_call(connection, message, cb, user_data); +} + +void __connmanctl_dbus_append_dict_entry(DBusMessageIter *iter, + const char *property, int type, void *value) +{ + DBusMessageIter dict_entry; + + dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL, + &dict_entry); + + append_variant(&dict_entry, property, type, value); + + dbus_message_iter_close_container(iter, &dict_entry); +} + +int __connmanctl_dbus_set_property_dict(DBusConnection *connection, + const char *path, const char *interface, + connmanctl_dbus_method_return_func_t cb, void *user_data, + const char *property, int type, + connmanctl_dbus_append_func_t append_fn, + void *append_user_data) +{ + DBusMessage *message; + DBusMessageIter iter, variant, dict; + + message = dbus_message_new_method_call("net.connman", path, + interface, "SetProperty"); + + if (message == NULL) + return -ENOMEM; + + dbus_message_iter_init_append(message, &iter); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &property); + dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, + 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, + &variant); + + dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &dict); + + append_fn(&dict, append_user_data); + + dbus_message_iter_close_container(&variant, &dict); + dbus_message_iter_close_container(&iter, &variant); + + return send_method_call(connection, message, cb, user_data); +} + +static void append_variant_array(DBusMessageIter *iter, const char *property, + connmanctl_dbus_append_func_t append_fn, + void *append_user_data) +{ + DBusMessageIter variant, array; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &property); + dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, + DBUS_TYPE_ARRAY_AS_STRING + DBUS_TYPE_STRING_AS_STRING, + &variant); + + dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY, + DBUS_TYPE_STRING_AS_STRING, &array); + + append_fn(&array, append_user_data); + + dbus_message_iter_close_container(&variant, &array); + dbus_message_iter_close_container(iter, &variant); +} + +void __connmanctl_dbus_append_dict_string_array(DBusMessageIter *iter, + const char *property, connmanctl_dbus_append_func_t append_fn, + void *append_user_data) +{ + DBusMessageIter dict_entry; + + dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL, + &dict_entry); + + append_variant_array(&dict_entry, property, append_fn, + append_user_data); + + dbus_message_iter_close_container(iter, &dict_entry); +} + +int __connmanctl_dbus_set_property_array(DBusConnection *connection, + const char *path, const char *interface, + connmanctl_dbus_method_return_func_t cb, void *user_data, + const char *property, int type, + connmanctl_dbus_append_func_t append_fn, + void *append_user_data) +{ + DBusMessage *message; + DBusMessageIter iter; + + if (type != DBUS_TYPE_STRING) + return -EOPNOTSUPP; + + message = dbus_message_new_method_call("net.connman", path, + interface, "SetProperty"); + + if (message == NULL) + return -ENOMEM; + + dbus_message_iter_init_append(message, &iter); + + append_variant_array(&iter, property, append_fn, append_user_data); + + return send_method_call(connection, message, cb, user_data); +} diff --git a/client/dbus_helpers.h b/client/dbus_helpers.h new file mode 100644 index 000000000..fde118372 --- /dev/null +++ b/client/dbus_helpers.h @@ -0,0 +1,73 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2013 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 + * + */ + +#ifndef __CONNMANCTL_DBUS_HELPERS_H +#define __CONNMANCTL_DBUS_HELPERS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void __connmanctl_dbus_print(DBusMessageIter *iter, const char *pre, + const char *dict, const char *sep); + +typedef int (*connmanctl_dbus_method_return_func_t)(DBusMessageIter *iter, + const char *error, void *user_data); +int __connmanctl_dbus_method_call(DBusConnection *connection, const char *path, + const char *interface, const char *method, + connmanctl_dbus_method_return_func_t cb, void * user_data, + int arg1, ...); + +int __connmanctl_dbus_set_property(DBusConnection *connection, + const char *path, const char *interface, + connmanctl_dbus_method_return_func_t cb, void * user_data, + const char *property, int type, void *value); + +typedef void (*connmanctl_dbus_append_func_t)(DBusMessageIter *iter, + void *user_data); + +void __connmanctl_dbus_append_dict_entry(DBusMessageIter *iter, + const char *property, int type, void *value); +int __connmanctl_dbus_set_property_dict(DBusConnection *connection, + const char *path, const char *interface, + connmanctl_dbus_method_return_func_t cb, void * user_data, + const char *property, int type, + connmanctl_dbus_append_func_t append_fn, + void *append_user_data); + +void __connmanctl_dbus_append_dict_string_array(DBusMessageIter *iter, + const char *property, connmanctl_dbus_append_func_t append_fn, + void *append_user_data); +int __connmanctl_dbus_set_property_array(DBusConnection *connection, + const char *path, const char *interface, + connmanctl_dbus_method_return_func_t cb, void *user_data, + const char *property, int type, + connmanctl_dbus_append_func_t append_fn, + void *append_user_data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/client/input.c b/client/input.c new file mode 100644 index 000000000..78f68a91a --- /dev/null +++ b/client/input.c @@ -0,0 +1,243 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2012-2013 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include "input.h" +#include "commands.h" + +static DBusConnection *connection; +static GMainLoop *main_loop; +static bool interactive = false; + +static bool save_input; +static char *saved_line; +static int saved_point; + +static connmanctl_input_func_t *readline_input_handler; + +void __connmanctl_quit(void) +{ + if (main_loop != NULL) + g_main_loop_quit(main_loop); +} + +bool __connmanctl_is_interactive(void) +{ + return interactive; +} + +void __connmanctl_save_rl(void) +{ + save_input = !RL_ISSTATE(RL_STATE_DONE); + + if (save_input) { + saved_point = rl_point; + saved_line = rl_copy_text(0, rl_end); + rl_save_prompt(); + rl_replace_line("", 0); + rl_redisplay(); + } +} + +void __connmanctl_redraw_rl(void) +{ + if (save_input) { + rl_restore_prompt(); + rl_replace_line(saved_line, 0); + rl_point = saved_point; + rl_redisplay(); + free(saved_line); + } + + save_input = 0; +} + +static void rl_handler(char *input) +{ + char **args, **trim_args; + int num, len, err, i; + + if (input == NULL) { + rl_newline(1, '\n'); + g_main_loop_quit(main_loop); + return; + } + + args = g_strsplit(input, " ", 0); + num = g_strv_length(args); + + trim_args = g_new0(char *, num + 1); + for (i = 0, len = 0; i < num; i++) { + if (*args[i] != '\0') { + trim_args[len] = args[i]; + len++; + } + } + + if (len > 0) { + + add_history(input); + + err = __connmanctl_commands(connection, trim_args, len); + + if (err > 0) + g_main_loop_quit(main_loop); + } + + g_strfreev(args); + g_free(trim_args); +} + +static gboolean input_handler(GIOChannel *channel, GIOCondition condition, + gpointer user_data) +{ + if (condition & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) { + g_main_loop_quit(main_loop); + return FALSE; + } + + if (readline_input_handler != NULL) + rl_callback_read_char(); + return TRUE; +} + +static char **complete_agent(const char *text, int start, int end) +{ + rl_attempted_completion_over = 1; + + return NULL; +} + +static char **complete_command(const char *text, int start, int end) +{ + char **command = NULL; + + rl_attempted_completion_over = 1; + + if (start == 0) + command = rl_completion_matches(text, + __connmanctl_lookup_command); + + return command; +} + +void __connmanctl_agent_mode(const char *prompt, + connmanctl_input_func_t input_handler) +{ + readline_input_handler = input_handler; + + if (input_handler != NULL) + rl_callback_handler_install(prompt, input_handler); + else { + rl_set_prompt(prompt); + rl_callback_handler_remove(); + rl_redisplay(); + } + rl_attempted_completion_function = complete_agent; +} + +void __connmanctl_command_mode(void) +{ + readline_input_handler = rl_handler; + + rl_callback_handler_install("connmanctl> ", rl_handler); + rl_attempted_completion_function = complete_command; +} + +int __connmanctl_input_init(int argc, char *argv[]) +{ + char *help[] = { + "help", + NULL + }; + guint source = 0; + int err; + DBusError dbus_err; + GIOChannel *channel; + + dbus_error_init(&dbus_err); + connection = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, &dbus_err); + + if (dbus_error_is_set(&dbus_err)) { + fprintf(stderr, "Error: %s\n", dbus_err.message); + dbus_error_free(&dbus_err); + return 1; + } + + channel = g_io_channel_unix_new(fileno(stdin)); + source = g_io_add_watch(channel, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL, + input_handler, NULL); + g_io_channel_unref(channel); + + if (argc < 2) { + interactive = true; + + __connmanctl_command_mode(); + err = -EINPROGRESS; + + } else { + interactive = false; + + if (strcmp(argv[1], "--help") == 0 || + strcmp(argv[1], "-h") == 0) + err = __connmanctl_commands(connection, help, 1); + else + err = __connmanctl_commands(connection, argv + 1, + argc -1); + } + + if (err == -EINPROGRESS) { + main_loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(main_loop); + + err = 0; + } + + g_source_remove(source); + + if (interactive == true) { + rl_callback_handler_remove(); + rl_message(""); + } + + dbus_connection_unref(connection); + if (main_loop != NULL) + g_main_loop_unref(main_loop); + + if (err < 0) + err = -err; + else + err = 0; + + return err; +} diff --git a/client/input.h b/client/input.h new file mode 100644 index 000000000..669435985 --- /dev/null +++ b/client/input.h @@ -0,0 +1,46 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2012-2013 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 + * + */ + +#ifndef __CONNMANCTL_INPUT_H +#define __CONNMANCTL_INPUT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void __connmanctl_quit(void); +bool __connmanctl_is_interactive(void); +void __connmanctl_save_rl(void); +void __connmanctl_redraw_rl(void); +typedef void connmanctl_input_func_t(char *input); +void __connmanctl_agent_mode(const char *prompt, + connmanctl_input_func_t input_handler); +void __connmanctl_command_mode(void); +int __connmanctl_input_init(int argc, char *argv[]); + +#ifdef __cplusplus +} +#endif + +#endif /* __CONNMANCTL_INPUT_H */ diff --git a/client/main.c b/client/main.c new file mode 100644 index 000000000..6d3c57f93 --- /dev/null +++ b/client/main.c @@ -0,0 +1,28 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2012-2013 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 + * + */ + +#include "input.h" + +int main(int argc, char *argv[]) +{ + return __connmanctl_input_init(argc, argv); +} diff --git a/client/services.c b/client/services.c new file mode 100644 index 000000000..045947c82 --- /dev/null +++ b/client/services.c @@ -0,0 +1,153 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2012-2013 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#include "services.h" + +static void print_service(char *path, DBusMessageIter *iter) +{ + char *name = "", *str = NULL; + int autoconn = 0, favorite = 0, count = 0; + char *property; + char state = ' '; + DBusMessageIter entry, val; + + while (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) { + + dbus_message_iter_recurse(iter, &entry); + dbus_message_iter_get_basic(&entry, &property); + if (strcmp(property, "Name") == 0) { + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &val); + dbus_message_iter_get_basic(&val, &name); + + } else if (strcmp(property, "State") == 0) { + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &val); + dbus_message_iter_get_basic(&val, &str); + + if (str != NULL) { + if (strcmp(str, "online") == 0) + state = 'O'; + else if (strcmp(str, "ready") == 0) + state = 'R'; + } + + } else if (strcmp(property, "AutoConnect") == 0) { + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &val); + dbus_message_iter_get_basic(&val, &autoconn); + + } else if (strcmp(property, "Favorite") == 0) { + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &val); + dbus_message_iter_get_basic(&val, &favorite); + } + + count++; + dbus_message_iter_next(iter); + } + + str = strrchr(path, '/'); + if (str != NULL) + str++; + else + str = path; + + if (count > 0) { + if (*name == '\0') + name = ""; + + fprintf(stdout, "%c%c%c %-20s %s", favorite != 0 ? '*' : ' ', + autoconn != 0 ? 'A' : ' ', state, name, str); + } else + fprintf(stdout, "%-24s %s", "unchanged", str); + +} + +static void list_service_array(DBusMessageIter *iter) +{ + DBusMessageIter array, dict; + char *path = NULL; + + while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRUCT) { + + dbus_message_iter_recurse(iter, &array); + if (dbus_message_iter_get_arg_type(&array) + != DBUS_TYPE_OBJECT_PATH) + return; + + dbus_message_iter_get_basic(&array, &path); + + dbus_message_iter_next(&array); + if (dbus_message_iter_get_arg_type(&array) + == DBUS_TYPE_ARRAY) { + dbus_message_iter_recurse(&array, &dict); + print_service(path, &dict); + } + + if (dbus_message_iter_has_next(iter) == TRUE) + fprintf(stdout, "\n"); + + dbus_message_iter_next(iter); + } +} + +void __connmanctl_services_list(DBusMessageIter *iter) +{ + DBusMessageIter array; + char *path; + + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY) + return; + + dbus_message_iter_recurse(iter, &array); + list_service_array(&array); + + dbus_message_iter_next(iter); + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY) + return; + + fprintf(stdout, "\n}, {"); + + dbus_message_iter_recurse(iter, &array); + while (dbus_message_iter_get_arg_type(&array) + == DBUS_TYPE_OBJECT_PATH) { + dbus_message_iter_get_basic(&array, &path); + fprintf(stdout, "\n%-24s %s", "removed", path); + + dbus_message_iter_next(&array); + } + +} diff --git a/client/services.h b/client/services.h new file mode 100644 index 000000000..0af05ff6a --- /dev/null +++ b/client/services.h @@ -0,0 +1,25 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2012-2013 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 as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 + * + */ + +#include + +void __connmanctl_services_list(DBusMessageIter *iter); diff --git a/configure.ac b/configure.ac new file mode 100644 index 000000000..ebc8170aa --- /dev/null +++ b/configure.ac @@ -0,0 +1,398 @@ +AC_PREREQ(2.60) +AC_INIT(connman, 1.15) + +AM_INIT_AUTOMAKE([foreign subdir-objects color-tests]) +AC_CONFIG_HEADERS([config.h]) + +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +AM_MAINTAINER_MODE + +AC_PREFIX_DEFAULT(/usr/local) + +PKG_PROG_PKG_CONFIG + +COMPILER_FLAGS + +AC_SUBST(abs_top_srcdir) +AC_SUBST(abs_top_builddir) + +AC_LANG_C + +AC_PROG_CC +AM_PROG_CC_C_O +AC_PROG_CC_PIE +AC_PROG_INSTALL +AC_PROG_MKDIR_P + +m4_define([_LT_AC_TAGCONFIG], []) +m4_ifdef([AC_LIBTOOL_TAGS], [AC_LIBTOOL_TAGS([])]) + +AC_DISABLE_STATIC +AC_PROG_LIBTOOL + +AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], + [disable code optimization through compiler]), [ + if (test "${enableval}" = "no"); then + CFLAGS="$CFLAGS -O0 -U_FORTIFY_SOURCE" + fi +]) + +GTK_DOC_CHECK + +AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], + [enable compiling with debugging information]), [ + if (test "${enableval}" = "yes" && + test "${ac_cv_prog_cc_g}" = "yes"); then + CFLAGS="$CFLAGS -g" + fi +]) + +AC_ARG_ENABLE(pie, AC_HELP_STRING([--enable-pie], + [enable position independent executables flag]), [ + if (test "${enableval}" = "yes" && + test "${ac_cv_prog_cc_pie}" = "yes"); then + CFLAGS="$CFLAGS -fPIE" + LDFLAGS="$LDFLAGS -pie" + fi +]) + +AC_ARG_ENABLE(threads, + AC_HELP_STRING([--enable-threads], [enable threading support]), + [enable_threads=${enableval}], [enable_threads="no"]) + +AC_ARG_ENABLE(hh2serial-gps, + AC_HELP_STRING([--enable-hh2serial-gps], [enable hh2serial GPS support]), + [enable_hh2serial_gps=${enableval}], [enable_hh2serial_gps="no"]) +AM_CONDITIONAL(HH2SERIAL_GPS, test "${enable_hh2serial_gps}" != "no") +AM_CONDITIONAL(HH2SERIAL_GPS_BUILTIN, test "${enable_hh2serial_gps}" = "builtin") + +AC_ARG_WITH(openconnect, AC_HELP_STRING([--with-openconnect=PROGRAM], + [specify location of openconnect binary]), [path_openconnect=${withval}]) + +AC_ARG_ENABLE(openconnect, + AC_HELP_STRING([--enable-openconnect], [enable openconnect support]), + [enable_openconnect=${enableval}], [enable_openconnect="no"]) +if (test "${enable_openconnect}" != "no"); then + if (test -z "${path_openconnect}"); then + AC_PATH_PROG(OPENCONNECT, [openconnect], [], $PATH:/sbin:/usr/sbin) + if (test -z "${OPENCONNECT}"); then + AC_MSG_ERROR(openconnect binary not found) + fi + else + OPENCONNECT="${path_openconnect}" + AC_SUBST(OPENCONNECT) + fi +fi +AM_CONDITIONAL(OPENCONNECT, test "${enable_openconnect}" != "no") +AM_CONDITIONAL(OPENCONNECT_BUILTIN, test "${enable_openconnect}" = "builtin") + +AC_ARG_WITH(openvpn, AC_HELP_STRING([--with-openvpn=PROGRAM], + [specify location of openvpn binary]), [path_openvpn=${withval}]) + +AC_ARG_ENABLE(openvpn, + AC_HELP_STRING([--enable-openvpn], [enable openvpn support]), + [enable_openvpn=${enableval}], [enable_openvpn="no"]) +if (test "${enable_openvpn}" != "no"); then + if (test -z "${path_openvpn}"); then + AC_PATH_PROG(OPENVPN, [openvpn], [], $PATH:/sbin:/usr/sbin) + if (test -z "${OPENVPN}"); then + AC_MSG_ERROR(openvpn binary not found) + fi + else + OPENVPN="${path_openvpn}" + AC_SUBST(OPENVPN) + fi +fi +AM_CONDITIONAL(OPENVPN, test "${enable_openvpn}" != "no") +AM_CONDITIONAL(OPENVPN_BUILTIN, test "${enable_openvpn}" = "builtin") + +AC_ARG_WITH(vpnc, AC_HELP_STRING([--with-vpnc=PROGRAM], + [specify location of vpnc binary]), [path_vpnc=${withval}]) + +AC_ARG_ENABLE(vpnc, + AC_HELP_STRING([--enable-vpnc], [enable vpnc support]), + [enable_vpnc=${enableval}], [enable_vpnc="no"]) +if (test "${enable_vpnc}" != "no"); then + if (test -z "${path_vpnc}"); then + AC_PATH_PROG(VPNC, [vpnc], [], $PATH:/sbin:/usr/sbin) + if (test -z "${VPNC}"); then + AC_MSG_ERROR(vpnc binary not found) + fi + else + VPNC="${path_vpnc}" + AC_SUBST(VPNC) + fi +fi +AM_CONDITIONAL(VPNC, test "${enable_vpnc}" != "no") +AM_CONDITIONAL(VPNC_BUILTIN, test "${enable_vpnc}" = "builtin") + +AC_ARG_ENABLE(l2tp, + AC_HELP_STRING([--enable-l2tp], [enable l2tp support]), + [enable_l2tp=${enableval}], [enable_l2tp="no"]) +if (test "${enable_l2tp}" != "no"); then + if (test -z "${path_pppd}"); then + AC_PATH_PROG(PPPD, [pppd], [/usr/sbin/pppd], $PATH:/sbin:/usr/sbin) + else + PPPD="${path_pppd}" + AC_SUBST(PPPD) + fi + AC_CHECK_HEADERS(pppd/pppd.h, dummy=yes, + AC_MSG_ERROR(ppp header files are required)) + if (test -z "${path_l2tp}"); then + AC_PATH_PROG(L2TP, [xl2tpd], [/usr/sbin/xl2tpd], $PATH:/sbin:/usr/sbin) + else + L2TP="${path_l2tp}" + AC_SUBST(L2TP) + fi +fi +AM_CONDITIONAL(L2TP, test "${enable_l2tp}" != "no") +AM_CONDITIONAL(L2TP_BUILTIN, test "${enable_l2tp}" = "builtin") + +AC_ARG_ENABLE(pptp, + AC_HELP_STRING([--enable-pptp], [enable pptp support]), + [enable_pptp=${enableval}], [enable_pptp="no"]) +if (test "${enable_pptp}" != "no"); then + if (test -z "${path_pppd}"); then + AC_PATH_PROG(PPPD, [pppd], [/usr/sbin/pppd], $PATH:/sbin:/usr/sbin) + else + PPPD="${path_pppd}" + AC_SUBST(PPPD) + fi + AC_CHECK_HEADERS(pppd/pppd.h, dummy=yes, + AC_MSG_ERROR(ppp header files are required)) + if (test -z "${path_pptp}"); then + AC_PATH_PROG(PPTP, [pptp], [/usr/sbin/pptp], $PATH:/sbin:/usr/sbin) + else + PPTP="${path_pptp}" + AC_SUBST(PPTP) + fi +fi +AM_CONDITIONAL(PPTP, test "${enable_pptp}" != "no") +AM_CONDITIONAL(PPTP_BUILTIN, test "${enable_pptp}" = "builtin") + +AC_CHECK_HEADERS(resolv.h, dummy=yes, + AC_MSG_ERROR(resolver header files are required)) +AC_CHECK_LIB(resolv, ns_initparse, dummy=yes, [ + AC_CHECK_LIB(resolv, __ns_initparse, dummy=yes, + AC_MSG_ERROR(resolver library support is required)) +]) + +AC_CHECK_FUNC(signalfd, dummy=yes, + AC_MSG_ERROR(signalfd support is required)) + +AC_CHECK_LIB(dl, dlopen, dummy=yes, + AC_MSG_ERROR(dynamic linking loader is required)) + +AC_ARG_ENABLE(iospm, AC_HELP_STRING([--enable-iospm], + [enable Intel OSPM support]), [enable_iospm=${enableval}]) +AM_CONDITIONAL(IOSPM, test "${enable_iospm}" = "yes") + +AC_ARG_ENABLE(tist, + AC_HELP_STRING([--enable-tist], [enable TI Shared Transport support]), + [enable_tist=${enableval}], [enable_tist="no"]) +AM_CONDITIONAL(TIST, test "${enable_tist}" != "no") +AM_CONDITIONAL(TIST_BUILTIN, test "${enable_tist}" = "builtin") + +AC_ARG_ENABLE(session-policy-local, + AC_HELP_STRING([--enable-session-policy-local], [enable local file Session policy configuration support]), + [enable_session_policy_local=${enableval}], [enable_session_policy_local="no"]) +AM_CONDITIONAL(SESSION_POLICY_LOCAL, test "${enable_session_policy_local}" != "no") +AM_CONDITIONAL(SESSION_POLICY_LOCAL_BUILTIN, test "${enable_session_policy_local}" = "builtin") + +AC_ARG_WITH(stats-max-file-size, AC_HELP_STRING([--with-stats-max-file-size=SIZE], + [Maximal size of a statistics round robin file]), + [stats_max_file_size=${withval}]) + +if (test -z "${stats_max_file_size}"); then + # default size is 16 kByte + stats_max_file_size="16 * 8 * 128" +fi + +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)) +AC_SUBST(GLIB_CFLAGS) +AC_SUBST(GLIB_LIBS) + +if (test "${enable_threads}" = "yes"); then + AC_DEFINE(NEED_THREADS, 1, [Define if threading support is required]) + PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes, + AC_MSG_ERROR(GThread >= 2.16 is required)) + GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS" + 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)) +AC_SUBST(DBUS_CFLAGS) +AC_SUBST(DBUS_LIBS) + +AC_ARG_WITH(dbusconfdir, AC_HELP_STRING([--with-dbusconfdir=PATH], + [path to D-Bus config directory]), [path_dbusconf=${withval}], + [path_dbusconf="`$PKG_CONFIG --variable=sysconfdir dbus-1`"]) +if (test -z "${path_dbusconf}"); then + DBUS_CONFDIR="${sysconfdir}/dbus-1/system.d" +else + DBUS_CONFDIR="${path_dbusconf}/dbus-1/system.d" +fi +AC_SUBST(DBUS_CONFDIR) + +AC_ARG_WITH(dbusdatadir, AC_HELP_STRING([--with-dbusdatadir=PATH], + [path to D-Bus data directory]), [path_dbusdata=${withval}], + [path_dbusdata="`$PKG_CONFIG --variable=datadir dbus-1`"]) +if (test -z "${path_dbusdata}"); then + DBUS_DATADIR="${datadir}/dbus-1/system-services" +else + DBUS_DATADIR="${path_dbusdata}/dbus-1/system-services" +fi +AC_SUBST(DBUS_DATADIR) + +AC_ARG_WITH([systemdunitdir], AC_HELP_STRING([--with-systemdunitdir=DIR], + [path to systemd service directory]), [path_systemdunit=${withval}], + [path_systemdunit="`$PKG_CONFIG --variable=systemdsystemunitdir systemd`"]) +if (test -n "${path_systemdunit}"); then + SYSTEMD_UNITDIR="${path_systemdunit}" + AC_SUBST(SYSTEMD_UNITDIR) +fi +AM_CONDITIONAL(SYSTEMD, test -n "${path_systemdunit}") + +PKG_CHECK_MODULES(XTABLES, xtables >= 1.4.11, dummy=yes, + AC_MSG_ERROR(Xtables library is required)) +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]), + [enable_polkit=${enableval}], [enable_polkit="no"]) +if (test "${enable_polkit}" != "no"); then + POLKIT_DATADIR="`$PKG_CONFIG --variable=actiondir polkit`" + POLKIT_DATADIR="" + if (test -z "${POLKIT_DATADIR}"); then + POLKIT_DATADIR="${datadir}/polkit-1/actions" + fi + AC_SUBST(POLKIT_DATADIR) +fi +AM_CONDITIONAL(POLKIT, test "${enable_polkit}" != "no") + +AC_ARG_ENABLE(selinux, AC_HELP_STRING([--enable-selinux], + [enable selinux support]), + [enable_selinux=${enableval}], [enable_selinux="no"]) +AM_CONDITIONAL(SELINUX, test "${enable_selinux}" != "no") + +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(neard, AC_HELP_STRING([--disable-neard], + [disable Neard support]), + [enable_neard=${enableval}]) +AM_CONDITIONAL(NEARD, test "${enable_neard}" != "no") + +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") + +if (test "${enable_tools}" != "no"); then + AC_PATH_PROGS(IPTABLES_SAVE, [iptables-save], [], + $PATH:/sbin:/usr/sbin) + IPTABLES_SAVE=$ac_cv_path_IPTABLES_SAVE +else + IPTABLES_SAVE="" +fi +AC_SUBST(IPTABLES_SAVE) + +AC_ARG_ENABLE(client, AC_HELP_STRING([--disable-client], + [disable command line client]), + [enable_client=${enableval}]) +AM_CONDITIONAL(CLIENT, test "${enable_client}" != "no") + +if (test "${enable_wispr}" != "no"); 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_CHECK_LIB(c, inotify_init, dummy=yes, + AC_MSG_ERROR(inotify library support is required)) +fi + +if (test "${enable_wifi}" != "no"); then + AC_PATH_PROG(WPASUPPLICANT, [wpa_supplicant], [], + $PATH:/sbin:/usr/sbin) +fi + +AC_ARG_ENABLE(datafiles, AC_HELP_STRING([--disable-datafiles], + [don't install configuration and data files]), + [enable_datafiles=${enableval}]) +AM_CONDITIONAL(DATAFILES, test "${enable_datafiles}" != "no") + +if (test "${enable_client}" != "no"); then + AC_CHECK_HEADERS(readline/readline.h, dummy=yes, + AC_MSG_ERROR(readline header files are required)) +fi + +AM_CONDITIONAL(VPN, test "${enable_openconnect}" != "no" -o \ + "${enable_openvpn}" != "no" -o \ + "${enable_vpnc}" != "no" -o \ + "${enable_l2tp}" != "no" -o \ + "${enable_pptp}" != "no") + +AC_OUTPUT(Makefile include/version.h src/connman.service + vpn/connman-vpn.service vpn/net.connman.vpn.service + scripts/connman doc/version.xml connman.pc) diff --git a/connman.pc.in b/connman.pc.in new file mode 100644 index 000000000..2af3c2bb1 --- /dev/null +++ b/connman.pc.in @@ -0,0 +1,14 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +plugindir=${libdir}/connman/plugins +scriptdir=${libdir}/connman/scripts + +Name: connman +Description: Connection Manager +Requires: glib-2.0 dbus-1 +Version: @VERSION@ +Libs: -module -avoid-version -export-symbols-regex connman_plugin_desc +Cflags: -I${includedir} diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 000000000..ce3e4333a --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,38 @@ + +DOC_MODULE = connman + +DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.xml + +DOC_SOURCE_DIR = ../src + +SCAN_OPTIONS = --rebuild-sections --source-dir=../include + +MKDB_OPTIONS = --sgml-mode --output-format=xml --tmpl-dir=. \ + --ignore-files=connman \ + --source-dir=../include \ + --source-suffixes=c,h + +MKTMPL_OPTIONS = --output-dir=. + +HFILE_GLOB = $(top_srcdir)/include/*.h +CFILE_GLOB = $(top_srcdir)/src/*.c $(top_srcdir)/src/*.h + +IGNORE_HFILES = connman connman.h + +HTML_IMAGES = + +content_files = connman-introduction.xml + +INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/gdbus \ + $(GTHREAD_CFLAGS) $(GMODULE_CFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) + +GTKDOC_LIBS = $(DBUS_LIBS) $(GLIB_LIBS) $(GMODULE_LIBS) $(GTHREAD_LIBS) + +MAINTAINERCLEANFILES = Makefile.in \ + $(DOC_MODULE).types $(DOC_MODULE)-*.txt *.sgml *.bak + +if ENABLE_GTK_DOC +include $(top_srcdir)/doc/gtk-doc.make +else +EXTRA_DIST = $(DOC_MAIN_SGML_FILE) connman-introduction.xml +endif diff --git a/doc/advanced-configuration.txt b/doc/advanced-configuration.txt new file mode 100644 index 000000000..3c08c8fdb --- /dev/null +++ b/doc/advanced-configuration.txt @@ -0,0 +1,61 @@ +Advanced configuration interface +******************************** + + +Configuration basics +==================== + +The default configuration method for all servers is automatic or something +like DHCP. In almost every case that should be just good enough, but if it +is not, Connection Manager supports manual configuration for Ethernet and +IP settings. + + +Configuration interface +======================= + +Every service contains two properties. One represents the current active +configuration and the other one allows manual configuration via the user. + +For IPv4 they are named "IPv4" and IPv4.Configuration". + +[ /profile/default/wifi_001122334455_42696720696e204a6170616e_managed_psk ] + Type = wifi + Name = Big in Japan + Mode = managed + Strength = 82 + Security = rsn + Favorite = true + State = ready + IPv4.Configuration = { Method=dhcp } + IPv4 = { Netmask=255.255.255.0 Method=dhcp Address=192.168.1.198 } + +The above WiFi network shows how the default configuration would look like +with a connected service. The configuration method is DHCP and the current +IP address is 192.168.1.198. + +The "IPv4" property is read-only and will emit PropertyChanged signals in +case the IP address of this interface changes. The "IPv4.Configuration" +property is read-write and allows changes. For example to use a static IP +configuration this call could be used: + + service.SetProperty("IPv4.Configuration", { "Method": "manual", + "Address": "192.168.1.100", + "Netmask": "255.255.255.0" }) + +The configuration itself is a dictionary with various fields. Not all of +them need to present. A lot of combinations are valid. + +For example the "Method" field has valid settings of "off", "fixed", "manual" +and "dhcp". The "fixed" value however can not be set by any user program. It +is an internal value that some 3G cards require. Switching to "off" will +remove and IP configuration from the interface. The "manual" method allows +for static address configuration. And "dhcp" will use DHCP to retrieve all +required information automatically. + +With a manual configuration, the fields "Address" and "Netmask" should be +given. In case "Netmask" is left out, the best netmask will be calculated. + +The "Gateway" field can be used to indicate the default route/gateway for +this interface. + diff --git a/doc/agent-api.txt b/doc/agent-api.txt new file mode 100644 index 000000000..a98343fe5 --- /dev/null +++ b/doc/agent-api.txt @@ -0,0 +1,256 @@ +Agent hierarchy +=============== + +Service unique name +Interface net.connman.Agent +Object path freely definable + +Methods void Release() + + This method gets called when the service daemon + unregisters the agent. An agent can use it to do + cleanup tasks. There is no need to unregister the + agent, because when this method gets called it has + already been unregistered. + + void ReportError(object service, string error) + + This method gets called when an error has to be + reported to the user. + + A special return value can be used to trigger a + retry of the failed transaction. + + 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 + a service and some extra input is required. For + example a passphrase or the name of a hidden network. + + The return value should be a dictionary where the + keys are the field names and the values are the + actual fields. Alternatively an error indicating that + the request got canceled can be returned. + + Most common return field names are "Name" and of + course "Passphrase". + + 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() + + This method gets called to indicate that the agent + request failed before a reply was returned. + +Fields string Name + + The name of a network. This field will be requested + when trying to connect to a hidden network. + + array{byte} SSID + + This field is an alternative to "Name" for WiFi + networks and can be used to return the exact binary + representation of a network name. + + Normally returning the "Name" field is the better + option here. + + string Identity + + Identity (username) for EAP authentication methods. + + string Passphrase + + The passphrase for authentication. For example a WEP + 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. In case of WPS + association through PIN method: when retrying, the + previous wpspin will be provided. + + string WPS + + This field requests the use of WPS to get associated. + This is an alternate choice against Passphrase when + requested service supports WPS. The reply can contain + either empty pin, if user wants to use push-button + method, or a pin code if user wants to use the pin + method. + + string Username + + Username for WISPr authentication. This field will be + requested when connecting to a WISPr-enabled hotspot. + + string Password + + Password for WISPr authentication. This field will be + requested when connecting to a WISPr-enabled hotspot. + +Arguments string Type + + Contains the type of a field. For example "psk", "wep" + "passphrase", "response", "ssid", "wpspin" or plain + "string". + + string Requirement + + Contains the requirement option. Valid values are + "mandatory", "optional", "alternate" or + "informational". + + The "alternate" value specifies that this field can be + returned as an alternative to another one. An example + would be the network name or SSID. + + 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", + "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", + { "Name" : { "Type" : "string", + "Requirement" : "mandatory", + "Alternates" : [ "SSID" ] + }, + "SSID" : { "Type" : "ssid", + "Requirement" : "alternate" + } + } + ==> { "Name" : "My hidden network" } + + Requesting a passphrase for a WPA2 network with WPS alternative: + + RequestInput("/service3", + { "Passphrase" : { "Type" : "psk", + "Requirement" : "mandatory", + "Alternates" : [ "WPS" ] + }, + "WPS" : { "Type" : "wpspin", + "Requirement" : "alternate" + } + } + + ==> { "WPS" : "123456" } + + Requesting a passphrase for a WPA2 network with WPS alternative + after an error on the previous one: + + RequestInput("/service3", + { "Passphrase" : { "Type" : "psk", + "Requirement" : "mandatory", + "Alternates" : [ "WPS" ] + }, + "WPS" : { "Type" : "wpspin", + "Requirement" : "alternate" + } + "PreviousPassphrase" : + { "Type" : "wpspin", + "Requirement : "informational", + "Value" : "123456" + } + + Requesting passphrase for a WPA-Enterprise network: + + RequestInput("/service4", + { "Identity" : { "Type" : "string", + "Requirement" : "mandatory" + }, + "Passphrase" : { "Type" : "passphrase", + "Requirement" : "mandatory" + } + } + + ==> { "Identity" : "alice", "Passphrase": "secret123" } + + Requesting challenge response for a WPA-Enterprise network: + + RequestInput("/service4", + { "Identity" : { "Type" : "string", + "Requirement" : "mandatory" + }, + "Passphrase" : { "Type" : "response", + "Requirement" : "mandatory" + } + } + + ==> { "Identity" : "bob", "Passphrase": "secret123" } + + 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" } diff --git a/doc/backtrace.txt b/doc/backtrace.txt new file mode 100644 index 000000000..ac8472ccb --- /dev/null +++ b/doc/backtrace.txt @@ -0,0 +1,28 @@ +ConnMan backtraces +****************** + +ConnMan dumps backtraces upon segmentation faults, bus errors and other +crashing signals. Regardless of the debug level you started connmand with, the +backtrace will be dumped to syslog. + +The ConnMan backtraces start with the following line: + -------- backtrace -------- +and will try to display function names if those can be resolved from the stack +addresses. All static functions name will not appear for example. + +For a more complete and useful stack frame output you can use the +test/backtrace script. It takes the actual binary that crashed and the +connmand logs. The logs can contain any connman debug strings on top of the +backtrace. + +Here is an example of the backtrace script usage: + +me@localhost:[~]$ backtrace /sbin/connmand connman.log +-------- backtrace -------- +[0]: __connman_debug_list_available() [log.c:117] +[1]: connman_driver_register() [element.c:515] +[2]: __connman_driver_rescan() [element.c:490] +[3]: disable_technology() [manager.c:391] +[4]: generic_message() [object.c:262] +----------------------------------- + diff --git a/doc/behavior-api.txt b/doc/behavior-api.txt new file mode 100644 index 000000000..5feea768b --- /dev/null +++ b/doc/behavior-api.txt @@ -0,0 +1,11 @@ +Interface behavior description +****************************** + + +Ethernet service +================ + +The Ethernet based service is a special case since it has no children, but +still can be manually connected and disconnected while also has an implicit +behavior when physically plugging in or removing an Ethernet cable. + diff --git a/doc/clock-api.txt b/doc/clock-api.txt new file mode 100644 index 000000000..6818f5a82 --- /dev/null +++ b/doc/clock-api.txt @@ -0,0 +1,87 @@ +Clock hierarchy +=============== + +Service net.connman +Interface net.connman.Clock +Object path / + +Methods dict GetProperties() [experimental] + + Returns all system clock properties. See the + properties section for available properties. + + Possible Errors: [service].Error.InvalidArguments + + void SetProperty(string name, variant value) [experimental] + + 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 + +Signals PropertyChanged(string name, variant value) [experimental] + + This signal indicates a changed value of the given + property. + + +Properties uint64 Time [readonly or readwrite] [experimental] + + Current system time in seconds since epoch. + + This value is present for changing the system time + if TimeUpdates is set to manual. + + It is not present for driving an updated display + of the system time. PropertyChanged signal for this + value are only send out if it gets changed or jumps + unexpectedly. + + In general application interested in the current + time should be using gettimeofday() and related + system calls. + + string TimeUpdates [readwrite] [experimental] + + Possible values are "manual" and "auto" to indicate + time update policy. + + With the "auto" setting the system tries to use as + many sources as possible to determine the correct + and updated time. + + string Timezone [readonly or readwrite] [experimental] + + Current system timezone string. Allowed values + are from the standard timezone data (tzdata) + package under /usr/share/zoneinfo. For example + strings like "America/Vancouver" or "Europe/Berlin". + + This value is present for changing the timezone + if TimezoneUpdates is set to manual. + + When the timezone gets changed a PropertyChanged + signal will be send out. + + string TimezoneUpdates [readwrite] [experimental] + + Possible values are "manual" and "auto" to indicate + timezone update policy. + + With the "auto" setting the system tries to use as + many sources as possible to determine the correct + timezone. + + array{string} Timeservers [readwrite] [experimental] + + List of global default NTP servers. The list should + be sorted in order of preference. + + If a service configuration provides NTP servers, + then they are preferred over the global ones. + + This list of servers is used when TimeUpdates is set + to auto. diff --git a/doc/coding-style.txt b/doc/coding-style.txt new file mode 100644 index 000000000..30690b761 --- /dev/null +++ b/doc/coding-style.txt @@ -0,0 +1,344 @@ +Every project has its coding style, and ConnMan is not an exception. This +document describes the preferred coding style for ConnMan code, in order to keep +some level of consistency among developers so that code can be easily +understood and maintained, and also to help your code survive under +maintainer's fastidious eyes so that you can get a passport for your patch +ASAP. + +First of all, ConnMan coding style must follow every rule for Linux kernel +(http://www.kernel.org/doc/Documentation/CodingStyle). There also exists a tool +named checkpatch.pl to help you check the compliance with it. Just type +"checkpatch.pl --no-tree patch_name" to check your patch. In theory, you need +to clean up all the warnings and errors except this one: "ERROR: Missing +Signed-off-by: line(s)". ConnMan does not used Signed-Off lines, so including +them is actually an error. In certain circumstances one can ignore the 80 +character per line limit. This is generally only allowed if the alternative +would make the code even less readable. + +Besides the kernel coding style above, ConnMan has special flavors for its own. +Some of them are mandatory (marked as 'M'), while some others are optional +(marked as 'O'), but generally preferred. + +M1: Blank line before and after an if/while/do/for statement +============================================================ +There should be a blank line before if statement unless the if is nested and +not preceded by an expression or variable declaration. + +Example: +1) +a = 1; +if (b) { // wrong + +2) +a = 1 + +if (b) { +} +a = 2; // wrong + +3) +if (a) { + if (b) // correct + +4) +b = 2; + +if (a) { // correct + +} + +b = 3; + +The only exception to this rule applies when a variable is being allocated: +array = g_try_new0(int, 20); +if (array == NULL) // Correct + return; + + +M2: Multiple line comment +========================= +If your comments have more then one line, please start it from the second line. + +Example: +/* + * first line comment // correct + * ... + * last line comment + */ + + +M3: Space before and after operator +=================================== +There should be a space before and after each operator. + +Example: +a + b; // correct + + +M4: Wrap long lines +=================== +If your condition in if, while, for statement or a function declaration is too +long to fit in one line, the new line needs to be indented not aligned with the +body. + +Example: +1) +if (call->status == CALL_STATUS_ACTIVE || + call->status == CALL_STATUS_HELD) { // wrong + connman_dbus_dict_append(); + +2) +if (call->status == CALL_STATUS_ACTIVE || + call->status == CALL_STATUS_HELD) { // correct + connman_dbus_dict_append(); + +3) +gboolean sim_ust_is_available(unsigned char *service_ust, unsigned char len, + num sim_ust_service index) // wrong +{ + int a; + ... +} + +4) +gboolean sim_ust_is_available(unsigned char *service_ust, unsigned char len, + enum sim_ust_service index) // correct +{ + int a; + ... +} + +If the line being wrapped is a function call or function declaration, the +preferred style is to indent at least past the opening parenthesis. Indenting +further is acceptable as well (as long as you don't hit the 80 character +limit). + +If this is not possible due to hitting the 80 character limit, then indenting +as far as possible to the right without hitting the limit is preferred. + +Example: + +1) +gboolean sim_ust_is_available(unsigned char *service_ust, unsigned char len, + enum sim_ust_service index); // worse + +2) +gboolean sim_ust_is_available(unsigned char *service_ust, unsigned char len, + enum sim_ust_service index); + // better + +M5: Git commit message 50/72 formatting +======================================= +The commit message header should be within 50 characters. And if you have +detailed explanatory text, wrap it to 72 character. + + +M6: Space when doing type casting +================================= +There should be a space between new type and variable. + +Example: +1) +a = (int *)b; // wrong +2) +a = (int *) b; // correct + + +M7: Don't initialize variable unnecessarily +=========================================== +When declaring a variable, try not to initialize it unless necessary. + +Example: +int i = 1; // wrong + +for (i = 0; i < 3; i++) { +} + + +M8: Use g_try_malloc instead of g_malloc +======================================== +When g_malloc fails, the whole program would exit. Most of time, this is not +the expected behavior, and you may want to use g_try_malloc instead. + +Example: +additional = g_try_malloc(len - 1); // correct +if (additional == NULL) + return FALSE; + + +M9: Follow the order of include header elements +=============================================== +When writing an include header the various elements should be in the following +order: + - #includes + - forward declarations + - #defines + - enums + - typedefs + - function declarations and inline function definitions + + +M10: Internal headers must not use include guards +================================================= +Any time when creating a new header file with non-public API, that header +must not contain include guards. + + +M11: Naming of enums +==================== + +Enums must have a descriptive name. The enum type should be small caps and +it should not be typedef-ed. Enum contents should be in CAPITAL letters and +prefixed by the enum type name. + +Example: + +enum animal_type { + ANIMAL_TYPE_FOUR_LEGS, + ANIMAL_TYPE_EIGHT_LEGS, + ANIMAL_TYPE_TWO_LEGS, +}; + +If the enum contents have values (e.g. from specification) the formatting +should be as follows: + +enum animal_type { + ANIMAL_TYPE_FOUR_LEGS = 4, + ANIMAL_TYPE_EIGHT_LEGS = 8, + ANIMAL_TYPE_TWO_LEGS = 2, +}; + +M12: Enum as switch variable +==================== + +If the variable of a switch is an enum, you must not include a default in +switch body. The reason for this is: If later on you modify the enum by adding +a new type, and forget to change the switch accordingly, the compiler will +complain the new added type hasn't been handled. + +Example: + +enum animal_type { + ANIMAL_TYPE_FOUR_LEGS = 4, + ANIMAL_TYPE_EIGHT_LEGS = 8, + ANIMAL_TYPE_TWO_LEGS = 2, +}; + +enum animal_type t; + +switch (t) { +case ANIMAL_TYPE_FOUR_LEGS: + ... + break; +case ANIMAL_TYPE_EIGHT_LEGS: + ... + break; +case ANIMAL_TYPE_TWO_LEGS: + ... + break; +default: // wrong + break; +} + +However if the enum comes from an external header file outside ConnMan +we cannot make any assumption of how the enum is defined and this +rule might not apply. + +M13: Check for pointer being NULL +================================= + +When checking if a pointer or a return value is NULL, explicitly compare to +NULL rather than use the shorter check with "!" operator. + +Example: +1) +array = g_try_new0(int, 20); +if (!array) // Wrong + return; + +2) +if (!g_at_chat_get_slave(chat)) // Wrong + return -EINVAL; + +3) +array = g_try_new0(int, 20); +if (array == NULL) // Correct + return; + + +M14: Always use parenthesis with sizeof +======================================= +The expression argument to the sizeof operator should always be in +parenthesis, too. + +Example: +1) +memset(stuff, 0, sizeof(*stuff)); + +2) +memset(stuff, 0, sizeof *stuff); // Wrong + + +M15: Use void if function has no parameters +=========================================================== +A function with no parameters must use void in the parameter list. + +Example: +1) +void foo(void) +{ +} + +2) +void foo() // Wrong +{ +} + +M16: Don't use hex value with shift operators +============================================== +The expression argument to the shift operators should not be in hex. + +Example: + +1) +1 << y + +2) +0x1 << y // Wrong + +O1: Shorten the name +==================== +Better to use abbreviation, rather than full name, to name a variable, +function, struct, etc. + +Example: +supplementary_service // too long +ss // better + +O2: Try to avoid complex if body +================================ +It's better not to have a complicated statement for if. You may judge its +contrary condition and return | break | continue | goto ASAP. + +Example: +1) +if (a) { // worse + struct voicecall *v; + call = synthesize_outgoing_call(vc, vc->pending); + v = voicecall_create(vc, call); + v->detect_time = time(NULL); + DBG("Registering new call: %d", call->id); + voicecall_dbus_register(v); +} else + return; + +2) +if (!a) + return; + +struct voicecall *v; +call = synthesize_outgoing_call(vc, vc->pending); +v = voicecall_create(vc, call); +v->detect_time = time(NULL); +DBG("Registering new call: %d", call->id); +voicecall_dbus_register(v); diff --git a/doc/config-format.txt b/doc/config-format.txt new file mode 100644 index 000000000..242992768 --- /dev/null +++ b/doc/config-format.txt @@ -0,0 +1,145 @@ +Connman configuration file format +********************************* + +Connman uses configuration files to provision existing services. Connman will +be looking for its configuration files at STORAGEDIR which by default points +to /var/lib/connman/. Configuration file names must not include other +characters than letters or numbers and must have a .config suffix. +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] +===================== + +These files can have an optional global entry describing the actual file. +The 2 allowed fields for that entry are: +- Name: Name of the network. +- Description: Description of the network. + + +Service entry [service_*] +========================= + +Each provisioned service must start with the [service_*] tag. Replace * with +an identifier unique to the config file. + +Allowed fields: +- Type: Service type. We currently only support wifi and ethernet. +- IPv4: The IPv4 address, netmask and gateway. Format of the entry + is network/netmask/gateway. The mask length can be used instead + of netmask. The field can also contain the string "off" or "dhcp". + If the setting is "off", then no IPv4 address is set to the interface. + If the setting is "dhcp", then DHCPv4 address resolution is activated. + Example: 192.168.1.2/24/192.168.1.1 + 192.168.200.100/255.255.255.0/192.168.200.1 +- IPv6: The IPv6 address, prefix length and gateway. Format of the entry + is network/prefixlen/gateway. For IPv6 addresses only prefix length is + accepted. The field can also contain the string "off" or "auto". + If the setting is "off", then no IPv6 address is set to the interface. + If the setting is "auto", then SLAAC or DHCPv6 is used. + Example: 2001:db8::2/64/2001:db8::1 +- IPv6.Privacy: IPv6 privacy option. Value can be either "disabled", + "enabled" or "prefered". See use_tempaddr variable description in Linux + kernel Documentation/networking/ip-sysctl.txt file. +- MAC: MAC address of the interface where this setting should be applied. + The MAC address is optional and if it is missing, then the first found + interface is used. The byte values must have prefix 0 added, + the bytes must be separated by ":" char and its length must be + exactly 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 = 17 characters. +- Nameservers: Comma separated list of nameservers +- SearchDomains: Comma separated list of DNS search domains +- Timeservers: Comma separated list of timeservers +- Domain: Domain name to be used + +If IPv4 address is missing then DHCP is used. If IPv6 address is missing, +then SLAAC or DHCPv6 is used. + +The following options are valid if Type is "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. +- 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. +- 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). +- Passphrase: RSN/WPA/WPA2 Passphrase +- Hidden: If set to true, then this AP is hidden. If missing or set to false, + then AP is not hidden. + + +Example +======= + +This is a configuration file for a network providing EAP-TLS, EAP-TTLS and +EAP-PEAP services. +The respective SSIDs are tls_ssid, ttls_ssid and peap_ssid and the file name +is example.config. +Please note that the SSID entry is for hexadecimal encoded SSID (e.g. "SSID = +746c735f73736964"). If your SSID does not contain any exotic character then +you should use the Name entry instead (e.g. "Name = tls_ssid"). + + +example@example:[~]$ cat /var/lib/connman/example.config +[global] +Name = Example +Description = Example network configuration + +[service_tls] +Type = wifi +SSID = 746c735f73736964 +EAP = tls +CACertFile = /home/user/.certs/ca.pem +ClientCertFile = /home/user/devlp/.certs/client.pem +PrivateKeyFile = /home/user/.certs/client.fsid.pem +PrivateKeyPassphraseType = fsid +Identity = user + +[service_ttls] +Type = wifi +Name = ttls_ssid +EAP = ttls +CACertFile = /home/user/.cert/ca.pem +Phase2 = MSCHAPV2 +Identity = user + +[service_peap] +Type = wifi +Name = peap_ssid +EAP = peap +CACertFile = /home/user/.cert/ca.pem +Phase2 = MSCHAPV2 +Identity = user + +[service_home_ethernet] +Type = ethernet +IPv4 = 192.168.1.42/255.255.255.0/192.168.1.1 +IPv6 = 2001:db8::42/64/2001:db8::1 +MAC = 01:02:03:04:05:06 +Nameservers = 10.2.3.4,192.168.1.99 +SearchDomains = my.home,isp.net +Timeservers = 10.172.2.1,ntp.my.isp.net +Domain = my.home + +[service_home_wifi] +Type = wifi +Name = my_home_wifi +Passphrase = secret +IPv4 = 192.168.2.2/255.255.255.0/192.168.2.1 +MAC = 06:05:04:03:02:01 diff --git a/doc/connman-docs.xml b/doc/connman-docs.xml new file mode 100644 index 000000000..d4059a413 --- /dev/null +++ b/doc/connman-docs.xml @@ -0,0 +1,121 @@ + + +]> + + + Connection Manager Reference Manual + Version &version; + + + Marcel + Holtmann + +
+ marcel@holtmann.org +
+
+
+
+ + + 2007-2008 + Intel Corporation. All rights reserved. + + + + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free + Documentation License, Version 1.1 or any later + version published by the Free Software Foundation with no + Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. You may obtain a copy of the GNU Free + Documentation License from the Free Software + Foundation by visiting their Web site or by writing + to: + +
+ The Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, + USA +
+
+
+
+ + + Design Overview + + + This part presents the design documentation for Connection Manager. + + + + + + + Manager interface + + + + + + + Device interface + + + + + + + Network interface + + + + + + + Service interface + + + + + + + Connection interface + + + + + + + Plugin API Reference + + + This part presents the function reference for Connection Manager. + + + + + + + + + + + + + License + + + + + + + Index + +
diff --git a/doc/connman-introduction.xml b/doc/connman-introduction.xml new file mode 100644 index 000000000..4672c2c7d --- /dev/null +++ b/doc/connman-introduction.xml @@ -0,0 +1,15 @@ + + + + + Introduction + + + About + + + + + + diff --git a/doc/connman.8 b/doc/connman.8 new file mode 100644 index 000000000..7297cf86c --- /dev/null +++ b/doc/connman.8 @@ -0,0 +1,79 @@ +.\" connman(8) manual page +.\" +.\" Copyright (C) 2012 Intel Corporation +.\" +.TH CONNMAN "8" "21 August 2012" +.SH NAME +ConnMan \- network management daemon +.SH SYNOPSIS +.B connmand [\-\-version] | [\-\-help] +.PP +.B connmand [\-\-config=] [\-\-debug=::...] [\-\-device=,,...] [\-\-nodevice=,,..] [\-\-wifi=,,...] [\-\-plugin=,,...] [\-\-noplugin=,,...] [\-\-nodaemon] [\-\-nodnsproxy] +.SH DESCRIPTION +The \fIConnMan\fP provides a daemon for managing internet connections +within devices running the Linux operating system. The Connection Manager is +designed to be slim and to use as few resources as possible. +It is a 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. +.P +.SH OPTIONS +The following options are supported: +.TP +.I "\-\-version" +Print the ConnMan software version and exit. +.TP +.I "\-\-help" +Print ConnMan's available options and exit. +.TP +.I "\-\-config=" +Specify configuration file to set up various settings for ConnMan. If not +specified, the default value of '/connman/main.conf' +is used; where is dependent on your distribution (usually +it's /etc). See \fBconnman.conf\fP(5) for more information on configuration +file. The use of config file is optional and sane default values +are used if config file is missing. +.TP +.I "\-\-debug=::..." +Sets how much information ConnMan sends to the log destination (usually +syslog's "daemon" facility). If the file options are omitted, then debugging +information from all the source files are printed. If file options are +present, then only debug prints from that source file are printed. +Example: --debug=src/service.c:plugins/wifi.c +.TP +.I "\-\-device=,,..." +Only manage these network interfaces. By default all network interfaces +are managed. +.TP +.I "\-\-nodevice=,,..." +Never manage these network interfaces. +.TP +.I "\-\-plugin=,,..." +Load these plugins only. The option can be a pattern containing +"*" and "?" characters. +.TP +.I "\-\-noplugin=,,..." +Never load these plugins. The option can be a pattern containing +"*" and "?" characters. +.TP +.I "\-\-wifi=,,..." +Wifi driver that WiFi/Supplicant should use. If omitted, then the value +of "nl80211,wext" is used by default. +.TP +.I "\-\-nodaemon" +Do not daemonize. This is useful for debugging, and directs log output to +the controlling terminal in addition to syslog. +.TP +.I "\-\-nodnsproxy" +Do not act as a DNS proxy. By default ConnMan will direct all DNS traffic +to itself by setting nameserver to 127.0.0.1 in \fBresolv.conf\fP(5) file. +If this is not desired and you want that all programs call directly some +DNS server, then you can use the --nodnsproxy option. +If this option is used, then ConnMan is not able to cache the DNS queries +because the DNS traffic is not going through ConnMan and that can cause +some extra network traffic. +.SH SEE ALSO +.BR connman.conf (5). diff --git a/doc/connman.conf.5 b/doc/connman.conf.5 new file mode 100644 index 000000000..1a2446710 --- /dev/null +++ b/doc/connman.conf.5 @@ -0,0 +1,130 @@ +.\" connman.conf(5) manual page +.\" +.\" Copyright (C) 2012 Intel Corporation +.\" +.TH "connman.conf" "5" "21 August 2012" "" +.SH NAME +main.conf \- ConnMan configuration file +.SH SYNOPSIS +/etc/connman/main.conf +.br +or +.br +\fI\fP/connman/main.conf +.br +where depends on your distribution or build. +.SH DESCRIPTION +.P +.I main.conf +is a configuration file for ConnMan. The configuration file is +optional but it can be used to set up various aspects of ConnMan's +behavior. The location of the file may be changed through use of +the "\-\-config=" argument for \fBconnman\fP (8). +.SH "FILE FORMAT" +.P +The configuration file format is key file format. +It consists of sections (groups) of key-value pairs. +Lines beginning with a '#' and blank lines are considered comments. +Sections are started by a header line containing the section enclosed +in '[' and ']', and ended implicitly by the start of the next section +or the end of the file. Each key-value pair must be contained in a section. +.P +Description of sections and available keys follows: +.SS [General] +This section is the only mandatory section of the configuration file. +.TP +.B InputRequestTimeout=\fPsecs\fP +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. +.TP +.B BrowserLaunchTimeout=\fPsecs\fP +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. +.TP +.B BackgroundScanning=\fPtrue|false\fP +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. +.TP +.B FallbackTimeservers=\fPserver1,server2,...\fP +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. +.TP +.B FallbackNameservers=\fPserver1,server2,...\fP +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. +.TP +.B DefaultAutoConnectTechnologies=\fPtechnology1,technology2,...\fP +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. +.TP +.B PreferredTechnologies=\fPtechnology1,technology2,...\fP +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 +or they are all tried. A service of a preferred technology +type in state 'ready' will get the default route when +compared to another preferred type further down the list +with state 'ready' or with 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 further down in the list. +.TP +.B NetworkInterfaceBlacklist=\fPinterface1,interface2,...\fP +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. +.TP +.B AllowHostnameUpdates=\fPtrue|false\fP +Allow connman to change the system hostname. This can +happen for example if we receive DHCP hostname option. +Default value is true. +.TP +.B SingleConnectedTechnology=\fPtrue|false\fP +Keep only a single connected technology at any time. When a new +service is connected by the user or a better one is found according +to PreferredTechnologies, the new service is kept connected and all +the other previously connected services are disconnected. With this +setting it does not matter whether the previously connected services +are in 'online' or 'ready' states, the newly connected service is +the only one that will be kept connected. A service connected by the +user will be used until going out of network coverage. With this +setting enabled applications will notice more network breaks than +normal. Default value is false. +.TP +.B TetheringTechnologies=\fPtechnology1,technology2,...\fP +List of technologies that are allowed to enable tethering separated by ",". +The default value is wifi,bluetooth,gadget. Only those technologies listed +here are used for tethering. If one wants to tether ethernet, +then add "ethernet" in the list. +NOTE that if ethernet tethering is enabled, then a DHCP server is +started on all ethernet interfaces. Tethered ethernet should +never be connected to corporate or home network as it will disrupt +normal operation of these networks. Due to this ethernet is not +tethered by default. Do not activate ethernet tethering unless you +really know what you are doing. +.TP +.B PersistentTetheringMode=\fPtrue|false\fP +Restore earlier tethering status when returning from offline mode, +re-enabling a technology, and after restarts and reboots. +Default value is false. +.SH "SEE ALSO" +.BR Connman (8) diff --git a/doc/connmanctl.1 b/doc/connmanctl.1 new file mode 100644 index 000000000..b71c6e62e --- /dev/null +++ b/doc/connmanctl.1 @@ -0,0 +1,190 @@ +.TH connmanctl 1 07/31/2012 "" "User Commands for Connman CLI" +.SH +NAME +connmanctl \- Connman CLI +.SH +SYNOPSIS +.BR connmanctl " [" +.BR enable " | " +.BR offlinemode "] [" +.BR disable " | " +.BR offlinemode "] [" +.BR technologies "] [" +.BR state "] [" +.BR services " [\-\-properties ]] [" +.BR scan " ] [" +.BR connect " ] [" +.BR config " \-\-