programming MSI pc2pc bluetooth key in Windows XP

Posted: 06-03-2004, 07:33 AM
Hi,

Here is a sample code, how to program MSI pc2pc bluetooth key in
Windows XP with C++. The main API constis of CommOpen, CommWrite and
CommClose. This sample is for specific bluetooth device, but here you
have idea what you need, for example using overlapping is a must in
our product, otherwise the software hangs when using WriteFile.

#include <windows.h>

#include <stdio.h>
#include "bl_port.h"
//TIMER_TIMEOUT in seconds
#define TIMER_TIMEOUT 3
#define RESPONSE_SIZE 1024
static BOOLEAN comm_runTimerThread = TRUE;
static BOOLEAN comm_timeOuted = FALSE;

static char comm_response[RESPONSE_SIZE];

static int comm_pos = 0;

FILE *comm_f;

void comm_debug(char*);
char comm_buf[256];
HANDLE handles[1];
BOOLEAN recRunning = TRUE;

OVERLAPPED overlapped2;
void notifySymbol(int group, int selection);
void attachThread();
void detachThread();

int NEAR ReadBlock( HANDLE hPort, LPSTR lpszBlock, int nMaxLength )
{
BOOL fReadStat ;
COMSTAT ComStat ;
DWORD dwErrorFlags;
DWORD dwLength;
DWORD dwError;
char szError[ 10 ] ;

// only try to read number of bytes in queue
ClearCommError( hPort, &dwErrorFlags, &ComStat ) ;
dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ;

if (dwLength > 0)
{
fReadStat = ReadFile( hPort, lpszBlock,
dwLength, &dwLength, &overlapped2 ) ;
if (!fReadStat)
{
if (GetLastError() == ERROR_IO_PENDING)
{
comm_debug("\n\rIO Pending");
// We have to wait for read to complete.
// This function will timeout according to the
// CommTimeOuts.ReadTotalTimeoutConstant variable
// Every time it times out, check for port errors
while(!GetOverlappedResult( hPort,
&overlapped2, &dwLength, TRUE ))
{
dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
// normal result if not finished
continue;
else
{
// an error occurred, try to recover
wsprintf( szError, "<CE-%u>", dwError ) ;
comm_debug(szError);
ClearCommError( hPort, &dwErrorFlags, &ComStat ) ;

break;
}

}

}
else
{
// some other error occurred
dwLength = 0 ;
ClearCommError( hPort, &dwErrorFlags, &ComStat ) ;
wsprintf( szError, "<CE-%u>", dwErrorFlags ) ;
comm_debug(szError);

}
}
}

return ( dwLength ) ;

} // end of ReadCommBlock()



int CommOpen (LPTSTR lpszPortName, int rate, int data_bits, int
stop_bits, int parity)
{
DWORD dwError,
dwThreadID;
DCB PortDCB;
COMMTIMEOUTS CommTimeouts;
HANDLE comm_hReadThread;
HANDLE comm_hPort;

// Open the serial port.
comm_hPort = CreateFile (lpszPortName, // Pointer to the name of the
port
GENERIC_READ | GENERIC_WRITE,
// Access (read-write) mode
0, // Share mode
NULL, // Pointer to the security
attribute
OPEN_EXISTING,// How to open the serial port
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
// Port attributes
NULL); // Handle to port with attribute
// to copy

// If it fails to open the port, return FALSE.
if ( comm_hPort == INVALID_HANDLE_VALUE )
{
// Could not open the port.
// MessageBox (NULL, TEXT("Cannot open bluetooth port"),
// TEXT("Error"), MB_OK);
dwError = GetLastError ();
return 0;
}

PortDCB.DCBlength = sizeof (DCB);

// Get the default port setting information.
GetCommState (comm_hPort, &PortDCB);

// Change the DCB structure settings.
PortDCB.BaudRate = rate; // Current baud
PortDCB.fBinary = TRUE; // Binary mode; no EOF check
PortDCB.fParity = FALSE; // Enable parity checking
PortDCB.fOutxCtsFlow = FALSE; // No CTS output flow control
PortDCB.fOutxDsrFlow = FALSE; // No DSR output flow control
PortDCB.fDtrControl = DTR_CONTROL_DISABLE;
// DTR flow control type
PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity
PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx
PortDCB.fOutX = FALSE; // No XON/XOFF out flow
control
PortDCB.fInX = FALSE; // No XON/XOFF in flow control
PortDCB.fErrorChar = FALSE; // Disable error replacement
PortDCB.fNull = FALSE; // Disable null stripping
PortDCB.fRtsControl = RTS_CONTROL_DISABLE;//
// RTS flow control
PortDCB.fAbortOnError = FALSE; // Do not abort reads/writes
on
// error
PortDCB.ByteSize = data_bits; // Number of
bits/byte, 4-8
PortDCB.Parity = parity; // 0-4=no,odd,even,mark,space
PortDCB.StopBits = stop_bits; // 0,1,2 = 1, 1.5, 2

// Configure the port according to the specifications of the DCB
// structure.
if (!SetCommState (comm_hPort, &PortDCB))
{
// Could not create the read thread.
MessageBox (NULL, TEXT("Unable to configure the bluetooth port"),
TEXT("Error"), MB_OK);
dwError = GetLastError ();
return 0;
}

// Retrieve the time-out parameters for all read and write
operations
// on the port.
GetCommTimeouts (comm_hPort, &CommTimeouts);

// Change the COMMTIMEOUTS structure settings.
CommTimeouts.ReadIntervalTimeout = 1;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 0;
CommTimeouts.WriteTotalTimeoutConstant = 0;

// Set the time-out parameters for all read and write operations
// on the port.
if (!SetCommTimeouts (comm_hPort, &CommTimeouts))
{
// Could not create the read thread.
MessageBox (NULL, TEXT("Unable to set the time-out parameters"),
TEXT("Error"), MB_OK);
dwError = GetLastError ();
return 0;
}

// Direct the port to perform extended functions SETDTR and SETRTS
// SETDTR: Sends the DTR (data-terminal-ready) signal.
// SETRTS: Sends the RTS (request-to-send) signal.
//EscapeCommFunction (comm_hPort, SETDTR);
//EscapeCommFunction (comm_hPort, SETRTS);

handles[0] = comm_hPort;
recRunning = TRUE;
// Create a read thread for reading data from the communication
port.
if (comm_hReadThread = CreateThread (NULL, 0, CommReadThread,
(LPVOID)0, 0,
&dwThreadID))
{
CloseHandle (comm_hReadThread);
}
else
{
// Could not create the read thread.
MessageBox (NULL, TEXT("Unable to create the read thread"),
TEXT("Error"), MB_OK);
dwError = GetLastError ();
return 0;
}

Sleep(500);
return 1;
}

