Android通过蓝牙模拟串口与BC05通信


BC05端:

编译环境是CSR的ADK1.1, 里面有例程, 有关模拟串口的有RFCOMM和SPP, 还不太清楚二者的区别

例程SPP有点问题, 编译可以通过, 但在链接时会找不到变量: 

ld: Undefined symbols:

$_sppGetServiceHandle

$_sppStoreServiceHandle

需要在ADK1.1下加入SPP的fix文件, 并重新编译库.

spp_server作用是把RF收到的数据转到实际的UART, 并把UART中收到的数据连接到RF.
TODO: 如何在程序中直接处理收到的RF数据, 而不是把数据转到UART交给其他MCU处理?
PS: 处理 UART sink 可以利用MessageSinkTask()将UART中断交给自己的handler处理, MessageSend()id值是MESSAGE_MORE_DATA(0x8000+33), 用同样的方法可以成功将RF sink 与handler绑定, 但把data强制转换成(MessageMoreData*)后, SourceMap()会失败, 因此需要搞清楚CSR底层有没有对这种情况提供可行的方案.

使用MessageSinkTak()可以实现

使用rfcomm_echo_server/rfcomm_echo_client这两个例程烧录到开发板上, 可以实现两个BC05的模拟串口通信: client端将数据发送给server, server收到后再原封不动发还给client, client需要通过上位机软件来实现发送和接收.
server一直在运行等待连接, client搜索不到一分钟后超时.

工程中的.led文件, 可以在编译时自动生成.c.h文件(如果编译选项改变了的话), 用来配置灯的状态.
工程中的.button文件, 可以在编译时自动生成.c.h文件(如果编译选项改变了的话), 用来配置按键.

主要用到的API: 
MessagePioTask()
PioDebounce32()
StreamConnect()
MessageSinkTask()


SPP_SERVER中 ConnectionInit()即把task和connection事件连接在一起, 这样在调用loop()以后, 底层会马上抛出CL_INIT_CFM和SPP_START_SERVICE_CFM这两个case, 可以在task中作相应处理或者忽略. 
真正开始spp server功能的其实是ConnectionWriteScanEnable()和SppStartService()这两个函数, 可以根据自己实际情况调用, 不一定非在CL_INIT_CFM case中, 调用后底层会抛出一系列连接请求case, 所以task中一定要有SPP_STOP_SERVICE_CFM, SPP_CONNECT_IND, SPP_SERVICE_CONNECT_CFM等case并处理连接请求. 





Android端:

BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
此处的蓝牙地址字符串address中, 如果有英文的话, 要大写.


private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");


btSocket = btDevice.createRfcommSocketToServiceRecord(MY_UUID);
btSocket.connect() maybe failed, replace it with getClass().getMethod() invoke()


synchronized 方法:
  声明是为了定义变量的作用范围和作用域
  通过在方法声明中加入 synchronized关键字来声明 synchronized 方法。如:
  public synchronized void accessVal(int newVal);
  synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。
  在 Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized ,以控制其对类的静态成员变量的访问。
  synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类的方法 run() 声明为 synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何 synchronized 方法的调用都永远不会成功。当然我们可以通过将访问类成员变量的代码放到专门的方法中,将其声明为 synchronized ,并在主方法中调用来解决这一问题,但是 Java 为我们提供了更好的解决办法,那就是 synchronized 块。




BUG list:

SPP server 端要stop SPP server service 时, 如果曾经成功连接过android client, SPP_STOP_SERVICE_CFM会报错: app_stop_sdp_unreg_fail, 出现一次不能复现;

第一次连接时, 配对成功后不能连接成功. 

如果手机端删除了server的配对信息, 再运行程序时将不能再次连接. 


spp server android第一次连接时的打印信息:

android发起连接:

spp_server.c                  328       CL_DM_ACL_OPENED_IND :- 0

spp_server.c                  273       CL_SM_REMOTE_IO_CAPABILITY_IND

spp_server.c                  282          Remote Addr: nap f8db uap 7f lap 006e3f47

spp_server.c                  291       CL_SM_IO_CAPABILITY_REQ_IND

spp_server.c                  362       Unhandled Message: 20483, 0x5003


android允许配对, 连接失败:

spp_server.c                  346       CL_SM_AUTHENTICATE_CFM :-

spp_server.c                  353          Remote Addr: nap f8db uap 7f lap 006e3f47

spp_server.c                  354          Status: 0

spp_server.c                  355          Key type 3

spp_server.c                  356          Bonded 1

spp_server.c                  310       CL_SM_AUTHORISE_IND :-

spp_server.c                  311           protocol_id: 0

spp_server.c                  312           channel: 3

spp_server.c                  313           incoming: 1

spp_server.c                  184       SPP_CONNECT_IND

spp_server.c                  310       CL_SM_AUTHORISE_IND :-

spp_server.c                  311           protocol_id: 0

spp_server.c                  312           channel: 1

spp_server.c                  313           incoming: 1

spp_server.c                  310       CL_SM_AUTHORISE_IND :-

spp_server.c                  311           protocol_id: 1

spp_server.c                  312           channel: 1

spp_server.c                  313           incoming: 1

spp_server.c                  310       CL_SM_AUTHORISE_IND :-

spp_server.c                  311           protocol_id: 0

spp_server.c                  312           channel: 1

spp_server.c                  313           incoming: 1

spp_server.c                  338       CL_RFCOMM_CONTROL_IND

spp_server.c                  205       SPP_SERVER_CONNECT_CFM_T :

spp_server.c                  211       Success

spp_server.c                  212       Memory Slots: 25

spp_server.c                  258       SPP_DISCONNECT_IND - status 1

spp_server.c                  259       The SPP Client disconnected!

spp_server.c                  310       CL_SM_AUTHORISE_IND :-

spp_server.c                  311           protocol_id: 0

spp_server.c                  312           channel: 1

spp_server.c                  313           incoming: 1

spp_server.c                  333       CL_DM_ACL_CLOSED_IND :- 22


重启程序:

spp_server.c                  328       CL_DM_ACL_OPENED_IND :- 0

spp_server.c                  362       Unhandled Message: 20483, 0x5003

spp_server.c                  310       CL_SM_AUTHORISE_IND :-

spp_server.c                  311           protocol_id: 0

spp_server.c                  312           channel: 3

spp_server.c                  313           incoming: 1

spp_server.c                  184       SPP_CONNECT_IND

spp_server.c                  310       CL_SM_AUTHORISE_IND :-

spp_server.c                  311           protocol_id: 1

spp_server.c                  312           channel: 1

spp_server.c                  313           incoming: 1

spp_server.c                  338       CL_RFCOMM_CONTROL_IND

spp_server.c                  205       SPP_SERVER_CONNECT_CFM_T :

spp_server.c                  211       Success

spp_server.c                  212       Memory Slots: 25



你可能感兴趣的:(Android)