Tom's Hardware > Forum > Mobility Technologies > Bluetooth > programming MSI pc2pc bluetooth key in Windows XP

programming MSI pc2pc bluetooth key in Windows XP

Forum Mobility Technologies : Bluetooth - programming MSI pc2pc bluetooth key in Windows XP

Tom's Hardware: Over 1.4 million members in 6 different countries available to answer all your high-tech questions. Sign up now! Its free!
Word :    Username :           
 

Archived from groups: alt.cellular.bluetooth (More info?)

 

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);
}

Sponsored Links
Register or log in to remove.
Tom's Hardware > Forum > Mobility Technologies > Bluetooth > programming MSI pc2pc bluetooth key in Windows XP
Go to:

There are 505 identified and unidentified users. To see the list of identified users, Click here.

Please mind

You are about to answer a thread that has been inactive for more than 6 months.
If you still wish to proceed, please ensure that your posting is original and does not duplicate or overlap any prior responses to this thread.

Add a reply Cancel
Sponsored links
  • Ask the community now
  • Publish
Ad
They won a badge
Join us in greeting them