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

📄 bthid.cxx

📁 CE下串口复用程序
💻 CXX
📖 第 1 页 / 共 5 页
字号:
//
//	Hid parser interface
//
//
//	Parser interface
//
int HidDevice::SetIdle(unsigned char bIdle) {
    // Initialize the packets
    BTHHIDPacket requestPacket;
    requestPacket.SetHeader(BTHID_SET_IDLE << 4);
    requestPacket.SetPayload(&bIdle, sizeof(bIdle));

	return WriteControlPacket (this, &requestPacket, BTH_WIRE_TIMEOUT, NULL);
}

int HidDevice::SetProtocol(E_BTHID_PROTOCOLS protocol) {
    // Initialize the packets
    BTHHIDPacket requestPacket;
    BTHID_Header_Parameter param;

    // Initialize the packets
    param.bRawHeader = 0;
    param.setprotocol_p.bProtocol = protocol;
    requestPacket.SetHeader((BTHID_SET_PROTOCOL << 4) | param.bRawHeader);

	return WriteControlPacket (this, &requestPacket, BTH_WIRE_TIMEOUT, NULL);
}

int HidDevice::SetReport(E_BTHID_REPORT_TYPES type, PCHAR pBuffer, int cbBuffer, int iTimeout) {
    // Initialize the packets
    BTHHIDPacket requestPacket;
    BTHID_Header_Parameter SetReport_param;

    // Initialize the packets
    SetReport_param.bRawHeader = 0;
    SetReport_param.setreport_p.bReportType = type;

    // Start by sending BTHIDSetReport_Request down the pipe.
    requestPacket.SetHeader((BTHID_SET_REPORT << 4) | SetReport_param.bRawHeader);
    requestPacket.SetPayload((PBYTE) pBuffer, cbBuffer);

	return WriteControlPacket (this, &requestPacket, iTimeout, NULL);
}

int HidDevice::GetReport(int iReportID, E_BTHID_REPORT_TYPES type, PCHAR pBuffer, int cbBuffer, PDWORD pcbTransfered, int iTimeout) {
    // Initialize the packets
    BTHHIDPacket requestPacket;
    BTHID_Header_Parameter GetReport_param;

    // Initialize the packets
    GetReport_param.bRawHeader = 0;
    GetReport_param.getreport_p.bReportType = type;
    GetReport_param.getreport_p.bSize = 0;

    // Start by sending BTHIDGetReport_Request down the pipe.
    requestPacket.SetHeader((BTHID_GET_REPORT << 4) | GetReport_param.bRawHeader);

	BTHHIDPacket *pPacket = NULL;
	int iErr = WriteControlPacket (this, &requestPacket, iTimeout, &pPacket);

	if (iErr == ERROR_SUCCESS) {
        // Check if the request succeeded
        BYTE bHeader = pPacket->GetHeader();
        if ((bHeader >> 4) == BTHID_DATA) {
	        // Request succeeded, get the payload to the caller
	        BYTE *pPacketPayload;
		    int   cbPacketPayload;

			pPacket->GetPayload(&pPacketPayload, &cbPacketPayload);
			if (cbBuffer >= cbPacketPayload) {
				memcpy(pBuffer, pPacketPayload, cbPacketPayload);
	            *pcbTransfered = cbPacketPayload;
			} else
				iErr = ERROR_INSUFFICIENT_BUFFER;
		} else
			iErr = ERROR_INVALID_DATA;

		pPacket->ReleasePayload ();
		delete pPacket;
	}

	return iErr;
}

//
// Main API section
//
static int HIDConnect (BT_ADDR *pbt) {
	BD_ADDR *pba = (BD_ADDR *)pbt;

	if (! gpState)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpState->Lock ();
	if (! gpState->fIsRunning) {
		gpState->Unlock ();

		return ERROR_SERVICE_NOT_ACTIVE;
	}

	HidDevice *pDev = FindDevice (pba);

	if (! pDev)
		pDev = MakeNewDevice (pba, FALSE);

	if (pDev && pDev->ckDeviceTimeout) {
		gpState->pSchedule->UnScheduleEvent (pDev->ckDeviceTimeout);
		pDev->ckDeviceTimeout = 0;
	}

	gpState->Unlock ();

	if (! pDev)
		return ERROR_CONNECTION_REFUSED;

	unsigned short cidControl = 0;
	int iRes = HIDConnect_Int (pba, BTH_PSM_CONTROL, &cidControl);
	if (iRes != ERROR_SUCCESS)
		return iRes;

	unsigned short cidInterrupt = 0;
	iRes = HIDConnect_Int (pba, BTH_PSM_INTERRUPT, &cidInterrupt);
	if (iRes != ERROR_SUCCESS) {
		HIDCloseCID_Int (cidControl);
		return iRes;
	}

	return ERROR_SUCCESS;
}

