NFC Enable 过程分析(三)

这篇文章用来分析NFC学习——NFC Enable 过程分析(一)中setp3-2:开启一些循环监听的线程服务。处理方法enableDisable().

code路径:packages/apps/nfc/src/com/android/nfc/P2pLinkManager.java,具体看enableDisable()中的处理code:

[html] view plain copy
  1. publicvoidenableDisable(booleansendEnable,booleanreceiveEnable){
  2. synchronized(this){
  3. if(!mIsReceiveEnabled&&receiveEnable){
  4. //setp1:启动SnepServer
  5. mDefaultSnepServer.start();
  6. //setp2:启动NdefPushServer
  7. mNdefPushServer.start();
  8. if(mEchoServer!=null){
  9. //setp3:启动EchoServer
  10. mHandler.sendEmptyMessage(MSG_START_ECHOSERVER);
  11. }
  12. }
  13. }
  14. }
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 plain copy
  1. publicvoidrun(){
  2. ........
  3. while(threadRunning){
  4. synchronized(SnepServer.this){
  5. //setp1-1:创建一个服务器端Socket连接
  6. mServerSocket=NfcService.getInstance().createLlcpServerSocket(mServiceSap,
  7. mServiceName,MIU,1,1024);
  8. }
  9. ......
  10. //接收Socket请求
  11. LlcpSocketcommunicationSocket=serverSocket.accept();
  12. if(communicationSocket!=null){
  13. //setp1-2:miu是什么,如何获取来的
  14. intmiu=communicationSocket.getRemoteMiu();
  15. intfragmentLength=(mFragmentLength==-1)?
  16. miu:Math.min(miu,mFragmentLength);
  17. //setp1-3:启动线程处理SnepMessenger
  18. newConnectionThread(communicationSocket,fragmentLength).start();
  19. }
  20. ......
  21. }
  22. }

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 plain copy
  1. staticjobjectcom_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv*e,jobjecto,
  2. jintnSap,jstringsn,jintmiu,jintrw,jintlinearBufferLength)
  3. {
  4. ......
  5. /*Createsocket*/
  6. /*setp1-1-1:函数在external/libnfc-nxp/src/phLibNfc.h声明,具体的函数作用,函数参数含义请查看代码中注释,&hLlcpSocket即是创建成功的Sokect的指针*/
  7. ret=phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
  8. &sOptions,
  9. &sWorkingBuffer,
  10. &hLlcpSocket,
  11. nfc_jni_llcp_transport_socket_err_callback,
  12. (void*)nat);
  13. ......
  14. /*CreatenewNativeLlcpServiceSocketobject,到此出现了我们分析到目前的mServerSocket的创建,返回的serviceSocket就是*/
  15. if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeLlcpServiceSocket",&(serviceSocket))==-1)
  16. {
  17. ALOGE("LlcpSocketobjectcreationerror");
  18. gotoerror;
  19. }
  20. ......
  21. returnserviceSocket;
  22. }

附上一张思路图,就清晰点


Setp1-2:miu如何得来的,看下面分析图


看到这张图,可能只是对函数的调用过程有个清晰的了解,但是miu到底是如何获取到的呢??这次我们从函数的调用最后来分析,即phFriNfc_LlcpTransport_Connection.c这个文件的函数。

[html] view plain copy
  1. NFCSTATUSphFriNfc_LlcpTransport_ConnectionOriented_SocketGetRemoteOptions(
  2. phFriNfc_LlcpTransport_Socket_t*pLlcpSocket,
  3. phLibNfc_Llcp_sSocketOptions_t*psRemoteOptions)
  4. {
  5. NFCSTATUSstatus=NFCSTATUS_SUCCESS;
  6. /*GetRemoteMIUX*/
  7. psRemoteOptions->miu=pLlcpSocket->remoteMIU;
  8. /*GetRemoteReceiveWindow*/
  9. psRemoteOptions->rw=pLlcpSocket->remoteRW;
  10. returnstatus;
  11. }
上面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 plain copy
  1. staticbooleanhandleRequest(SnepMessengermessenger,Callbackcallback)throwsIOException{
  2. SnepMessagerequest;
  3. ......
  4. //从SnepMessenger中取出SnepMessage
  5. request=messenger.getMessage();
  6. if(((request.getVersion()&0xF0)>>4)!=SnepMessage.VERSION_MAJOR){
  7. messenger.sendMessage(SnepMessage.getMessage(
  8. SnepMessage.RESPONSE_UNSUPPORTED_VERSION));
  9. }elseif(request.getField()==SnepMessage.REQUEST_GET){
  10. /*发送SnepMessage,SnepMessage来源于CallBack的实现,sendMessage把SnepMessage转换成byte[]通过LlcpSocketsocket发送数据*/
  11. messenger.sendMessage(callback.doGet(request.getAcceptableLength(),
  12. request.getNdefMessage()));
  13. }elseif(request.getField()==SnepMessage.REQUEST_PUT){
  14. if(DBG)Log.d(TAG,"puttingmessage"+request.toString());
  15. //发送SnepMessage,SnepMessage来源于Callback的实现
  16. messenger.sendMessage(callback.doPut(request.getNdefMessage()));
  17. }else{
  18. if(DBG)Log.d(TAG,"Unknownrequest("+request.getField()+")");
  19. messenger.sendMessage(SnepMessage.getMessage(
  20. SnepMessage.RESPONSE_BAD_REQUEST));
  21. }
  22. returntrue;
  23. }
上面code涉及到CallBack一个回调接口,它实现在P2pLinkManager.java中

[html] view plain copy
  1. finalSnepServer.CallbackmDefaultSnepCallback=newSnepServer.Callback(){
  2. @Override
  3. publicSnepMessagedoPut(NdefMessagemsg){
  4. /*该方法中有个EventLogTags.writeNfcNdefReceived的调用,我始终没找到它的具体方法实现在哪儿*/
  5. onReceiveComplete(msg);
  6. returnSnepMessage.getMessage(SnepMessage.RESPONSE_SUCCESS);
  7. }
  8. @Override
  9. publicSnepMessagedoGet(intacceptableLength,NdefMessagemsg){
  10. NdefMessageresponse=mHandoverManager.tryHandoverRequest(msg);
  11. if(response!=null){
  12. onReceiveHandover();
  13. returnSnepMessage.getSuccessResponse(response);
  14. }else{
  15. returnSnepMessage.getMessage(SnepMessage.RESPONSE_NOT_FOUND);
  16. }
  17. }
  18. };

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是什么东西,故不做翻译了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值