蓝牙文件接收的过程

来源:互联网 发布:c语言小项目 编辑:程序博客网 时间:2024/04/28 11:50
接收文件流程:

1.     蓝牙开启后,蓝牙状态即是 BluetoothAdapter.STATE_ON

2.     BluetoothOppService Receiver接收到BluetoothAdapter.STATE_ON后,启动startSocketListener()

void BtoppServiceBroadcastReceiver::onReceive(const sp<Context>& context, const sp<Intent>& intent) {
    GLOGENTRY();
    sp<BluetoothOppService> mspbtoppser = mwpbtoppserice.promote();
    CHECK_NULL_POINTER_RETURN(mspbtoppser);

    sp<String> action = intent->getAction();

    if (action->equals(BluetoothAdapter::ACTION_STATE_CHANGED())) {
        switch (intent->getIntExtra(BluetoothAdapter::EXTRA_STATE(), BluetoothAdapter::ERROR)) {
            case BluetoothAdapter::STATE_ON:
                GLOGI("Receiver BLUETOOTH_STATE_CHANGED_ACTION, BLUETOOTH_STATE_ON");
                mspbtoppser->startSocketListener();
                break;
            case BluetoothAdapter::STATE_TURNING_OFF:
                GLOGI("Receiver DISABLED_ACTION");
                mspbtoppser->mSocketListener->stop();
                mspbtoppser->mListenStarted = false;
                {
                    RecursiveMutex::Autolock _l(mspbtoppser->mBluetoothOppServiceMutex);
                    if (mspbtoppser->mUpdateThread == NULL) {
                        mspbtoppser->stopSelf();
                    }
                }
                break;
        }
    }
}

3.     mSocketListener.start(mHandler) 里通过handler发送一个MSG_INCOMING_BTOPP_CONNECTION消息

void BluetoothOppService::startSocketListener() {
    GLOGENTRY();
    GLOGI("start RfcommListener");
    mSocketListener->start(mHandler);
    GLOGV("RfcommListener started");
}

bool BluetoothOppRfcommListener::start(const sp<Handler>& callback) {
    GLOGENTRY();
    if (mSocketAcceptThread == NULL) {
        mCallback = callback;

        mSocketAcceptThread = new BTORFCLThread(this);
        mInterrupted = false;
        if (!Constants::USE_TCP_SIMPLE_SERVER) {
            mSocketAcceptThread->run("BtOppRfcommListener");
        }
    }
    return true;
}

bool BTORFCLThread::threadLoop() {
    GLOGENTRY();
    sp<BluetoothOppRfcommListener> spbtorfcl = mwpbtorfcl.promote();
    if (spbtorfcl == NULL) {
        LOGE("spbtorfcl is NULL");
        return false;
    }

..............
        }
        GLOGV("TCP listen thread finished");
    } else {
        bool serverOK = true;
        GLOGI("Create BtServerSocket");
        /*
         * it's possible that create will fail in some cases.
         * retry for 10 times
         */
        for (int32_t i = 0; i < BluetoothOppRfcommListener::CREATE_RETRY_TIME && !spbtorfcl->mInterrupted; i++) {
            GLOGD("BTORFCLThread::threadLoop() i = %d", i);
            spbtorfcl->mBtServerSocket = spbtorfcl->mAdapter->listenUsingInsecureRfcommOn(spbtorfcl->mBtOppRfcommChannel);
            if (spbtorfcl->mBtServerSocket == NULL) {
                LOGE("Error create RfcommServerSocket");
                serverOK = false;
            }

            if (!serverOK) {
                {
                    RecursiveMutex::Autolock _l(spbtorfcl->mBluetoothOppRfcommListenerMutex);
                    GLOGI("wait 3 seconds");
                    // TODO TODO TODO
                    // check
                    Thread::milliSleep(3000);
                }
            } else {
                break;
            }
        }
        if (!serverOK) {
            LOGE("Error start listening after %d try", BluetoothOppRfcommListener::CREATE_RETRY_TIME);
            spbtorfcl->mInterrupted = true;
        }
        if (!spbtorfcl->mInterrupted) {
            GLOGI("Accept thread started on channel %d", spbtorfcl->mBtOppRfcommChannel);
        }
        sp<BluetoothSocket> clientSocket = NULL;
        while (!spbtorfcl->mInterrupted) {
            GLOGI("BTORFCLThread::threadLoop() while loop");
            clientSocket = spbtorfcl->mBtServerSocket->accept();
            if (clientSocket != NULL) {
                sp<BluetoothDevice> btdevice = clientSocket->getRemoteDevice();
                GLOGI("Accepted connectoin from %s", SP_TOSTRING_STR(btdevice));
                sp<BluetoothOppRfcommTransport> transport = new BluetoothOppRfcommTransport(clientSocket);
                sp<Message> msg = Message::obtain();
                msg->setTarget(spbtorfcl->mCallback);
                msg->what = BluetoothOppRfcommListener::MSG_INCOMING_BTOPP_CONNECTION;
                msg->obj = transport;
                msg->sendToTarget();
            } else  {
                LOGE("Error accept connection");
                return false;
            }
        }
        GLOGI("BluetoothSocket listen thread finished");
    }

    return false;
}