static int HIDVerify (unsigned char *ucSDP, unsigned int cSDP) {
	if (! gpState)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpState->Lock ();
	if (! gpState->fIsRunning) {
		gpState->Unlock ();

		return ERROR_SERVICE_NOT_ACTIVE;
	}

	BTHHIDSdpParser sdpParser;

    int iErr = sdpParser.Start (ucSDP, cSDP);

	BOOL bb = FALSE;

    if (iErr == ERROR_SUCCESS)
	    iErr = sdpParser.GetHIDReconnectInitiate(&bb);

    if (iErr == ERROR_SUCCESS)
		iErr = sdpParser.GetHIDNormallyConnectable(&bb);

    if (iErr == ERROR_SUCCESS)
		iErr = sdpParser.GetHIDVirtualCable(&bb);

    // Pass in an empty structure to retrieve the size of the blob
    BLOB blobReportDescriptor = {0, NULL};

    if (iErr == ERROR_SUCCESS)
	    iErr = sdpParser.GetHIDReportDescriptor(&blobReportDescriptor);

	if (iErr == ERROR_SUCCESS) {
	    // Now we have the size. Allocate and requery.
	    SVSUTIL_ASSERT(blobReportDescriptor.cbSize > 0);
		blobReportDescriptor.pBlobData = (unsigned char *)g_funcAlloc (blobReportDescriptor.cbSize, g_pvAllocData);
		iErr = sdpParser.GetHIDReportDescriptor(&blobReportDescriptor);

		if (iErr == ERROR_SUCCESS)
			g_funcFree (blobReportDescriptor.pBlobData, g_pvFreeData);
	}

	sdpParser.End ();

	if (iErr != ERROR_SUCCESS) {
		IFDBG(DebugOut (DEBUG_LAYER_TRACE, L"BTH HID: HIDVerify - parsing SDP record failed\n"));
	} else {
		IFDBG(DebugOut (DEBUG_LAYER_TRACE, L"BTH HID: HIDVerify - successfully parsed SDP record\n"));
	}

	gpState->Unlock ();

	return iErr;
}

//
//	Marshaling code
//
#define TASK_CONNECT	1
#define TASK_VERIFY		2

struct Task {
	unsigned int what;

	union {
		struct {
			BT_ADDR b;
		} Connect;

		struct {
			unsigned int cSDP;
			unsigned char ucSDP[1];
		} Verify;
	};
};

static DWORD WINAPI ExecThread (LPVOID lpTask) {
	Task *pTask = (Task *)lpTask;

	DWORD dwError = ERROR_CALL_NOT_IMPLEMENTED;

	if (pTask->what == TASK_CONNECT)
		dwError = HIDConnect (&pTask->Connect.b);
	else if (pTask->what == TASK_VERIFY)
		dwError = HIDVerify (pTask->Verify.ucSDP, pTask->Verify.cSDP);

	return dwError;
}

static int Exec (Task *pTask) {
	HANDLE hThread = CreateThread (NULL, 0, ExecThread, pTask, 0, NULL);
	if (! hThread)
		return GetLastError ();

	WaitForSingleObject (hThread, INFINITE);
	DWORD dwCode;

	if (! GetExitCodeThread (hThread, &dwCode))
		dwCode = GetLastError ();

	CloseHandle (hThread);
	return dwCode;
}

#if defined (UNDER_CE)
//
//	Driver service funcs...
//
extern "C" BOOL WINAPI DllMain( HANDLE hInstDll, DWORD fdwReason, LPVOID lpvReserved) {
	switch(fdwReason) {
		case DLL_PROCESS_ATTACH:
			DisableThreadLibraryCalls ((HMODULE)hInstDll);
			svsutil_Initialize ();
			break;

		case DLL_PROCESS_DETACH:
			svsutil_DeInitialize ();
			break;
	}
	return TRUE;
}

#if defined (SDK_BUILD)
HANDLE OpenEvent (DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSTR lpName) {
	return CreateEvent (NULL, TRUE, FALSE, lpName);
}
#endif

static DWORD WINAPI StackInitialize (LPVOID lpUnused) {
	for (int i = 0 ; i < 100 ; ++i) {
		HANDLE hBthStackInited = OpenEvent (EVENT_ALL_ACCESS, FALSE, BTH_NAMEDEVENT_STACK_INITED);

		if (hBthStackInited) {
			DWORD dwRes = WaitForSingleObject (hBthStackInited, INFINITE);
			CloseHandle (hBthStackInited);
			if (WAIT_OBJECT_0 == dwRes)
				return hiddev_CreateDriverInstance ();
		}

		Sleep (1000);
	}

	return ERROR_TIMEOUT;
}

