NFC学习——NFC Enable 过程分析(三)
2013-11-11 13:10
417 查看
这篇文章用来分析NFC学习——NFC Enable 过程分析(一) 中setp 3-2:开启一些循环监听的线程服务。处理方法enableDisable().
code路径:packages/apps/nfc/src/com/android/nfc/P2pLinkManager.java,具体看enableDisable()中的处理code:
[html] view
plaincopy
public void enableDisable(boolean sendEnable, boolean receiveEnable) {
synchronized (this) {
if (!mIsReceiveEnabled && receiveEnable) {
//setp1:启动SnepServer
mDefaultSnepServer.start();
//setp2:启动NdefPushServer
mNdefPushServer.start();
if (mEchoServer != null) {
//setp3:启动EchoServer
mHandler.sendEmptyMessage(MSG_START_ECHOSERVER);
}
}
}
}
Setp1:启动SnepServer,此Server的作用是接收NDEF消息,并把它推送给LLCP(Logical Link Control Protocol).启动SnepServer最后转到其内部类ServerThread去处理,ServerThread继承Thread,具体分析它的run方法。
code路径:packages/apps/nfc/src/com/android/nfc/snep/SnepServer.java
[html] view
plaincopy
public void run() {
........
while (threadRunning) {
synchronized (SnepServer.this) {
//setp1-1:创建一个服务器端Socket连接
mServerSocket = NfcService.getInstance().createLlcpServerSocket(mServiceSap,
mServiceName, MIU, 1, 1024);
}
......
//接收Socket请求
LlcpSocket communicationSocket = serverSocket.accept();
if (communicationSocket != null) {
//setp1-2:miu 是什么,如何获取来的
int miu = communicationSocket.getRemoteMiu();
int fragmentLength = (mFragmentLength == -1) ?
miu : Math.min(miu, mFragmentLength);
//setp1-3: 启动线程处理SnepMessenger
new ConnectionThread(communicationSocket, fragmentLength).start();
}
......
}
}
Setp1-1:创建服务器端mServerSocket中参数如下:
mServiceSap:socket 端口,默认是4;
mServiceName:从命名可以看出,它是socket名称
MIU:全称是Maximum information Unit ,LLCP中数据单元中消息最大的长度(不知道是不是按byte算的),
1:
1024:是buffer的长度,至于它的作用是什么,赞时还不知道。
mServerSocket的创建过程:通过NfcService调用createLlcpServerSocket(),而NfcService直接返回的DeviceHost.createLlcpServerSocket()的调用,DeviceHost仅仅只是一个接口,DeviceHost.createLlcpServerSocket()具体实现在NativeNfcManager.createLlcpServerSocket().NativeNfcManager则直接调用JNI方法com_android_nfc_NfcManager_doCreateLlcpServiceSocket()来实现其创建功能,其中的参数为了书写方便都省略了。
[html] view
plaincopy
static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, jobject o,
jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength)
{
......
/* Create socket */
/*setp1-1-1:函数在external/libnfc-nxp/src/phLibNfc.h声明,具体的函数作用,函数参数含义请查看代码中注释,&hLlcpSocket即是创建成功的Sokect的指针*/
ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
&sOptions,
&sWorkingBuffer,
&hLlcpSocket,
nfc_jni_llcp_transport_socket_err_callback,
(void*)nat);
......
/* Create new NativeLlcpServiceSocket object,到此出现了我们分析到目前的 mServerSocket的创建,返回的serviceSocket就是*/
if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeLlcpServiceSocket",&(serviceSocket)) == -1)
{
ALOGE("Llcp Socket object creation error");
goto error;
}
......
return serviceSocket;
}
附上一张思路图,就清晰点
Setp1-2:miu如何得来的,看下面分析图
看到这张图,可能只是对函数的调用过程有个清晰的了解,但是miu到底是如何获取到的呢??这次我们从函数的调用最后来分析,即phFriNfc_LlcpTransport_Connection.c这个文件的函数。
[html] view
plaincopy
NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_SocketGetRemoteOptions(
phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
phLibNfc_Llcp_sSocketOptions_t* psRemoteOptions)
{
NFCSTATUS status = NFCSTATUS_SUCCESS;
/* Get Remote MIUX */
psRemoteOptions->miu = pLlcpSocket->remoteMIU;
/* Get Remote Receive Window */
psRemoteOptions->rw = pLlcpSocket->remoteRW;
return status;
}
上面code可以发现phFriNfc_LlcpTransport_Socket_t 的remoteMIU 直接赋给phLibNfc_Llcp_sSocketOptions_t的miu.这就是我们要找的答案。phFriNfc_LlcpTransport_Socket_t 和phLibNfc_Llcp_sSocketOptions_t具体是什么就不做研究了。
setp1-3: 启动线程处理SnepMessenger,从新开启一个Thread处理SnepMessage,处理code 还是SnepServer.java
[html] view
plaincopy
static boolean handleRequest(SnepMessenger messenger, Callback callback) throws IOException {
SnepMessage request;
......
//从SnepMessenger中取出SnepMessage
request = messenger.getMessage();
if (((request.getVersion() & 0xF0) >> 4) != SnepMessage.VERSION_MAJOR) {
messenger.sendMessage(SnepMessage.getMessage(
SnepMessage.RESPONSE_UNSUPPORTED_VERSION));
} else if (request.getField() == SnepMessage.REQUEST_GET) {
/*发送SnepMessage,SnepMessage来源于CallBack的实现,sendMessage 把SnepMessage转换成byte[]通过LlcpSocket socket发送数据*/
messenger.sendMessage(callback.doGet(request.getAcceptableLength(),
request.getNdefMessage()));
} else if (request.getField() == SnepMessage.REQUEST_PUT) {
if (DBG) Log.d(TAG, "putting message " + request.toString());
//发送SnepMessage,SnepMessage来源于Callback的实现
messenger.sendMessage(callback.doPut(request.getNdefMessage()));
} else {
if (DBG) Log.d(TAG, "Unknown request (" + request.getField() +")");
messenger.sendMessage(SnepMessage.getMessage(
SnepMessage.RESPONSE_BAD_REQUEST));
}
return true;
}
上面code涉及到CallBack一个回调接口,它实现在P2pLinkManager.java中
[html] view
plaincopy
final SnepServer.Callback mDefaultSnepCallback = new SnepServer.Callback() {
@Override
public SnepMessage doPut(NdefMessage msg) {
/*该方法中有个EventLogTags.writeNfcNdefReceived 的调用,我始终没找到它的具体方法实现在哪儿*/
onReceiveComplete(msg);
return SnepMessage.getMessage(SnepMessage.RESPONSE_SUCCESS);
}
@Override
public SnepMessage doGet(int acceptableLength, NdefMessage msg) {
NdefMessage response = mHandoverManager.tryHandoverRequest(msg);
if (response != null) {
onReceiveHandover();
return SnepMessage.getSuccessResponse(response);
} else {
return SnepMessage.getMessage(SnepMessage.RESPONSE_NOT_FOUND);
}
}
};
setp2:启动NdefPushServer,setp3:启动EchoServer的过程和setp1:启动SnepServer过程类似,具体可以参照setp1,在此就不做详细分析。
以上分析中涉及到SnepServer,NdefPushServer,EchoServer。看下这三个文件中对自己的注释说明。。
SnepServer:A simple server that accepts NDEF messages pushed to it over an LLCP connection. Those messages are typically set on the client side by using NfcAdapter.enableForegroundNdefPush.通过LLCP接收NDEF 消息,并把消息通过NfcAdapter.enableForegroundNdefPush设置到客户端。
NdefPushServer:同SnepServer。
EchoServer:EchoServer is an implementation of the echo server that is used in the nfcpy LLCP test suite. Enabling the EchoServer allows to test Android NFC devices against nfcpy,这是code中给的注释说明,但不知到nfcpy是什么东西,故不做翻译了。
code路径:packages/apps/nfc/src/com/android/nfc/P2pLinkManager.java,具体看enableDisable()中的处理code:
[html] view
plaincopy
public void enableDisable(boolean sendEnable, boolean receiveEnable) {
synchronized (this) {
if (!mIsReceiveEnabled && receiveEnable) {
//setp1:启动SnepServer
mDefaultSnepServer.start();
//setp2:启动NdefPushServer
mNdefPushServer.start();
if (mEchoServer != null) {
//setp3:启动EchoServer
mHandler.sendEmptyMessage(MSG_START_ECHOSERVER);
}
}
}
}
Setp1:启动SnepServer,此Server的作用是接收NDEF消息,并把它推送给LLCP(Logical Link Control Protocol).启动SnepServer最后转到其内部类ServerThread去处理,ServerThread继承Thread,具体分析它的run方法。
code路径:packages/apps/nfc/src/com/android/nfc/snep/SnepServer.java
[html] view
plaincopy
public void run() {
........
while (threadRunning) {
synchronized (SnepServer.this) {
//setp1-1:创建一个服务器端Socket连接
mServerSocket = NfcService.getInstance().createLlcpServerSocket(mServiceSap,
mServiceName, MIU, 1, 1024);
}
......
//接收Socket请求
LlcpSocket communicationSocket = serverSocket.accept();
if (communicationSocket != null) {
//setp1-2:miu 是什么,如何获取来的
int miu = communicationSocket.getRemoteMiu();
int fragmentLength = (mFragmentLength == -1) ?
miu : Math.min(miu, mFragmentLength);
//setp1-3: 启动线程处理SnepMessenger
new ConnectionThread(communicationSocket, fragmentLength).start();
}
......
}
}
Setp1-1:创建服务器端mServerSocket中参数如下:
mServiceSap:socket 端口,默认是4;
mServiceName:从命名可以看出,它是socket名称
MIU:全称是Maximum information Unit ,LLCP中数据单元中消息最大的长度(不知道是不是按byte算的),
1:
1024:是buffer的长度,至于它的作用是什么,赞时还不知道。
mServerSocket的创建过程:通过NfcService调用createLlcpServerSocket(),而NfcService直接返回的DeviceHost.createLlcpServerSocket()的调用,DeviceHost仅仅只是一个接口,DeviceHost.createLlcpServerSocket()具体实现在NativeNfcManager.createLlcpServerSocket().NativeNfcManager则直接调用JNI方法com_android_nfc_NfcManager_doCreateLlcpServiceSocket()来实现其创建功能,其中的参数为了书写方便都省略了。
[html] view
plaincopy
static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, jobject o,
jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength)
{
......
/* Create socket */
/*setp1-1-1:函数在external/libnfc-nxp/src/phLibNfc.h声明,具体的函数作用,函数参数含义请查看代码中注释,&hLlcpSocket即是创建成功的Sokect的指针*/
ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
&sOptions,
&sWorkingBuffer,
&hLlcpSocket,
nfc_jni_llcp_transport_socket_err_callback,
(void*)nat);
......
/* Create new NativeLlcpServiceSocket object,到此出现了我们分析到目前的 mServerSocket的创建,返回的serviceSocket就是*/
if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeLlcpServiceSocket",&(serviceSocket)) == -1)
{
ALOGE("Llcp Socket object creation error");
goto error;
}
......
return serviceSocket;
}
附上一张思路图,就清晰点
Setp1-2:miu如何得来的,看下面分析图
看到这张图,可能只是对函数的调用过程有个清晰的了解,但是miu到底是如何获取到的呢??这次我们从函数的调用最后来分析,即phFriNfc_LlcpTransport_Connection.c这个文件的函数。
[html] view
plaincopy
NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_SocketGetRemoteOptions(
phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
phLibNfc_Llcp_sSocketOptions_t* psRemoteOptions)
{
NFCSTATUS status = NFCSTATUS_SUCCESS;
/* Get Remote MIUX */
psRemoteOptions->miu = pLlcpSocket->remoteMIU;
/* Get Remote Receive Window */
psRemoteOptions->rw = pLlcpSocket->remoteRW;
return status;
}
上面code可以发现phFriNfc_LlcpTransport_Socket_t 的remoteMIU 直接赋给phLibNfc_Llcp_sSocketOptions_t的miu.这就是我们要找的答案。phFriNfc_LlcpTransport_Socket_t 和phLibNfc_Llcp_sSocketOptions_t具体是什么就不做研究了。
setp1-3: 启动线程处理SnepMessenger,从新开启一个Thread处理SnepMessage,处理code 还是SnepServer.java
[html] view
plaincopy
static boolean handleRequest(SnepMessenger messenger, Callback callback) throws IOException {
SnepMessage request;
......
//从SnepMessenger中取出SnepMessage
request = messenger.getMessage();
if (((request.getVersion() & 0xF0) >> 4) != SnepMessage.VERSION_MAJOR) {
messenger.sendMessage(SnepMessage.getMessage(
SnepMessage.RESPONSE_UNSUPPORTED_VERSION));
} else if (request.getField() == SnepMessage.REQUEST_GET) {
/*发送SnepMessage,SnepMessage来源于CallBack的实现,sendMessage 把SnepMessage转换成byte[]通过LlcpSocket socket发送数据*/
messenger.sendMessage(callback.doGet(request.getAcceptableLength(),
request.getNdefMessage()));
} else if (request.getField() == SnepMessage.REQUEST_PUT) {
if (DBG) Log.d(TAG, "putting message " + request.toString());
//发送SnepMessage,SnepMessage来源于Callback的实现
messenger.sendMessage(callback.doPut(request.getNdefMessage()));
} else {
if (DBG) Log.d(TAG, "Unknown request (" + request.getField() +")");
messenger.sendMessage(SnepMessage.getMessage(
SnepMessage.RESPONSE_BAD_REQUEST));
}
return true;
}
上面code涉及到CallBack一个回调接口,它实现在P2pLinkManager.java中
[html] view
plaincopy
final SnepServer.Callback mDefaultSnepCallback = new SnepServer.Callback() {
@Override
public SnepMessage doPut(NdefMessage msg) {
/*该方法中有个EventLogTags.writeNfcNdefReceived 的调用,我始终没找到它的具体方法实现在哪儿*/
onReceiveComplete(msg);
return SnepMessage.getMessage(SnepMessage.RESPONSE_SUCCESS);
}
@Override
public SnepMessage doGet(int acceptableLength, NdefMessage msg) {
NdefMessage response = mHandoverManager.tryHandoverRequest(msg);
if (response != null) {
onReceiveHandover();
return SnepMessage.getSuccessResponse(response);
} else {
return SnepMessage.getMessage(SnepMessage.RESPONSE_NOT_FOUND);
}
}
};
setp2:启动NdefPushServer,setp3:启动EchoServer的过程和setp1:启动SnepServer过程类似,具体可以参照setp1,在此就不做详细分析。
以上分析中涉及到SnepServer,NdefPushServer,EchoServer。看下这三个文件中对自己的注释说明。。
SnepServer:A simple server that accepts NDEF messages pushed to it over an LLCP connection. Those messages are typically set on the client side by using NfcAdapter.enableForegroundNdefPush.通过LLCP接收NDEF 消息,并把消息通过NfcAdapter.enableForegroundNdefPush设置到客户端。
NdefPushServer:同SnepServer。
EchoServer:EchoServer is an implementation of the echo server that is used in the nfcpy LLCP test suite. Enabling the EchoServer allows to test Android NFC devices against nfcpy,这是code中给的注释说明,但不知到nfcpy是什么东西,故不做翻译了。
相关文章推荐
- NFC学习——NFC Enable 过程分析(一)
- NFC学习——NFC Enable 过程分析(一)
- NFC学习——NFC Enable 过程分析(二)
- NFC学习——NFC Enable 过程分析(三)
- NFC学习——NfcService 启动过程分析
- NFC学习——NFC Enable 过程分析(一)
- NFC学习——NfcService 启动过程分析
- LINUX内核分析第八周学习总结——进程的切换和系统的一般执行过程
- pspice学习笔记(7)--模拟电路分析计算基本过程
- vlc学习计划(5)--网络数据流接收处理过程分析
- spring源码学习之路---深度分析IOC容器初始化过程(四)
- vlc学习计划(7)--从接收到数据流到播放视频的过程分析
- BT源代码学习心得(十五):客户端源代码分析(下载过程中的块选取策略)
- MFC OnFileNew OnFileOpen过程分析代码(以记录MFC学习点滴)
- mfc学习之分析mfc程序执行过程
- 学习笔记4-项目的目录结构与安装及启动过程分析
- 8051 MCU学习之分析单片机的启动过程
- 05-S3C2440学习之内核(初步)编译、配置过程分析
- Netty学习6-ChanelHandler【2】调用过程源码分析
- WEB请求过程的深入学习(深入分析JavaWeb技术内幕,第一章读后总结和深入学习)