4.     这个消息在BluetoothOppServicehandler处理后创建一个  createServerSession(transport);

void BtoppServiceHandler::handleMessage(const sp<Message>& msg) {
    GLOGENTRY();
    GLOGI("BtoppServiceHandler::handleMessage, msg->what %d", msg->what);
    sp<BluetoothOppService> mspbtoppser = mwpbtoppserice.promote();
    CHECK_NULL_POINTER_RETURN(mspbtoppser);

    switch (msg->what) {
        ..................................
        }
        case BluetoothOppRfcommListener::MSG_INCOMING_BTOPP_CONNECTION:
        {
            GLOGI("Get incoming connection");
            sp<ObexTransport> transport = safe_cast<ObexTransport*>(msg->obj);
            /*
             * Strategy for incoming connections:
             * 1. If there is no ongoing transfer, no on-hold connection, start it
             * 2. If there is ongoing transfer, hold it for 20 seconds(1 seconds * 20 times)
             * 3. If there is on-hold connection, reject directly
             */
            if (mspbtoppser->mBatchs->size() == 0 && mspbtoppser->mPendingConnection == NULL) {
                GLOGI("Start Obex Server");
                mspbtoppser->createServerSession(transport);
            } else {
                if (mspbtoppser->mPendingConnection != NULL) {
                    GLOGW("OPP busy! Reject connection");
                    // try {
                        transport->close();
                    // } catch(IOException e) {
                    //    LOGE("close tranport error");
                    // }
                } else if (Constants::USE_TCP_DEBUG && !Constants::USE_TCP_SIMPLE_SERVER) {
                    GLOGI("Start Obex Server in TCP DEBUG mode");
                    mspbtoppser->createServerSession(transport);
                } else {
                    GLOGI("OPP busy! Retry after 1 second");
                    mspbtoppser->mIncomingRetries = mspbtoppser->mIncomingRetries + 1;
                    mspbtoppser->mPendingConnection = transport;
                    sp<Message> msg1 = Message::obtain(mspbtoppser->mHandler);
                    msg1->what = BluetoothOppService::MSG_INCOMING_CONNECTION_RETRY;
                    mspbtoppser->mHandler->sendMessageDelayed(msg1, 1000);
                }
            }
            break;
        }

5.     createServerSession   mServerSession.preStart(),进而new obexSesstion,接收文件

void BluetoothOppService::createServerSession(const sp<ObexTransport>& transport) {
    GLOGENTRY();
    mServerSession = new BluetoothOppObexServerSession(this, transport);
    GLOGD("BluetoothOppService:: BluetoothOppObexServerSession count %d", getStrongCount());
    mServerSession->preStart();
    GLOGI("Get ServerSession %s for incoming connection %s", mServerSession->toString()->string(), transport->toString()->string());
}

void BluetoothOppObexServerSession::preStart() {
    GLOGENTRY();
    GLOGI("BluetoothOppObexServerSession preStart");
    GLOGD("acquire full WakeLock");
    if (!mWakeLock->isHeld()) {
        GLOGD("acquire in");
        mWakeLock->acquire();
    }

    GLOGI("Create ServerSession with transport %s", SP_TOSTRING_STR(mTransport));
    sp<Authenticator> auth = NULL;
    mSession = new ServerSession(mTransport, this, auth);
    if (mSession == NULL) {
        LOGE("Create server session error");
    }

}

OPP接收文件进度的更新:

BluetoothOppService.java里调用mNotifier.updateNotification(),通过Handlder来实现没100ms来更新一次UI,更新UI是另起的一个线程

NotificationUpdateThread,在该线程里更新进度updateActiveNotification

0 0
原创粉丝点击