Cubietruck---28.android蓝牙分析6_初始化

1.分析一下初始化的过程
btif/src/btif_core.c
  1. btif_enable_bluetooth_evt
  2. {
  3.     /* initialize a2dp service */
  4.     btif_av_init();

  5.     /* init rfcomm & l2cap api */
  6.     btif_sock_init();

  7.     /* init pan */
  8.     btif_pan_init();

  9.     /* load did configuration */
  10.     bte_load_did_conf(BTE_DID_CONF_FILE);
  11. }


在btif/src/btif_sock.c中
  1. bt_status_t btif_sock_init()
  2. {
  3.     btsock_thread_init();   //初始化一些全局变量
  4.     btsock_thread_create(btsock_signaled, NULL);
  5.     btsock_rfc_init(handle);
  6.     return BT_STATUS_FAIL;
  7. }


在btif/src/btif_sock_thread.c中
  1. int btsock_thread_create(btsock_signaled_cb callback, btsock_cmd_cb cmd_callback)
  2. {
  3.     int ret = FALSE;
  4.     asrt(callback || cmd_callback);
  5.     lock_slot(&thread_slot_lock);
  6.     int h = alloc_thread_slot();
  7.     unlock_slot(&thread_slot_lock);
  8.     if(>= 0)
  9.     {
  10.         init_poll(h); //会调用init_cmd_fd中的socketpair创建读写的双通道
  11.         if((ts[h].thread_id = create_thread(sock_poll_thread, (void*)h)) != -1)  //创建线程
  12.         {
  13.             dbmsg("h:%d, thread id:%d", h, ts[h].thread_id);
  14.             ts[h].callback = callback;
  15.             ts[h].cmd_callback = cmd_callback;
  16.         }
  17.         else
  18.         {
  19.             free_thread_slot(h);
  20.             h = -1;
  21.         }
  22.     }
  23.     return h;
  24. }




2. listen的过程
2.1 jni层会首先获取协议栈中的socket_profile的接口
在/packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp中
  1. static bool initNative(JNIEnv* env, jobject obj) {
  2.     sBluetoothInterface->init(&sBluetoothCallbacks);  //首先获取bt协议栈库的接口
  3.     //然后调用协议栈的接口get_profile_interface,传入BT_PROFILE_SOCKETS_ID,就
  4.     sBluetoothSocketInterface = (btsock_interface_t *)sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID);
  5. }
在协议栈的btif/src/bluethooth.c中
  1. static const void* get_profile_interface (const char *profile_id)
  2. {
  3.     if (is_profile(profile_id, BT_PROFILE_SOCKETS_ID))
  4.         return btif_sock_get_interface();
  5. }
返回sock_if函数指针,所以这个sBluetoothSocketInterface就是socket_profile的接口
2.2 jni层会调用socket_profile的接口中的listen
在./packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp中
createSocketChannelNative中会调用
    sBluetoothSocketInterface->listen(...);  //这个sBluetoothSocketInterface就是socket_profile的接口
在协议栈btif/src/btif_sock.c中
  1. static bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
  2.         const uint8_t* service_uuid, int channel, int* sock_fd, int flags)
  3. {
  4.     //只支持RFCOMM
  5.     btsock_rfc_listen(service_name, service_uuid, channel, sock_fd, flags);        
  6. }
在协议栈btif/src/btif_rfc.c中
  1. bt_status_t btsock_rfc_listen(const char* service_name, const uint8_t* service_uuid, int channel,
  2.                             int* sock_fd, int flags)
  3. {
  4.     rfc_slot_t* rs = alloc_rfc_slot(NULL, service_name, service_uuid, channel, flags, TRUE);
  5.     BTA_JvCreateRecordByUser((void *)rs->id);
  6.     *sock_fd = rs->app_fd;    //将app_fd作为用户端监听
  7.     rs->app_fd = -1; //the fd ownership is transferred to app
  8.     status = BT_STATUS_SUCCESS;
  9.     btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_EXCEPTION, rs->id);
  10.     return status;
  11. }
最后的btsock_thread_add_fd 就是调用send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0)
向socketpair的fdw端写入命令
在btif/src/btif_sock_thread.c中
  1. int btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id)
  2. {
  3.     sock_cmd_t cmd = {CMD_ADD_FD, fd, type, flags, user_id};
  4.     return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd);
  5. }
2.3 在poll中的线程函数sock_poll_thread会收到这个事件并处理
  1. static void *sock_poll_thread(void *arg)
  2. {
  3.     struct pollfd pfds[MAX_POLL];
  4.     memset(pfds, 0, sizeof(pfds));
  5.     int h = (int)arg;
  6.     for(;;)
  7.     {
  8.         //线程每次都要prepare_poll_fds,把在add_poll中新增的需要poll的fd,添加到pollfd集合中来
  9.         prepare_poll_fds(h, pfds);        
  10.         poll(pfds, ts[h].poll_count, -1);  //此处的poll会返回,并继续向下执行
  11.         int need_process_data_fd = TRUE;
  12.         if(pfds[0].revents)  
  13.         {
  14.             process_cmd_sock(h);     //开始处理cmd             
  15.         }
  16.         if(need_process_data_fd)
  17.             process_data_sock(h, pfds, ret);
  18.     }
  19.     return 0;
  20. }
