`
jgsj
  • 浏览: 963113 次
文章分类
社区版块
存档分类
最新评论

Android Phone模块 三

 
阅读更多

RIL


public RIL(Context context, int preferredNetworkType, int cdmaSubscription,int phoneId) {
	super(context);
	mCdmaSubscription = cdmaSubscription;
	mPreferredNetworkType = preferredNetworkType;
	mPhoneType = RILConstants.NO_PHONE;

	mPhoneId = phoneId;
	if (mPhoneId != PhoneFactory.DEFAULT_PHONE_ID) {
		SOCKET_NAME_RIL = SOCKET_NAME_RIL + phoneId;
	}
	PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
	mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
	mWakeLock.setReferenceCounted(false);
	mWakeLockTimeout = SystemProperties.getInt(TelephonyProperties.PROPERTY_WAKE_LOCK_TIMEOUT,DEFAULT_WAKE_LOCK_TIMEOUT);
	mRequestMessagesPending = 0;
	mRequestMessagesWaiting = 0;
	//创建ril发送线程
	mSenderThread = new HandlerThread("RILSender");
	mSenderThread.start();
	Looper looper = mSenderThread.getLooper();
	mSender = new RILSender(looper);

	ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
	if (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false) {
		riljLog("Not starting RILReceiver: wifi-only");
	} else {
		riljLog("Starting RILReceiver");
		//创建接收线程
		mReceiver = new RILReceiver();
		mReceiverThread = new Thread(mReceiver, "RILReceiver");
		mReceiverThread.start();
		IntentFilter filter = new IntentFilter();
		filter.addAction(Intent.ACTION_SCREEN_ON);
		filter.addAction(Intent.ACTION_SCREEN_OFF);
		context.registerReceiver(mIntentReceiver, filter);
	}
}
RIL线程模型:

RILSender

当上层需要向rild服务发送请求时,通过RIL的send函数来完成。
public void handleMessage(Message msg) {
	RILRequest rr = (RILRequest) (msg.obj);
	RILRequest req = null;
	switch (msg.what) {
	case EVENT_SEND:
		boolean alreadySubtracted = false;
		try {
			LocalSocket s;
			s = mSocket;
			if (s == null) {
				rr.onError(RADIO_NOT_AVAILABLE, null);
				rr.release();
				if (mRequestMessagesPending > 0)
					mRequestMessagesPending--;
				alreadySubtracted = true;
				return;
			}
			synchronized (mRequestsList) {
				mRequestsList.add(rr);
				mRequestMessagesWaiting++;
			}
			if (mRequestMessagesPending > 0)
				mRequestMessagesPending--;
			alreadySubtracted = true;
			byte[] data;
			data = rr.mp.marshall();
			rr.mp.recycle();
			rr.mp = null;
			if (data.length > RIL_MAX_COMMAND_BYTES) {
				throw new RuntimeException("Parcel larger than max bytes allowed! "+ data.length);
			}
			// parcel length in big endian
			dataLength[0] = dataLength[1] = 0;
			dataLength[2] = (byte) ((data.length >> 8) & 0xff);
			dataLength[3] = (byte) ((data.length) & 0xff);
			s.getOutputStream().write(dataLength);
			s.getOutputStream().write(data);
		} catch (IOException ex) {
			Log.e(LOG_TAG, "IOException", ex);
			req = findAndRemoveRequestFromList(rr.mSerial);
			if (req != null || !alreadySubtracted) {
				rr.onError(RADIO_NOT_AVAILABLE, null);
				rr.release();
			}
		} catch (RuntimeException exc) {
			Log.e(LOG_TAG, "Uncaught exception ", exc);
			req = findAndRemoveRequestFromList(rr.mSerial);
			if (req != null || !alreadySubtracted) {
				rr.onError(GENERIC_FAILURE, null);
				rr.release();
			}
		} finally {
			releaseWakeLockIfDone();
		}
		if (!alreadySubtracted && mRequestMessagesPending > 0) {
			mRequestMessagesPending--;
		}
		break;

	case EVENT_WAKE_LOCK_TIMEOUT:
		synchronized (mWakeLock) {
			if (mWakeLock.isHeld()) {
				if (mRequestMessagesWaiting != 0) {
					mRequestMessagesWaiting = 0;
				}
				if (mRequestMessagesPending != 0) {
					mRequestMessagesPending = 0;
				}
				mWakeLock.release();
			}
		}
		break;
	}
}

写入rild套接字的数据为:


发送步骤:

1.生成RILRequest,此时将生成m_Serial(请求的Token)并将请求号,数据,及其Result Message 对象填入到RILRequest中

2.使用send将RILRequest打包到EVENT_SEND消息中发送到到RIL Sender Handler

3.RilSender 接收到EVENT_SEND消息,将RILRequest通过套接口发送到RILD,同时将RILRequest保存在mRequest中以便应答消息的返回。

RILReceiver


public void run() {
	int retryCount = 0;
	try {
		for (;;) {
			LocalSocket s = null;
			LocalSocketAddress l;
			try {
				//创建socket并连接到rild
				s = new LocalSocket();
				l = new LocalSocketAddress(SOCKET_NAME_RIL,LocalSocketAddress.Namespace.RESERVED);
				s.connect(l);
			} catch (IOException ex) {
				try {
					if (s != null) {
						s.close();
					}
				} catch (IOException ex2) {
					// ignore failure to close after failure to connect
				}
				if (retryCount == 8) {
					Log.e(LOG_TAG, "Couldn't find '" + SOCKET_NAME_RIL
							+ "' socket after " + retryCount
							+ " times, continuing to retry silently");
				} else if (retryCount > 0 && retryCount < 8) {
					Log.i(LOG_TAG, "Couldn't find '" + SOCKET_NAME_RIL
							+ "' socket; retrying after timeout");
				}
				try {
					Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
				} catch (InterruptedException er) {
				}
				retryCount++;
				continue;
			}
			retryCount = 0;
			mSocket = s;
			Log.i(LOG_TAG, "Connected to '" + SOCKET_NAME_RIL + "' socket");
			int length = 0;
			try {
				InputStream is = mSocket.getInputStream();
				//循环从socket中读取消息
				for (;;) {
					Parcel p;
					length = readRilMessage(is, buffer);
					if (length < 0) {
						break;
					}
					p = Parcel.obtain();
					p.unmarshall(buffer, 0, length);
					p.setDataPosition(0);
					processResponse(p);
					p.recycle();
				}
			} catch (java.io.IOException ex) {
				Log.i(LOG_TAG, "'" + SOCKET_NAME_RIL + "' socket closed",ex);
			} catch (Throwable tr) {
				Log.e(LOG_TAG, "Uncaught exception read length=" + length+ "Exception:" + tr.toString());
			}
			//socket连接断开,请求所有请求并重新连接
			Log.i(LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL+ "' socket");
			setRadioState(RadioState.RADIO_UNAVAILABLE);
			try {
				mSocket.close();
			} catch (IOException ex) {
			}
			mSocket = null;
			RILRequest.resetSerial();
			clearRequestsList(RADIO_NOT_AVAILABLE, false);
		}
	} catch (Throwable tr) {
		Log.e(LOG_TAG, "Uncaught exception", tr);
	}
	notifyRegistrantsRilConnectionChanged(-1);
}

接收步骤

1.分析接收到的Parcel,根据类型不同进行处理。

2.根据数据中的Token(mSerail),反查mRequest,找到对应的请求信息。

3.将是接收到的数据转换成结果数据。

4.将结果放在RequestMessage中发回到请求的发起者。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics