连接管理器 (ConnMan) 是一个连接管理守护进程 , 用于管理运行 Linux 操作系统中设备的互联网连接 它以快速连贯同步的方式对不断变化的网络条件提供了低内存消耗
ConnMan 拥有各种插件, 是一个完全模块化的系统, 可以扩展支持各种有线或无线技术, 允许对各种用例进行简单的适配和修改 例如 DHCP 和 DNS 这样的配置方法就是使用插件实现的所有的应用程序都使用 D-Bus 来与 ConnMan 通信, 与嵌入式 Yocto 构建系统一起使用, 是 GENIVI 规范的一部分
ConnMan 遵循 GPL v2.0 许可, 英特尔是该项目的主要贡献者其内部架构如下:
图 1
功能特性
以下特性嵌入到 ConnMan 中:
通用插件基础结构
设备和网络抽象(带有基本存储支持)
IPv4, IPv4-LL (link-local) 和 DHCP 以及 IPv6, DHCPv6,V6 到 V4 的 隧道等
高级路由和 DNS 配置
内置 DNS 代理和智能缓存
内置的 WISPr 热点登录和门户检测
时区配置(手动和自动的 NTP)
代理处理(手动和自动的 WPAD)
网络支持(USB, 蓝牙和 WiFi AP 模式)
详细统计处理(家居及漫游)
可以启用各种插件来支持网络:
以太网插件
Wifi 插件 WEP40 / WEP128 及 WPA/WPA2(个人及企业)
蓝牙插件(使用 BlueZ)
2g / 3g / 4g 插件(使用 oFono)
还提供了附加功能的插件:
回路接口设置
PACrunner 代理
PolicyKit 授权工具
D-Bus 接口
应用程序都使用 D-Bus 来与 ConnMan 通信, 通过管理器对象来实现应用入口管理器对象包含服务对象的引用(接口), 其他接口包括 VPN 时钟任务技术会话通知对等代理和计数器等
图 2
D-Bus Manager 接口
D-Bus Manager 解释了所有的方法和属性
图 3
检索所有全局属性的简单方法如下:
- bus = dbus.SystemBus()
- manager = dbus.Interface(bus.get_object("net.connman", "/"), "net.connman.Manager")
- properties = manager.GetProperties()
改变一个全局属性也非常简单 例如, 启用所谓的飞行模式 (AKA flight mode) 可以以设置该属性: manager.SetProperty ("OfflineMode", dbus.Boolean (1))
图 4
服务接口
高级用户接口易于访问网络细节和用户选择的偏好 这是服务列表和接口(图 5), 以一个单一的平面和排序列表来维护所有可用的服务
图 5
图 6
服务状态
图 7
每个服务的基本状态都是 "空闲", 这意味着这项服务目前根本没有使用 它也不是试图连接或做任何其他事情
"关联" 状态表明该服务试图建立与网络的低级连接 -- 例如, 与 WiFi 接入点相关联 / 连接
在 "配置" 状态下, 表示服务正在尝试检索 / 配置 IP 设置
"准备好" 状态标志着一个成功连接的设备, 并不意味着它有默认的路由, 但是基本的 IP 操作将会成功
"断开" 状态, 表明服务将终止当前连接并返回到 "空闲" 状态
"失败" 状态表明一种错误的行为, 类似于 "空闲" 状态, 服务没有连接
服务的使用
下面是如何获得一个服务对象:
service = dbus.Interface(bus.get_object("net.connman", path), "net.connman.Service")
它还包含连接或断开特定服务的方法, ConnMan 可以根据策略或通过外部事件 (如在以太网电缆中插入) 自动连接服务
图 8
图 9
技能接口
基本的设备配置任务是通过技能接口完成的, 例如, 通过技术接口来切换设备(例如通过 RFKILL)
图 10
用户可以通过 OfflineMode 属性激活离线 (飞行) 模式 在离线模式下, 包括以太网在内的所有技能都被关闭 在离线模式下, 用户可以通过使用 rfkill 命令来临时激活单个技能
ConnMan 的一些细节
可以通过命令行参数来启动 ConnMan:
- -c, --config=FILE Load the specified configuration file instead of /usr/local/etc/connman/main.conf
- -d, --debug=DEBUG Specify debug options to enable
- -i, --device=DEV Specify networking device or interface
- -I, --nodevice=DEV Specify networking interface to ignore
- -p, --plugin=NAME,... Specify plugins to load
- -P, --noplugin=NAME,... Specify plugins not to load
- -W, --wifi=NAME Specify driver for WiFi/Supplicant
- -n, --nodaemon Don't fork daemon to background
- -r, --nodnsproxy Don't enable DNS Proxy
- --nobacktrace Don't print out backtrace information
使用示例如下:
connmand -i wlan0 -I eth0 --nodnsproxy --nodaemon >& connman.log
主配置文件 (main.conf) 如下:
- InputRequestTimeout = 120 (default)---------> input request ( ex. passphrase) timeout
- BrowserLaunchTimeout = 300 ( default) -----> The request for launching a browser for portal pages
- BackgroundScanning = true --------------------> option for background scanning
- FallbackTimeservers = --------------------------> List of fallback timeservers ( used by NTP sync) separated by ","
- FallbackNameservers = -------------------------> List of fallback nameservers
- DefaultAutoConnectTechnologies = -----------> List of technologies that are marked autoconnectable by default.
- PreferredTechnologies = ------------------------> List of preferred technologies from - most preferred one to least preferred
- NetworkInterfaceBlacklist = vmnet,vboxnet,virbr,ifb,ve-,vb- ---> List of blacklisted network interfaces
- AllowHostnameUpdates = true -----------------> Allow connman to change the system hostname ( ex. dhcp hostname option)
- SingleConnectedTechnology = false -----------> Keep only a single connected technology at any time
- TetheringTechnologies = wifi,bluetooth,gadget
- PersistentTetheringMode = false --------------> Restore earlier tethering status when returning from offline mode
- Enable6to4 = false ------------------------------> Automatically enable Anycast 6to4 if possible (not recommended. see RFC6343 )
- EnableOnlineCheck = false --------------------> Enable use of http get as on online status check
- AlwaysConnectedTechnologies = -------------> List of technologies with AutoConnect = true which are always connected regardless of PreferredTechnologies setting
ConnMan 使用配置文件来提供现有的服务, 在 /var/lib/Connman / 目录下 配置文件名不能包含字母或数字以外的其他字符, 并且必须有一个 Config 后缀. 例如:
- Ex. #cat /var/lib/connman/example.config
- [global]
- Name = Example
- Description = Example network configuration
- [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
设置和配置文件是为用户经常连接的网络而自动创建的, 例如:
- # cat /var/lib/connman/settings
- [global]
- OfflineMode=false
- [WiFi]
- Enable=true
- Tethering=false
- [Bluetooth]
- Enable=false
- Tethering=false
Vpn 设置可以在 /var/lib/connman-VPN/
写一个插件
基本插件包含通过 CONNMAN 定义的插件描述, 以及通过该描述定义的 init / exit 回调例如:
- #include <connman/plugin.h>
- static int example_init(void)
- {
- return 0;
- }
- static void example_exit(void)
- {
- }
- CONNMAN_PLUGIN_DEFINE(example, "Example plugin", CONNMAN_VERSION,
- example_init, example_exit)
插件通过技术网络和设备以及其他基础结构与 ConnMan 的核心功能相互作用 以下是技术基础设施:
- ex. bluetooth plugin
- static struct connman_technology_driver tech_driver = {
- .name = "bluetooth",
- .type = CONNMAN_SERVICE_TYPE_BLUETOOTH,
- .probe = bluetooth_tech_probe,
- .remove = bluetooth_tech_remove,
- .set_tethering = bluetooth_tech_set_tethering,
- };
为了让连接管理器了解新的插件, 需要通过调用 ConnMan 驱动注册器来注册它的驱动程序
connman_technology_driver_register(&tech_driver);
设备
设备代表给定技术的真实设备, 每种技术都可能有很多设备
- static struct connman_device_driver device_driver = {
- .name = "bluetooth",
- .type = CONNMAN_DEVICE_TYPE_BLUETOOTH,
- .probe = bluetooth_device_probe,
- .remove = bluetooth_device_remove,
- .enable = bluetooth_device_enable,
- .disable = bluetooth_device_disable,
- };
注册驱动程序:
connman_device_driver_register(&device_driver);
此外, 需要为每个插件编写处理新设备的检测代码; 蓝牙插件通过为 BlueZ-d-bus 接口来注册观察者来实现 一旦新的蓝牙设备出现, 插件需要通过调用 ConnMan 设备创建来通知 ConnMan 内涵 对于蓝牙插件, 这个调用将是:
- struct connman_device *device;
- device = connman_device_create("bluetooth", CONNMAN_DEVICE_TYPE_BLUETOOTH)
网络
连接管理器为插件提供了一种手段, 用于处理为每种技术建立 / 处理连接的细节 对于蓝牙插件, 需要注册一个 connmannetworkdriver:
- static struct connman_network_driver network_driver = {
- .name = "bluetooth",
- .type = CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN,
- .probe = bluetooth_pan_probe,
- .remove = bluetooth_pan_remove,
- .connect = bluetooth_pan_connect,
- .disconnect = bluetooth_pan_disconnect,
- };
然后, 调用注册函数:
connman_network_driver_register(&network_driver);
源文件的结构解读
初始化函数将在 src/main.c 中在运行主循环之前调用
- src/util.c - /dev/urandom support
- src/inotify.c - used by the core (config.c) and the session policy plugin
- src/technology.c used for technology interface
- src/notifier.c basic notifier infrastructure
- src/agent.c agent interface
- src/service.c used for service interface
- src/peer_service.c p2p peer service API
- src/peer.c p2p peer objects core logic
- src/provider.c provider infrastructure
- src/network.c network infrastructure used by plug-ins
- src/config.c framework for configuration files
- src/device.c device infrastructure used by plug-ins
- src/iptables.c iptables support (netfilter chains and rules)
- src/firewall-iptables.c, nftables.c (older firewall.c) firewall infrastructure.
- src/nat.c used for NAT
- src/tethering.c tethering infrastructure
- src/manager.c Manager interface
- src/stats.c used for storing service stats ( mmaped into memory)
- src/ipconfig.c IP configuration framework
- src/rtnl.c netlink support
- src/session.c Allows 3rd party applications to request a network session
- src/resolver.c resolver framework
- src/dhcp.c, dhcpv6.c dhcp framework
- src/rfkill.c rfkill interface support
- src/machine.c - basic systemd-hostnamed ( machine-type- chassis) support
命令行客户端
ConnMan 有一个标准的命令行客户端 connmanctl 它可以有两种运行模式:
在命令行模式中, 命令输入作为对 connmanctl 命令的参数, 就像 systemctl 一样
交互式模式是在没有参数的情况下键入 connmanctl 来开始的 将改变为 connmanctl 表示它正在等待用户命令, 就像 python 交互模式一样
connmanctl 示例:
1. 启用和禁用 WiFi
- $ connmanctl technologies - check for the line that says Powered: True/False.
- $ connmanctl enable wifi - To power the wifi on.
- $ connmanctl disable wifi To power off the wifi.
2. 连接到一个开放的访问点
本示例的命令显示如何在命令行模式下运行控制器 为了扫描网络, connmanctl 接受简单的技术名参数 扫描附近的 WiFi 网络:
- $ connmanctl scan wifi To list the available networks found after a scan run (example output):
- $ connmanctl services
- *AO MyNetwork wifi_dc85de828967_68756773616d_managed_psk OtherNET wifi_dc85de828967_38303944616e69656c73_managed_psk AnotherOne wifi_dc85de828967_3257495245363836_managed_wep FourthNetwork wifi_dc85de828967_4d7572706879_managed_wep AnO6penNetwork wifi_dc85de828967_4d6568657272696e_managed_none
- $ connmanctl connect wifi_dc85de828967_4d6568657272696e_managed_none
3. 连接到受保护的 AP
对于受保护的 AP, 提供一些信息给 ConnMan 守护进程, 例如一个密码
- $ connmanctl
- connmanctl> scan wifi ----- To list services:
- connmanctl> services
- connmanctl> agent on --- register the agent to handle user requests.
- connmanctl> connect wifi_dc85de828967_38303944616e69656c73_managed_psk
代理需要根据所连接的网络类型提供更多信息, 代理还将打印关于它所需要信息的额外数据, 如下面的示例所示
Agent RequestInput wifi_dc85de828967_38303944616e69656c73_managed_psk Passphrase = [ Type=psk, Requirement=mandatory ] Passphrase?
提供完请求的信息后, 然后键入 quit 退出如果提供的信息是正确的, 那现在应该就连接到受保护的 AP 了
各种硬件接口被在 ConnMan 中称为技术, 要列出可用的技术, 可以运行:
$ connmanctl technologies
那些技术可以通过以下方式进行:
- $ connmanctl enable technology_type
- $ connmanctl disable technology_type
例如, 切换 WiFi:
$ connmanctl disable wifi
测试与调试
ConnMan 同时也提供了基于 python 的测试脚本(ex. test-connman, list-services 等) 通过这些脚本支持连接断开自动连接服务扫描启用禁用非线性状态等基本操作
可以使用 - d 命令行选项在 ConnMan 中激活调试打印
- -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.
Connman 的一些组件有基于环境变量启动的调试版本 如果环境变量已设置, 则相应组件将打印一些额外的调试信息可以使用下列环境变量:
* CONNMAN_DHCP_DEBUG: Dhcpv4 相关调试信息
* CONNMAN_DHCPV6_DEBUG: DHCPv6 相关调试信息
* CONNMAN_IPTABLES_DEBUG: 使用 iptables 时的额外信息
* CONNMAN_RESOLV_DEBUG: 名称解析器调试打印 这些调试信息用于当 ConnMan 解析主机名称以供自己使用 请注意, DNS 代理调试版本不使用此环境变量 为此, 我们可以使用 "-d src / dnsproxy"c" 命令行选项
* CONNMAN_SUPPLICANT_DEBUG : 调试打印, 用于控制和 wpa 拼接过程之间的通信
* CONNMAN_web_DEBUG: 当 ConnMan 在 Wispr 进行互联网连接检查时的调试信息
例如:
CONNMAN_SUPPLICANT_DEBUG=1 src/connmand -n
译自 http://www.embedded-computing.com/dev-tools-and-os/the-connman
来源: http://blog.csdn.net/wireless_com/article/details/79467506