void WriterGeneric(HANDLE hp, char * lpBuf, DWORD dwToWrite)
{
OVERLAPPED osWrite = {0};
HANDLE hArray[1];
DWORD dwWritten;
DWORD dwRes;

//
// create this writes overlapped structure hEvent
//
osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (osWrite.hEvent == NULL)
;//ErrorInComm("CreateEvent (overlapped write hEvent)");

hArray[0] = osWrite.hEvent;

//
// issue write
//
if (!WriteFile(hp, lpBuf, dwToWrite, &dwWritten, &osWrite)) {
if (GetLastError() == ERROR_IO_PENDING) {
//
// write is delayed
//
dwRes = WaitForMultipleObjects(1, hArray, FALSE,
INFINITE);
switch(dwRes)
{
//
// write event set
//
case WAIT_OBJECT_0:
SetLastError(ERROR_SUCCESS);
if (!GetOverlappedResult(hp, &osWrite,
&dwWritten, FALSE)) {
if (GetLastError() ==
ERROR_OPERATION_ABORTED)
comm_debug("Write aborted\r\n");
else
comm_debug("GetOverlappedResult(in
Writer)");
}

if (dwWritten != dwToWrite) {
if (GetLastError() == ERROR_SUCCESS)
comm_debug("Write timed out.
(overlapped)\r\n");
else
comm_debug("Error writing data to
port (overlapped)");
}

break;


//
// wait timed out
//
case WAIT_TIMEOUT:
comm_debug("Wait Timeout in
WriterGeneric.\r\n");
break;

case WAIT_FAILED:
default: comm_debug("WaitForMultipleObjects
(WriterGeneric)");
break;
}
}
else
; //
// writefile failed, but it isn't delayed
//
comm_debug("WriteFile (in Writer)");
}
else {
//
// writefile returned immediately
//
if (dwWritten != dwToWrite)
;comm_debug("Write timed out. (immediate)\r\n");
}

CloseHandle(osWrite.hEvent);

return;
}

DWORD ComWriteBuf (HANDLE hp, int* buf ,int buf_len)
{
DWORD dwError = S_OK;
BYTE* byteBuf;
int i;
byteBuf = (BYTE*)malloc(buf_len * sizeof(BYTE));
for (i = 0; i < buf_len; i++) {
byteBuf[i] = (BYTE)buf[i];
}

WriterGeneric(hp, byteBuf, buf_len);
free(byteBuf);
return dwError;
}


void comm_putToResponse(BYTE byte) {
comm_response[comm_pos] = (char) byte;
comm_pos++;
if (comm_pos >= RESPONSE_SIZE) {
comm_pos = 0;
}

if ((comm_response[0] == (char)0x93) && (comm_pos == 13)) {
comm_pos = 0;
notifySymbol((int)comm_response[3], (int)comm_response[4]);
}
}


/************************************************** *********************

PortReadThread (LPVOID lpvoid)

************************************************** *********************/
DWORD WINAPI CommReadThread (LPVOID lpvoid)
{
int i = (int) lpvoid;
HANDLE hp = handles[i];

DWORD dwEvtMask ;
OVERLAPPED os ;
int nLength ;
BYTE abIn[ 1 + 1] ;
attachThread();
Sleep(3000);
memset( &os, 0, sizeof( OVERLAPPED ) ) ;

// create I/O event used for overlapped read

os.hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) ; // no name
if (os.hEvent == NULL)
{
comm_debug("Failed to create event for thread!");
return ( FALSE ) ;
}

if (!SetCommMask( hp, EV_RXCHAR ))
return ( FALSE ) ;

while ( recRunning )
{
dwEvtMask = 0 ;

WaitCommEvent( hp, &dwEvtMask, NULL );

if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
{
do
{
if (nLength = ReadBlock( hp, (LPSTR) abIn, 1))
{
comm_putToResponse(abIn[0]);
}
}
while ( nLength > 0 ) ;
}
}

// get rid of event handle

CloseHandle( os.hEvent ) ;

// clear information in structure (kind of a "we're done flag")
// hCommWatchThread = NULL;
//dwThreadID = 0;

return( TRUE ) ;
}

void comm_StopTimerThread() {
comm_runTimerThread = FALSE;
}

/************************************************** *********************

PortClose (HANDLE hCommPort)

************************************************** *********************/
BOOL CommClose (int hCommPort)
{
DWORD dwError;
//comm_debug("comm close");
recRunning = FALSE;

comm_StopTimerThread();
// Close the communication port.
if (!CloseHandle (handles[hCommPort - 1]))
{
dwError = GetLastError ();
sprintf(comm_buf, "CommClose failed, error=%d", dwError);
comm_debug(comm_buf);
return FALSE;
}
else
{
Sleep(500);
return TRUE;
}

return FALSE;
}

DWORD WINAPI comm_TimerThread (LPVOID lpvoid) {

DWORD orig;
DWORD now;

orig = GetTickCount();

do {
now = GetTickCount();
Sleep(100);
if ((now - orig) > (TIMER_TIMEOUT * 1000)) {
comm_timeOuted = TRUE;
}
} while ((comm_runTimerThread == TRUE) && (comm_timeOuted == FALSE));

return 0;
}

void comm_StartTimerThread() {
HANDLE hTimerThread;
DWORD dwThreadID;

comm_runTimerThread = TRUE;
comm_timeOuted = FALSE;

if (hTimerThread = CreateThread (NULL, 0, comm_TimerThread, 0, 0,
&dwThreadID))
{
CloseHandle (hTimerThread);
}
else {
comm_debug("TimerThread creation failed!");
}
}


BOOLEAN comm_waitFor(char* reply, int len) {

comm_StartTimerThread();
do {
Sleep(100);
} while ((comm_timeOuted == FALSE) && (memcmp(reply, comm_response,
len) != 0));

comm_StopTimerThread();

return !comm_timeOuted;
}


DWORD CommWrite(int port, int* message, int msg_len, int* reply, int
reply_len) {
DWORD ret = S_FALSE;
int i = 0;
HANDLE hp;
char reply_buf[RESPONSE_SIZE];

hp = handles[port -1];
//Sleep (500);
comm_response[0] = 0;
comm_response[1] = 0;
comm_response[2] = 0;
comm_pos = 0;
ret = ComWriteBuf (hp, message, msg_len);
if( ret != S_OK) {
return ret;
}
if ((reply != NULL) && (reply_len > 0)) {
for (i = 0; i < reply_len; i++) {
reply_buf[i] = (char)reply[i];
}

if (comm_waitFor(reply_buf, reply_len) == FALSE) {
comm_debug("reply failed");

ret = ERROR_TIMEOUT;
goto Exit;
}

}

ret = S_OK;
//comm_debug("sending successful");
Exit:
free (message);
if (reply != NULL) {
free(reply);
}
comm_pos = 0;
return ret;
}

void comm_debug(char* message) {
comm_f = fopen("commdebug.txt","a");
fprintf(comm_f, "%s\n", message);
fclose(comm_f);
}
Reply With Quote

Responses to "programming MSI pc2pc bluetooth key in Windows XP"

 
Thread Tools Display Modes
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
bluetooth dialer on windows-based pc Mark E. Daniel Bluetooth 0 05-11-2004 01:13 AM
USB Bluetooth dongle crashes Windows XP Sen Bluetooth 1 02-26-2004 02:00 AM
bluetooth on windows 2003 Sven Hezel Bluetooth 2 12-18-2003 01:00 PM
Bluetooth PC appliation requires under windows. Martin Adams Bluetooth 6 11-26-2003 01:20 PM
Belkin Bluetooth USB on Windows -- So Slow......... Bluetooth Bluetooth 2 10-23-2003 06:06 PM


All times are GMT. The time now is 11:08 AM.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33