Android以太网框架情景分析之NetworkFactory与NetworkAgent深入分析_android以太网框架情景分析之ethernetnetworkfactory深入分析-CSDN博客
Android以太网框架情景分析之NetworkFactory与NetworkAgent深入分析
最新推荐文章于 2023-09-07 10:00:03 发布
IT先森
最新推荐文章于 2023-09-07 10:00:03 发布
阅读量6.6k
收藏
32
点赞数
14
分类专栏:
Android网络之以太网框架分析
文章标签:
NetworkFactory
NetworkAgent
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/tkwxty/article/details/107363504
版权
Android网络之以太网框架分析
专栏收录该内容
7 篇文章
22 订阅
订阅专栏
Android以太网框架情景分析之NetworkFactory与NetworkAgent深入分析
Android网络框架分析系列文章目录:
Android P适配以太网功能开发指南 Android以太网框架情景分析之启动简介 Android以太网框架情景分析之EthernetServiceImpl和NetworkManagementService交互深入分析 Android以太网框架情景分析之NetworkManagementService和netd交互深入分析二 Android以太网框架情景分析之NetworkManagementService和netd交互深入分析一 Android以太网框架情景分析之NetworkFactory与NetworkAgent深入分析 AsyncChannel原理分析以及实操演练
引言
在前面的章节中Android以太网框架情景分析之启动简介我们介绍了以太网框架的整体启动流程,然后说到了EthernetNetworkFactory类是Ethernet的核心管理类,几乎包含了Ethernet所有的网络管理操作,这其中就包括各种网络的注册网络以及和ConnectifyService服务的交互(主要是通知网络状态的变化,评分机制的变化)。那么本章节将会重点来讲解EthernetNetworkFactory,而这其中的重重之重是NetworkFactory与NetworkAgent和ConnectifyService的通信机制的建立。
本篇章演示的源码是在Android 7.1 msm8953平台上,其中涉及的源码路径如下所示:
frameworks/base/services/java/com/android/server/
---ConnectivityService.java
---INativeDaemonConnectorCallbacks.java
---NativeDaemonConnector.java
---NetworkManagementService.java
---SystemServer.java
---SystemServiceManager.java
frameworks/base/core/java/android/net/
---ConnectivityManager.java
---EthernetManager.java
---IConnectivityManager.aidl
---IEthernetManager.aidl
---LinkProperties.java
---NetworkPolicy.java
---NetworkAgent.java
---NetworkFactory.java
---NetworkInfo.java
---ProxyInfo.java
frameworks/opt/net/ethernet/java/com/android/server/ethernet/
---EthernetConfigStore.java
---EthernetNetworkFactory.java
---EthernetServiceImpl.java
---EthernetService.java
在正式开始本篇的介绍前,还是附上祖传的以太网框架相关类调用关系图,这样能让大伙先在整体流程上有个概括,这样在分析代码走神的时候还可以回来看看,自己到那里了,将要到那里去。
一. EthernetNetworkFactory的初始化
在前面我们扯了一大推的理论知识和前期准备,从现在开始就是开始真正的源码分析了,在前面的篇章中我们分析到了EthernetNetworkFactory,那么我们就接着上篇继续分析了,开干,各位小伙伴们系好安全带,开始发车了。
1.1 EthernetNetworkFactory.EthernetNetworkFactory
分析Java中的一个类,一般从构造方法开始,这里我们也不能免俗也从构造方法开始,这里的该构造函数比较简单,主要就是初始化一些成员变量信息,这里不是我们重点关注的。
class EthernetNetworkFactory {
EthernetNetworkFactory(RemoteCallbackList
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, "");//设置网络基本信息,如网络类型,网络别名
mLinkProperties = new LinkProperties();
initNetworkCapabilities();
mListeners = listeners;
}
}
}
1.2 EthernetNetworkFactory.start
class EthernetNetworkFactory {
/**
* Begin monitoring connectivity
*/
public synchronized void start(Context context, Handler target) {
// The services we use.
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
mNMService = INetworkManagementService.Stub.asInterface(b);//获取NetworkManagementService服务端代理,在前期知识储备中我们有讲过NetworkManagementService主要用于和Netd通信
mEthernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE);//获取EthernetManager服务端代理
// Interface match regex.
mIfaceMatch = context.getResources().getString(
com.android.internal.R.string.config_ethernet_iface_regex);
// Create and register our NetworkFactory.
mFactory = new LocalNetworkFactory(NETWORK_TYPE, context, target.getLooper());//这个是重点,注意第三个参数,这个会在章节二重点介绍
mFactory.setCapabilityFilter(mNetworkCapabilities);
mFactory.setScoreFilter(-1); // this set high when we have an iface
mFactory.register();//向ConnectivityService注册自己
mContext = context;
// Start tracking interface change events.
mInterfaceObserver = new InterfaceObserver();
try {
mNMService.registerObserver(mInterfaceObserver);
} catch (RemoteException e) {
Log.e(TAG, "Could not register InterfaceObserver " + e);
}
// If an Ethernet interface is already connected, start tracking that.
// Otherwise, the first Ethernet interface to appear will be tracked.
try {
final String[] ifaces = mNMService.listInterfaces();
for (String iface : ifaces) {
synchronized(this) {
if (maybeTrackInterface(iface)) {
// We have our interface. Track it.
// Note: if the interface already has link (e.g., if we
// crashed and got restarted while it was running),
// we need to fake a link up notification so we start
// configuring it. Since we're already holding the lock,
// any real link up/down notification will only arrive
// after we've done this.
if (mNMService.getInterfaceConfig(iface).hasFlag("running")) {
updateInterfaceState(iface, true);
}
break;
}
}
}
} catch (RemoteException|IllegalStateException e) {
Log.e(TAG, "Could not get list of interfaces " + e);
}
}
这里可以看到start方法接收一个Handler对象作为参数,对于该参数我们回溯一下是从EthernetServiceImpl.start()中传入的,它新建了一个HandlerThread对象,并传入作为参数,这个Handler对象很重要,因为它会有多重的传递,串联起了以太网的网络管理。并且在代码中创建了一个LocalNetworkFactory对象,而我们的LocalNetworkFactory继承自NetworkFactory。
二. NetworkFactory网络工厂类详解及注册流程分析
我们知道各个具有网络连接的对象(WIFI,BT,PHONE)都需要向ConnectivityService注册自己,并把自己所提供的网络的分值告诉ConnectivityService。而Android为了ConnectivityService便于统一管理,每一个具备提供网络服务的对象都需要创建一个NetworkFactory的子类对象,并利用该对象注册自己,以及提供自己的分值。并且我们可以通过搜索发现确实WIFI/BT/PHONE/ETHERNET都有实现了NetworkFactory工厂类。如下所示,而我们的LocalNetworkFactory的也在此行列中,那先让我们看看NetworkFactory究竟是如何定义的。
XXX/frameworks$ grep -nr "extends NetworkFactory" ./
./base/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java:430: private static class MockNetworkFactory extends NetworkFactory {
./opt/telephony/src/java/com/android/internal/telephony/PhoneSwitcher.java:222: private static class PhoneSwitcherNetworkRequestListener extends NetworkFactory {
./opt/telephony/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java:42:public class TelephonyNetworkFactory extends NetworkFactory {
./opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java:127: private class LocalNetworkFactory extends NetworkFactor {
./opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java:4083: private class WifiNetworkFactory extends NetworkFactory {
./opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java:4116: private class UntrustedWifiNetworkFactory extends NetworkFactory {
XXX/packages$ grep -nr "extends NetworkFactory" ./
./apps/Bluetooth/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactory.java:49:public class BluetoothTetheringNetworkFactory extends NetworkFactory {
NetworkFactory网络注册的时序图如下所示:
2.1 NetworkFactory类简介
好吗,前面空洞的介绍了NetworkFactory的功能,下面得实打实的来点干货分析分析了,不然没有料不是!
/**
* A NetworkFactory is an entity that creates NetworkAgent objects.
* The bearers register with ConnectivityService using {@link #register} and
* their factory will start receiving scored NetworkRequests. NetworkRequests
* can be filtered 3 ways: by NetworkCapabilities, by score and more complexly by
* overridden function. All of these can be dynamic - changing NetworkCapabilities
* or score forces re-evaluation of all current requests.
*
* If any requests pass the filter some overrideable functions will be called.
* If the bearer only cares about very simple start/stopNetwork callbacks, those
* functions can be overridden. If the bearer needs more interaction, it can
* override addNetworkRequest and removeNetworkRequest which will give it each
* request that passes their current filters.
* @hide
**/
public class NetworkFactory extends Handler {
public NetworkFactory(Looper looper, Context context, String logTag,
NetworkCapabilities filter) {
super(looper);
LOG_TAG = logTag;
mContext = context;
mCapabilityFilter = filter;
}
//将当前网络注册到ConnectivityService
public void register() {
if (DBG) log("Registering NetworkFactory");
if (mMessenger == null) {
mMessenger = new Messenger(this);
ConnectivityManager.from(mContext).registerNetworkFactory(mMessenger, LOG_TAG);
}
}
//处理网络请求,用于打开或者释放当前连接,一般在有新的网络接入时会触发此处
protected void handleAddRequest(NetworkRequest request, int score) {
NetworkRequestInfo n = mNetworkRequests.get(request.requestId);
if (n == null) {
if (DBG) log("got request " + request + " with score " + score);
n = new NetworkRequestInfo(request, score);
mNetworkRequests.put(n.request.requestId, n);
} else {
if (VDBG) log("new score " + score + " for exisiting request " + request);
n.score = score;
}
if (VDBG) log(" my score=" + mScore + ", my filter=" + mCapabilityFilter);
evalRequest(n);
}
//被子类实现
protected void startNetwork() { }
protected void stopNetwork() { }
//更新当前网络的分值
public void setScoreFilter(int score) {
sendMessage(obtainMessage(CMD_SET_SCORE, score, 0));
}
}
可以看到,这里的NetworkFactory 可以分为如下三个知识点:
这里我们可以看到NetworkFactory 继承于Handler,从该类的字面理解我们可以把它当作一个工厂类,对相关网络的请求和终止操作都通过该对象进行处理。并且从注释可知NetworkFactory与NetworkAgent对象有密切关系,至于为什么说它们有密切的关系,这个先不点破,大伙可以跟着代码分析来自行体会。而且可知NetworkFactory会通过register()方法向ConnectivityService进行注册。其中它的方法start/stopNetwork()是提供的回调函数 ,我们可以通过这两个函数来请求或终止网络:
2.2 NetworkFactory注册到ConnectivityService服务
既然这里提到了注册,通常注册到目的一般是想通过注册到目的端,然后当目的端的状态发生变化的时候回调发起端的相关方法或者接口,而我们这里的注册也不能免俗!通过后面的分析你会分析原来也是依照这个套路来进行的。
//NetworkFactory.java
public void register() {
if (DBG) log("Registering NetworkFactory");
if (mMessenger == null) {
mMessenger = new Messenger(this);//注意这里的是Messenger,其参数为NetworkFactory本身,且Messenger是可序列的所以可以跨进程Binder传递
ConnectivityManager.from(mContext).registerNetworkFactory(mMessenger, LOG_TAG);//
}
}
在正式开始分析前,有必要认识一下Messenger类,这个可不是Message,不是,不是!如果小伙伴们对Messenger和AsyncChannel不熟悉,强烈建议小伙伴们抽出一点时间参见AsyncChannel原理分析以及实操演练的篇章,里面有具体讲解了Messenger和AsyncChannle,如果不搞懂上述两个内容,后续的相关知识点小伙伴可能会一头雾水了!这里我们可以用一句话来概括Messenger主要是为了实现AsyncChannel通信而封装的一个类,而AsyncChannle又是为了实现Handler跨进程或者相同进程通信而封装的一个类。
而我们在前面的篇章知道,我们在创建LocalNetworkFactory对象时,我们给它指定了一个特定线程的Looper对象,而这个Looper得最终来源是EthernetServiceImpl的start方法,如下所示:
//EthernetServiceImpl.java
public void start() {
Log.i(TAG, "Starting Ethernet service");
HandlerThread handlerThread = new HandlerThread("EthernetServiceThread");
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper());//根本来源
mTracker.start(mContext, mHandler);
mStarted.set(true);
}
结合前面的两点,我们再来捋一捋!这里我们的registerNetworkFactory方法参数Messenger对象是一个可以跨进程传递的实例对象,你可以认为它代表一个Handler对象,既然是Handler对象,那么我们可以像使用Handler对象一样,使用Messenger对象来发送消息了,而此处该引用指向mNetworkFactory这个Handler对象,它绑定的Looper属于一个特定的线程,它在EthernetServiceImpl中创建。
然后们接着继续分析registerNetworkFactory方法,如下所示:
//ConnectivityManager.java
public static ConnectivityManager from(Context context) {
return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
}
public void registerNetworkFactory(Messenger messenger, String name) {
try {
mService.registerNetworkFactory(messenger, name);//详见章节2.3
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
一看就是老套路,获取CONNECTIVITY_SERVICE服务,这个服务就是我们的ConnectivityService服务,然后通过Binder调用ConnectivityService服务的registerNetworkFactory方法,对于Binder不熟悉的小伙伴们可以看看Android Binder指南让你对Android的Binder有一个比较深入的认识和了解。
2.3 ConnectivityService.registerNetworkFactory
历经重重险阻,万水千山的终于来到了ConnectivityService的世界,让我们紧跟源码继续分析!
//ConnectivityService.java
private static class NetworkFactoryInfo {
public final String name;
public final Messenger messenger;
public final AsyncChannel asyncChannel;
public NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel) {
this.name = name;//要注册的网络名称,譬如Ethernet,wifi,bt等
this.messenger = messenger;//
this.asyncChannel = asyncChannel;
}
}
public void registerNetworkFactory(Messenger messenger, String name) {
enforceConnectivityInternalPermission();//权限检测忽略
NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel());//内部类,对相关的信息进行封装
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi));//InternalHandler对象用于处理内部事务
}
这里的NetworkFactoryInfo 是一个ConnectivityService的内部类,用来封装一些变量信息,而我们这里用它保存了将要注册的网络信息名称(Ethernet)以及特定的Messenger对象messenger,并且将新创建的匿名AsyncChannel通道类对象也保存到其中了。
接着通过InternalHandler对象mHandler向自己发送了一条信息EVENT_REGISTER_NETWORK_FACTORY并且携带了NetworkFactoryInfo相关信息,这里的InternalHandler是ConnectivityService的内部Handler主要用于其内部一些事务的处理流程,我们直接直捣黄龙看其对EVENT_REGISTER_NETWORK_FACTORY的处理流程,如下所示:
//ConnectivityService.java
private class InternalHandler extends Handler {
public InternalHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
......
case EVENT_REGISTER_NETWORK_FACTORY: {
handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj);//详见章节2.4
break;
......
}
}
}
}
2.4 ConnectivityService.handleRegisterNetworkFactory
//ConnectivityService.java
private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) {
if (DBG) log("Got NetworkFactory Messenger for " + nfi.name);
mNetworkFactoryInfos.put(nfi.messenger, nfi);
nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger);//是不是有种似曾识相的感觉
}
这里的mNetworkFactoryInfos是一个HashMap对象,在此处将前面创建的NetworkFactoryInfo对象nfi的参数Messenger位key,以NetworkFactoryInfo对象nfi为value添加到mNetworkFactoryInfos中。接着调用前面创建的匿名AsyncChannel对象建立连接,对于这个知识点还是建议大伙抽出一定的时间参阅博客AsyncChannel原理分析以及实操演练,这里我还是简单的分析下调用connect的后续流程,如下所示:
//AsyncChannel.java
public void connect(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
connected(srcContext, srcHandler, dstMessenger);
replyHalfConnected(STATUS_SUCCESSFUL);
}
public void connected(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
mSrcContext = srcContext;
mSrcHandler = srcHandler;
mSrcMessenger = new Messenger(mSrcHandler);
mDstMessenger = dstMessenger;
linkToDeathMonitor();
}
private void replyHalfConnected(int status) {
Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_HALF_CONNECTED);
msg.arg1 = status;
msg.obj = this;
msg.replyTo = mDstMessenger;
if (!linkToDeathMonitor()) {
msg.arg1 = STATUS_BINDING_UNSUCCESSFUL;
}
mSrcHandler.sendMessage(msg);
}
通过上面的connect流程简要分析,我们可以得到如下两点结论:
这里通过调用connect方法带入参数,对AsyncChannel中的变量进行相关的初始化,初始化之后mSrcHandler指向了ConnectivityService中的NetworkStateTrackerHandler对象mTrackerHandler,它主要负责接收网络模块发送的消息,并进行网络更新;并且这里的mSrcMessenger表示了对该Handler对象的一个引用;最后的mDstMessenger 指向了EthernetNetworkFactory中的LocalNetworkFactory对象,该对象也是一个Handler。在这里要特别关注Handler和Messenger的来源和出处,不是说自古英雄不问出处吗,看来有时候古人还是欺我啊。 最后通过mSrcHandler发送了CMD_CHANNEL_HALF_CONNECTED的相关指令,将会在ConnectivityService中对象中的mTrackerHandler被处理,处理逻辑如下:
//ConnectivityService.java
private class NetworkStateTrackerHandler extends Handler {
public NetworkStateTrackerHandler(Looper looper) {
super(looper);
}
private boolean maybeHandleAsyncChannelMessage(Message msg) {
switch (msg.what) {
default:
return false;
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
handleAsyncChannelHalfConnect(msg);//此处处理,详见章节2.5
break;
}
case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
if (nai != null) nai.asyncChannel.disconnect();
break;
}
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
handleAsyncChannelDisconnected(msg);
break;
}
}
return true;
}
2.5 ConnectivityService.handleAsyncChannelHalfConnect
//ConnectivityService.java
private void handleAsyncChannelHalfConnect(Message msg) {
AsyncChannel ac = (AsyncChannel) msg.obj;
if (mNetworkFactoryInfos.containsKey(msg.replyTo)) {//又见到老熟人了mNetworkFactoryInfos
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
if (VDBG) log("NetworkFactory connected");
// A network factory has connected. Send it all current NetworkRequests.
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
if (nri.request.isListen()) continue;
NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK,
(nai != null ? nai.getCurrentScore() : 0), 0, nri.request);//详见章节2.6
}
} else {
loge("Error connecting NetworkFactory");
mNetworkFactoryInfos.remove(msg.obj);
}
} else if (mNetworkAgentInfos.containsKey(msg.replyTo)) {//NetworkAgent注册的时候会走这个分支
......
}
}
还记得大明湖畔的夏雨荷吗!错了,还记得2.4章节的mNetworkFactoryInfos吗,在该章节里面我们会将NetworkFactoryInfo添加到其中,而此时我们会从其中取出来进行匹配,既然我们已经添加了当然能匹配到了,所以最终会调用到如下的逻辑流程:
AsyncChannel ac = (AsyncChannel) msg.obj;
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
if (nri.request.isListen()) continue;
NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK,
(nai != null ? nai.getCurrentScore() : 0), 0, nri.request);//详见章节2.6
}
这里最终会调用到AsyncChannel对象ac的mDstMessenger发送CMD_REQUEST_NETWORK消息,而通过前面的分析我们知道mDstMessenger是指向了EthernetNetworkFactory中的LocalNetworkFactory,从字面理解该请求可以理解为向LocalNetworkFactory请求一个网络, 而此时还处于初始化阶段还没有为以太网创建NetworkRequest请求,所以mNetworkForRequestId.get取出的内容为空,从而sendMessage发送的第二个参数arg1为为0这个很重要。
2.6 NetworkFactory.handleAddRequest
我找遍LocalNetworkFactory也没有看到Handler的处理消息的方法handleMessage,好吗它的处理方法在其父类LocalNetworkFactory中实现的,那我们就来看看它是怎么处理CMD_REQUEST_NETWORK消息的:
//NetworkFactory.java
public void handleMessage(Message msg) {
switch (msg.what) {
case CMD_REQUEST_NETWORK: {
handleAddRequest((NetworkRequest)msg.obj, msg.arg1);//处理请求
break;
}
case CMD_CANCEL_REQUEST: {
handleRemoveRequest((NetworkRequest) msg.obj);
break;
}
case CMD_SET_SCORE: {
handleSetScore(msg.arg1);
break;
}
case CMD_SET_FILTER: {
handleSetFilter((NetworkCapabilities) msg.obj);
break;
}
}
}
protected void handleAddRequest(NetworkRequest request, int score) {
NetworkRequestInfo n = mNetworkRequests.get(request.requestId);
if (n == null) {
if (DBG) log("got request " + request + " with score " + score);
n = new NetworkRequestInfo(request, score);
mNetworkRequests.put(n.request.requestId, n);
} else {
if (VDBG) log("new score " + score + " for exisiting request " + request);
n.score = score;
}
if (VDBG) log(" my score=" + mScore + ", my filter=" + mCapabilityFilter);
evalRequest(n);//详见章节2.7
}
在这里由于是第一次接收到CMD_REQUEST_NETWORK的请求,因此NetworkRequestInfo 对象n为null,所以将会在NetworkFactory中创建NetworkRequestInfo的对象并且将其存储到列表mNetworkRequests中供后续使用,然后调用方法evalRequest进入网络评价过程。
2.7 NetworkFactory.evalRequest
//NetworkFactory.java
private void evalRequest(NetworkRequestInfo n) {
if (VDBG) log("evalRequest");
if (n.requested == false && n.score < mScore &&
n.request.networkCapabilities.satisfiedByNetworkCapabilities(
mCapabilityFilter) && acceptRequest(n.request, n.score)) {
if (VDBG) log(" needNetworkFor");
needNetworkFor(n.request, n.score);//详见章节2.8
n.requested = true;
} else if (n.requested == true &&
(n.score > mScore || n.request.networkCapabilities.satisfiedByNetworkCapabilities(
mCapabilityFilter) == false || acceptRequest(n.request, n.score) == false)) {
if (VDBG) log(" releaseNetworkFor");
releaseNetworkFor(n.request);
n.requested = false;
} else {
if (VDBG) log(" done");
}
}
该逻辑就是整个网络注册系统最关键的地方,其逻辑分为如下两条线路:
如果NetworkRequestInfo没有被requested过,并且其分值(n.score)小于当前NetworkFactory自己的分值(mScore),那么就说明,当前NetworkFactory所处的网络优先级高于其他网络的优先级,就会触发当前NetworkFactory所在网络的needNetworkFor()流程,也就是连接建立流程,并将标记NetworkRequestInfo.requested=true。当NetworkRequestInfo被requested过(也就是当前网络被needNetworkFor过),此时如果再次收到请求,并且携带的新score大于当前NetworkFactory所处网络的mScore,那么就说明当前NetworkFactory所在网络优先级已经不是最高,需要将其releaseNetworkFor掉,并标记NetworkRequestInfo.requested=false。
对于初始化流程来说,由于NetworkRequestInfo是刚才在handleAddRequest新创建的,所以其requested状态必然为false,而且我们前面提到,ConnectivityService发送CMD_REQUEST_NETWORK时携带的分值参数为0,并且对于以太网网络来说,其mScore=70(至于这个70在什么地方赋值的,这个先忽略,后续的篇章中会讲到此处),因此此时的判定状态将会是:n.requested=false 且n.score < mScore,那么在这种环境下,对于以太网网络环境初始化过程来说,将会满足第一个if判断,进入needNetworkFor流程,也就是触发以太网网络的建立。
这里插播一个知识点,假如客户提出网络共存需求,即有客户提出,也就是机器中所有的物理传输介质(WiFi、Mobil、Ethernet)都必须可以同时可以进行网络通信工作,不能互斥。通过设置不同主机IP地址使用不同的网络类型,设置规则发送给Netd,而实现需求。而在这里我们可见,同一时间只能存在一种网络通信方式,即优先级。也就是WiFi、Mobil、以太网他们之间是互斥的,同一时间只有一种通信方式在线提供服务。那要怎么操作呢?
其实这里就涉及到了evalRequest的评分机制了,要想WiFi、Mobil、Ethernet网络共存,我们可以通过修改评分回调的逻辑实现共存,也就是当进入评分互斥的逻辑时不调用网络释放接口,就能实现网络共存不互斥的需求。也就是通过控制传入的score值大小,可以是设置为40,最终走到needNetworkFor的这个逻辑中去就能实现网络共存。
2.8 NetworkFactory.evalRequest
//NetworkFactory.java
protected void needNetworkFor(NetworkRequest networkRequest, int score) {
if (++mRefCount == 1) startNetwork();
}
//EthernetNetworkFactory.java
private class LocalNetworkFactory extends NetworkFactory {
protected void startNetwork() {
onRequestNetwork();//详见章节2.9
}
}
兜兜转转最后走到了EthernetNetworkFactory中的onRequestNetwork来处理Ethernet的连接操作,包括对静态IP和DHCP的处理。到这里onRequestNetwork处理完成,一个NetworkFactory对象的注册过程就结束了。
2.9 EthernetNetworkFactory.onRequestNetwork
//EthernetNetworkFactory.java
public void onRequestNetwork() {
synchronized(EthernetNetworkFactory.this) {
if (mIpProvisioningThread != null) {
return;
}
}
final Thread ipProvisioningThread = new Thread(new Runnable() {
public void run() {
if (DBG) {
Log.d(TAG, String.format("starting ipProvisioningThread(%s): mNetworkInfo=%s",
mIface, mNetworkInfo));
}
LinkProperties linkProperties;
IpConfiguration config = mEthernetManager.getConfiguration();
if (config.getIpAssignment() == IpAssignment.STATIC) {
if (!setStaticIpAddress(config.getStaticIpConfiguration())) {
// We've already logged an error.
mIpProvisioningThread = null;
return;
}
if (PAX_ETHERNET) {
StaticStatus = true;
}
linkProperties = config.getStaticIpConfiguration().toLinkProperties(mIface);
if (config.getProxySettings() == ProxySettings.STATIC ||
config.getProxySettings() == ProxySettings.PAC) {
linkProperties.setHttpProxy(config.getHttpProxy());
}
} else {
mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddr);
WaitForProvisioningCallback ipmCallback = new WaitForProvisioningCallback() {
@Override
public void onLinkPropertiesChange(LinkProperties newLp) {
synchronized(EthernetNetworkFactory.this) {
if (mNetworkAgent != null && mNetworkInfo.isConnected()) {
mLinkProperties = newLp;
mNetworkAgent.sendLinkProperties(newLp);
}
}
}
};
synchronized(EthernetNetworkFactory.this) {
stopIpManagerLocked();
mIpManager = new IpManager(mContext, mIface, ipmCallback);
if (config.getProxySettings() == ProxySettings.STATIC ||
config.getProxySettings() == ProxySettings.PAC) {
mIpManager.setHttpProxy(config.getHttpProxy());
}
final String tcpBufferSizes = mContext.getResources().getString(
com.android.internal.R.string.config_ethernet_tcp_buffers);
if (!TextUtils.isEmpty(tcpBufferSizes)) {
mIpManager.setTcpBufferSizes(tcpBufferSizes);
}
final ProvisioningConfiguration provisioningConfiguration =
mIpManager.buildProvisioningConfiguration()
.withProvisioningTimeoutMs(0)
.build();
mIpManager.startProvisioning(provisioningConfiguration);
}
linkProperties = ipmCallback.waitForProvisioning();
if (linkProperties == null ) {
Log.e(TAG, "IP provisioning error");
// set our score lower than any network could go
// so we get dropped.
mFactory.setScoreFilter(-1);
synchronized(EthernetNetworkFactory.this) {
stopIpManagerLocked();
}
mIpProvisioningThread = null;
return;
}
}
synchronized(EthernetNetworkFactory.this) {
if (mNetworkAgent != null) {
Log.e(TAG, "Already have a NetworkAgent - aborting new request");
stopIpManagerLocked();
mIpProvisioningThread = null;
return;
}
mLinkProperties = linkProperties;
mNetworkInfo.setIsAvailable(true);
mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr);
// Create our NetworkAgent.
mNetworkAgent = new NetworkAgent(mFactory.getLooper(), mContext,
NETWORK_TYPE, mNetworkInfo, mNetworkCapabilities, mLinkProperties,
NETWORK_SCORE) {
public void unwanted() {
synchronized(EthernetNetworkFactory.this) {
if (this == mNetworkAgent) {
stopIpManagerLocked();
mLinkProperties.clear();
mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null,
mHwAddr);
updateAgent();
mNetworkAgent = null;
try {
mNMService.clearInterfaceAddresses(mIface);
} catch (Exception e) {
Log.e(TAG, "Failed to clear addresses or disable ipv6" + e);
}
} else {
Log.d(TAG, "Ignoring unwanted as we have a more modern " +
"instance");
}
}
};
};
mIpProvisioningThread = null;
}
if (DBG) {
Log.d(TAG, String.format("exiting ipProvisioningThread(%s): mNetworkInfo=%s",
mIface, mNetworkInfo));
}
}
});
synchronized(EthernetNetworkFactory.this) {
if (mIpProvisioningThread == null) {
mIpProvisioningThread = ipProvisioningThread;
mIpProvisioningThread.start();
}
}
}
尼玛这个方法的逻辑代码也太多了,我们牛逼的谷歌工程师就不知道拆分拆分吗,这一头看不都尾巴的代码,这个各位在分析的时候可以不要硬啃,我们这里只用关心NetworkAgent。通过前面的分析我们可知NetworkFactory将自己注册到ConnectivityService,然后在EthernetNetworkFactory中快速响应ConnectivityService的网络请求,但是这种通道请求时单向的,只能由ConnectivityService流向NetworkFactory而不能反过来。那此时就一个问题了假如我们的EthernetNetworkFactory需要和ConnectivityService进行双向通信呢,这就轮到了我们的NetworkAgent上场了。
三. NetworkAgent网络代理类详解及注册流程分析
通过我们第二章节的分析可知NetworkFactory可以被看做是ConnectivityService向链路网络(以太网,蓝牙,WIFI)请求的统一接口.,那么NetworkAgent网络代理则可以认为是是ConnectivityService和链路网络管理者(如EthernetNetworkFactory)之间的双向信使,在NetworkFactory和ConnectivityService建立连接并调用onRequestNetwork之后通过NetworkAgent,EthernetNetworkFactory可以向ConnectivityService执行如下操作:
更新网络状态 NetworkInfo(断开、连接中、已连接等)更新链路配置 LinkProperties(本机网口、IP、DNS、路由信息等)更新网络能力 NetworkCapabilities(信号强度、是否收费等)
ConnectivityService可以向EthernetNetworkFactory执行如下操作,但是遗憾的是EthernetNetworkFactory都放任没有处理:
更新网络有效性(即NetworkMonitor的网络检测结果)禁止自动连接由于网络不可上网等原因主动断开网络
到这里我们应该知道了,NetworkAgent提供了ConnectivityService和EthernetNetworkFactory之间双向通信的能力。原理类似NetworkFactory,也是使用了AsyncChannel和Messenger,其时序图如下红色框标记所示:
3.1 NetWorkFactory和NetworkAgent之间的关系究竟是啥
还记得在章节2.1的时候留下的一个小小疑问点吗!我们说NetWorkFactory和NetworkAgent之间存在着紧密的联系,那这个紧密联系是什么呢!通过从前面的代码分析我们可以知道NetworkAgent是被NetworkFactory创建的(通过前面的时序图也可以看到),这里的创建并不是说在NetworkFactory内部创建NetworkAgent,而是说,在NetworkFactory这个环境就绪之后,网络提供者才可以创建NetworkAgent。并且在一个NetworkFactory中可以创建不同的NetworkAgent,他们拥有不同的Capabilities等参数而他们之间还有一个区别就是NetworkFactory是在系统初始化时就被创建,而NetworkAgent是在真正接入网络时才会创建。
我们可以用运营商之间的关系来比喻他们的关系。 NetworkFactory相当于不同的运营商,比如中国电信、铁通、移动,他们具备联通互联网的能力,当用户入网时就决定了自己的运营商(即完成NetworkFactory初始化)。但同时在每个运营商内部又创建各个不同的接入点,比如对于中国电信来说,还分为上海电信、河北电信等,只有当用户打开电脑真正上网的时候,才会被分配具体的接入点(即完成NetworkAgent初始化)。 也就是说,同一个NetworkFactory可以在不同的时刻根据需要创建不同的NetworkAgent,比如使用数据上网时,会根据当前的需要(发送MMS还是IMS,或者单纯上网)来创建不同参数的NetworkAgent(不同的APN参数)对象,然后将其注册到ConnectivityService中,而同理在以太网络环境中也是如此可能当前联网是DHCP动态获取或者静态设置IP或者是以太网络代码,也会来创建不同参数的NetworkAgent然后注册到ConnectivityService中。
3.2 NetworkAgent类简介
前面从理论阶段介绍了NetworkAgent的基本情况,现在得现场相亲熟悉熟悉了,媒婆介绍得吹得再好还是得现场感受下不!下面得上点干货来点实际的东西了。翠花上酸菜!
public abstract class NetworkAgent extends Handler {
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc) {
super(looper);
LOG_TAG = logTag;
mContext = context;
if (ni == null || nc == null || lp == null) {
throw new IllegalArgumentException();
}
if (VDBG) log("Registering NetworkAgent");
ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
Context.CONNECTIVITY_SERVICE);
netId = cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni),
new LinkProperties(lp), new NetworkCapabilities(nc), score, misc);//注册到ConnectivityService中
}
@Override
public void handleMessage(Message msg) {
}
abstract protected void unwanted();//虚方法
}
这里NetworkAgent 的是Hnadler的一个子类,通常Handler吗大多情况是用来处理消息的这里也不例外。而它的unwanted()是一个虚方法,必须在子类中被实现,而在章节二的后面我们在初始化NetworkAgent 的时候实现了它,当ConnectivityService不再需要当前网络连接时调用它(看来ConnectivityService也是个负心汉啊)。除了清除掉网络配置信息,还会把mNetworkAgent置为null。从代码中可以看出mNetworkAgent是否为null标志了当前是否该类型的网络连接正在使用,如果有则不会处理新的网络请求。
//EthernetNetworkFactory.java
mNetworkAgent = new NetworkAgent(mFactory.getLooper(), mContext,
NETWORK_TYPE, mNetworkInfo, mNetworkCapabilities, mLinkProperties,
NETWORK_SCORE) {
public void unwanted() {
synchronized(EthernetNetworkFactory.this) {
if (this == mNetworkAgent) {
stopIpManagerLocked();
mLinkProperties.clear();
mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null,
mHwAddr);
updateAgent();
mNetworkAgent = null;
try {
mNMService.clearInterfaceAddresses(mIface);
} catch (Exception e) {
Log.e(TAG, "Failed to clear addresses or disable ipv6" + e);
}
} else {
Log.d(TAG, "Ignoring unwanted as we have a more modern " +
"instance");
}
}
};
};
3.3 NetworkAgent注册到ConnectivityService
前面我们在口口声声的说NetworkAgent注册到ConnectivityService中,可是却怎么也找不到和NetworkFactory类似的register的方法,好吗NetworkAgent没有专门提供注册接口,而是直接在构造方法中注册了,具体逻辑如下:
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc) {
super(looper);
LOG_TAG = logTag;
mContext = context;
if (ni == null || nc == null || lp == null) {
throw new IllegalArgumentException();
}
if (VDBG) log("Registering NetworkAgent");
ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
Context.CONNECTIVITY_SERVICE);
netId = cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni),
new LinkProperties(lp), new NetworkCapabilities(nc), score, misc);
}
这个注册方法还是老套路和前面NetworkFactory的注册类似,其中的第一个参数是Messenge对象,这个也是实现双向通信的关键!这里最终通过Binder调用到了ConnectivityService中。
3.4 ConnectivityService.registerNetworkAgent
历经重重险阻,万水千山的终于来到了ConnectivityService的世界,让我们紧跟源码继续分析!
public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
int currentScore, NetworkMisc networkMisc) {
enforceConnectivityInternalPermission();
// TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
// satisfies mDefaultRequest.
final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
new Network(reserveNetId()), new NetworkInfo(networkInfo), new LinkProperties(
linkProperties), new NetworkCapabilities(networkCapabilities), currentScore,
mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest, this);//通过传递过来的参数,初始化NetworkAgentInfo对象nai
synchronized (this) {
nai.networkMonitor.systemReady = mSystemReady;
}
addValidationLogs(nai.networkMonitor.getValidationLogs(), nai.network,
networkInfo.getExtraInfo());
if (DBG) log("registerNetworkAgent " + nai);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai));
return nai.network.netId;
}
这里的传入的参数Messenger对象messenger是前面NetworkAgent的引用,这个也是实现NetworkAgent和ConnectivityService双向跨进程通信的关键,然后在ConnectivityService的内部创建了一个新的对象NetworkAgentInfo,该对象中保留了传递进来的一系列参数,包括NetworkAgent的Messenger对象、NetworkInfo、NetworkCapabilities、score以及创建了一个用于通讯的AsyncChannel通道。 然后就把当前创建的NetworkAgentInfo对象放入EVENT_REGISTER_NETWORK_AGENT消息中,发送给Handler处理:
//ConnectivityService.java
private class InternalHandler extends Handler {
public void handleMessage(Message msg) {
NetworkInfo info;
switch (msg.what) {
case EVENT_REGISTER_NETWORK_AGENT: {
handleRegisterNetworkAgent((NetworkAgentInfo)msg.obj);//详见章节3.5
break;
}
}
}
3.5 ConnectivityService.handleRegisterNetworkAgent
//ConnectivityService.java
private void handleRegisterNetworkAgent(NetworkAgentInfo na) {
if (VDBG) log("Got NetworkAgent Messenger");
mNetworkAgentInfos.put(na.messenger, na);//将NetworkAgentInfo保存到mNetworkAgentInfos列表中
synchronized (mNetworkForNetId) {
mNetworkForNetId.put(na.network.netId, na);
}
//发送单向通道连接请求
na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger);
NetworkInfo networkInfo = na.networkInfo;
na.networkInfo = null;
updateNetworkInfo(na, networkInfo);//更新最新的NetworkInfo信息
}
在该阶段,ConnectivityService主要干了三件事情:
将新要注册的NetworkAgentInfo信息保存到HashMap列表mNetworkAgentInfos中利用NetworkAgentInfo对象na的AsyncChannle工具类向NetWrokAgent发起单向通道连接更新最新的NetworkAgentInfo状态
如果对AsyncChannel还有不清楚的小伙伴,墙烈建议参见篇章AsyncChannel看这就对了,此时我们可以看到AsyncChannel通过connect方法发起的单向通道连接,按照AsyncChannel通信的逻辑将会在mTrackerHandler收到CMD_CHANNEL_HALF_CONNECTED的消息,历史和其的相似啊和NetWorkFactory注册的过程:
//ConnectivityService.java
private class NetworkStateTrackerHandler extends Handler {
public NetworkStateTrackerHandler(Looper looper) {
super(looper);
}
private boolean maybeHandleAsyncChannelMessage(Message msg) {
switch (msg.what) {
default:
return false;
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
handleAsyncChannelHalfConnect(msg);
break;
}
case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
if (nai != null) nai.asyncChannel.disconnect();
break;
}
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
handleAsyncChannelDisconnected(msg);
break;
}
}
return true;
}
//ConnectivityService.java
private void handleAsyncChannelHalfConnect(Message msg) {
AsyncChannel ac = (AsyncChannel) msg.obj;
if (mNetworkFactoryInfos.containsKey(msg.replyTo)) {//NetWorkFactory注册走的是此通道
......
} else if (mNetworkAgentInfos.containsKey(msg.replyTo)) {//NetworkAgent注册走此通道
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
if (VDBG) log("NetworkAgent connected");
// A network agent has requested a connection. Establish the connection.
mNetworkAgentInfos.get(msg.replyTo).asyncChannel.
sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
} else {
......
}
}
}
因为此时发起的是NetworkAgent注册流程所以会在第二个分支,因为我们前面已经将要注册的NetWorkAgent信息存储到了mNetworkAgentInfos中。这里我们可以看到走入该分支以后,此时ConnectivityService与NetworkAgent之间单向通道建立完成后,然后又通过sendMessage发起了双向通道的请求,此时在NetworkAgent端,将会收到CMD_CHANNEL_FULL_CONNECTION的消息。
3.6 NetWorkAgent.handleMessage
//NetworkAgent.java
public void handleMessage(Message msg) {
switch (msg.what) {
case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
if (mAsyncChannel != null) {
} else {
AsyncChannel ac = new AsyncChannel();
ac.connected(null, this, msg.replyTo);
//告知ConnectivityService双向连接成功
ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED, AsyncChannel.STATUS_SUCCESSFUL);
synchronized (mPreConnectedQueue) {
mAsyncChannel = ac;
for (Message m : mPreConnectedQueue) {
//如果有缓存消息,则发送出去
ac.sendMessage(m);
}
mPreConnectedQueue.clear();
}
}
break;
}
}
}
至此ConnectivityService和NetWrokAgent的双向通道建立完成,随后通过AsyncChannel发送CMD_CHANNEL_FULLY_CONNECTED消息,表示整个AsyncChannel的连接成功,可以进行通信了。同时,还会遍历mPreConnectedQueue集合,这个集合中保存了当mAsyncChannel为null时的所有与更新网络信息相关的message,通过ac.sendMessage()向CS发送所有的message进行状态更新(要注意,ac对象的mSrcHanlder为当前NetworkAgent,mDstMessenger指向NetworkStateTrackerHandler)。
3.7 NetWorkAgent通知ConnectivityService网络状态的变化
还记得在章节三的开端说的我们可以通过NetworkAgent向ConnectivityService报告网络的变化,通知它进行网络状态的更新吗。而在EthernetNetworkFactory中通过updateAgen完成此项工作(至于怎么触发updateAgen这个本篇不予讨论,这个就牵涉到其它的知识点了),逻辑如下:
//EthernetNetworkFactory.java
public void updateAgent() {
synchronized (EthernetNetworkFactory.this) {
if (mNetworkAgent == null) return;
if (DBG) {
Log.i(TAG, "Updating mNetworkAgent with: " +
mNetworkCapabilities + ", " +
mNetworkInfo + ", " +
mLinkProperties);
}
mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
mNetworkAgent.sendNetworkInfo(mNetworkInfo);
mNetworkAgent.sendLinkProperties(mLinkProperties);
// never set the network score below 0.
mNetworkAgent.sendNetworkScore(mLinkUp? NETWORK_SCORE : 0);
}
}
我们这里以sendNetworkScore为例说明:
//NetWorkAgent.java
public void sendNetworkScore(int score) {
if (score < 0) {
throw new IllegalArgumentException("Score must be >= 0");
}
queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new Integer(score));
}
private void queueOrSendMessage(Message msg) {
synchronized (mPreConnectedQueue) {
if (mAsyncChannel != null) {
mAsyncChannel.sendMessage(msg);
} else {
mPreConnectedQueue.add(msg);
}
}
}
这个应该又是老套路了吗,通过已经建立的AsyncChannel连接向ConnectifyService发送消息,并附带需要更新的NetworkInfo对象,这样ConnectivityService中NetworkStateTrackerHandler就可以收到消息,并进行网络状态更新了。
结语
修行至此,恭喜读者你已经对EthernetNetworkFactory类的功能了然于心了,但是这个还只是个开始,关于Android以太网框架的情景分析还有涉及到和netd的交互逻辑,具体详见博客Android网络框架情景分析之NetworkManagementService和Netd交互深入分析一。
写在最后
各位读者看官朋友们,Android以太网框架情景分析之NetworkFactory与NetworkAgent深入分析到这里结束了,希望能吸引你,激发你的学习欲望和斗志。在最后麻烦读者朋友们如果本篇对你有帮助,关注和点赞一下,当然如果有错误和不足的地方也可以拍砖。
特别鸣谢如下博客: https://blog.csdn.net/u010961631/article/details/48971651 https://blog.csdn.net/qq_14978113/article/details/89182253
优惠劵
IT先森
关注
关注
14
点赞
踩
32
收藏
觉得还不错?
一键收藏
知道了
13
评论
Android以太网框架情景分析之NetworkFactory与NetworkAgent深入分析
2.4 EthernetNetworkFactory以太网网络管理类 EthernetNetworkFactory类是Ethernet的核心管理类,几乎包含了Ethernet所有的网络管理操作,该类的源码路径为frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java。2,.4.1 EthernetNetworkFactory.EthernetNetworkFactory 该构造.
复制链接
扫一扫
专栏目录
NetworkAgent 更新过程
08-15
包含NetworkAgent直接与间接的更新过程,有详细流程图
Android以太网框架情景分析之EthernetServiceImpl和NetworkManagementService交互深入分析
IT先森
08-07
3806
Android以太网框架情景分析之以太网服务和NetworkManagementService交互深入分析
前言
通过前面的篇章Android以太网框架情景分析之NetworkManagementService和netd交互深入分析一和Android以太网框架情景分析之NetworkManagementService和netd交互深入分析二,我想小伙伴们对
...
13 条评论
您还未登录,请先
登录
后发表或查看评论
Android 9.0 网络评分之---NetworkFactory
秦逸轩的博客
12-24
2170
一、网络评分框架图
二、NetworkFactory 与ConnectivityService连接过程
拿以太网为例,以太网的网口检测类EthernetTracker 会在自己的构造函数中将以太网类型的networkfactory 注册到ConnectivityService中。
EthernetTracker(Context context, Handler handler) {
mHandler = handler;
// The services we use.
IBind
Android 以太网服务启动流程
franc521的博客
03-25
4389
Android 以太网服务启动流程
一、引言
阅读本文需要对Android系统的启动流程有一定的了解。如果读者还没有这方面的知识,建议大家先了解一下这方面的知识,鄙人后面也会专门做相关系列文章。这里先大概简单阐述一下(这里我们重点关注init以上的进程服务),方便阅读本文章。Android 在kernel内核启动后会加载启动Init进程,在Init进程中启动各种服务,包括显示系统的SurfaceFlinger,音频系统AudioFlinger,网络守护进程Netd等等,其中最重要一个进程是system_se
Android网络框架情景分析之NetworkManagementService和Netd交互深入分析二
IT先森
08-06
3912
二. NetworkManagementService和Netd交互深入分析
通过前面的章节我想小伙伴已经对Netd有了一个比较深层次的认知了,Netd一方面接收处理内核上报的网络状态信息然后将相关指令发送给上层,另外一方面接收上层传递下来的指令执行对应的命令。尼玛!这里多次提到的上层究竟是个啥玩意,其实就是我们本章节要讲到的NetworkManagementService服务(该服务的内容非常多,这里我们只重点关注其怎么和Netd交互的)
https://www.kancloud.cn/alex_.
NetworkAgent和NetworkFactory
LeBron_Wu_的博客
05-30
242
ConnectivityManager和ConnectivityService讲解
主要作用
监听网络连接(WiFi, Cellular等) ;
通过NetworkAgent监听网络连接的变化。NetworkAgent是Bearer和ConnectivityService沟通的桥梁,Bearer通过NetworkAgent将网络信息更新到ConnectivityService中;ConnectivityService通过NetworkAgent给Bearer发送一些控制类的消息等
当网络连接发生变
网络连接评分机制之NetworkAgent(原)
阿杜的专栏
10-08
1万+
前面介绍了开机过程中各个网络提供者的初始化过程,其实就是创建自己的NetworkFactory,并将其注册到ConnectivityService。而在介绍NetworkFactory的时候,我们看到该类的官方注释中有这么一句描述:
"A NetworkFactory is an entity that creates NetworkAgent objects."
EthernetManager Android设置以太网静态IP
jgw2008的专栏
09-06
4552
下边是引入jar包直接调用的代码,通过EthernetManager 的setConfiguration方法来设置,但是需要构造IpConfiguration 和StaticIpConfiguration对象,IpConfiguration.IpAssignment.STATIC就代表设置为静态IP,也可以设置DHCP。想要设置以太网为静态IP通过搜索是需用到EthernetManager,但是EthernetManager是谷歌隐藏的API,app是无法调用到的,所以只能通过反射来进行设置。
DHCP协议详解
热门推荐
zzd_zzd的博客
03-09
4万+
文章目录什么是DHCPDHCP协议DHCP报文种类DHCP报文格式DHCP工作流程IP地址分配方式租约表工作流程服务器处理流程
什么是DHCP
DHCP(Dynamic Host Configuration Protocol,动态主机配置协议),前身是BOOTP协议,是一个局域网的网络协议,使用UDP协议工作,统一使用两个IANA分配的端口:67(服务器端),68(客户端)。DHCP通常被用于局...
【安卓Framework学习】Wifi框架学习之核心类
qq_39036223的博客
04-13
7843
前段时间做了一个wifi相关的需求,但是看了安卓wifi的标准api之后发现不够用,仍然会出现许多问题,比如wifi连接会有不稳定的时候,有时候能连接上有时候无法连接,但是却不知道是什么原因。为此萌发了去翻看wifi框架的源码进行学习。本文主要是针对wifi框架中的一些核心类,根据自己看源码的注释进行理解学习,可能理解得不那么精确,但掌握大致的意思。文中所有涉及到的源码均来源于Android11.........................
Android - NetWork
PURSUE__LIFE的博客
04-29
4268
1 配置网络协议
网络编程第一件事就是: 配置网络协议
2 请求流程
3 代码编写
这里先铺垫一些基础知识:
查询数据库,网络请求等都是耗时的操作。
生命周期方法 -> 自动调用 -> 主线程(UI线程) -> 不能执行耗时的操作(读文件,网络请求)
onResume onCreate 这些都是生命周期方法
1、那如果有耗时的操作,我们不在主线程,那该怎么办? 再创建一个线程就好了!
2、所有的UI操作必须在主线程中执行
Android以太网开关流程分析
franc521的博客
04-01
4687
Android以太网开关流程分析
一、引言
在Android 以太网服务启动流程中我们启动了EthernetService(ES),NetworkManagementService(NMS)等服务,其中ES作为Binder的服务端,向客户端EthernetManger提供了调用接口的引用。因此,应用可以通过EthernetManger来访问以太网的相关接口。本篇文章将从APP调用以太网的使能和关闭的接口流程作为切入点来分析,以太网框架中,上层app是如何将指令传递到底层。图1-1所示为以太网使能和关闭
Android以太网框架情景分析之启动简介
IT先森
07-15
5418
Android以太网框架情景分析
Android以太网架构源码
franc521的博客
03-23
4171
Android 以太网框架源码分析启动篇
一 引言
以太网在各类android设备形态中目前是比较成熟的技术,尤其对于android系统的电视、平板以及机顶盒等都有支持有线网口的预留。最近正好做一个关于Android以太网的需求(后面在Android 系统相关问题和需求的相关文章中会具体介绍这个需求),就顺便研究一下以太网的整体框架和流程。整体流程是很复杂,但是其中有一些细小的知识点还是需要关注的。这里主要基于Along的Android 10来分析。好嘞,话不多说,先看下Android以太网框架设计的代码目
Android 网络管理
abc20899的专栏
05-09
201
系统中对网络的判断和选在是在Connectivityervice这个服务中来处理的,在系统启动的时候会启动这个系统服务:
系统启动完毕后,ConnectivityService在系统启动的时候就启动了。
在android内部,用framework/base/core/res/res/values/config.xml中定义了网络的类型:
"default,wif...
网络连接评分机制之NetworkFactory
最新发布
xiaowang_lj的博客
09-07
955
*** @hide**/这里的注释介绍了该类的基本作用和注册方法,其开头的部分介绍到,该对象可以用来创建NetworkAgent,而结尾的hide标明该类是隐藏类,也就是说第三方应用无法使用,也就意味着第三方应用是无法承担网络连接的责任。从其继承关系看到,他的本质是一个Handler类。//将当前网络注册到ConnectivityService//处理网络请求,用于打开或者释放当前连接//更新当前网络的分值以上三个是最重要的方法,在接下来的分析中将会多次看到他们的调用。
[RK3288][Android6.0] WiFi之NetworkFactory形成的评分机制
Kris Fei's blog
07-21
2168
Platform: Rockchip
OS: Android 6.0
Kernel: 3.10.92NetworkFactory作为网络评分机制中一个重要角色而存在,每个模块实现需要继承NetworkFactory当Wifi状态机初始化处于默认状态时,会注册WifiNetworkFactory
processMessage -> WifiStateMachine.java//DefaultS
Android 7 源码分析系列导读
weixin_33704591的博客
10-09
126
关于作者
郭孝星,程序员,吉他手,主要从事Android平台基础架构方面的工作,欢迎交流技术方面的问题,可以去我的Github提issue或者发邮件至guoxiaoxingse@163.com与我交流。
文章目录
一 基础篇
二 工具篇
三 书籍篇
二 源码篇
第一次阅览本系列文章,请参见导读,更多文章请参见文章目录。
本篇文章是本系列文章的导读文章,强烈建议第一次阅读本系列本章的同学先看...
Android系统源代码情景分析-0712学习
qq_43898917的博客
07-14
410
情景分析
android代码中,settings模块如何获取到framework NETWORK_NOT_FOUND_EVENT这个状态
05-30
在Android中,Settings模块...其中,如果接收到的广播类型为ACTION_NETWORK_STATE_CHANGED,则可以通过获取extra数据中的NetworkAgent.EVENT_NETWORK_STATUS_CHANGED来判断网络状态是否为NETWORK_NOT_FOUND_EVENT状态。
“相关推荐”对你有帮助么?
非常没帮助
没帮助
一般
有帮助
非常有帮助
提交
IT先森
CSDN认证博客专家
CSDN认证企业博客
码龄14年
暂无认证
214
原创
5036
周排名
1696
总排名
121万+
访问
等级
1万+
积分
4164
粉丝
1764
获赞
1730
评论
3543
收藏
私信
关注
热门文章
使用Gson解析复杂的json数据
200263
Android.bp入门指南之浅析Android.bp语法
34951
Android下添加新的自定义键值和按键处理流程
31492
Android下DLNA开发简介
30602
Android.bp编译提示ninja: error: unknown target ‘MODULES-IN-xxx‘终极指南
27525
分类专栏
OpenHarmony
8篇
Android graphic深入分析
8篇
理解Android build系统
14篇
其它
2篇
Android应用程序窗口设计实现
7篇
Android P适配指南
8篇
Android音视频
1篇
Android四大组件系列
16篇
JNI/NDK入门指南
19篇
PackageManagerService源码分析
9篇
Android P开机启动流程分析
7篇
Android P之init进程启动源码分析
6篇
zygote进程启动流程
2篇
system_server启动流程分析
2篇
Android网络之以太网框架分析
7篇
从Android程序员角度理解JVM
2篇
Kotlin学习
1篇
Android SELinux开发多场景实战指南
8篇
杂谈
2篇
Ubuntu下Android开发调试
4篇
Android Java层Native通信多场景实战指南
5篇
Android开发妙用adb
3篇
C++
3篇
Android实战开发指南
43篇
Android Binder框架实现源码深入分析
25篇
Android Binder多场景实战开发指南
7篇
Android系统
24篇
Android下DLNA开发
3篇
最新评论
Android Binder框架实现之Native层addService详解之请求的反馈
IT先森:
为爪点赞!
Android Binder框架实现之Native层addService详解之请求的反馈
hnlgzb:
挑个人少的 留个爪
Android minigbm框架普法
种瓜大爷:
火文,好评!
Android SELinux开发入门指南之如何增加Java Binder Service权限
Chester Chai:
1.vi编辑device/sprd/sharkle/common/plat_sepolicy/private/service_contexts在其最后添加如下规则:
u:object_r:XxxSystemUtil_service:s0
是不是应该是:
XxxSystemUtil u:object_r:XxxSystemUtil_service:s0
Android minigbm框架普法
IT先森:
可不能再叫我水文了!
您愿意向朋友推荐“博客详情页”吗?
强烈不推荐
不推荐
一般般
推荐
强烈推荐
提交
最新文章
OpenHarmony下musl编译工具链普法
Android minigbm框架普法
OpenHarmony下GN语法普法
2024年9篇
2023年6篇
2022年9篇
2021年18篇
2020年132篇
2019年24篇
2016年1篇
2015年21篇
2014年5篇
目录
目录
分类专栏
OpenHarmony
8篇
Android graphic深入分析
8篇
理解Android build系统
14篇
其它
2篇
Android应用程序窗口设计实现
7篇
Android P适配指南
8篇
Android音视频
1篇
Android四大组件系列
16篇
JNI/NDK入门指南
19篇
PackageManagerService源码分析
9篇
Android P开机启动流程分析
7篇
Android P之init进程启动源码分析
6篇
zygote进程启动流程
2篇
system_server启动流程分析
2篇
Android网络之以太网框架分析
7篇
从Android程序员角度理解JVM
2篇
Kotlin学习
1篇
Android SELinux开发多场景实战指南
8篇
杂谈
2篇
Ubuntu下Android开发调试
4篇
Android Java层Native通信多场景实战指南
5篇
Android开发妙用adb
3篇
C++
3篇
Android实战开发指南
43篇
Android Binder框架实现源码深入分析
25篇
Android Binder多场景实战开发指南
7篇
Android系统
24篇
Android下DLNA开发
3篇
目录
评论 13
被折叠的 条评论
为什么被折叠?
到【灌水乐园】发言
查看更多评论
添加红包
祝福语
请填写红包祝福语或标题
红包数量
个
红包个数最小为10个
红包总金额
元
红包金额最低5元
余额支付
当前余额3.43元
前往充值 >
需支付:10.00元
取消
确定
下一步
知道了
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝
规则
hope_wisdom 发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额
0
抵扣说明:
1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。 2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。
余额充值
Android以太网框架情景分析之NetworkFactory与NetworkAgent深入分析 | 航行学园
跳转到主要内容
Toggle navigation
航行学园
Main navigation
首页
web工具
格式化工具
转换工具
编码/加密工具
HTML/CSS
PHP
分类
移动开发
编程语言
架构
数据库
前端
刷课插件
Games
drupal
综合记录
Linux
Search
Android以太网框架情景分析之NetworkFactory与NetworkAgent深入分析
面包屑
首页
>
栏目
>
Node.js简介及如何学习Node.js
>
Plant Amber Pendant Long Necklace Clothing Jewelry
Android以太网框架情景分析之NetworkFactory与NetworkAgent深入分析
前言
在前面的章节中Android以太网框架情景分析之启动简介我们介绍了以太网框架的整体启动流程,然后说到了EthernetNetworkFactory类是Ethernet的核心管理类,几乎包含了Ethernet所有的网络管理操作,这其中就包括各种网络的注册网络以及和ConnectifyService服务的交互(主要是通知网络状态的变化,评分机制的变化)。那么本章节将会重点来讲解EthernetNetworkFactory,而这其中的重重之重是NetworkFactory与NetworkAgent和ConnectifyService的通信机制的建立。
本篇章演示的源码是在Android 7.1 msm8953平台上,其中涉及的源码路径如下所示:
frameworks/base/services/java/com/android/server/
---ConnectivityService.java
---INativeDaemonConnectorCallbacks.java
---NativeDaemonConnector.java
---NetworkManagementService.java
---SystemServer.java
---SystemServiceManager.java
frameworks/base/core/java/android/net/
---ConnectivityManager.java
---EthernetManager.java
---IConnectivityManager.aidl
---IEthernetManager.aidl
---LinkProperties.java
---NetworkPolicy.java
---NetworkAgent.java
---NetworkFactory.java
---NetworkInfo.java
---ProxyInfo.java
frameworks/opt/net/ethernet/java/com/android/server/ethernet/
---EthernetConfigStore.java
---EthernetNetworkFactory.java
---EthernetServiceImpl.java
---EthernetService.java
在正式开始本篇的介绍前,还是附上祖传的以太网框架相关类调用关系图,这样能让大伙先在整体流程上有个概括,这样在分析代码走神的时候还可以回来看看,自己到那里了,将要到那里去。
一. EthernetNetworkFactory的初始化
在前面我们扯了一大推的理论知识和前期准备,从现在开始就是开始真正的源码分析了,在前面的篇章中我们分析到了EthernetNetworkFactory,那么我们就接着上篇继续分析了,开干,各位小伙伴们系好安全带,开始发车了。
1.1 EthernetNetworkFactory.EthernetNetworkFactory
分析Java中的一个类,一般从构造方法开始,这里我们也不能免俗也从构造方法开始,这里的该构造函数比较简单,主要就是初始化一些成员变量信息,这里不是我们重点关注的。
class EthernetNetworkFactory {
EthernetNetworkFactory(RemoteCallbackList
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, "");//设置网络基本信息,如网络类型,网络别名
mLinkProperties = new LinkProperties();
initNetworkCapabilities();
mListeners = listeners;
}
}
}
1.2 EthernetNetworkFactory.start
class EthernetNetworkFactory {
/**
* Begin monitoring connectivity
*/
public synchronized void start(Context context, Handler target) {
// The services we use.
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
mNMService = INetworkManagementService.Stub.asInterface(b);//获取NetworkManagementService服务端代理,在前期知识储备中我们有讲过NetworkManagementService主要用于和Netd通信
mEthernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE);//获取EthernetManager服务端代理
// Interface match regex.
mIfaceMatch = context.getResources().getString(
com.android.internal.R.string.config_ethernet_iface_regex);
// Create and register our NetworkFactory.
mFactory = new LocalNetworkFactory(NETWORK_TYPE, context, target.getLooper());//这个是重点,注意第三个参数,这个会在章节二重点介绍
mFactory.setCapabilityFilter(mNetworkCapabilities);
mFactory.setScoreFilter(-1); // this set high when we have an iface
mFactory.register();//向ConnectivityService注册自己
mContext = context;
// Start tracking interface change events.
mInterfaceObserver = new InterfaceObserver();
try {
mNMService.registerObserver(mInterfaceObserver);
} catch (RemoteException e) {
Log.e(TAG, "Could not register InterfaceObserver " + e);
}
// If an Ethernet interface is already connected, start tracking that.
// Otherwise, the first Ethernet interface to appear will be tracked.
try {
final String[] ifaces = mNMService.listInterfaces();
for (String iface : ifaces) {
synchronized(this) {
if (maybeTrackInterface(iface)) {
// We have our interface. Track it.
// Note: if the interface already has link (e.g., if we
// crashed and got restarted while it was running),
// we need to fake a link up notification so we start
// configuring it. Since we're already holding the lock,
// any real link up/down notification will only arrive
// after we've done this.
if (mNMService.getInterfaceConfig(iface).hasFlag("running")) {
updateInterfaceState(iface, true);
}
break;
}
}
}
} catch (RemoteException|IllegalStateException e) {
Log.e(TAG, "Could not get list of interfaces " + e);
}
}
这里可以看到start方法接收一个Handler对象作为参数,对于该参数我们回溯一下是从EthernetServiceImpl.start()中传入的,它新建了一个HandlerThread对象,并传入作为参数,这个Handler对象很重要,因为它会有多重的传递,串联起了以太网的网络管理。并且在代码中创建了一个LocalNetworkFactory对象,而我们的LocalNetworkFactory继承自NetworkFactory。
二. NetworkFactory网络工厂类详解及注册流程分析
我们知道各个具有网络连接的对象(WIFI,BT,PHONE)都需要向ConnectivityService注册自己,并把自己所提供的网络的分值告诉ConnectivityService。而Android为了ConnectivityService便于统一管理,每一个具备提供网络服务的对象都需要创建一个NetworkFactory的子类对象,并利用该对象注册自己,以及提供自己的分值。并且我们可以通过搜索发现确实WIFI/BT/PHONE/ETHERNET都有实现了NetworkFactory工厂类。如下所示,而我们的LocalNetworkFactory的也在此行列中,那先让我们看看NetworkFactory究竟是如何定义的。
XXX/frameworks$ grep -nr "extends NetworkFactory" ./
./base/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java:430: private static class MockNetworkFactory extends NetworkFactory {
./opt/telephony/src/java/com/android/internal/telephony/PhoneSwitcher.java:222: private static class PhoneSwitcherNetworkRequestListener extends NetworkFactory {
./opt/telephony/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java:42:public class TelephonyNetworkFactory extends NetworkFactory {
./opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java:127: private class LocalNetworkFactory extends NetworkFactor {
./opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java:4083: private class WifiNetworkFactory extends NetworkFactory {
./opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java:4116: private class UntrustedWifiNetworkFactory extends NetworkFactory {
XXX/packages$ grep -nr "extends NetworkFactory" ./
./apps/Bluetooth/src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactory.java:49:public class BluetoothTetheringNetworkFactory extends NetworkFactory {
NetworkFactory网络注册的时序图如下所示:
2.1 NetworkFactory类简介
好吗,前面空洞的介绍了NetworkFactory的功能,下面得实打实的来点干货分析分析了,不然没有料不是!
/**
* A NetworkFactory is an entity that creates NetworkAgent objects.
* The bearers register with ConnectivityService using {@link #register} and
* their factory will start receiving scored NetworkRequests. NetworkRequests
* can be filtered 3 ways: by NetworkCapabilities, by score and more complexly by
* overridden function. All of these can be dynamic - changing NetworkCapabilities
* or score forces re-evaluation of all current requests.
*
* If any requests pass the filter some overrideable functions will be called.
* If the bearer only cares about very simple start/stopNetwork callbacks, those
* functions can be overridden. If the bearer needs more interaction, it can
* override addNetworkRequest and removeNetworkRequest which will give it each
* request that passes their current filters.
* @hide
**/
public class NetworkFactory extends Handler {
public NetworkFactory(Looper looper, Context context, String logTag,
NetworkCapabilities filter) {
super(looper);
LOG_TAG = logTag;
mContext = context;
mCapabilityFilter = filter;
}
//将当前网络注册到ConnectivityService
public void register() {
if (DBG) log("Registering NetworkFactory");
if (mMessenger == null) {
mMessenger = new Messenger(this);
ConnectivityManager.from(mContext).registerNetworkFactory(mMessenger, LOG_TAG);
}
}
//处理网络请求,用于打开或者释放当前连接,一般在有新的网络接入时会触发此处
protected void handleAddRequest(NetworkRequest request, int score) {
NetworkRequestInfo n = mNetworkRequests.get(request.requestId);
if (n == null) {
if (DBG) log("got request " + request + " with score " + score);
n = new NetworkRequestInfo(request, score);
mNetworkRequests.put(n.request.requestId, n);
} else {
if (VDBG) log("new score " + score + " for exisiting request " + request);
n.score = score;
}
if (VDBG) log(" my score=" + mScore + ", my filter=" + mCapabilityFilter);
evalRequest(n);
}
//被子类实现
protected void startNetwork() { }
protected void stopNetwork() { }
//更新当前网络的分值
public void setScoreFilter(int score) {
sendMessage(obtainMessage(CMD_SET_SCORE, score, 0));
}
}
可以看到,这里的NetworkFactory 可以分为如下三个知识点:
这里我们可以看到NetworkFactory 继承于Handler,从该类的字面理解我们可以把它当作一个工厂类,对相关网络的请求和终止操作都通过该对象进行处理。并且从注释可知NetworkFactory与NetworkAgent对象有密切关系,至于为什么说它们有密切的关系,这个先不点破,大伙可以跟着代码分析来自行体会。
而且可知NetworkFactory会通过register()方法向ConnectivityService进行注册。
其中它的方法start/stopNetwork()是提供的回调函数 ,我们可以通过这两个函数来请求或终止网络:
2.2 NetworkFactory注册到ConnectivityService服务
既然这里提到了注册,通常注册到目的一般是想通过注册到目的端,然后当目的端的状态发生变化的时候回调发起端的相关方法或者接口,而我们这里的注册也不能免俗!通过后面的分析你会分析原来也是依照这个套路来进行的。
//NetworkFactory.java
public void register() {
if (DBG) log("Registering NetworkFactory");
if (mMessenger == null) {
mMessenger = new Messenger(this);//注意这里的是Messenger,其参数为NetworkFactory本身,且Messenger是可序列的所以可以跨进程Binder传递
ConnectivityManager.from(mContext).registerNetworkFactory(mMessenger, LOG_TAG);//
}
}
在正式开始分析前,有必要认识一下Messenger类,这个可不是Message,不是,不是!如果小伙伴们对Messenger和AsyncChannel不熟悉,强烈建议小伙伴们抽出一点时间参见AsyncChannel原理分析以及实操演练的篇章,里面有具体讲解了Messenger和AsyncChannle,如果不搞懂上述两个内容,后续的相关知识点小伙伴可能会一头雾水了!这里我们可以用一句话来概括Messenger主要是为了实现AsyncChannel通信而封装的一个类,而AsyncChannle又是为了实现Handler跨进程或者相同进程通信而封装的一个类。
而我们在前面的篇章知道,我们在创建LocalNetworkFactory对象时,我们给它指定了一个特定线程的Looper对象,而这个Looper得最终来源是EthernetServiceImpl的start方法,如下所示:
//EthernetServiceImpl.java
public void start() {
Log.i(TAG, "Starting Ethernet service");
HandlerThread handlerThread = new HandlerThread("EthernetServiceThread");
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper());//根本来源
mTracker.start(mContext, mHandler);
mStarted.set(true);
}
结合前面的两点,我们再来捋一捋!这里我们的registerNetworkFactory方法参数Messenger对象是一个可以跨进程传递的实例对象,你可以认为它代表一个Handler对象,既然是Handler对象,那么我们可以像使用Handler对象一样,使用Messenger对象来发送消息了,而此处该引用指向mNetworkFactory这个Handler对象,它绑定的Looper属于一个特定的线程,它在EthernetServiceImpl中创建。
然后们接着继续分析registerNetworkFactory方法,如下所示:
//ConnectivityManager.java
public static ConnectivityManager from(Context context) {
return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
}
public void registerNetworkFactory(Messenger messenger, String name) {
try {
mService.registerNetworkFactory(messenger, name);//详见章节2.3
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
一看就是老套路,获取CONNECTIVITY_SERVICE服务,这个服务就是我们的ConnectivityService服务,然后通过Binder调用ConnectivityService服务的registerNetworkFactory方法,对于Binder不熟悉的小伙伴们可以看看Android Binder指南让你对Android的Binder有一个比较深入的认识和了解。
2.3 ConnectivityService.registerNetworkFactory
历经重重险阻,万水千山的终于来到了ConnectivityService的世界,让我们紧跟源码继续分析!
//ConnectivityService.java
private static class NetworkFactoryInfo {
public final String name;
public final Messenger messenger;
public final AsyncChannel asyncChannel;
public NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel) {
this.name = name;//要注册的网络名称,譬如Ethernet,wifi,bt等
this.messenger = messenger;//
this.asyncChannel = asyncChannel;
}
}
public void registerNetworkFactory(Messenger messenger, String name) {
enforceConnectivityInternalPermission();//权限检测忽略
NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel());//内部类,对相关的信息进行封装
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi));//InternalHandler对象用于处理内部事务
}
这里的NetworkFactoryInfo 是一个ConnectivityService的内部类,用来封装一些变量信息,而我们这里用它保存了将要注册的网络信息名称(Ethernet)以及特定的Messenger对象messenger,并且将新创建的匿名AsyncChannel通道类对象也保存到其中了。
接着通过InternalHandler对象mHandler向自己发送了一条信息EVENT_REGISTER_NETWORK_FACTORY并且携带了NetworkFactoryInfo相关信息,这里的InternalHandler是ConnectivityService的内部Handler主要用于其内部一些事务的处理流程,我们直接直捣黄龙看其对EVENT_REGISTER_NETWORK_FACTORY的处理流程,如下所示:
//ConnectivityService.java
private class InternalHandler extends Handler {
public InternalHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
......
case EVENT_REGISTER_NETWORK_FACTORY: {
handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj);//详见章节2.4
break;
......
}
}
}
}
2.4 ConnectivityService.handleRegisterNetworkFactory
//ConnectivityService.java
private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) {
if (DBG) log("Got NetworkFactory Messenger for " + nfi.name);
mNetworkFactoryInfos.put(nfi.messenger, nfi);
nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger);//是不是有种似曾识相的感觉
}
这里的mNetworkFactoryInfos是一个HashMap对象,在此处将前面创建的NetworkFactoryInfo对象nfi的参数Messenger位key,以NetworkFactoryInfo对象nfi为value添加到mNetworkFactoryInfos中。接着调用前面创建的匿名AsyncChannel对象建立连接,对于这个知识点还是建议大伙抽出一定的时间参阅博客AsyncChannel原理分析以及实操演练,这里我还是简单的分析下调用connect的后续流程,如下所示:
//AsyncChannel.java
public void connect(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
connected(srcContext, srcHandler, dstMessenger);
replyHalfConnected(STATUS_SUCCESSFUL);
}
public void connected(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
mSrcContext = srcContext;
mSrcHandler = srcHandler;
mSrcMessenger = new Messenger(mSrcHandler);
mDstMessenger = dstMessenger;
linkToDeathMonitor();
}
private void replyHalfConnected(int status) {
Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_HALF_CONNECTED);
msg.arg1 = status;
msg.obj = this;
msg.replyTo = mDstMessenger;
if (!linkToDeathMonitor()) {
msg.arg1 = STATUS_BINDING_UNSUCCESSFUL;
}
mSrcHandler.sendMessage(msg);
}
通过上面的connect流程简要分析,我们可以得到如下两点结论:
这里通过调用connect方法带入参数,对AsyncChannel中的变量进行相关的初始化,初始化之后mSrcHandler指向了ConnectivityService中的NetworkStateTrackerHandler对象mTrackerHandler,它主要负责接收网络模块发送的消息,并进行网络更新;并且这里的mSrcMessenger表示了对该Handler对象的一个引用;最后的mDstMessenger 指向了EthernetNetworkFactory中的LocalNetworkFactory对象,该对象也是一个Handler。在这里要特别关注Handler和Messenger的来源和出处,不是说自古英雄不问出处吗,看来有时候古人还是欺我啊。
最后通过mSrcHandler发送了CMD_CHANNEL_HALF_CONNECTED的相关指令,将会在ConnectivityService中对象中的mTrackerHandler被处理,处理逻辑如下:
//ConnectivityService.java
private class NetworkStateTrackerHandler extends Handler {
public NetworkStateTrackerHandler(Looper looper) {
super(looper);
}
private boolean maybeHandleAsyncChannelMessage(Message msg) {
switch (msg.what) {
default:
return false;
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
handleAsyncChannelHalfConnect(msg);//此处处理,详见章节2.5
break;
}
case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
if (nai != null) nai.asyncChannel.disconnect();
break;
}
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
handleAsyncChannelDisconnected(msg);
break;
}
}
return true;
}
2.5 ConnectivityService.handleAsyncChannelHalfConnect
//ConnectivityService.java
private void handleAsyncChannelHalfConnect(Message msg) {
AsyncChannel ac = (AsyncChannel) msg.obj;
if (mNetworkFactoryInfos.containsKey(msg.replyTo)) {//又见到老熟人了mNetworkFactoryInfos
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
if (VDBG) log("NetworkFactory connected");
// A network factory has connected. Send it all current NetworkRequests.
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
if (nri.request.isListen()) continue;
NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK,
(nai != null ? nai.getCurrentScore() : 0), 0, nri.request);//详见章节2.6
}
} else {
loge("Error connecting NetworkFactory");
mNetworkFactoryInfos.remove(msg.obj);
}
} else if (mNetworkAgentInfos.containsKey(msg.replyTo)) {//NetworkAgent注册的时候会走这个分支
......
}
}
还记得大明湖畔的夏雨荷吗!错了,还记得2.4章节的mNetworkFactoryInfos吗,在该章节里面我们会将NetworkFactoryInfo添加到其中,而此时我们会从其中取出来进行匹配,既然我们已经添加了当然能匹配到了,所以最终会调用到如下的逻辑流程:
AsyncChannel ac = (AsyncChannel) msg.obj;
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
if (nri.request.isListen()) continue;
NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK,
(nai != null ? nai.getCurrentScore() : 0), 0, nri.request);//详见章节2.6
}
这里最终会调用到AsyncChannel对象ac的mDstMessenger发送CMD_REQUEST_NETWORK消息,而通过前面的分析我们知道mDstMessenger是指向了EthernetNetworkFactory中的LocalNetworkFactory,从字面理解该请求可以理解为向LocalNetworkFactory请求一个网络, 而此时还处于初始化阶段还没有为以太网创建NetworkRequest请求,所以mNetworkForRequestId.get取出的内容为空,从而sendMessage发送的第二个参数arg1为为0这个很重要。
2.6 NetworkFactory.handleAddRequest
我找遍LocalNetworkFactory也没有看到Handler的处理消息的方法handleMessage,好吗它的处理方法在其父类LocalNetworkFactory中实现的,那我们就来看看它是怎么处理CMD_REQUEST_NETWORK消息的:
//NetworkFactory.java
public void handleMessage(Message msg) {
switch (msg.what) {
case CMD_REQUEST_NETWORK: {
handleAddRequest((NetworkRequest)msg.obj, msg.arg1);//处理请求
break;
}
case CMD_CANCEL_REQUEST: {
handleRemoveRequest((NetworkRequest) msg.obj);
break;
}
case CMD_SET_SCORE: {
handleSetScore(msg.arg1);
break;
}
case CMD_SET_FILTER: {
handleSetFilter((NetworkCapabilities) msg.obj);
break;
}
}
}
protected void handleAddRequest(NetworkRequest request, int score) {
NetworkRequestInfo n = mNetworkRequests.get(request.requestId);
if (n == null) {
if (DBG) log("got request " + request + " with score " + score);
n = new NetworkRequestInfo(request, score);
mNetworkRequests.put(n.request.requestId, n);
} else {
if (VDBG) log("new score " + score + " for exisiting request " + request);
n.score = score;
}
if (VDBG) log(" my score=" + mScore + ", my filter=" + mCapabilityFilter);
evalRequest(n);//详见章节2.7
}
在这里由于是第一次接收到CMD_REQUEST_NETWORK的请求,因此NetworkRequestInfo 对象n为null,所以将会在NetworkFactory中创建NetworkRequestInfo的对象并且将其存储到列表mNetworkRequests中供后续使用,然后调用方法evalRequest进入网络评价过程。
2.7 NetworkFactory.evalRequest
//NetworkFactory.java
private void evalRequest(NetworkRequestInfo n) {
if (VDBG) log("evalRequest");
if (n.requested == false && n.score < mScore &&
n.request.networkCapabilities.satisfiedByNetworkCapabilities(
mCapabilityFilter) && acceptRequest(n.request, n.score)) {
if (VDBG) log(" needNetworkFor");
needNetworkFor(n.request, n.score);//详见章节2.8
n.requested = true;
} else if (n.requested == true &&
(n.score > mScore || n.request.networkCapabilities.satisfiedByNetworkCapabilities(
mCapabilityFilter) == false || acceptRequest(n.request, n.score) == false)) {
if (VDBG) log(" releaseNetworkFor");
releaseNetworkFor(n.request);
n.requested = false;
} else {
if (VDBG) log(" done");
}
}
该逻辑就是整个网络注册系统最关键的地方,其逻辑分为如下两条线路:
如果NetworkRequestInfo没有被requested过,并且其分值(n.score)小于当前NetworkFactory自己的分值(mScore),那么就说明,当前NetworkFactory所处的网络优先级高于其他网络的优先级,就会触发当前NetworkFactory所在网络的needNetworkFor()流程,也就是连接建立流程,并将标记NetworkRequestInfo.requested=true。
当NetworkRequestInfo被requested过(也就是当前网络被needNetworkFor过),此时如果再次收到请求,并且携带的新score大于当前NetworkFactory所处网络的mScore,那么就说明当前NetworkFactory所在网络优先级已经不是最高,需要将其releaseNetworkFor掉,并标记NetworkRequestInfo.requested=false。
对于初始化流程来说,由于NetworkRequestInfo是刚才在handleAddRequest新创建的,所以其requested状态必然为false,而且我们前面提到,ConnectivityService发送CMD_REQUEST_NETWORK时携带的分值参数为0,并且对于以太网网络来说,其mScore=70(至于这个70在什么地方赋值的,这个先忽略,后续的篇章中会讲到此处),因此此时的判定状态将会是:n.requested=false 且n.score < mScore,那么在这种环境下,对于以太网网络环境初始化过程来说,将会满足第一个if判断,进入needNetworkFor流程,也就是触发以太网网络的建立。
这里插播一个知识点,假如客户提出网络共存需求,即有客户提出,也就是机器中所有的物理传输介质(WiFi、Mobil、Ethernet)都必须可以同时可以进行网络通信工作,不能互斥。通过设置不同主机IP地址使用不同的网络类型,设置规则发送给Netd,而实现需求。而在这里我们可见,同一时间只能存在一种网络通信方式,即优先级。也就是WiFi、Mobil、以太网他们之间是互斥的,同一时间只有一种通信方式在线提供服务。那要怎么操作呢?
其实这里就涉及到了evalRequest的评分机制了,要想WiFi、Mobil、Ethernet网络共存,我们可以通过修改评分回调的逻辑实现共存,也就是当进入评分互斥的逻辑时不调用网络释放接口,就能实现网络共存不互斥的需求。也就是通过控制传入的score值大小,可以是设置为40,最终走到needNetworkFor的这个逻辑中去就能实现网络共存。
2.8 NetworkFactory.evalRequest
//NetworkFactory.java
protected void needNetworkFor(NetworkRequest networkRequest, int score) {
if (++mRefCount == 1) startNetwork();
}
//EthernetNetworkFactory.java
private class LocalNetworkFactory extends NetworkFactory {
protected void startNetwork() {
onRequestNetwork();//详见章节2.9
}
}
兜兜转转最后走到了EthernetNetworkFactory中的onRequestNetwork来处理Ethernet的连接操作,包括对静态IP和DHCP的处理。到这里onRequestNetwork处理完成,一个NetworkFactory对象的注册过程就结束了。
2.9 EthernetNetworkFactory.onRequestNetwork
//EthernetNetworkFactory.java
public void onRequestNetwork() {
synchronized(EthernetNetworkFactory.this) {
if (mIpProvisioningThread != null) {
return;
}
}
final Thread ipProvisioningThread = new Thread(new Runnable() {
public void run() {
if (DBG) {
Log.d(TAG, String.format("starting ipProvisioningThread(%s): mNetworkInfo=%s",
mIface, mNetworkInfo));
}
LinkProperties linkProperties;
IpConfiguration config = mEthernetManager.getConfiguration();
if (config.getIpAssignment() == IpAssignment.STATIC) {
if (!setStaticIpAddress(config.getStaticIpConfiguration())) {
// We've already logged an error.
mIpProvisioningThread = null;
return;
}
if (PAX_ETHERNET) {
StaticStatus = true;
}
linkProperties = config.getStaticIpConfiguration().toLinkProperties(mIface);
if (config.getProxySettings() == ProxySettings.STATIC ||
config.getProxySettings() == ProxySettings.PAC) {
linkProperties.setHttpProxy(config.getHttpProxy());
}
} else {
mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddr);
WaitForProvisioningCallback ipmCallback = new WaitForProvisioningCallback() {
@Override
public void onLinkPropertiesChange(LinkProperties newLp) {
synchronized(EthernetNetworkFactory.this) {
if (mNetworkAgent != null && mNetworkInfo.isConnected()) {
mLinkProperties = newLp;
mNetworkAgent.sendLinkProperties(newLp);
}
}
}
};
synchronized(EthernetNetworkFactory.this) {
stopIpManagerLocked();
mIpManager = new IpManager(mContext, mIface, ipmCallback);
if (config.getProxySettings() == ProxySettings.STATIC ||
config.getProxySettings() == ProxySettings.PAC) {
mIpManager.setHttpProxy(config.getHttpProxy());
}
final String tcpBufferSizes = mContext.getResources().getString(
com.android.internal.R.string.config_ethernet_tcp_buffers);
if (!TextUtils.isEmpty(tcpBufferSizes)) {
mIpManager.setTcpBufferSizes(tcpBufferSizes);
}
final ProvisioningConfiguration provisioningConfiguration =
mIpManager.buildProvisioningConfiguration()
.withProvisioningTimeoutMs(0)
.build();
mIpManager.startProvisioning(provisioningConfiguration);
}
linkProperties = ipmCallback.waitForProvisioning();
if (linkProperties == null ) {
Log.e(TAG, "IP provisioning error");
// set our score lower than any network could go
// so we get dropped.
mFactory.setScoreFilter(-1);
synchronized(EthernetNetworkFactory.this) {
stopIpManagerLocked();
}
mIpProvisioningThread = null;
return;
}
}
synchronized(EthernetNetworkFactory.this) {
if (mNetworkAgent != null) {
Log.e(TAG, "Already have a NetworkAgent - aborting new request");
stopIpManagerLocked();
mIpProvisioningThread = null;
return;
}
mLinkProperties = linkProperties;
mNetworkInfo.setIsAvailable(true);
mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr);
// Create our NetworkAgent.
mNetworkAgent = new NetworkAgent(mFactory.getLooper(), mContext,
NETWORK_TYPE, mNetworkInfo, mNetworkCapabilities, mLinkProperties,
NETWORK_SCORE) {
public void unwanted() {
synchronized(EthernetNetworkFactory.this) {
if (this == mNetworkAgent) {
stopIpManagerLocked();
mLinkProperties.clear();
mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null,
mHwAddr);
updateAgent();
mNetworkAgent = null;
try {
mNMService.clearInterfaceAddresses(mIface);
} catch (Exception e) {
Log.e(TAG, "Failed to clear addresses or disable ipv6" + e);
}
} else {
Log.d(TAG, "Ignoring unwanted as we have a more modern " +
"instance");
}
}
};
};
mIpProvisioningThread = null;
}
if (DBG) {
Log.d(TAG, String.format("exiting ipProvisioningThread(%s): mNetworkInfo=%s",
mIface, mNetworkInfo));
}
}
});
synchronized(EthernetNetworkFactory.this) {
if (mIpProvisioningThread == null) {
mIpProvisioningThread = ipProvisioningThread;
mIpProvisioningThread.start();
}
}
}
尼玛这个方法的逻辑代码也太多了,我们牛逼的谷歌工程师就不知道拆分拆分吗,这一头看不都尾巴的代码,这个各位在分析的时候可以不要硬啃,我们这里只用关心NetworkAgent。通过前面的分析我们可知NetworkFactory将自己注册到ConnectivityService,然后在EthernetNetworkFactory中快速响应ConnectivityService的网络请求,但是这种通道请求时单向的,只能由ConnectivityService流向NetworkFactory而不能反过来。那此时就一个问题了假如我们的EthernetNetworkFactory需要和ConnectivityService进行双向通信呢,这就轮到了我们的NetworkAgent上场了。
三. NetworkAgent网络代理类详解及注册流程分析
通过我们第二章节的分析可知NetworkFactory可以被看做是ConnectivityService向链路网络(以太网,蓝牙,WIFI)请求的统一接口.,那么NetworkAgent网络代理则可以认为是是ConnectivityService和链路网络管理者(如EthernetNetworkFactory)之间的双向信使,在NetworkFactory和ConnectivityService建立连接并调用onRequestNetwork之后通过NetworkAgent,EthernetNetworkFactory可以向ConnectivityService执行如下操作:
更新网络状态 NetworkInfo(断开、连接中、已连接等)
更新链路配置 LinkProperties(本机网口、IP、DNS、路由信息等)
更新网络能力 NetworkCapabilities(信号强度、是否收费等)
ConnectivityService可以向EthernetNetworkFactory执行如下操作,但是遗憾的是EthernetNetworkFactory都放任没有处理:
更新网络有效性(即NetworkMonitor的网络检测结果)
禁止自动连接
由于网络不可上网等原因主动断开网络
到这里我们应该知道了,NetworkAgent提供了ConnectivityService和EthernetNetworkFactory之间双向通信的能力。原理类似NetworkFactory,也是使用了AsyncChannel和Messenger,其时序图如下红色框标记所示:
3.1 NetWorkFactory和NetworkAgent之间的关系究竟是啥
还记得在章节2.1的时候留下的一个小小疑问点吗!我们说NetWorkFactory和NetworkAgent之间存在着紧密的联系,那这个紧密联系是什么呢!通过从前面的代码分析我们可以知道NetworkAgent是被NetworkFactory创建的(通过前面的时序图也可以看到),这里的创建并不是说在NetworkFactory内部创建NetworkAgent,而是说,在NetworkFactory这个环境就绪之后,网络提供者才可以创建NetworkAgent。并且在一个NetworkFactory中可以创建不同的NetworkAgent,他们拥有不同的Capabilities等参数而他们之间还有一个区别就是NetworkFactory是在系统初始化时就被创建,而NetworkAgent是在真正接入网络时才会创建。
我们可以用运营商之间的关系来比喻他们的关系。
NetworkFactory相当于不同的运营商,比如中国电信、铁通、移动,他们具备联通互联网的能力,当用户入网时就决定了自己的运营商(即完成NetworkFactory初始化)。但同时在每个运营商内部又创建各个不同的接入点,比如对于中国电信来说,还分为上海电信、河北电信等,只有当用户打开电脑真正上网的时候,才会被分配具体的接入点(即完成NetworkAgent初始化)。
也就是说,同一个NetworkFactory可以在不同的时刻根据需要创建不同的NetworkAgent,比如使用数据上网时,会根据当前的需要(发送MMS还是IMS,或者单纯上网)来创建不同参数的NetworkAgent(不同的APN参数)对象,然后将其注册到ConnectivityService中,而同理在以太网络环境中也是如此可能当前联网是DHCP动态获取或者静态设置IP或者是以太网络代码,也会来创建不同参数的NetworkAgent然后注册到ConnectivityService中。
3.2 NetworkAgent类简介
前面从理论阶段介绍了NetworkAgent的基本情况,现在得现场相亲熟悉熟悉了,媒婆介绍得吹得再好还是得现场感受下不!下面得上点干货来点实际的东西了。翠花上酸菜!
public abstract class NetworkAgent extends Handler {
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc) {
super(looper);
LOG_TAG = logTag;
mContext = context;
if (ni == null || nc == null || lp == null) {
throw new IllegalArgumentException();
}
if (VDBG) log("Registering NetworkAgent");
ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
Context.CONNECTIVITY_SERVICE);
netId = cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni),
new LinkProperties(lp), new NetworkCapabilities(nc), score, misc);//注册到ConnectivityService中
}
@Override
public void handleMessage(Message msg) {
}
abstract protected void unwanted();//虚方法
}
这里NetworkAgent 的是Hnadler的一个子类,通常Handler吗大多情况是用来处理消息的这里也不例外。而它的unwanted()是一个虚方法,必须在子类中被实现,而在章节二的后面我们在初始化NetworkAgent 的时候实现了它,当ConnectivityService不再需要当前网络连接时调用它(看来ConnectivityService也是个负心汉啊)。除了清除掉网络配置信息,还会把mNetworkAgent置为null。从代码中可以看出mNetworkAgent是否为null标志了当前是否该类型的网络连接正在使用,如果有则不会处理新的网络请求。
//EthernetNetworkFactory.java
mNetworkAgent = new NetworkAgent(mFactory.getLooper(), mContext,
NETWORK_TYPE, mNetworkInfo, mNetworkCapabilities, mLinkProperties,
NETWORK_SCORE) {
public void unwanted() {
synchronized(EthernetNetworkFactory.this) {
if (this == mNetworkAgent) {
stopIpManagerLocked();
mLinkProperties.clear();
mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null,
mHwAddr);
updateAgent();
mNetworkAgent = null;
try {
mNMService.clearInterfaceAddresses(mIface);
} catch (Exception e) {
Log.e(TAG, "Failed to clear addresses or disable ipv6" + e);
}
} else {
Log.d(TAG, "Ignoring unwanted as we have a more modern " +
"instance");
}
}
};
};
3.3 NetworkAgent注册到ConnectivityService
前面我们在口口声声的说NetworkAgent注册到ConnectivityService中,可是却怎么也找不到和NetworkFactory类似的register的方法,好吗NetworkAgent没有专门提供注册接口,而是直接在构造方法中注册了,具体逻辑如下:
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc) {
super(looper);
LOG_TAG = logTag;
mContext = context;
if (ni == null || nc == null || lp == null) {
throw new IllegalArgumentException();
}
if (VDBG) log("Registering NetworkAgent");
ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
Context.CONNECTIVITY_SERVICE);
netId = cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni),
new LinkProperties(lp), new NetworkCapabilities(nc), score, misc);
}
这个注册方法还是老套路和前面NetworkFactory的注册类似,其中的第一个参数是Messenge对象,这个也是实现双向通信的关键!这里最终通过Binder调用到了ConnectivityService中。
3.4 ConnectivityService.registerNetworkAgent
历经重重险阻,万水千山的终于来到了ConnectivityService的世界,让我们紧跟源码继续分析!
public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
int currentScore, NetworkMisc networkMisc) {
enforceConnectivityInternalPermission();
// TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
// satisfies mDefaultRequest.
final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
new Network(reserveNetId()), new NetworkInfo(networkInfo), new LinkProperties(
linkProperties), new NetworkCapabilities(networkCapabilities), currentScore,
mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest, this);//通过传递过来的参数,初始化NetworkAgentInfo对象nai
synchronized (this) {
nai.networkMonitor.systemReady = mSystemReady;
}
addValidationLogs(nai.networkMonitor.getValidationLogs(), nai.network,
networkInfo.getExtraInfo());
if (DBG) log("registerNetworkAgent " + nai);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai));
return nai.network.netId;
}
这里的传入的参数Messenger对象messenger是前面NetworkAgent的引用,这个也是实现NetworkAgent和ConnectivityService双向跨进程通信的关键,然后在ConnectivityService的内部创建了一个新的对象NetworkAgentInfo,该对象中保留了传递进来的一系列参数,包括NetworkAgent的Messenger对象、NetworkInfo、NetworkCapabilities、score以及创建了一个用于通讯的AsyncChannel通道。
然后就把当前创建的NetworkAgentInfo对象放入EVENT_REGISTER_NETWORK_AGENT消息中,发送给Handler处理:
//ConnectivityService.java
private class InternalHandler extends Handler {
public void handleMessage(Message msg) {
NetworkInfo info;
switch (msg.what) {
case EVENT_REGISTER_NETWORK_AGENT: {
handleRegisterNetworkAgent((NetworkAgentInfo)msg.obj);//详见章节3.5
break;
}
}
}
3.5 ConnectivityService.handleRegisterNetworkAgent
//ConnectivityService.java
private void handleRegisterNetworkAgent(NetworkAgentInfo na) {
if (VDBG) log("Got NetworkAgent Messenger");
mNetworkAgentInfos.put(na.messenger, na);//将NetworkAgentInfo保存到mNetworkAgentInfos列表中
synchronized (mNetworkForNetId) {
mNetworkForNetId.put(na.network.netId, na);
}
//发送单向通道连接请求
na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger);
NetworkInfo networkInfo = na.networkInfo;
na.networkInfo = null;
updateNetworkInfo(na, networkInfo);//更新最新的NetworkInfo信息
}
在该阶段,ConnectivityService主要干了三件事情:
将新要注册的NetworkAgentInfo信息保存到HashMap列表mNetworkAgentInfos中
利用NetworkAgentInfo对象na的AsyncChannle工具类向NetWrokAgent发起单向通道连接
更新最新的NetworkAgentInfo状态
如果对AsyncChannel还有不清楚的小伙伴,墙烈建议参见篇章AsyncChannel看这就对了,此时我们可以看到AsyncChannel通过connect方法发起的单向通道连接,按照AsyncChannel通信的逻辑将会在mTrackerHandler收到CMD_CHANNEL_HALF_CONNECTED的消息,历史和其的相似啊和NetWorkFactory注册的过程:
//ConnectivityService.java
private class NetworkStateTrackerHandler extends Handler {
public NetworkStateTrackerHandler(Looper looper) {
super(looper);
}
private boolean maybeHandleAsyncChannelMessage(Message msg) {
switch (msg.what) {
default:
return false;
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
handleAsyncChannelHalfConnect(msg);
break;
}
case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
if (nai != null) nai.asyncChannel.disconnect();
break;
}
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
handleAsyncChannelDisconnected(msg);
break;
}
}
return true;
}
//ConnectivityService.java
private void handleAsyncChannelHalfConnect(Message msg) {
AsyncChannel ac = (AsyncChannel) msg.obj;
if (mNetworkFactoryInfos.containsKey(msg.replyTo)) {//NetWorkFactory注册走的是此通道
......
} else if (mNetworkAgentInfos.containsKey(msg.replyTo)) {//NetworkAgent注册走此通道
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
if (VDBG) log("NetworkAgent connected");
// A network agent has requested a connection. Establish the connection.
mNetworkAgentInfos.get(msg.replyTo).asyncChannel.
sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
} else {
......
}
}
}
因为此时发起的是NetworkAgent注册流程所以会在第二个分支,因为我们前面已经将要注册的NetWorkAgent信息存储到了mNetworkAgentInfos中。这里我们可以看到走入该分支以后,此时ConnectivityService与NetworkAgent之间单向通道建立完成后,然后又通过sendMessage发起了双向通道的请求,此时在NetworkAgent端,将会收到CMD_CHANNEL_FULL_CONNECTION的消息。
3.6 NetWorkAgent.handleMessage
//NetworkAgent.java
public void handleMessage(Message msg) {
switch (msg.what) {
case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
if (mAsyncChannel != null) {
} else {
AsyncChannel ac = new AsyncChannel();
ac.connected(null, this, msg.replyTo);
//告知ConnectivityService双向连接成功
ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED, AsyncChannel.STATUS_SUCCESSFUL);
synchronized (mPreConnectedQueue) {
mAsyncChannel = ac;
for (Message m : mPreConnectedQueue) {
//如果有缓存消息,则发送出去
ac.sendMessage(m);
}
mPreConnectedQueue.clear();
}
}
break;
}
}
}
至此ConnectivityService和NetWrokAgent的双向通道建立完成,随后通过AsyncChannel发送CMD_CHANNEL_FULLY_CONNECTED消息,表示整个AsyncChannel的连接成功,可以进行通信了。同时,还会遍历mPreConnectedQueue集合,这个集合中保存了当mAsyncChannel为null时的所有与更新网络信息相关的message,通过ac.sendMessage()向CS发送所有的message进行状态更新(要注意,ac对象的mSrcHanlder为当前NetworkAgent,mDstMessenger指向NetworkStateTrackerHandler)。
3.7 NetWorkAgent通知ConnectivityService网络状态的变化
还记得在章节三的开端说的我们可以通过NetworkAgent向ConnectivityService报告网络的变化,通知它进行网络状态的更新吗。而在EthernetNetworkFactory中通过updateAgen完成此项工作(至于怎么触发updateAgen这个本篇不予讨论,这个就牵涉到其它的知识点了),逻辑如下:
//EthernetNetworkFactory.java
public void updateAgent() {
synchronized (EthernetNetworkFactory.this) {
if (mNetworkAgent == null) return;
if (DBG) {
Log.i(TAG, "Updating mNetworkAgent with: " +
mNetworkCapabilities + ", " +
mNetworkInfo + ", " +
mLinkProperties);
}
mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
mNetworkAgent.sendNetworkInfo(mNetworkInfo);
mNetworkAgent.sendLinkProperties(mLinkProperties);
// never set the network score below 0.
mNetworkAgent.sendNetworkScore(mLinkUp? NETWORK_SCORE : 0);
}
}
我们这里以sendNetworkScore为例说明:
//NetWorkAgent.java
public void sendNetworkScore(int score) {
if (score < 0) {
throw new IllegalArgumentException("Score must be >= 0");
}
queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new Integer(score));
}
private void queueOrSendMessage(Message msg) {
synchronized (mPreConnectedQueue) {
if (mAsyncChannel != null) {
mAsyncChannel.sendMessage(msg);
} else {
mPreConnectedQueue.add(msg);
}
}
}
这个应该又是老套路了吗,通过已经建立的AsyncChannel连接向ConnectifyService发送消息,并附带需要更新的NetworkInfo对象,这样ConnectivityService中NetworkStateTrackerHandler就可以收到消息,并进行网络状态更新了。
结语
修行至此,恭喜读者你已经对EthernetNetworkFactory类的功能了然于心了,但是这个还只是个开始,关于Android以太网框架的情景分析还有涉及到和netd的交互逻辑,这个我会在后续的章节继续讲解的。
写在最后
各位读者看官朋友们,Android以太网框架情景分析之NetworkFactory与NetworkAgent深入分析到这里结束了,希望能吸引你,激发你的学习欲望和斗志。在最后麻烦读者朋友们如果本篇对你有帮助,关注和点赞一下,当然如果有错误和不足的地方也可以拍砖。
特别鸣谢如下博客:
https://blog.csdn.net/u010961631/article/details/48971651
https://blog.csdn.net/qq_14978113/article/details/89182253
最新内容
hitball - 弹珠儿
puzzle - 拼图
breaklovers - 拆散小情侣
blockdown - 掉方块
run - 跑男
stardog - 星星狗
candy - 怪物要糖果
candytbc - 怪物要糖果(中间版)
2048
Flappy bird- 笨鸟先飞像素鸟
Footer menu
免责声明
隐私政策
Copyright © 2024. All rights reserved
Ethernet-to-the-Factory 1.2 Design and Implementation Guide - Ethernet-to-the-Factory Solution Overview [Design Zone for Manufacturing] - Cisco
Skip to content
Skip to search
Skip to footer
Cisco.com Worldwide
Products and Services
Solutions
Support
Learn
Explore Cisco
How to Buy
Partners Home
Partner Program
Support
Tools
Find a Cisco Partner
Meet our Partners
Become a Cisco Partner
HomeSolutionsDesign Zone
Ethernet-to-the-Factory 1.2 Design and Implementation Guide
Bias-Free Language
Bias-Free Language
The documentation set for this product strives to use bias-free language. For the purposes of this documentation set, bias-free is defined as language that does not imply discrimination based on age, disability, gender, racial identity, ethnic identity, sexual orientation, socioeconomic status, and intersectionality. Exceptions may be present in the documentation due to language that is hardcoded in the user interfaces of the product software, language used based on RFP documentation, or language that is used by a referenced third-party product. Learn more about how Cisco is using Inclusive Language.
Book Contents
Book Contents
Preface
Ethernet-to-the-Factory Solution Overview
Solution Architecture
Basic Network Design
Implementation of the Cell/Area Zone
Implementation of Security
Implementation of High Availability
Implementation of Network Management
Characterization of the EttF Cell/Area Zone Design
Configuration of the EttF Cell/Area Zone
Configuration of the EttF Demilitarized Zone
EttF High Availability Testing
Search
Find Matches in This Book
Save
Log in to Save Content
Available Languages
Download
Download Options
Book Title
Ethernet-to-the-Factory 1.2 Design and Implementation Guide
Chapter Title
Ethernet-to-the-Factory Solution Overview
PDF - Complete Book
(9.79 MB)
PDF - This Chapter (1.01 MB)
View with Adobe Reader on a variety of devices
Results
Updated: July 17, 2008
Chapter: Ethernet-to-the-Factory Solution Overview
Chapter Contents
Executive Summary
Introduction
Cisco EttF 1.1 Solution—Description and Justification
Target Customer
Plant Managers and Control Engineers
Manufacturing IT
Applications and Services Supported by the Cisco EttF Solution
Cisco EttF Solution Benefits
Cisco EttF Solution Features
Real-Time Communication, Determinism, and Performance
Availability
Security
Manageability
Logical Segmentation
Physicality and Topology
Compatibility
Scalability
Scope of the Cisco EttF Solution
Key Terms and Definitions
Industrial Automation and Control Background
History of Industrial Automation and Control Networks
Industrial Automation and Control System Components
Physical Layer
Networking Equipment
Industrial Automation and Control Devices
Industrial Computing
Industrial Automation and Control System Communication Protocols
Communication Model
Industrial Automation and Control Protocol Overview
Common Industrial Protocol Overview
Close
Ethernet-to-the-Factory Solution Overview
Executive Summary
This design and implementation guide represents a collaborative development effort from Cisco Systems and Rockwell Automation. It is built on, and adds to, design guidelines from the Cisco Ethernet-to-the-Factory solution and the Rockwell Automation Integrated Architecture™.
Faced with internal pressures to cut costs and external demands for better products and services, manufacturers are realizing the benefits of a converged network, such as the following:
•Greater visibility
•Better data integration
•Shorter lead times
•Increased turnaround
•Reduced costs
•Simplified management
The key targets are industrial automation and control systems, which benefit greatly from the transition to modern networking technologies from the factory-optimized networks typically in use today. New services and streamlined efficiency result when the information contained within these automation and control systems is available and shared throughout the larger enterprise. Access to existing production information is presently gated by disparate, proprietary, and closed systems. Manufacturers and their industrial suppliers are discovering that standard communication and uniform networking of industrial systems is the key to optimized services, greater visibility, and lower total cost of ownership (TCO). They are starting to embrace standard information technology, particularly Ethernet and IP, for industrial automation and control environments.
Although most manufacturers recognize that Ethernet and the IP protocol suite will be the de-facto networking standard in manufacturing environments in the near future, only a few have fully adopted standards-based Ethernet network architectures for industrial automation. Much of this resistance can be attributed to the aversion to disrupting existing systems, the accounting realities of fully-depreciated assets, and the general ebb and flow of production investment cycles. Resistance to migration also comes from the market being serviced by small niche vendors with narrowly-designed products or limited support capabilities. As bigger players start to enter the market and create an industry-wide industrial networking standards organization, the market is poised to explode.
Cisco and Rockwell Automation believe standard networking technology offers value inside industrial operations when the technology is part of larger integrated, industrial automation architectures. Cisco calls this the Ethernet-to-the-Factory (EttF) Architecture. Rockwell Automation calls this Integrated Architecture.
The purpose of this architecture is to accelerate the convergence of standard networking technologies with the industrial automation and control environment. This solution architecture and relevant design and implementation guidelines will give customers, partners, and the marketplace the confidence and background necessary to employ EttF. This solution architecture must be tailored to support automation and control systems. By adopting the solution architecture, the manufacturing process will have to operate at higher levels of performance, efficiency, and uptime as under the previous solutions. At the same time, it must also safely and securely integrate these systems into the broader manufacturing environment; only at this point will all the benefits be available to the manufacturing enterprise.
Introduction
Cisco EttF 1.1 Solution—Description and Justification
The industrial manufacturing environment of today is very similar to the IBM legacy mainframe environments of the mid 1990s. Although these legacy industrial systems are functional, they are costly to maintain, difficult to connect, and slow to evolve. With their factory floor-optimized protocols, specific operating requirements, and separate staffs, manufacturers are also struggling to evolve. Whether their industrial automation and control systems are discrete, process, batch, or hybrid, manufacturers need their systems to interact in real-time with the other enterprise applications, supply chain partners, and end customers. To accomplish this, manufacturers are bringing their industrial automation systems online. When doing this, manufacturers encounter a number of challenges, such as the following:
•Production reliability—As manufacturing operations become globally integrated, manufacturers are challenged to provide consistent access to data while making the manufacturing environment programmable and flexible. Security, availability, and asset use are critically important to manufacturing companies because industrial automation and control equipment is mission-critical, and efficiency is important to remain competitive.
•Cost—Legacy industrial automation and control systems, although often fully depreciated in existing manufacturing environments, can be difficult to bring online and can require significant investment.
•Product design integration—Data silos and closed systems hinder the ability to reduce time to market for new products.
•Service integration—In an effort to provide differentiated service, manufacturers are struggling to create systems to capture and incorporate data from their products that are in operation.
•Data interaction and management—Incorporating real-time factory productivity and operational data into manufacturing execution systems (MES), customer relationship management (CRM), supply chain management (SCM), and other enterprise resource planning (ERP) systems is an increasingly complex data translation exercise.
•Partner connections—With an aging and decreasing workforce and increased production complexity, manufacturers are trying to find ways to leverage relationships with industrial automation and control vendors to support their factory floor systems.
These challenges are pushing manufacturers to adopt standard Ethernet and IP technologies throughout the manufacturing environment. By moving to standard technologies, manufacturers can:
•Realize significant cost savings—Standard Ethernet and IP technology has greater market penetration and thus is more likely than existing factory floor networking technologies to give manufacturers a significantly lower total cost of ownership (TCO).
•Provide better maintenance—As access to skilled production staff becomes difficult, legacy industrial automation and control technology is becoming more complex to maintain than standard Ethernet and IP networking technology.
•Enhance their flexibility—Standard Ethernet and IP technology allows for rapid production gains, new functionality, and evolving capabilities in the manufacturing environment and beyond.
•Increase efficiency—Standard Ethernet and IP technology eases integration with business systems by using a common network to share information between production and business systems.
Manufacturing organizations and their production operations want to use the newer standard networking technologies in industrial automation and control networks, but there has been little guidance from industrial networking or automation suppliers to date. In addition, although the automation and control industry as a whole has embraced standard networking over legacy, proprietary networking, some industrial automation and control vendors continue to suggest that standard Ethernet and IP technology is not good enough for manufacturing environments. The principle argument has been that deterministic and time-sensitive manufacturing environments require more than what Ethernet and IP technologies can deliver. Others question the inherent determinism, reliability, and resiliency of Ethernet and IP technologies. Some have even asserted that standard networking technology in production environments makes manufacturers more susceptible to security risks. Although there is some basis for these concerns, there is little substantive data to make or support these claims. Modern, full-duplex, switched Ethernet networks offer real-time performance, including latency, jitter, and (non) packet loss capabilities, that equals or surpasses the older fieldbus networks they replace. In addition, these modern networks have mature and tested technologies to safely secure the network and the systems they interconnect beyond what is available for the older fieldbus networks.
EttF is an architecture that provides standards-based network services to the applications, devices, and equipment found in modern industrial automation and control systems, and integrates them into the wider enterprise network. The Cisco EttF 1.1 solution gives design and implementation guidance to achieve the real-time communication requirements needed for determinism as well as the reliability and resiliency required by the industrial and automation control systems. By bringing the Cisco EttF Architecture to market, Cisco can enable manufacturing customers to meet all the challenges of a fully-integrated industrial automation system. The Cisco EttF Architecture also enhances the status of Cisco as a trusted business partner, not only for manufacturing customers but also for industrial automation partners.
Target Customer
The Cisco EttF solution is targeted at manufacturing customers seeking to integrate or upgrade their industrial automation and control networks to standard networking technologies. These customers want to do the following:
•Lower the TCO of their current industrial automation and control network approach
•Integrate the industrial automation and control systems with the wider enterprise
•Take advantage of the networking innovations provided by using standards-based technologies
Decisions impacting industrial automation and control networks of the factory floor are typically driven by plant managers and control engineers, rather than the IT department. Additionally, they rely on a completely different vendor and support supply chain for their industrial automation and control systems than typically found in the IT department. This is driven by the different requirements of a factory floor. That being said, the IT departments of manufacturing customers are increasingly engaging with plant managers and control engineers to leverage the knowledge and expertise in standard networking technologies.
The Cisco EttF solution recognizes and targets the IT department and the plant managers and control engineers. Each camp has different perspectives and requirements for a successful EttF implementation (see Figure 1-1).
Figure 1-1 Business/Technical Decision Makers—IT versus Automation and Control
For the IT department, it is critical to understand the various factory floor requirements and operating environment, and to implement an appropriate solution. For the plant managers and control engineers, a deeper knowledge of the capabilities and functioning of standard networking technologies is required. The Cisco EttF solution includes a large number of references to "basic" networking concepts to recognize the need to raise the level of knowledge and expertise of business and technical decision makers.
To increase its value and impact, the Cisco EttF solution will be brought to market with a key industrial automation and control systems partner, Rockwell Automation. This will allow the Cisco EttF solution to benefit not only from the deep expertise in industrial automation and control systems found in this partner, but also to more effectively target the various business and technical decision makers.
To summarize, the industrial automation and control systems toward which the Cisco EttF solution is targeted see various business and technical decision makers introduced into the decision process. These decision makers often have differing business objectives and concerns that must be recognized. These decision makers rely on different vendors and integrators for solutions and their implementation. In addition, the typical decision makers (IT) stay involved, but may need awareness levels raised concerning the differences and challenges posed by the manufacturing environment.
Plant Managers and Control Engineers
As mentioned, plant managers and control engineers are key decision makers for the Cisco EttF solution.
Plant managers are business decision makers for this solution and are responsible for achieving production targets by ensuring plant reliability, uptime, and energy efficiency. Their performance is typically measured by plant profitability, throughput, quality, and return on assets. Technology decisions are made related to reliability, risk-free operation, environment fit, and company-wide standards. Plant managers usually depend on vendors for support based on track record and industry knowledge.
Control engineers are technical decision makers for this solution, and are responsible for the design, implementation, and operations of the industrial automation and control systems that operate the production facility. They are responsible for the automation equipment that supports the basic manufacturing process. They have a direct share of the responsibility of the quality and consistency of the end product, and often report to the plant manager.
For both these decision makers, the key business drivers include the following:
•Reliability—The solution must support the operational availability of the production facility.
•Cost—Capital comes at a premium, and additional costs (or costlier components) must add clear value that is understood by the plant manager.
•Ease of integration—Not just with enterprise applications, but ease of integrating remote or vendor expertise in a secure manner.
•Flexibility—The ability to rely on common off-the-shelf (COTS) equipment, provided by a number of vendors and supported from a common expertise (often found in the IT department).
Key concerns include the following:
•Performance—Ability of the network infrastructure to meet the real-time communications requirements of the industrial automation and control systems.
•Availability—Both the ability to limit the impact on operations of upgrading or maintaining the Cisco EttF solution, and the reliability of the supported base network infrastructure features to handle outages with minimal impact.
•Manageability—Ease of configuring, maintaining, and fixing the Cisco EttF solution.
•Compatibility—How the network infrastructure supports various types of industrial communications (see Industrial Automation and Control System Communication Protocols) and the devices, controllers, human-machine interfaces (HMIs), and applications already in use.
Both plant managers and control engineers typically rely on vendors with strong knowledge and track records in industrial automation and control. These vendors have varying degrees of capability and knowledge in deploying standards-based networking technologies and the relevant technical issues. By going to market with this solution jointly with a key vendor, the objective is to bring the relevant partners, channels, and integrators up to speed on the availability and capabilities of industrial Ethernet in general and specifically the Cisco EttF solution.
Manufacturing IT
Although IT managers are typically the business and technical decision makers for network infrastructure, they have not typically been involved with network infrastructure for industrial automation and control systems for a wide variety of reasons. They are often seen by the plant managers and control engineers as an obstacle to be avoided, rather than a partner to be relied on for skills, expertise, and services. They are usually making decisions to focus on standardized solutions, to re-use whenever possible, and to reduce cost. There is often a cultural gap between IT and the manufacturing world. However, because IT managers often have the deepest knowledge and expertise in standard networking technologies within the enterprise, their involvement is often required for a truly successful implementation of industrial Ethernet. To help overcome the cultural gap, the Cisco EttF solution does the following:
•Raises IT awareness of the particular challenges and requirements for industrial automation and control systems
•Outlines a solution and relevant design and implementation guidance that allows both to focus on a mutually-acceptable solution
•Pulls IT into the environment to deliver expertise and services based on their strength in standards-based networking technologies
Applications and Services Supported by the Cisco EttF Solution
The Cisco EttF solution primarily supports industrial automation and control systems and their integration into the overall enterprise network. Industrial automation and control systems consist of the following:
•Automation devices, such as robots, sensors, actuator, and drives
•Human-machine interfaces (HMIs) that provide visual status reports and control of the automated manufacturing process
•Controllers such as programmable automation controllers (PACs) and the distributed control system (DCS)
•Higher level plant systems, including the manufacturing execution system (MES) and historians
This version of the architecture focuses on the above items that support EtherNet/IP, which is driven by the Common Industrial Protocol (CIP) (see Industrial Automation and Control System Communication Protocols) and in particular are tested with Rockwell Automation devices, controllers, and applications.
The key networking services that are supported in this version of the EttF architecture include the following:
•Local area networking (typically defined as OSI Layers 1 and 2) to all the above items, including topology, port configuration, subnet and VLAN configuration, network protocols for spanning tree, and quality of service (QoS)
•Routing (typically defined as Layer 3) for all the above items, as well as to other areas of an enterprise network
•Design and implementation recommendations for network technical considerations such as topology, resiliency, and redundancy (including Spanning Tree Protocol), and handling of multicast traffic (including Internet Group Management Protocol configuration)
•IP address allocation, assigning, and related services (for example, DHCP, BootP, and DNS)
•Basic network management
•Network security for the industrial automation and control systems including demilitarized zone (DMZ), firewall, intrusion protection, endpoint security, and security monitoring, analysis, and response
These will be applied to small (up to 50 Ethernet nodes) to medium (up to 200 Ethernet nodes) environments.
Cisco EttF Solution Benefits
The value proposition for the Cisco EttF solution is as follows:
•Enables and simplifies integration of industrial automation and control systems with enterprise networks to improve the flow and integration of production information into business systems.
•Enables remote access for production engineers, partners, and industrial automation and control equipment vendors for diagnostics and maintenance. Increases efficiency and response time and enables industrial automation and control vendors to provide services to customers that may have limited subject matter expert (SME) resources.
•Reduces operating and capital costs by using open standards to eliminate the need to support multiple protocols in industrial automation and control networks and to provide manufacturing companies more options when purchasing automation equipment.
•Integrates more quickly advances in networking technology that come from working with standards-based technologies (for example, voice, video, and security).
Integrating advanced technologies and working with leading industrial automation and control vendors such as Rockwell Automation allows Cisco to have a unique value proposition relative to the rest of the industry by providing benefits beyond those associated with integration and use of open standards, including the following:
•Combining two areas of expertise: the networking expertise of Cisco with the industrial automation and control expertise of Rockwell Automation for the benefit of the customer.
•Providing integrated security specifically configured for industrial automation and control networks to protect vital manufacturing assets, limit access to production equipment, and help address issues such as patch management.
•Providing a foundation for deploying additional advanced technologies such as voice, video, and wireless on the converged network at the control level as the technology matures and the business requires.
•Simplifying deployment and helping to bridge the gap that often exists between IT and industrial automation and control networks by integrating and validating architectures with leading partners in the industrial automation and control market that ensure compliance with relevant industry standards.
The above capabilities depend on the deployment of technologies based on standard Ethernet and IP, and help demonstrate the value of open standards to differentiate Cisco and its partners from other "standards-based" Ethernet and non-standard solutions on the market.
Cisco EttF Solution Features
Industrial automation and control network environments have evolved over the years, driven by a number of key design features. These features are not specific to industrial Ethernet, but to networking for industrial automation and control systems in general. In the move towards industrial Ethernet, many of these design features still apply, although the importance sometimes shifts. For example, with Ethernet and IP-based industrial networks, security is a pressing issue, particularly if there are no access restrictions between industrial automation and control systems and the larger business system. This section defines the following eight key features that the industry expects as best practices:
•Real-Time Communication, Determinism, and Performance
•Availability
•Security
•Manageability
•Logical Segmentation
•Physicality and Topology
•Compatibility
•Scalability
This document provides details on why and how to take advantage of these benefits. The industry, and especially manufacturing participants such as plant managers, control engineers, and their partners and vendors, are looking for simple guidelines and recommendations. Each chapter in this document highlights key recommendations and steps to follow when designing and implementing an industrial Ethernet solution.
Real-Time Communication, Determinism, and Performance
Industrial automation and control systems differ from their IT counterparts in their need to support real-time communications, which means communicating messages with minimal latency (time delay between message sent and message received) and jitter (the variance of the latency). Real-time communications help the industrial automation and control systems become more deterministic. Although the network plays a role in determinism, a number of other factors, such as end-device latency and response time, are also involved. Therefore, the capabilities of standards-based networks to support challenging real-time communications are described in this document.
Industrial automation and control networks have various real-time communications requirements based on the type of application, as shown in
Figure 1-2.
Figure 1-2 Real-Time Applications (Source: ARC Research, 2006)
The Cisco EttF solution provides design and implementation guidance to help customers achieve the real-time communications requirements of their industrial automation and control systems.
Key considerations in achieving real-time communications include the following:
•Number of switches and routers and amount of traffic in the Layer 2 network, which affects latency and jitter.
•Ratio of LAN ports to uplink ports based on traffic loads and patterns. Typically, this means using 10/100 Mbps for devices and 10/100/1000 Mbps for uplinks.
•Use of Internet Group Management Protocol (IGMP) to manage the efficient delivery of multicast traffic.
•Use of QoS parameters to meet the real-time requirements of various traffic flows.
Availability
Availability of the industrial automation and control systems has a direct correlation to the operational efficiency of a production facility. Because the network is a key aspect of the overall system, these requirements translate directly to the network.
Note that limitations in the network technology may also limit the application of high availability features. For example, the lack of the ability of the network to converge quickly enough and the cost associated with redundant wiring have often led to non-redundant topologies being implemented in industrial networking environments. The Cisco EttF solution outlines the capabilities so as to let customers and integrators make decisions on the level of network availability needed for the overall system.
High availability considerations are identified in each aspect of the Cisco EttF solution. Key considerations include the following:
•Creating alternative data communication paths, regardless of physical layout. Risk profile, opportunity cost, culture, and other variables determine how much and to what level redundant paths are required.
•Eliminating single points of failure with critical operations, including such items as dual power supplies, alternate routes for redundant media, redundant industrial automation and control network infrastructure, such as routers, switches, and firewalls.
•Using advanced network resiliency and convergence techniques to improve availability, such as EtherChannel/trunks, 802.1w Rapid Spanning Tree Protocol (RSTP), Hot Standby Routing Protocol (HSRP),
•Although redundant star topology offers the best convergence capabilities, consider alternative ring recovery techniques when configured in a ring topology.
•Using routing protocols such as EIGRP or OSPF to achieve high availability.
Security
IP-based networking facilitates interconnection of the industrial automation control system with the enterprise LAN. Many industries have implemented enterprise applications for more efficient production, as well as Internet business applications to communicate more efficiently with their suppliers, customers, and business partners. Internet-based enterprise resource planning (ERP) and supply chain management (SCM) systems simplify connections both to other organizations and to internal business processes. These connections can enable greater efficiencies in processes and manufacturing. In large manufacturing or utility operations, small percentage increases in efficiency can translate into significant cost savings.
However, connecting the industrial automation and control network to the enterprise network brings the security risks of the Internet and enterprise network to the industrial automation and control system. Mitigating these risks is more difficult and more critical than in the enterprise network because of the higher requirement for availability in an industrial automation and control system and the sensitivity of these systems to various disruptions. Of the three security properties of confidentiality, integrity, and availability, control systems are primarily concerned with availability and integrity. Many of the applications that industrial automation and control networks support cannot be stopped or interrupted without serious physical or loss of productivity with measurable financial damage. On the other hand, in enterprise networks that are the primary design consideration for the Internet Protocol (IP) suite, confidentiality and integrity are the primary design considerations. For example, it is preferable for an e-commerce server to be temporarily unavailable rather than for it to lose transactions or divulge credit card numbers. Consequently, the network architectures, firewall configurations, intrusion detection configurations, and other aspects of a security deployment require tuning and customization to properly support industrial automation and control systems. The industrial automation and control systems industry has been struggling for several years to determine how to build secure, reliable control systems based on IP.
Although standards bodies such as ISA SP99 are still debating security design axioms, there is at least an approximate consensus on what a secure industrial automation and control architecture should provide. This includes an industrial automation and control network that is highly available and redundant, has fast convergence, thus being more deterministic and therefore more suitable for real-time control, and is secure against both outside and inside threats. The specific security principles of the EttF architecture are as follows:
•Control data flows between different levels (ACLs, firewall rules, etc).
•Prevent direct communication between industrial automation and control systems and enterprise systems.
•Restrict real-time production data to the industrial automation and control network.
•Restrict enterprise access to the mirror version or copies of production data to the DMZ.
•Authenticate and authorize user access based on the level within the industrial automation and control network and the role (read/read-write/local/remote/vendor/partner).
•Control rogue access inside the industrial automation and control network (port level MAC address controls, administratively shutdown unused ports, etc).
•Control which devices can be plugged into the switch (for example, port security, DHCP snooping).
•Detect and mitigate malicious traffic originating from infected devices that are plugged into the industrial automation and control network.
•Detect and mitigate malicious traffic originating from the corporate IT network.
•Secure connectivity for remote access to automation devices.
•Use DMZ design options based on costs and levels of security and redundancy required.
•Limit rogue network communication activity from impacting networking devices (set root bridge, SNMP capabilities, and so on).
•Regarding data and services in the DMZ, connection initiation should originate from either the manufacturing or enterprise zone and terminate in the DMZ. Connections originating from the DMZ should be exceptions.
•Document and define policy and risk appropriate for the environment.
The above are provided as principles, with the understanding that customers may choose to make exceptions.
Manageability
Manageability is a key consideration for industrial automation and control systems. Individuals with a basic level of networking skills should be able to manage and monitor the network.
Key manageability concerns include the following:
•Configuring switches using the command-line interface (CLI), element management system (one GUI configures one switch), solution management system (one GUI configures multiple switches), or by downloading pre-defined templates
•Leveraging existing SNMP-based management systems when and where they make sense
•Using other network devices such as routers and security appliances with similar configuration functionality
•Using SmartPort templates for easy port configuration based on application types
•Assigning consistent IP addresses to devices. IP addresses are often coded into the logic of various industrial automation and control devices, rather than using dynamic IP address services such as Dynamic Host Configuration Protocol (DHCP).
•Considering various easy replacement options for network infrastructure elements
•Using systems that offer notification of critical network events (for example, if an Ethernet link goes up or down), and the means to diagnose and debug problems within the network infrastructure
•Staging software upgrades for network devices
•Allowing for patch management of Windows-based automation devices
•Standardizing hardware and software elements wherever possible
•Driving the integration of basic network administration into the existing applications based on various industrial automation and control network protocols
Logical Segmentation
Standard networking technologies provides logical segmentation: managed and controlled inter-connectivity between various parts of the network. Logical segmentation integrates logically (or physically) isolated networks of the production facility with the enterprise and external networks to safely and securely share data, services, and access from the industrial automation and control systems. Logical segmentation is critical for industrial Ethernet because it helps ensure that availability, determinism, performance, manageability, and security requirements are maintained. Logical segmentation means allowing required communication between devices while preventing extraneous traffic from interfering with critical communications between devices on the industrial automation and control network. Logical segmentation is required because industrial Ethernet network architectures may generate traffic that is not readily compatible with general enterprise traffic, and vice versa. For example, multicast traffic in a manufacturing environment may use multicast addresses that overlap with those in the enterprise zone, or traffic in either zone may set QoS markings that create issues in the other zone. The fundamental tenet of logical segmentation is that the manufacturing traffic be separate from the enterprise traffic.
Insulation can be achieved via numerous mechanisms. The Cisco EttF solution provides design and implementation guidelines on the key considerations and mechanisms that can be applied, including the following:
•Using an additional physical or logical De-Militarized Zone (DMZ) to segregate the manufacturing control network from the corporate IT network, especially to do the following:
–Halt the mixing of incompatible traffic
–Create clear administrative boundaries to manage organizational control and configuration differences between the manufacturing and enterprise zones
–Safely and securely share data and services between the zones
•Using hierarchically-tiered switches inside the industrial automation and control network to further segment manufacturing functional areas. (See the following subsections for related parameters in this situation.)
•Limiting the number of devices per Layer 2 domain in industrial automation and control networks to devices that must talk to each other in order to maintain more control over performance characteristics and easily develop a more granular security model.
•Using virtual LANs (VLANs) to create logical structures around Layer 2 domains.
•Using routers/Layer 3 switches to interconnect VLANs.
•Controlling broadcast, multicast, or unicast storms with port-level rate controls where appropriate.
Physicality and Topology
Another key differentiator of industrial automation and control systems is the environment in which the manufacturing process is occurring. Physical constraints in the manufacturing industry are significant. The networking systems need to recognize challenges in spatial and environmental conditions. End devices, such as controllers, drives, and HMIs, located in harsh environments such as the production floor often need to meet environment specifications such as IEC529 (ingress protection) or National Electrical Manufacturers Association (NEMA) specifications. The end device may be located in physically disparate locations (up to miles away), and in non-controlled or even harsh conditions in terms of temperature, humidity, vibration, noise, explosiveness, electronic interference, and so forth. These requirements are conditions of the network device and are not a specific focus of the Cisco EttF solution. Additionally, the physical media infrastructure is also driven by the location of the end-devices and physical requirements of the environment, with special consideration given to the potential for high noise, but is not currently a specific focus of this solution.
The physical layout of the manufacturing facility or the automation equipment also impacts the network topology for automation networks. Unlike traditional IT networks, which are largely redundant star topology networks, industrial automation and control networks have significant physical limitations that drive the use of topologies such as linear-bus and ring. In manufacturing plants with long production lines, or equipment with long runs and interconnected operations (such as a printing press, or similar types of equipment), it is often not feasible or cost-effective to use a redundant star topology. In manufacturing environments, the costs of cabling are significantly higher than typical office conditions to meet the harsh physical requirements. Although the redundant star network topology offers the best resiliency, convergence, and overall performance, the additional cabling complexity and constraints of a redundant star limit its applicability in manufacturing environments.
In addition, current industrial automation and control applications do not use significant bandwidth, and are therefore not significantly impacted by the potential bandwidth limitations of ring or linear-bus topologies. In many cases, the industrial automation and control network is a combination of topologies, with large rings connecting multiple star-based manufacturing cells.
Cost considerations also drive the architectural and technology directions of many manufacturing companies. Given the physical layout of a manufacturing plant and industrial automation and control equipment, it is often significantly cheaper to implement a ring topology than a redundant star topology.
Based on these considerations, the design guidelines provide information regarding the trade-offs between the various topologies to help customers, partners, and account teams to make appropriate design decisions. Because of their significant use in manufacturing, bus topologies are discussed, as well as the associated trade-offs between bus, ring, and redundant star architectures (such as availability, and etc).
For a summary of the advantages and disadvantages of each topology, see Cell/Area Topology Comparison, page 2-25.
Figure 1-3 shows a star topology. Note that Figure 1-3 to Figure 1-5 are meant to depict the network device topology and not necessarily the number or type of end devices.
Figure 1-3 Star Topology
Figure 1-4 shows a ring topology.
Figure 1-4 Ring Topology
Figure 1-5 shows a bus topology.
Figure 1-5 Bus Topology
The Cisco EttF solution design and implementation guidelines include the following key considerations:
•Choose a topology that meets the performance, cost, and spatial requirements of the automation and control application.
•The layout of plant operations, conduit/wiring paths, cost, and desired level of availability determine whether the network topology follows a tree, ring, star, or trunk and drop topology, or a hybrid.
•Use ruggedized/hardened network devices in the factory environment where needed, but consider using non-industrial routers, switches, and firewalls where possible to reduce cost.
•The number of automation devices and grace ports for programming/troubleshooting and 10 percent spare for future expansion determines the type and size of switch needed at various levels.
•Hierarchically-layered switches may be required to address density, distance, or communication path challenges.
Compatibility
By definition, industrial Ethernet (IE) protocols should operate on standard networking technologies and infrastructure. However, standard networking technologies have a wide range of service and configuration options that need to be considered to effectively support the industrial automation and control application. As well, various IE protocols rely upon various networking features to operate at required performance levels.
EttF must show compatibility with the IE protocols and communication models of the applications that run on it. This typically means supporting the types of traffic they generate, such as TCP and UDP (multicast and unicast), as well as any features and functions they expect of the network, such as quality of service (QoS). A large number of types of traffic may exist in an industrial Ethernet network, including automation and control protocols such as CIP, Modbus/TCP or OPC, as well as common protocols such as web browsing (HTTP), file transfer (FTP), and many others. The Cisco EttF solution outlines how to design and implement compatible network architectures.
Industrial Automation and Control System Communication Protocols lists the relevant general industrial protocols and the corresponding industrial Ethernet versions. This solution architecture focuses on the Common Industrial Protocol (CIP). Other network protocols are considered (see the sub-sections on traffic flows in Cell/Area Zone, page 2-2 and Manufacturing Zone, page 2-33).
Scalability
Once installed, industrial automation and control systems, once installed, tend not to grow, but rather are replaced or have additional lines, systems, or functions. Industrial automation and control systems come in a wide range of sizes, from the small OEM solutions to the extremely large factory complexes (for example, an automotive plant). The industrial automation and control system may include only a small number of devices (up to 50) to multiple 10,000s of devices. The solution architecture concepts and recommendations need to be applicable to that range, noting the considerations for various sizes.
This version of the solution architecture focuses on basic concepts, tested in typical small-to-medium network installations. Rather than focusing on full-range and scalability testing, this solution architecture focused on defining and testing core concepts that are applicable to a full range of factory floor sizes. The basic concepts in this guide are applicable to the range of industrial automation and control systems.
Key scalability considerations include the following:
•Network infrastructure sizing and performance constraints
•Network infrastructure tiering to meet spatial, size, and performance criteria
•Link aggregation to achieve higher bandwidth requirement
•IP addressing schema and allocation mechanism
•Maintenance and management considerations as manual tasks have greater impact in large environments
Scope of the Cisco EttF Solution
This phase of the Cisco EttF solution is meant to introduce a basic network architecture based on standard technologies to provide services to industrial automation and control systems. The first phase is a starter kit for customers, partners, and vendors seeking to implement a basic EttF solution.
Key aspects of this phase include the following:
•The Cisco EttF 1.1 solution focuses on wired solutions for the industrial automation and control systems.
•The Cisco EttF 1.1 solution is designed for small (less than 50 Ethernet endpoints or nodes) to medium (less than 200 Ethernet nodes) manufacturing environments.
•The Cisco EttF 1.1 solution introduces key technical considerations such as the following:
–Topology
–Real-time communications
–OSI Layers 2 and 3 configuration including basic routing protocols
–Insulation and segmentation including VLANs and DMZ design
–Multicast traffic handling including IGMP protocol
–Quality of service (QoS)
–Redundancy and resiliency (including application of the standard RSTP)
–IP address allocation, assignment, and related services (for example, DHCP, and DNS) in a manufacturing perspective
–Basic network management
–Network security for the automation and control systems including DMZ, firewall, intrusion protection, endpoint security, and security monitoring, analysis, and response
•Design and implementation is based on EtherNet/IP (driven by CIP) based automation and control systems.
Key Terms and Definitions
•Industrial Automation and Control systems—Refers to the set of devices and applications used to automate and control the relevant manufacturing process. Rather than use various terms with a similar meaning e.g. production systems, factory floor systems, we standardized on this term for use in this paper. That is not to suggest any specific focus or limitations. We intend that the ideas and concepts outline herein are applicable in various types of manufacturing including but not limited to batch, continuous, discrete, hybrid and process.
•Cell/Area Zone—A logical section or subset (physical, geographical or function) of the production facility. It typically contains Level 0-2 devices (see Automation and Control Reference Model).
•Demilitarized Zone (DMZ)—Refers to a buffer or network segment between 2 network zones. A DMZ is commonly found between a corporate network and the internet where data and services can be shared/accessed from users in either the internet or corporate networks. A DMZ is typically established with network firewalls to manage and secure the traffic from either zone.
•Determinism—is a property of an overall automation and control system that behaves determined only by initial state and input. Many factors impact the deterministic nature of a system, including network performance. For the purposes of this document, we will consider the network low latency, minimal jitter and minimal packet loss as the key network criteria that impact the deterministic nature of the overall automation and control system.
•Ethernet—is a family of frame-based networking technologies or standards (IEEE 802.3) for local area networks. It defines standards for common addressing format and the physical and data link (or Media Access Control) layers of the OSI Model. See the IEEE 802.3 working group's site (http://www.ieee802.org/3/) for more details on the set of standards.
•Factory or Factory Floor—This document chose to use Factory Floor as the keyword to describe the area in which the manufacturing process and control takes place. This is not to exclude similar words such as plant, production facility, or any other term used to refer to the area in which the manufacturing process exists. In fact, they can be used interchangeably, but for the purpose of consistency, we chose to use Factory Floor.
•IP Protocol Suite—Is a set of networking standards on which the internet and most enterprise networking is based. It includes the Layer 3 Internet Protocol (IP), the layer 4 Transmission Control Protocol (TCP) and User Datagram Protocol (UDP).
•Jitter—Refers to the variation in Latency (see definition below). Jitter is important as often larger variations in the delay due to communications can negatively impact the 'deterministic' nature of the relevant system.
•Latency—Refers to the delay in communications due to transmission media (Switches, Routers and cables) between any two end-devices. Latency could also refer to the processing time in an application to process a message.
•Layer—Refers to layers of the OSI Model which logically describe the functions that make up networked communications (see Networking Equipment).
•Level—Refers to levels of the Automation and Control Reference Model that describe functions and domains of control within manufacturing organizations.
•Manufacturing Zone—Refers to the complete set of applications, systems, infrastructure and devices that are critical to the continued operations of the factory floor.
Industrial Automation and Control Background
History of Industrial Automation and Control Networks
From the beginning, manufacturing environments have relied on numerous technologies to enable communication at the plant, cell, or I/O level. Typically, the technologies deployed were purpose-built and vendor-specific. Figure 1-6 provides a list of some of the types of protocols used in manufacturing environments.
Figure 1-6 Control Protocols Overview (Source: David Humphries, ARC)
The industrial automation and control industry as a whole has been moving away from the purpose-built and vendor-specific communication protocols for reasons that include the following:
•Difficulty of finding and training people who can debug a specific communication network technology
•Difficulty of extracting data for production reporting with older fieldbuses
•Expense of using vendor-specific technology to tie industrial automation and control systems together
•End user frustration in procuring industrial automation and control systems because of the confusion related to various fieldbus technologies
•Complexity of integrating various technologies into the overall industrial automation and control system
Ethernet and the IP protocol suite are now the ultimate solution to the multiple standalone industrial automation and control protocols. Ethernet and the IP protocol suite are standard technologies that provide a robust, cost-effective, easy-to-implement, and easy-to-troubleshoot mechanism for transmitting industrial automation data. Industrial networks based on standard Ethernet and IP technologies define the physical and transport layer for moving data. However, these technologies do not replace fieldbus communication standards per se. For example, fieldbus communication standards still define the data and its meaning and determine how messaging occurs. Each technology has its purpose, depending on the protocol and the data that is in the device.
Industrial Automation and Control System Components
Physical Layer
Many of the purpose-built and vendor-specific industrial technologies have specific physical media requirements that often require unique cabling (such as co-axial) and specialized termination (such as serial connectors). These various physical layer specifications result in a complete physical media upgrade when migrating from one system to another. In comparison, industrial Ethernet uses standard Ethernet wiring; either twisted pair cables, or multimode or single mode fiber. The connectors for these various types of Ethernet wiring are also standardized with RJ45 connectors for copper cables, and SC or ST connectors for fiber optic cables. In extreme cases, sealed connectors may be required. The benefit of Ethernet is that after the Ethernet physical plant is installed, it can be used to connect hardware and software from multiple vendors.
Typical Ethernet speeds are 10Mbps, 100Mbps, and 1Gbps. 10 Gbps is mainly being deployed in enterprise-wide backbone networks. Most industrial automation and control installations rely upon 10Mbps or 100Mbps Ethernet and Gigabit Ethernet is appearing in industrial system backbones.
The physical layout and communication requirements of a manufacturing environment dictate how various Ethernet-based resources are physically connected. Typical Ethernet environments have full duplex connection via a redundant star topology. Other options are possible such as ring, trunk and drop, and daisy chain. Specific operating constraints when using Ethernet in these other models are discussed in Chapter 4, "Implementation of the Cell/Area Zone ."
Networking Equipment
As the industrial automation and control industry adopts standard Ethernet and IP technologies, it benefits from the access to a wide range of standard networking equipment. The type of device required depends on many factors, the first being what type of communication protocol is in use. As Figure 1-7 shows, various types of devices work at different layers of the OSI model and common devices that perform representative interconnect functions.
Note For the purpose of this document, the term layer refers to layers of the OSI model. For example, Layer 3 refers to the Network layer of the OSI model, and in standard networking refers to the IP protocol.
Figure 1-7 OSI Model
Many early factory floor Ethernet networks used simple, cheap repeaters (also known as hubs) to connect industrial automation and control systems together. In many cases, these were the same Ethernet hubs that were handling front-office workstations. As a multi-port broadcast device, a hub does the following:
"Creates one big collision domain, with all traffic shared. As more network nodes are added or traffic increases, every node in the collision domain has a greater chance of slowing communication or having a collision. Additionally, because industrial automation and control networks are not configured to differentiate between the relative importance of Ethernet packets, it is possible for non-essential traffic on the network (perhaps people backing up their computers to the network server or printing a large document across the network) to slow or collide with essential traffic (such as inter-PLC communication or HMI polling)." (Source:http://www.cisco.com/warp/public/779/smbiz/languide/p4.html)
The next advancement in industrial network design was to use switches; a type of multi-port Layer 2 bridge. Switches can divide networks into VLANs that segment devices into logical work groups. Ethernet switches also typically have a fast internal backbone, which helps eliminate collisions among data packets. Switches separate collision domains and map Ethernet nodes based on address and port. When an industrial automation and control device is directly connected to a non-blocking switch in full-duplex mode, potential collisions are eliminated. This occurs because full-duplex Ethernet devices can both send and receive packets of Ethernet data at the same time. This increases the level of determinism of Ethernet, assuring that packets arrive with much greater certainty, and that each port has more bandwidth available for communication at any time.
Adding some intelligence to the switch improves traffic management capabilities, meaning that the switch can provide more granular quality-of-service (QoS) for industrial automation and control networks. One example is the management of multicast traffic to communicate critical I/O data applied in most implementations of EtherNet/IP. Management of the multicast (rather than treating it as broadcasts as unmanaged switches do) significantly reduces the number of messages that end devices and network infrastructure must process, leading to better network and device performance. As another example, by assigning a priority to time-sensitive data, intelligent Ethernet switches can prioritize that traffic above lower-priority data. This ensures that high-priority traffic always traverses the network, even if the network becomes congested. Switches can also classify, reclassify, police, mark, and even drop incoming data packets as application priorities require. The use of managed versus unmanaged switches is a key consideration facing those implementing industrial automation and control networks today. Both Cisco and Rockwell Automation highly recommend the use of managed switches. For further details on managed versus unmanaged switches, see Network Design Overview, page 2-26.
In some cases, Layer 3 switches or routers are used in manufacturing environments. Layer 3 switches or routers connect LANs or VLANs. They use information in the IP header (Layer 3) to do so. Regardless of the specific layer being connected, switches provide industrial automation and control networks with many of the safeguards that were realized by the natural separation inherent in existing factory floor optimized networks.
The specifics of how a Layer 2 switch is used compared to a Layer 3 switch, how to implement multi-cast management and how QoS can be implemented is addressed in Cell/Area Zone, page 2-10.
Industrial Automation and Control Devices
Numerous types of devices are used in industrial automation and control systems. Some are small, simple, single function sensors or input/output devices (e.g., a light or on-off switch), while others are complex, programmable automation controllers (PACs). The breadth and depth of available devices is driven primarily by industrial automation and control vendors and their partners and suppliers. Figure 1-8 shows some of the various types of devices used in the manufacturing environment.
Figure 1-8 Industrial Devices
Older lower-level industrial automation and control devices tend to use specific industrial automation and control protocols and are capable of only low data rates and volumes, albeit with deterministic characteristics. More advanced industrial automation and control devices have internal logic optimized for I/O control with the ability to support higher data rates and volumes. Many of these newer industrial automation and control devices now come standard with more communication options including Ethernet and IP. For example, controllers now come with options of 512 K to 100+ MB of memory, integrated serial communication interfaces (integrated RS-232-C, RS-422 or RS-485 ports for SCADA, ASCII, or peer-to-peer communication), modular and scalable EtherNet/IP, and ControlNet and/or DeviceNet communication interfaces.
The trend with most industrial automation and control devices is to add more functionality and capabilities at all levels. This is occurring because of the continual evolution in the microelectronics industry and access to lower cost components with more functionality. The low cost of microcontrollers is already making it easy for design engineers to include Ethernet and IP in a growing number of products that exist in common industrial automation and control systems. As with many electronic technologies, after a few high-end products incorporate a feature or function, it rapidly becomes a common attribute on many of the emerging new products.
Even so, there is and will continue to be a place for simple, low cost, and lower capability devices in industrial automation and control systems. When Ethernet and IP represents too much of a cost and capability increase for the end device itself, these devices will continue to communicate via simple, non-Ethernet I/O networks; for example, a distributed I/O device used as an Ethernet network concentrator connecting a number of simple devices, such as a push button, to a controller.
Industrial Computing
Computing technology has been used for years in purpose-built and vendor-specific manufacturing environments. Just as with IT, the technology has migrated from mainframes and mini-computers with dumb terminals to standalone, dedicated computing platforms. With the cost of computing highly commoditized, the trend now is to put computing power anywhere in the industrial automation and control network using high performance CPUs. By using fanless and diskless PCs with features such as capacitive touchscreens, class 1 division 2 environment certification, and mission-critical solid-state drives, computing platforms are now suitable for any harsh industrial or embedded device application.
From an operating system perspective, most industrial automation and control vendors have moved away from legacy or custom-built operating systems to common off-the-shelf operating systems based on Microsoft or Unix derivatives (including Linux) for many products. The benefit of this development is a simpler and faster application programming environment both for vendors as well as end users. This migration has coincided with the overall general trend in the software industry towards Internet browser-based technology. This gives automation vendors the ability to embed web interfaces directly into industrial automation and control devices.
The downside of all these developments is a significant amount of system complexity related to security and patch management. The specific application requirement of industrial automation and control systems is discussed in Chapter 2, "Solution Architecture."
Industrial Automation and Control System Communication Protocols
Communication Model
The communication messaging model in manufacturing environments has only loose ties to traditional client-server or peer-to-peer IT models. Unlike the typical IT environment, standards-based Ethernet and IP industrial automation and control communications have different patterns, loads, and frequencies required by the manufacturing process they support. Standards-based industrial automation and control communications are also driven by status polling between devices, cyclic data transfer, or change of state message patterns. The various requirements of the layers previously discussed have led key industrial automation and control providers to define a variety of communication models, including OSI layers 1 to 7 networking protocols.
These communication models have both strong commonalities and differences. In common, they differentiate the control or I/O traffic between devices and the PACs (EttF levels 0-1) and administration traffic within the upper layer applications down to the PAC (EttF levels 1-3). This differentiation is made to meet the stringent requirements at these lower levels (see Industrial Automation and Control Reference Model, page 2-1). However, the models can differ greatly at the control or I/O level. One example is the producer-consumer model applied in the Open Device Vendor Association (ODVA) Common Industrial Protocol (CIP). This model describes how devices "produce" data to be "consumed" by other devices; in particular, the PACs that take action on their data and control their behavior. These models are incorporated into the industrial automation and control protocols described below. They are important because they impact or shape the network traffic that is produced by the applications that use them.
CIP, for example, defines two distinct message types: explicit messages and implicit messages. In an explicit message, the action is explicitly implied in the message; for example, read the value of a variable. Explicit is a request/response, client/server-like protocol typically used for "information" and administrative messaging and is implemented over the Layer 4 TCP protocol. In an implicit message, the data is implied; the communicating parties inherently know how to parse the message content because of contextual knowledge. Explicit messages are information messages used for additional device configuration and diagnostics of features of the industrial automation and control device. Explicit messages are highly variable in both size and frequency based on configuration and application.
Implicit messages are typically used for cyclic, Input/Output messages to/from controllers and devices. Implicit messages are sent either unicast or multicast over the Layer 4 UDP protocol. Implicit messaging or real-time control is sent at specified intervals, and although the size can vary, it is consistent after the configuration is set and is generally smaller than explicit messages. Implicit messages contain control data that must be interpreted very quickly by the receiving device, which demands network and end-device performance that is different than other traffic. With implicit traffic, the UDP protocol is used (either unicast or multicast) to minimize processing resources and time on the end device.
Network traffic in manufacturing environments can include significant and varying amounts of unicast, multicast, or broadcast traffic driven by the communication models applied (e.g., producer/consumer, client/server, master/slave, multi-master, or peer-to-peer relationships). For the purpose of this document, we focused on the network implications of the Producer consumer model applied in CIP. These differing communication models and the protocols into which they are embedded drive various configuration considerations for the networks that support the automation and control systems. For example, the CIP use of multicast traffic generates different network configuration considerations. However, these differences are focused on specific areas of a manufacturing network where the networking requirements are the most significantly different than standard IT networks. Chapter 2, "Solution Architecture," introduces a framework and model for industrial automation and control to clearly describe these areas and the network implications to be considered when designing and implementing the systems.
Industrial Automation and Control Protocol Overview
Most Ethernet and IP-based industrial automation and control protocols have a common core. This includes the physical transmission technology (Ethernet, Layer 1), the bus access method (Ethernet, Layer 2), the Internet Protocol (IP, Layer 3), the TCP and UDP protocols (Layer 4), the Hypertext Transfer Protocol (HTTP), the File Transfer Protocol (FTP), and the Simple Network Management Protocol (SNMP). All these are established in the IT industry and are being implemented to varying degrees, unchanged in industrial automation and control applications.
The goal of an Ethernet and IP-based industrial automation and control network is to ensure that the control protocol of choice, assuming it is based on standard Ethernet and IP, is supported to meet the operating constraints of the industrial automation and control systems.
Table 1-1 shows a list of some industrial automation and control protocols that support or partially support standard networking.
Table 1-1 Control Network Protocols
Fieldbus Protocol
Ethernet Implementation
Leading Vendors
Standards Body
Application
DeviceNet, ControlNet
EtherNet/IP (EIP)
Rockwell Automation, Schneider (EIP), Omron, Eaton
ODVA
Industrial automation process control
PROFIBUS DP, PA, and so on
PROFINET CBA, I/O, IRT, and so on
Seimens
PROFIBUS Foundation
Industrial automation process control
Modbus
Ethernet Modbus TCP
Schnieder
Modbus.org
Industrial automation process control
Foundation Fieldbus
Foundation Fieldbus High-Speed Ethernet
Emerson, Honeywell, ABB
Fieldbus Foundation
Process control
CAN/ CAN-Bus
ETHERNET Powerlink
Bernecker, + Rainer
ETHERNET Powerlink Standardization Group
Motion control
Sercos Interface
Sercos III
Bosch Rexroth
SERCOS International
Motion control
However, there are some differences in the application protocols for real-time communication as well as the object and engineering models for system configuration. These differences lead to different considerations and deployments of industrial automation and control networks. Of these protocols, EttF Architecture Phase 1 is focused on exploring only the ODVA implementation of CIP on the Ethernet and the IP protocol suite referred to as EtherNet/IP.
In addition to the approach taken to integrate with Ethernet (physical and data layers) and the IP protocol suite, these application protocols have also identified various messaging frameworks that dictate the type of traffic and traffic patterns found in the industrial automation and control network.
Table 1-2 briefly describes some of the key characteristics of the various protocols.
Table 1-2 Various Features of Different Industrial Ethernet Protocols
IE Protocol
Encapsulated Telegram
TCP/IP UDP/IP
Port Usage
Profile/Object Support
EtherNet/IP
Common Industrial Protocol (CIP)
TCP/IP explicit UDP/IP implicit
44818 2222
Legacy
Modbus/TCP
Modbus
TCP/IP
502
Legacy
PROFINET CBA PROFINET I/O and IRT
Profibus Plus
TCP/IP Special Data link
Dynamic
ORPC
OPC (OLE for Process Control)
DCOM/XML
TCP/IP
Dynamic
DCOM / XML
MMS TCP/IP
MMS
TCP
MMS
.NET for Manufacturing
COM
TCP/IP
80
DCOM/ XML
Foundation Fieldbus HSE
H1
UDP/TCP Optimized
Dynamic
Legacy plus
iDA
N/A
UDP/IP
Dynamic
XML
AADS-net
N/A
UDP/IP
Dynamic
Possible
The various protocols and their application of the Ethernet/TCP/IP stack drive particular considerations in the configuration of the network. Using CIP and the "producer-consumer" model as an example, the control-level devices use UDP unicast and/or multicast to send critical, cylic I/O data out on the network. Although the choice to use multicast or unicast is the choice of the device vendor, multicast is the default mode of communication of I/O data in CIP implementation in EtherNet/IP.
The ability to control multicast traffic in the control levels of the network is a very important aspect of the network devices. Figure 1-9 shows how without multicast control features, the bandwidth requirements in an industrial automation and control network application increase exponentially (versus a linear increase) with the increase in the number of devices. This is just an example of the type of network design, configuration, and implementation considerations specific to industrial automation and control protocols.
Figure 1-9 Producer-Consumer Network Impact
In summary, a wide number of protocols are in operation in industrial automation and control networks. Design and implementation guidelines need to consider the various protocols and their underlying communication models. This initial version covers EtherNet/IP and the CIP protocol along with the producer-consumer communication model. Over time, this architecture and the subsequent deliverables will take into account the various communication relationships, protocols, and Ethernet/TCP/IP implementations when designing, implementing, and operating an industrial automation and control network.
Common Industrial Protocol Overview
CIP is a messaging protocol that defines how various industrial automation and control devices, systems, and applications come together to form an industrial automation and control system, as shown in Figure 1-10. CIP is an application-layer protocol (OSI Layers 5-7). EtherNet/IP extends the application of Ethernet TCP/IP to the factory floor for CIP-based applications.
Figure 1-10 Common Industrial Protocol (Source: ODVA)1
CIP is a connection-based protocol and offers two main types of messaging: explicit and implicit. The protocol specifies a set of objects and services used to develop industrial automation and control systems. CIP is implemented on three network layers: DeviceNet, ControlNet, and EtherNet/IP. This document is concerned only with EtherNet/IP.
For more information on CIP and the various network layers, see the ODVA website at the following URL: http://www.odva.org; and ControlNet International at the following URL: http://www.controlnet.org.
The important aspects of the CIP implementation of EtherNet/IP are the various types of messaging that are used and how they are implemented in standard Ethernet TCP/IP.
Table 1-3 provides a brief overview of the CIP messaging types and their key networking characteristics.
Table 1-3 CIP Communication Overview
CIP mode
CIP message type
Description
Response time requirements
Layer 4 type
Packet Size (Bytes)
1
Port
2
Unconnected
Unconnected
Basically used to open a CIP connection with another device. This mode is only temporarily used.
Seconds
TCP
~500
44818
Connected
Explicit
Non-time-critical information data. For example, between a controller and a manufacturing historian application.
100s of milliseconds to seconds
TCP
~500
44818
Implicit or I/O
Time-critical control information usually passed on regular intervals in a "producer-consumer" multicast communication model. For example, between a controller and a drive (PAC to device) or between controllers (PAC-to-PAC).
< Millisecond to 10s of milliseconds
UDP multicast and unicast
100 - 200
2222
1 These are typical numbers, although depending on the application and customer can be different 2 These are registered ports for EtherNet/IP, although non-registered ports may be used in EtherNet/IP.
Other key technical considerations for EtherNet/IP implementations include the following:
•The producer-consumer model specifies that "producers" of I/O data communicate via UDP unicasts or multicasts. The consumers (for example, controllers) typically respond with UDP unicast messages. Rockwell Automation and the ODVA therefore recommend the application of IGMP to manage the multicast traffic flow.
•Multicast traffic in current installations is stamped with a time-to-live (TTL) value of 1, rendering the multicast packets un-routable. This limitation forces all nodes that produce and consume information from one another to exist in the same subnetwork/VLAN. The capability to change/increase this value has been outlined in the most recent version of Volume 2 (EtherNet/IP Adaptation of CIP) of the CIP Specification release 1.3, which was published in December, 2006. For the purpose of this solution architecture, it is assumed CIP-based multicast traffic is not routable.
•By the current EtherNet/IP standard, a multicast group is created for each Ethernet adapter that "produces" information, and for each "produced" tag (shared piece of data) established by a controller. EtherNet/IP specifies an algorithm to establish the multicast address and the commands to join and leave multicast groups. Current EtherNet/IP multicasting is based on IGMP version 2, although there are devices (producers) that may still be based on IGMP version 1. IGMP version 1 devices should function in a version 2 environment. This was not tested in the Cisco EttF solution.
•Depending on the device producer, options may be enabled to configure whether the traffic generated by the PAC for each "produced" tag is unicast and multicast. This allows more flexibility in cell/area design and a means to manage the number of multicast groups within a cell/area.
•No CIP-EtherNet/IP QoS guidelines have been developed, so devices and applications typically do not mark either MAC-layer class-of-service (CoS) or IP-layer Differentiated Services Code Point (DSCP) fields. The ODVA has included a placeholder in the specification for QoS and work is currently ongoing to develop an approach.
1 EtherNet/IP, ControlNet, DeviceNet, and CIP are trademarks of ODVA, Inc.
Was this Document Helpful?
Yes
No
Feedback
Contact Cisco
Open a Support Case
(Requires a Cisco Service Contract)
-1.4%����
1 0 obj <>stream
application/pdf
iText 1.4.1 (by lowagie.com)
endstream
endobj
2 0 obj <>stream
application/pdf
iText 1.4.1 (by lowagie.com)
endstream
endobj
3 0 obj<>/ExtGState<>/XObject<>/ProcSet[/PDF/Text/ImageC]/Properties<>/Font<>>>/CropBox[0 0 612 792]/Rotate 0/MediaBox[0 0 612 792]>>
endobj
4 0 obj <>stream
H��Wko�X��_q?ڋX�ӲE�6�t�n��-�tcߩ�$�������N�i�mG�$��<<<\�j:�f�z�buw��Z�~�i��z�ui������y���ҝ���ԕZ�~]��>���������;�7���:q�0N��/_��U���[�zw�*��z;[���U�v��n]���,Q.�'�۸*�<�W�r6W�ퟳ_���3��{*���ſ�Sq詬��na����;!~"O����\�|�+��75���Y���{k�)f�:v|�����n�q�u\�Zҕ�V�o*v� G���9a�$8�G����]]9Y�O�9�m��<���с~y�D���@exw�� �)������oW�"B��cw�r�����%���NLz��ɉ"���ɼ��*��[_>ؓ�붮��^,�yѪ��U�Xn�z��q�L���{��[,�x�m����F�Vg�F�S9}������r=g���bϻZ�y��Uݞ��ce�ɯG-)J#�7t W-='��}�����X�s��R�E���]��U�Ց��ؘ���pGU��_S�B��ֱ͗�H���U[DZ��[����U[?��:^@�p����5R�2K�R�fפ�Vi�����h�:�)J���K$�v(�� �tQ1���l_ d�sg �,U>���yoغ!�vpy�m���!Җ����{����g���؉���I;��B���{�uA�?�?�7X��*WD[� vl��{�n���<-
]������*L���)x�����MȶoM���A�D���wo����t՛tu����%Iy� ����=ǣ�� y���7�M萋d��7�g���D o���4�������>:��z���-���qQ߸�&����e�;k�j�#i�* ȸ�:O8}�}�l����?����V�H�O|����QZ��,�e{����A+�@��R�� |��Bp��� ��$c��b�����Į���<�Y��MH���@����QLՂ�C�tr��C���TY�`�w��j�z�����ȉ�Xx����nT�6h ��Xu)s�A�r�|ጡ�M�t9a�x`����:z���1�KB-�g54F�Q�:��4Ao�i9ޘ����z���Z�w�fǶ�KͳLFY�-
�>�e�?���9�����L]j
<��y�)��3&��xo(ʓ-oI�o�/�=a>�\B+�<�c?t��}=���-��ڴ��k;6�H��8�ilv9ކ��O��pL_�U��3�Xt7��CZш)aq��mh)����"1Y������<|��4���{D��'|H�H��!�v���;�
��y��,aL!p�mS�N_.���т� wI*�βΜ8b�9B-(�|�X�
y��F>ҌrU�v�����O�J�]��)��v�XX�GNq�ؖ���R��P��� �/���cy��ɴ�S�i�~-L��2�����,!�
�i�:R�w����i�#F����y�&�<�?}'��|;DU)�0�,b���lKyc�ذ�A{��ҳ�pP�����<�����9IbÁqZ�;�:�a���AӲ\������r��r��i����m�AȒ����EfD��NbI[ņ&R��Ć8�sF�h��K^��&=�
sϖ�ぽ��ȑo���4u��q��|��%%,%��*�*�)��0�%ܳ�-/&�П�4�&�{��#A8�֜w�~F���q���UҦ�u4a۸�cا�1m{檄X�'�Y��(�7&�&����Q���fSÍ>��l��F�su
z����'�ȶ�t��?Yk�r��p�A�@QQ�zN'Ӄ��i@v����Pr�"YA^� ���H ��t'{�䕝39���%9g�;���Y�/k����4}�O�B����ΰL3j$��;ʺ�_�>�=[7���@��>�fP�؎����T���d"� VA'u,�v��P���1h�4��JւS����9��Xb�\�珰��C�z.���;��tv{ӎ����.g*z`�`��C�k�|�#�N����IdE}@�ǒB� "Н���Q� �{�&xh(v���o�<ޅ�V��R��@���a_���<�=w� o�?��������l�;� ����p�$|��"��t�t��
B���~��ݍ#�BW|}���RC�t�u@7\qN�l��M]S��)�OT�a�;O����3�4��N��sM�d�V���G��D@X��yu{[Z�S� �خQ/K*����8�h^�y~���Q�/Μ W���WF7V�~�_]��5�[���后�n�R�p/���d���$|����V���D�\
�a
�f\'F���2�p��\�/�����xY��6�4�����O���ɐ!�(j�|oh��=o ��J��z,���R��$�b��ݺ�I�|����$�(����Y�q�{��d?eA56s�I�-�nt��i��f��vdɋ�y.O�4/�}G �ha�s��gE���g��a~��C�.��N��� ��h��բ�TrS��D� tP�Ҭ��URm˦���W�m��lg��`\����u�q�=�Ǫı�~Q�֮#��-
�&�;�a�K���.��a��+|��AP�[��n���.�6Ҁ
h�^;�c݇zhDH�����˱[�K�r�G� ���]�q%�c 8W5���q$e!����� &�N�M;X�Ctz��<��.4F����g��{[W�Lpv�X� K�1�P�+�4p2�qU ���Sz�6V9����H����v��`vFU��9��mB�q?F��+��6���K�G}ѬP��&&$� wՊ�=�L�2��J4%�I�D㧟���C.=o���ib�I���`��U.�)22(߶xr�:{:��=��X��Hub����~���r?˼�|��P�i�'�[#�a�kS(� x����Uw��*�Fs��`+[�,��(�l�Q��,mՌ�]�X��a����?m������ܳ�g< z!����TM�)!�|�b=�%�I*m�ߙ�_ G���
endstream
endobj
5 0 obj<>
endobj
6 0 obj[/ICCBased 25 0 R]
endobj
7 0 obj<>
endobj
9 0 obj <>stream
���� Adobe d� �� �
$$''$$53335;;;;;;;;;; %% ## ((%%((22022;;;;;;;;;;�� M " ��?
3 !1AQa"q�2���B#$R�b34r��C%�S���cs5���&D�TdE£t6�U�e���u��F'���������������Vfv��������7GWgw�������� 5 !1AQaq"2����B#�R��3$b�r��CScs4�%���&5��D�T�dEU6te����u��F���������������Vfv��������'7GWgw������� ? �M�_s��� s�������Y��YU�j�h��Bd���Y���ǙSoƤYU�X�j>nS N�Z�D ��Ǻb�~�}hs�մ����ߪ�X�����֏���˲-�Sz�r�+������{n.?�hQ��짻Ɍ.��o:n���ި������H�^��������� ��6�w�Տٖ7"�m�����`G�y�P|�NPx-i�ѵ39�ɬ{N��<���m+k�����Z�&)�/�L���Ǎs��V���U;�c����Y��E��XƗ9��>1.W�[�OM��������@i&?��2�"L�{@�w?Z��wL�.6��հ�:�3��#�����۩��$�I�@��nu��w�?��u�}�U���-?H���M϶�̻�H��9q�9o��.#Ba;X�J�M����S���8̻Oq����R q2�1�q7Fe�=��~�|��]�;�O��ʨ�4�Ҳ����� �aH�x�x1<�X0����<Ѵ'6\9�����~ ��� v��~�8U�\yH�BV����։=��<Ϸ�� ��H'�;H�}����; �)l�G�I�����+a�8u�c>��֖�s[���� �W?Ɓk�}_��K���P�KD�x�HiHII���`-n�!�}Ĕ>��1\�Pu�54Z=7�uL;7]���$�˚���@����2l��pѨ�\�d~rw��=i����� z_�������W�7F����zo���'p��㽿ޗ��^knf�Mz��G�]?ա�q�x�7"~���۷��V���3��oo�����M��y�e41����>ӿ�+y,_�c�:vc6�[�ʯ`��N����w�m�]���*,����V X溲_q�X��������w����-o� �݀�_E�;H ?�G�wG֓�`���NC��&������M�u�^.�6ƥ�@���fϪ�M�I�f>i^8�=�P[K�+��J k��9��2x�^����m:��Wq��Q��"d�Շj�e#�T�����5�5��T� x{�g��G�4�W����}�����k�屽f�Y�6�á��#��F�1E����/9���E6�e�4����~�R��e���s�2���:�3���:K[�`��hu"���%�v��q�T���;��kA-�~3��X����ݸհ8��o$oo5'�֫��MU�ts\�t۵�*�n���ZU�49������3�(�c�_��?��)� ye�����+����/�Y���e��c���ѣ�}�"��V���h�����?*�:ul�X���{@w
t�z�?+����4�2���Pd�Џ��T��"��S�K?F���?^G^n>E[�]ny����u�T��`Y���{���l{�f��5���<�&2�FE����m��}?����0�R�2x�g�N�[�u�=[�����,m��e�m�^�w�Q?W>��2*v�����z����C�^��s���Q_��Κ?�MC�V�~�t�=�'�9���?}ѧ�@n�8��l����X0G����)�C���^U��O���v�L��iuN$�� ��~�a<������O�z� �Ok|$8�Vx1k��Hw��B����?³���&� �8]��w�%Juv��c�*c�UO��Ύ�t�U_�T�ve1!c� �n��Mg�Cw֞�� r���T�v�7�^E/��,���Ee���9ڷ&�9�N��?\z-����q�=;e�)�V���V� �C�������9���8HX�c2���uC�^n���-��\4�|�
u�~�X|� *ђ�I��-F;sC�@))N�|,��8�2�C])��~��ߑp_U��س��7[���q#k~��c��/�]��f�u��y.T�_^3FGVnB)�h��p �|��ڡ� U���9�}��}�(̤�mJD)���O*.�ǒ�����K�%�!J��q]"y�>@�}�����+��I<�J�$4���ҭ�(p�Y��8�ȴ@s���VM � ���;� Ц�2H���k}�Q���b�:OdxQ����ɀ�q�hc��r�V�@�������
-���h�6#�Qv3�����j7P<�K�V�wk��e.�"D1��`)}��mܠBAyoE�V�^��O�����=�\��G��8 ��4�zN%-�� W[�h ��%��v�(���i���W9�go�q���x"�=��C��R�ddd�q��� Uj݅����?�S�mI��e�eV� �z\p�,�Y�������ܗ��<�X?S�mZzm�0=v���{�oT��tR��_��W��"���P����_༩��/T�/t�� s�� {/!�-�#C�؊���Q^Ac}:`�J�:�G8�� ��EX���KCY��/���i�4H�o�{�44�e����yI�F�<�� $��C��*���q� n���*Qe4�pJo��̌b~;� "�fT�,|l?���5�>�� ���� �ޱ��k�Z�vy�'��������6!#A�L�7���C��旬�4��<��s��"� 6���WX�GįX�7��7D����۷u��;�B���$vPn�Y����{,|d0� 4k����ƻ����C���n�VK��f��ku�����k�+�W����4�k��$�ۧy��
*��t�� i��q��������6
� �2���Bx����׳����'�V�� qM��C��粣�*Ϧ����U��ѱ�8}����������� ��օ�U�Kq�=�#��K�e������x#��?��X�Ī}�j��`0Äx'���T�} ���h���Ƿsd�'��Y��e�5�7۽�f�ʗTǺ��� Tm�}� ϴ{G�l���kZ�\\�caI�Z����~}yV�c���l`ys�7S���Q��q�a{���p#��E��6b���fQ1��u�vH�U�~2���p��·TG��v��Buih�� @��XΣE�.yU�K �-��WG���n�bu<�;9�sw�1� ~^{��#�4>gElcW^4��s�Zj�hka�2�)�_�u����X6VO;fA�<���;rV>>NC�Y �� Ƈݸ����K���7��w��q<%�f�쎘�1�6d4�������1$����ޕ�:]��-�v���$�� �>?���i���>�SY���q�nU��}�0�COa�G�s��έWM��?�������͗��0}����u��GI��,������=� #��9Ͽ;�gY��ݾ֒�U�+��h����.�9QgS�bP5�;�� �x|W=v&@a��s�� d����dW]��CZߥǂ��p��g�ZL�6�=�.:k�s�b�їm9Ls-o��p� +����G@e��s���e��Kv��ӏk�������|bǐ�[�p Lt�r��oqq�<��V&K���S��Oi塧�Ȭ����qǶ�ͻ���S{��A��y�t��ɕ��ewp�a>��@:��O��uG;��Q�q����tr��ܯt�tO���O�y� �ɏ��Ǘ�X�g��܌s��Q�V 7F� ���!�� a.0$�����4X��hp��r�W��e`����>�Nd �l�kʥ��z}�j����h��#��J�N���70U�S@=�h���vhY�� �{�p�ܦfCqpݓh/ʰ�_��Q�2���h�qs�������.����'o�˼3���ls��8�8�s����]��[Mn�O1:���s ��!��W>P�@u��d��cti�Q������U�ݻ༏'��u�~�0�����އ�2�{ 2���>1�O�'
Cj�,v��uW+��!�"5�V�)���oe �Ƿ��6�ʃ�� ��>!%>��=�?M�of���|��1poWk��ְ�p U�� ��?~�V�q� ��� ��k�����v���GU��u��u�Y�Uz�705��j��i�G�[z�&;i�ͽ�юs�po� Z�����o����r�[+;9�X�va�}ϥ�s���o���|'(촀�u}x�c��0�Ŏ��'�y��4V?������s���g��,����������%tn����2N��$��'�.m�\z������$� �%U��/^�C�^�{3k?�@K�}Y�8y%�z�Q ��2A��9���L�̇ٝ�7�6�K�~C@9%�T��dd�g"�-'_{���� ����}�����J }�e1�k:}2-h�u����?$�"wM<��N�Fc��a�X��s��s��k��ExL1nc�H�H���qh�{Xֵ�� �/+���_�SL��<7r���A�M� �m@G��O�)6�`w<�>�;�OtZk��Z(DR
Qh��[�:� �
�H� �G�� �4��f�'�@#_<�[}��kl ����*O�d�q�欴;��IAa�Y�-zk2����"S�Qc\G "}���$�_բ>����w0��'�V�c���;%Ěj0���Q8���}����xK�U�Ī@�kfO�-ϩ2Ϭ�³0�����'-���'P�?��[n��Ɔ�Ua��P_R)Q��(j�gm������>�,������ &5���v={%��9�>�\5��� O���x�\�oZ£���UK6�l/��u�p,ٶy�P'E�<�^Q�9�����2:s!i���NX��.c�04k��~f����4��?�\��p�h�L��c�u���W�� �S0%0J�� t��z�Qed1��D��>>K\����ՏK�{X���4\+�����[[�� �%�\N���`?�)wz=��m�8@k��:������]����0�Ӻf6nA���e�߽���������}�K2\փZ?
����Ut������uGg�wR�Q��Wԃ�]�9Y5�I� 7u,���&� �I��s��]67J��ۋEx�����ΪQ��aSr��h�hh�Se���̬rCbH� A���m����X�` ��O�U�ײzm&�Ub��K� ;���U�H�$0g� ��y/=�ͻ"�.�ľ���%���4A{�e�?� �K�|_A}~EQ�\v�`.Um��6�U��<=�|��;�oS��;&���%�O�8j�DD����ݎʩŴ� =��� �:k�@õ�; �ۻ3!ޖ�`o��������r:GR%�i�&tn����*�s�{YnI>����@:'ʱu�tU��8Z���A�w+W7�����-�\��nl�P���a�Tc����ȝƶ����YzK��*��~�x{S�En�7���N���"�h���P���~�]�\������6nݴx������^.}�Ϩߊ�������s�Si(>�g�G�E��X��=KA`w�^M}W�R�[��K@iuq.;��;B�GY�F�Q�q�0�cX��{�Bӧ���Dj�t�����Ma�9"�_\���W[4\_S7��v;�M��{";,��:��7��O� Vm����@��ޱ֟%�F��;� }�Wu�����;��%T�[�E�YԱ�@��N��Xt?qZ_T��_��hb��?�p����ܻ�E�;�In�t� ��31��^Y��oi?w *�Pf�[��p � �]^}�E�y����.�ߨ�|� ؐU>� sKLk�� M�;�`��_^�v�WV{���r�c�1��e89ڍ�u�BF�N�R�/�fe
�����k�DH�Lxy.fʝ��f3�;O��-:��?�d<�vA{�\A?��nK�Ym��h�dH��SnU���=��>'�A�_3�U��챶��7�D��w�q���5mn�y�Mء� �F�����!��O�o�[�����m}^�>��e��,p���R���Z ��������6��R�� ���TzݟUn������d;n�9���%��2k��C}Wm$?�~E�S�!��N�nf%w��� �
��P�r�b�,��z�=�� T肞�Y*-Q7r���h�9'��ЫT�籰� ��J�(�&N�\�9�� � �m���q[�b�tB|~�����k��<��� R���'M�������nc���1[=����] �9��]���WSC<� "l�Q
-M�
B�yV c����p��8�e\7:�EUpl>g��� !���soO�qck!�y-�d����s�颪*mU41�֎ M��V5M���Z'�I�ܓ�4"��V�fN�%�J�\�'��xe�?')�/$��9�'ĝW��L��:�{�!���3����]O�C����� xmm���h��L�D��$z�����=;�����������R����摬L�*�4�^A��>��:e��H���?$V[Xt;�����&dɔ�YN�,��,$hdǘG���4�c7&���d"�8�i�Y ᠕m��- ��V m-�v*۳�CZ�:�M���L�ld��ܦjO*_l�li D�C�,kG��U:�@d3�Va�� O��Ymk=�����KXI:�+/s��t�K��L��)�( C��J��eX�~��k^����49��ux����0�? ��^oĦ��~��
1�~+���|L�� �/����n�o�X'���Ä��}F8�ƙ k ���� 7a�t��Ƽz��IcH���]��0�:G�j:�N�4e��P��n�i���_MvNK�c��k]�� ��ܭ�E�v5��#$�}.64�N���OP��� ��f[�|dO�{@���1ju��V�#^|�.ѯ��p$yꡙ���[F�/iC��~*X�X��I��� ���m��'� �� 7p9��;� �h���ٸ�~(���
�u�σ�� 7�h���?�w�A?��#~U�{���V��?j� ��!�ڗt*��n����r��μT���<�\���.c�X�#��ߌ��U�8'h�S����o�WWh���V~Un�'A���P��prX�@ ���Q�]�]�'��e�m`.��N0�����P�N��=S�c2�tp`�P�s"=M?��k)st7�Dwy�*�N��/c�`u/�=� �����8�Քӫ���"�:1��KF���� ������u9��=� d�� ȧX�]��c`�����R��۲���5=���LB�e�����z@j��Ū��o�\��6���V;*�I?X:3bs*`{�����Z\�X,�z��^i�Y ;t��������d]�}�?F I?�|u�C�ZE='����o�Ӊ{2�6�zl$� v����գN+��Q��qh5��`���y�l��,Llr���ʹ~�ژ~�y���h�{��J})���Wu~���0=�>-����z[�h��CZ�5U�:oJ�
�����2 aӯi�?��ݦ�����EG��$��J�>��r����`�~@�A$�����C=���K=�S �NfQ� �Š�<ڹx���]����9� gp�� H���|�ϳ�H}�$��b9�]��wB�3���RMV=��� 5�Qƍ������ӻg��s2i}��:� N��� v�Lx����[��C�5��c�*�+v�e��`�����u�r:�����cu�����k�.��>}0�f{+���a.�T�S�㦺"M���x�5��hyk\dr@�mvI����]�n|p�� �|Q�Տ=��,ߓV�mN 4v����[e �t,k��n�+~����#i�#O-B��:[o����X�jt��7�qN�[K�DQ����^=�O���<��^c4cݶ��X�U��^����B��<#ED��`�
���Ce��2���X����@���?%.��]��!�Ii���#_�V��R�Z͌;v�{ձ�Q�k#�%�x�S_���WT��Mo>�������ʹ>�x086{�H����6��0�/ ��tڞ9����5�Q�JgoH���ѱ��'hi���}_�`$]�n��&r����-cIsu'�e?���l�qsk��/sxk[��t�Y�솖���2�����F`���6��#�m�ZUt,F�c뺋�L2dž�k햖,̌\��X�����$�-5D.�#V����*sM� �$� 9:v\����;\�Z}\��h��e���!��Ѵ*��1������ĎZd�� ��v�*���K�pil"u�ַ��Zˇ�����:X�2,q� Y�k3�i�C��6Dޑ��@��U��m��K�Ə�����q�1ε�� ���^� �d�$�s�>+s��� D��\&uG���5�ili�Dm������̰���X�O�ޥ��w��S� s�۬��ly-���K�y�go���ԟ���EA�s�s�H�怊�;umd�XLbSW.��/k5��'��zm����p���k�+�vb�I ����i�RM�̺�8ӵ�$ cI��
lhy�E�k[;Z�A?�
�xts��hS�0����D�����k]Uo�n�O`�n�>�a��K"Ǽ0:&�9#����m� �o���n�><|Ѩ��?k��an���H�a�v�> ճ�}D���~��G�c������� ���:�̋=1��ă���yr�B̼���f��-����L����F8q�eT*;�TE�u4QhEh�8���,����v����5�;�U^�m��������m� �a���b��X.��?��1� /�
���}�Ο��\�����?�� ̐\���K��.��ީ�|KetSq(�ȷ�V��R=:�io��O���U�����M?�%�}X�����;�ɹ� �N������"�V����$#ȹ�R������ %ruu즾̬v�o���]!���Dh���y��n�ތ�_��^�x���z�&�S�w��65�'��5� |
|H�-48I�U����?�Y/mY�-y��e�> �]�Oa+���7٫�B���,���.�+�c�n���H�I��):-|��WP�o^���q�1�� ��f-�V�ј:��r����Uޠ�6��jg|�����O⦄�5�H[^.}�uo���\m�Ҫ#�J�f�Pn$;�~YA�3{�}�z�T�6g�� w�DF�\|4_�Lr���r��ۧQ�8y>�-5�\i�)��Wq�HL-1�E��r9���6���ʘ�<�N�e�$���8���Rl��˕1����9��F�M��u>��uU��;k���R���9��Sm���dʨ�f�;k��!���u܊��k�5�U�A D��i>0BgϷv�>���������B�-�q�l�>azEl�[G��\�LoV?�����;�� �{��% ���\�V����Dv��HE��r1z�Xج�`$��F��X]j�t��Uf0����h����~��u_���D��>G��&��U��r�`�s�\�c���}>�����=^��v�cwk.ԏ)�Dv��- �w����ӻ$��EۨddΎ���� �O�*��gtf>�<������� yL:����IK��p���3���0G�*�Y��@������I'O���)8�Up�x��K�
z�� �7���o�ڋ����7�q���q���������v��N���}��o�ŏ�_��?��Uؗݏf;�͖rv:g@?}e�a���9�4ƿ���Jϣ�.߸����W���z�]���d$ǂΑ���F���N�G��8�N�_WQȰ��U��<