⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bthsco.cxx

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 CXX
📖 第 1 页 / 共 5 页
字号:
    }

    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: Stack Is Down\n"));

    gpLayerState->Unlock ();
    return ERROR_SUCCESS;
}

static DWORD WINAPI StackUp (LPVOID lpVoid) 
{
	if (! gpLayerState) {
		return ERROR_SERVICE_NOT_ACTIVE;
	}
	
    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: Stack Up received :: UP\n"));

	// gpLayerState may be disconnecting, in which case StackDown does not need 
	// to do anything.
	if(WaitForSingleObject(gpLayerState->hClosingEvent, 0) != WAIT_TIMEOUT) {
		return 0;
	}

    StackInitDevice();

    gpLayerState->Lock ();
    if ((! gpLayerState->fIsRunning) || gpLayerState->fConnected) {
        IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: Stack Up received :: already up\n"));
        gpLayerState->Unlock ();

        return ERROR_SERVICE_NOT_ACTIVE;
    }

    gpLayerState->fConnected = TRUE;
    gpLayerState->Unlock ();

    StackNotifyUser(BTH_STACK_UP);

    return ERROR_SUCCESS;
}

//////////////////////////////////////////////////////////////////
//  Callbacks
//////////////////////////////////////////////////////////////////

static int sco_CallAborted_Out (void *pCallContext, int iError) 
{
    if (! gpLayerState)
        return ERROR_SERVICE_NOT_ACTIVE;

    gpLayerState->Lock ();

    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: Call Aborted :: call 0x%08x, error %d\n", pCallContext, iError));

    if (! gpLayerState->fIsRunning) {
        IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: Call Aborted :: system shutdown\n"));
        gpLayerState->Unlock ();
        return ERROR_SERVICE_NOT_ACTIVE;
    }

    Call *pCall = CallVerify ((Call*)pCallContext, 0);
    if (! pCall) {
        IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: Call Aborted :: call not found\n"));
        gpLayerState->Unlock ();
        return ERROR_NOT_FOUND;
    }

    CallRemove (pCall);
    CallSignal (pCall, iError);

    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: Call Abort :: aborted call 0x%08x type %d\n", pCall, pCall->fCallType));

    gpLayerState->Unlock ();

    return ERROR_SUCCESS;
}

static int sco_FinishVoidCall(void *pCallContext, unsigned char status, unsigned char fCallType)
{
	if (! gpLayerState) {
		return ERROR_SERVICE_NOT_ACTIVE;
	}
	
    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_FinishVoidCall call 0x%08x, status 0x%02x, type %d\n", pCallContext, status, fCallType));

    int iResult = StatusToError (status, ERROR_INTERNAL_ERROR);

    if (status != 0) {
        return sco_CallAborted_Out (pCallContext, iResult);
    }

    gpLayerState->Lock();

    if (!gpLayerState->fIsRunning || !gpLayerState->fConnected) {
        IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_FinishVoidCall call 0x%08x :: system shutdown\n", pCallContext));
        gpLayerState->Unlock();
        return ERROR_SERVICE_NOT_ACTIVE;
    }

    Call *pCall = CallVerify((Call*)pCallContext, fCallType);
    if (!pCall) {
        IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_FinishVoidCall call 0x%08x :: call not found\n", pCallContext));
        gpLayerState->Unlock();
        return ERROR_NOT_FOUND;
    }

    CallRemove (pCall);
    CallSignal (pCall, iResult);

    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_FinishVoidCall call 0x%08x :: completed call\n", pCallContext));

    gpLayerState->Unlock ();

    return ERROR_SUCCESS;
}

static int sco_Disconnect_Out (void *pCallContext, unsigned char status) 
{
	if (! gpLayerState) {
		return ERROR_SERVICE_NOT_ACTIVE;
	}
	
    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: Disconnect_Out :: call 0x%08x, status 0x%02x\n", pCallContext, status));

    if (status != 0) {
        return sco_CallAborted_Out (pCallContext, StatusToError (status, ERROR_INTERNAL_ERROR));
    }

    return ERROR_SUCCESS;
}

static int sco_AcceptConnectionRequest_Out (void *pCallContext, unsigned char status)
{
	if (! gpLayerState) {
		return ERROR_SERVICE_NOT_ACTIVE;
	}
	
    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_AcceptConnectionRequest_Out :: call 0x%08x, status 0x%02x\n", pCallContext, status));

    if (status != 0) {
        return sco_CallAborted_Out (pCallContext, StatusToError (status, ERROR_INTERNAL_ERROR));
    }

    return ERROR_SUCCESS;
}

static int sco_AddSCOConnection_Out (void *pCallContext, unsigned char status) 
{
	if (! gpLayerState) {
		return ERROR_SERVICE_NOT_ACTIVE;
	}
	
    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_AddSCOConnection_Out :: call 0x%08x, status 0x%02x\n", pCallContext, status));

    if (status != 0) {
        return sco_CallAborted_Out (pCallContext, StatusToError (status, ERROR_INTERNAL_ERROR));
    }

    return ERROR_SUCCESS;
}