//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//		EXECUTION THREAD: Client-application!
//			These functions are only executed on the caller's thread
// 			i.e. the thread belongs to the client application
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//	@func PVOID | BHI_Init | Device initialization routine
//  @parm DWORD | dwInfo | Info passed to RegisterDevice
//  @rdesc	Returns a DWORD which will be passed to Open & Deinit or NULL if
//			unable to initialize the device.
//	@remark	Routine exported by a device driver.  "PRF" is the string passed
//			in as lpszType in RegisterDevice
extern "C" DWORD BHI_Init (DWORD Index) {
	DebugInit();

	HANDLE hBthStackInited = OpenEvent (EVENT_ALL_ACCESS, FALSE, BTH_NAMEDEVENT_STACK_INITED);
	if (hBthStackInited) {
		DWORD dwRes = WaitForSingleObject (hBthStackInited, 0);
		CloseHandle (hBthStackInited);
		if (WAIT_OBJECT_0 == dwRes)
			return (DWORD)(hiddev_CreateDriverInstance () == ERROR_SUCCESS);
	}

	CloseHandle (CreateThread (NULL, 0, StackInitialize, NULL, 0, NULL));

	return TRUE;
}

//	@func PVOID | BHI_Deinit | Device deinitialization routine
//  @parm DWORD | dwData | value returned from BHI_Init call
//  @rdesc	Returns TRUE for success, FALSE for failure.
//	@remark	Routine exported by a device driver.  "PRF" is the string
//			passed in as lpszType in RegisterDevice
extern "C" BOOL BHI_Deinit(DWORD dwData) {
	hiddev_CloseDriverInstance ();

	DebugDeInit();

	return TRUE;
}

//	@func PVOID | BHI_Open		| Device open routine
//  @parm DWORD | dwData		| value returned from BHI_Init call
//  @parm DWORD | dwAccess		| requested access (combination of GENERIC_READ
//								  and GENERIC_WRITE)
//  @parm DWORD | dwShareMode	| requested share mode (combination of
//								  FILE_SHARE_READ and FILE_SHARE_WRITE)
//  @rdesc	Returns a DWORD which will be passed to Read, Write, etc or NULL if
//			unable to open device.
//	@remark	Routine exported by a device driver.  "PRF" is the string passed
//			in as lpszType in RegisterDevice
extern "C" DWORD BHI_Open (DWORD dwData, DWORD dwAccess, DWORD dwShareMode) {
	HANDLE *ph = (HANDLE *)g_funcAlloc (sizeof(HANDLE), g_pvAllocData);

	ph[0] = NULL;

	return (DWORD)ph;
}

//	@func BOOL | BHI_Close | Device close routine
//  @parm DWORD | dwOpenData | value returned from BHI_Open call
//  @rdesc	Returns TRUE for success, FALSE for failure
//	@remark	Routine exported by a device driver.  "PRF" is the string passed
//			in as lpszType in RegisterDevice
extern "C" BOOL BHI_Close (DWORD dwData)  {
	HANDLE *ph = (HANDLE *)dwData;

	if (ph && ph[0])
		ProcessExited (ph[0]);

	if (ph)
		g_funcFree (ph, g_pvFreeData);

	return TRUE;
}

//	@func DWORD | BHI_Write | Device write routine
//  @parm DWORD | dwOpenData | value returned from BHI_Open call
//  @parm LPCVOID | pBuf | buffer containing data
//  @parm DWORD | len | maximum length to write [IN BYTES, NOT WORDS!!!]
//  @rdesc	Returns -1 for error, otherwise the number of bytes written.  The
//			length returned is guaranteed to be the length requested unless an
//			error condition occurs.
//	@remark	Routine exported by a device driver.  "PRF" is the string passed
//			in as lpszType in RegisterDevice
//
extern "C" DWORD BHI_Write (DWORD dwData, LPCVOID pInBuf, DWORD dwInLen) {
	return -1;
}

//	@func DWORD | BHI_Read | Device read routine
//  @parm DWORD | dwOpenData | value returned from BHI_Open call
//  @parm LPVOID | pBuf | buffer to receive data
//  @parm DWORD | len | maximum length to read [IN BYTES, not WORDS!!]
//  @rdesc	Returns 0 for end of file, -1 for error, otherwise the number of
//			bytes read.  The length returned is guaranteed to be the length
//			requested unless end of file or an error condition occurs.
//	@remark	Routine exported by a device driver.  "PRF" is the string passed
//			in as lpszType in RegisterDevice
//
extern "C" DWORD BHI_Read (DWORD dwData, LPVOID pBuf, DWORD Len) {
	return -1;
}

//	@func DWORD | BHI_Seek | Device seek routine
//  @parm DWORD | dwOpenData | value returned from BHI_Open call
//  @parm long | pos | position to seek to (relative to type)
//  @parm DWORD | type | FILE_BEGIN, FILE_CURRENT, or FILE_END
//  @rdesc	Returns current position relative to start of file, or -1 on error
//	@remark	Routine exported by a device driver.  "PRF" is the string passed
//		 in as lpszType in RegisterDevice

extern "C" DWORD BHI_Seek (DWORD dwData, long pos, DWORD type) {
	return (DWORD)-1;
}

//	@func void | BHI_PowerUp | Device powerup routine
//	@comm	Called to restore device from suspend mode.  You cannot call any
//			routines aside from those in your dll in this call.
extern "C" void BHI_PowerUp (void) {
	return;
}
//	@func void | BHI_PowerDown | Device powerdown routine
//	@comm	Called to suspend device.  You cannot call any routines aside from
//			those in your dll in this call.
extern "C" void BHI_PowerDown (void) {
	return;
}

//	@func BOOL | BHI_IOControl | Device IO control routine
//  @parm DWORD | dwOpenData | value returned from BHI_Open call
//  @parm DWORD | dwCode | io control code to be performed
//  @parm PBYTE | pBufIn | input data to the device
//  @parm DWORD | dwLenIn | number of bytes being passed in
//  @parm PBYTE | pBufOut | output data from the device
//  @parm DWORD | dwLenOut |maximum number of bytes to receive from device
//  @parm PDWORD | pdwActualOut | actual number of bytes received from device
//  @rdesc	Returns TRUE for success, FALSE for failure
//	@remark	Routine exported by a device driver.  "PRF" is the string passed
//		in as lpszType in RegisterDevice
extern "C" BOOL BHI_IOControl(DWORD dwData, DWORD dwCode, PBYTE pBufIn,
			  DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
			  PDWORD pdwActualOut)
{
#if ! defined (SDK_BUILD)
	if (dwCode == IOCTL_PSL_NOTIFY) {
		PDEVICE_PSL_NOTIFY pPslPacket = (PDEVICE_PSL_NOTIFY)pBufIn;
		if ((pPslPacket->dwSize == sizeof(DEVICE_PSL_NOTIFY)) && (pPslPacket->dwFlags == DLL_PROCESS_EXITING)){
			SVSUTIL_ASSERT (*(HANDLE *)dwData == pPslPacket->hProc);
			ProcessExited ((HANDLE)pPslPacket->hProc);
		}

		return TRUE;
	}
#endif

	HANDLE *ph = (HANDLE *)dwData;
	SVSUTIL_ASSERT (ph);

	if (! ph[0])
		ph[0] = GetCallerProcess ();

	SVSUTIL_ASSERT (ph[0] == GetCallerProcess());

	int iError = ERROR_SUCCESS;

	switch (dwCode) {
    case BTHHID_IOCTL_HIDConnect:
		if (dwLenIn == sizeof(BT_ADDR)) {
			Task *pTask = (Task *)LocalAlloc (LMEM_FIXED, sizeof(Task));
			if (pTask) {
				pTask->what = TASK_CONNECT;
				memcpy (&pTask->Connect.b, pBufIn, sizeof(pTask->Connect.b));
				iError = Exec(pTask);
				LocalFree (pTask);
			} else
				iError = ERROR_OUTOFMEMORY;
		} else
			iError = ERROR_INVALID_PARAMETER;
		break;

	case BTHHID_IOCTL_HIDVerify:
		if (dwLenIn > 0) {
			Task *pTask = (Task *)LocalAlloc (LMEM_FIXED, sizeof(Task) + dwLenIn);
			if (pTask) {
				pTask->what = TASK_VERIFY;
				memcpy (pTask->Verify.ucSDP, pBufIn, dwLenIn);
				pTask->Verify.cSDP = dwLenIn;
				iError = Exec(pTask);
				LocalFree (pTask);
			} else
				iError = ERROR_OUTOFMEMORY;
		} else
			iError = ERROR_INVALID_PARAMETER;
		break;

	default:
		IFDBG(DebugOut (DEBUG_WARN, L"Unknown control code %d\n", dwCode));
		iError = ERROR_CALL_NOT_IMPLEMENTED;
	}

	if (iError != ERROR_SUCCESS) {
		SetLastError(iError);
		return FALSE;
	}

	return TRUE;
}

#if defined(UNDER_CE) && CE_MAJOR_VER < 0x0003
extern "C" int _isctype(int c, int mask) {
	if ((c < 0) || (c > 0xff))
		return 0;
	return iswctype((wchar_t)c,(wctype_t)mask);
}
#endif //defined(UNDER_CE) && CE_MAJOR_VER < 0x0003

#endif	// UNDER_CE

⌨️ 快捷键说明

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