process_cmd_sock中会recv,此处的cmd=CMD_ADD_FD
在btif/src/btif_sock_thread.c中
  1. static int process_cmd_sock(int h)
  2. {
  3.     sock_cmd_t cmd = {-1, 0, 0, 0, 0};
  4.     int fd = ts[h].cmd_fdr;
  5.     recv(fd, &cmd, sizeof(cmd), MSG_WAITALL);  
  6.     switch(cmd.id)
  7.     {
  8.         case CMD_ADD_FD:
  9.             add_poll(h, cmd.fd, cmd.type, cmd.flags, cmd.user_id);
  10.             break;        
  11.     }
  12.     return TRUE;
  13. }
add_poll 的作用就是把cmd . fd 添加到pollfd集合中去,下次线程中的poll就去轮询这个cmd.fd了



3. connect的过程
在/packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp中
  1. static int connectSocketNative(JNIEnv *env, jobject object, jbyteArray address, jint type,
  2.                                    jbyteArray uuidObj, jint channel, jint flag) {
  3.     if (!sBluetoothSocketInterface) return NULL;
  4.     sBluetoothSocketInterface->connect((bt_bdaddr_t *) addr, (btsock_type_t) type, (const uint8_t*) uuid, channel, &socket_fd, flag);
  5. }
connect 在协议栈btif/src/btif_sock.c中
  1. static bt_status_t btsock_connect(const bt_bdaddr_t *bd_addr, btsock_type_t type,
  2.         const uint8_t* uuid, int channel, int* sock_fd, int flags)
  3. {
  4.     switch(type)
  5.     {
  6.         case BTSOCK_RFCOMM:
  7.             status = btsock_rfc_connect(bd_addr, uuid, channel, sock_fd, flags);
  8.             break;        
  9.     }
  10.     return status;
  11. }

在btif/src/btif_sock_rfc.c中
  1. bt_status_t btsock_rfc_connect(const bt_bdaddr_t *bd_addr, const uint8_t* service_uuid,
  2.         int channel, int* sock_fd, int flags)
  3. {
  4.     if(sock_fd == NULL || (service_uuid == NULL && (channel < 1 || channel > 30)))
  5.     {
  6.         dbmsg("invalid rfc channel:%d or sock_fd:%p, uuid:%p", channel, sock_fd,
  7.                           service_uuid);
  8.         return BT_STATUS_PARM_INVALID;
  9.     }
  10.     *sock_fd = -1;
  11.     if(!is_init_done())
  12.         return BT_STATUS_NOT_READY;
  13.     int status = BT_STATUS_FAIL;
  14.     lock_slot(&slot_lock);
  15.     rfc_slot_t* rs = alloc_rfc_slot(bd_addr, NULL, service_uuid, channel, flags, FALSE);
  16.     if(rs)
  17.     {
  18.         if(is_uuid_empty(service_uuid))
  19.         {
  20.             dbmsg("connecting to rfcomm channel:%d without service discovery", channel);
  21.             if(BTA_JvRfcommConnect(rs->security, rs->role, rs->scn, rs->addr.address,
  22.                         rfcomm_cback, (void*)rs->id) == BTA_JV_SUCCESS)
  23.             {
  24.                 if(send_app_scn(rs))
  25.                 {
  26.                     btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM,
  27.                                                         SOCK_THREAD_FD_RD, rs->id);
  28.                     *sock_fd = rs->app_fd;
  29.                     rs->app_fd = -1; //the fd ownership is transferred to app
  30.                     status = BT_STATUS_SUCCESS;
  31.                 }
  32.                 else cleanup_rfc_slot(rs);
  33.             }
  34.             else cleanup_rfc_slot(rs);
  35.         }
  36.         else
  37.         {
  38.             tSDP_UUID sdp_uuid;
  39.             sdp_uuid.len = 16;
  40.             memcpy(sdp_uuid.uu.uuid128, service_uuid, sizeof(sdp_uuid.uu.uuid128));
  41.             logu("service_uuid", service_uuid);
  42.             *sock_fd = rs->app_fd;
  43.             rs->app_fd = -1; //the fd ownership is transferred to app
  44.             status = BT_STATUS_SUCCESS;
  45.             rfc_slot_t* rs_doing_sdp = find_rfc_slot_requesting_sdp();
  46.             if(rs_doing_sdp == NULL)
  47.             {
  48.                 BTA_JvStartDiscovery((UINT8*)bd_addr->address, 1, &sdp_uuid, (void*)rs->id);
  49.                 rs->f.pending_sdp_request = FALSE;
  50.                 rs->f.doing_sdp_request = TRUE;
  51.             }
  52.             else
  53.             {
  54.                 rs->f.pending_sdp_request = TRUE;
  55.                 rs->f.doing_sdp_request = FALSE;
  56.             }
  57.             btsock_thread_add_fd(pth, rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD, rs->id);
  58.         }
  59.     }
  60.     unlock_slot(&slot_lock);
  61.     return status;
  62. }






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值