static int sco_WriteSCOFlowControlEnable_Out (void *pCallContext, unsigned char status)
{
	if (! gpLayerState) {
		return ERROR_SERVICE_NOT_ACTIVE;
	}
	
    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_WriteSCOFlowControlEnable_Out :: call 0x%08x, status 0x%02x\n", pCallContext, status));

    return sco_FinishVoidCall(pCallContext, status, CALL_TYPE_WRITE_SCO_FLOW_CONTROL);
}

static int sco_DataPacketDown_Out (void *pCallContext, int iError) 
{
	if (! gpLayerState) {
		return ERROR_SERVICE_NOT_ACTIVE;
	}
	
    IFDBG(DebugOut (DEBUG_DATA_PACKET_DOWN, L"SCO :: sco_DataPacketDown_Out :: call 0x%08x, error %d\n", pCallContext, iError));

    gpLayerState->Lock();

    if (!gpLayerState->fIsRunning || !gpLayerState->fConnected) {
        IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_DataPacketDown_Out :: system shutdown\n"));
        gpLayerState->Unlock();
        return ERROR_SERVICE_NOT_ACTIVE;
    }

    // find the call
    Call *pCall = CallVerify((Call*)pCallContext, 0);
    if (!pCall) {
        IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_DataPacketDown_Out :: call not found\n"));
        gpLayerState->Unlock();
        return ERROR_NOT_FOUND;
    }

    if (pCall->fCallType == CALL_TYPE_DATA_PACKET_DOWN) {
        void  *pUserData          = gpLayerState->pUserData;
        void  *pPacketUserContext = pCall->uParameters.DataPacketDown.pPacketUserContext;
        USHORT hConnection        = pCall->uParameters.DataPacketDown.hConnection;

        CallRemove (pCall);
        CallSignal (pCall, iError);

        SCO_CALLBACK_DataPacketDown pCallBack = gpLayerState->sco_callbacks.DataPacketDown;
        if (pCallBack) {

            int iRes = ERROR_INTERNAL_ERROR;

            gpLayerState->AddRef ();
            IFDBG(DebugOut (DEBUG_DATA_PACKET_DOWN, L"SCO :: sco_DataPacketDown_Out :: going into callback\n"));
            gpLayerState->Unlock ();

            __try {
                iRes = pCallBack (pUserData, pPacketUserContext, hConnection, (DWORD)iError);
            } __except (1) {
                IFDBG(DebugOut (DEBUG_ERROR, L"SCO :: sco_DataPacketDown_Out :: exception in callback\n"));
            }

            gpLayerState->Lock  ();
            IFDBG(DebugOut (DEBUG_DATA_PACKET_DOWN, L"SCO :: sco_DataPacketDown_Out :: came from callback\n"));
            gpLayerState->DelRef ();

            if (!(gpLayerState->fIsRunning && gpLayerState->fConnected)) {
                IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_DataPacketDown_Out :: ERROR_SHUTDOWN_IN_PROGRESS\n"));
                gpLayerState->Unlock();
                return ERROR_SHUTDOWN_IN_PROGRESS;
            }
        }

    } else if (pCall->fCallType == CALL_TYPE_WRITE_PACKET) {

        CallRemove (pCall);
        CallSignal (pCall, iError);

    } else {
        IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_DataPacketDown_Out :: call not found\n"));
        gpLayerState->Unlock();
        return ERROR_NOT_FOUND;
    }


    IFDBG(DebugOut (DEBUG_DATA_PACKET_DOWN, L"SCO :: sco_DataPacketDown_Out :: Completed call 0x%08x\n", pCall));

    gpLayerState->Unlock ();

    return ERROR_SUCCESS;
}

static int sco_WriteVoiceSetting_Out (void *pCallContext, unsigned char status)
{
	if (! gpLayerState) {
		return ERROR_SERVICE_NOT_ACTIVE;
	}
	
    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_WriteVoiceSetting_Out :: call 0x%08x, status 0x%02x\n", pCallContext, status));

    return sco_FinishVoidCall(pCallContext, status, CALL_TYPE_WRITE_VOICE_SETTING);
}

static int sco_ReadVoiceSetting_Out (void *pCallContext, unsigned char status, unsigned short voice_channel_setting)
{
	if (! gpLayerState) {
		return ERROR_SERVICE_NOT_ACTIVE;
	}
	
    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_ReadVoiceSetting_Out :: call 0x%08x, status 0x%02x\n", pCallContext, status));

    int iResult = StatusToError (status, ERROR_INTERNAL_ERROR);

    if (status != 0) {
        return sco_CallAborted_Out (pCallContext, iResult);
    }

    gpLayerState->Lock();

    if (!gpLayerState->fIsRunning || !gpLayerState->fConnected) {
        IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_ReadVoiceSetting_Out :: system shutdown\n"));
        gpLayerState->Unlock();
        return ERROR_SERVICE_NOT_ACTIVE;
    }

    Call *pCall = CallVerify((Call*)pCallContext, CALL_TYPE_READ_VOICE_SETTING);
    if (!pCall) {
        IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_ReadVoiceSetting_Out :: call not found\n"));
        gpLayerState->Unlock();
        return ERROR_NOT_FOUND;
    }

    CallRemove (pCall);
    pCall->uParameters.ReadVoiceSetting.Setting.usSetting = voice_channel_setting;
    CallSignal (pCall, iResult);

    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_ReadVoiceSetting_Out :: Completed call 0x%08x\n", pCall));

    gpLayerState->Unlock ();

    return ERROR_SUCCESS;
}

static int sco_ReadSCOFlowControlEnable_Out (void *pCallContext, unsigned char status, unsigned char SCO_flow_control_enable)
{
	if (! gpLayerState) {
		return ERROR_SERVICE_NOT_ACTIVE;
	}
	
    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_ReadSCOFlowControlEnable_Out :: call 0x%08x, status 0x%02x enabled=%d\n",
        pCallContext, status, SCO_flow_control_enable));

    int iResult = StatusToError (status, ERROR_INTERNAL_ERROR);

    if (status != 0) {
        return sco_CallAborted_Out (pCallContext, iResult);
    }

    gpLayerState->Lock();

    if (!gpLayerState->fIsRunning || !gpLayerState->fConnected) {
        IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_ReadSCOFlowControlEnable_Out :: system shutdown\n"));
        gpLayerState->Unlock();
        return ERROR_SERVICE_NOT_ACTIVE;
    }

    Call *pCall = CallVerify((Call*)pCallContext, CALL_TYPE_READ_SCO_FLOW_CONTROL);
    if (!pCall) {
        IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_ReadSCOFlowControlEnable_Out :: call not found\n"));
        gpLayerState->Unlock();
        return ERROR_NOT_FOUND;
    }

    CallRemove (pCall);
    pCall->uParameters.ReadScoFlowControl.bEnabled = SCO_flow_control_enable;
    CallSignal (pCall, iResult);

    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_ReadSCOFlowControlEnable_Out :: Completed call 0x%08x\n", pCall));

    gpLayerState->Unlock ();

    return ERROR_SUCCESS;
}

//////////////////////////////////////////////////////////////////
//  Events
//////////////////////////////////////////////////////////////////

static int sco_Stack_Event (void *pUserContext, int iEvent, void *pEventContext)
{
	if (! gpLayerState) {
		return ERROR_SERVICE_NOT_ACTIVE;
	}

    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: Stack EVENT :: %s\n", iEvent == BTH_STACK_DISCONNECT ? L"BTH_STACK_DISCONNECT" : (iEvent == BTH_STACK_DOWN ? L"BTH_STACK_DOWN" : (iEvent == BTH_STACK_UP ? L"UP" : L"Unknown"))));

    if (iEvent == BTH_STACK_DISCONNECT)
        CloseHandle (CreateThread (NULL, 0, StackDisconnect, NULL, 0, NULL));
    else if (iEvent == BTH_STACK_DOWN)
        CloseHandle (CreateThread (NULL, 0, StackDown, NULL, 0, NULL));
    else if (iEvent == BTH_STACK_UP)
        CloseHandle (CreateThread (NULL, 0, StackUp, NULL, 0, NULL));

    return ERROR_SUCCESS;
}

static int sco_ConnectionComplete_Event(void            *pUserContext, 
                                        void            *pCallContext, 
                                        unsigned char   status, 
                                        unsigned short  connection_handle, 
                                        BD_ADDR         *pba, 
                                        unsigned char   link_type, 
                                        unsigned char   encryption_mode)
{
	if (! gpLayerState) {
		return ERROR_SERVICE_NOT_ACTIVE;
	}
	
    IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_ConnectionComplete_Event :: call=%#x status=%#x handle=%#x pba=%04x%08x link=%d, encrypt=%d\n", 
        pCallContext, status, connection_handle, pba->NAP, pba->SAP, link_type, encryption_mode));

    SVSUTIL_ASSERT (link_type == BT_LINK_TYPE_SCO);

    gpLayerState->Lock ();

    if (! gpLayerState->fIsRunning) {
        IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_ConnectionComplete_Event :: shutting down\n"));
        gpLayerState->Unlock ();
        return ERROR_SERVICE_NOT_ACTIVE;
    }

    Call *pCall = CallVerify ((Call*)pCallContext, 0);
    if (!pCall) {
        IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_ConnectionComplete_Event :: no context\n"));
        gpLayerState->Unlock ();
        return ERROR_NOT_FOUND;
    }
    if (    (pCall->fCallType != CALL_TYPE_CONNECT)
        &&  (pCall->fCallType != CALL_TYPE_ACCEPT_INCOMING_CONNECTION)) {
        IFDBG(DebugOut (DEBUG_SCO_TRACE, L"SCO :: sco_ConnectionComplete_Event :: no context\n"));
        gpLayerState->Unlock ();
        return ERROR_NOT_FOUND;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -