I would like to be able to send and receive data through Bluetooth in C++. I discovered that system(win 8.1) create 2 virtual ports for paired device. When I try to send data to connected port("incoming") using WriteFile, function returns success and 0 byte were written.
My problems
- can't send and read bytes to virtual BT serial port.
- I use "GetDefaultCommConfig" to check if serial port is active. It's works for usb UART connection but sometimes fail for virtual ports.
My questions:
- Should I connect to 2 ports, write bytes to "outgoing" and listen on "incoming" port?
- What should I change in my code to resolve my problem?
- Why windows create 2 serial ports for Bluetooth?
Code:
#define _CRT_SECURE_NO_WARNINGS
#include "rs232.h"
using namespace std;
HANDLE Cport;
string comName;
char comport[14];
char baudr[64];
bool OpenComport(char *portCOM, int baudrate, int useDtrControl, string &refErrors)
{
char errors[200];
sprintf(comport, "\\\\.\\%s", portCOM);
switch(baudrate)
{
case 110 : strcpy(baudr, "baud=110 data=8 parity=N stop=1");
break;
case 300 : strcpy(baudr, "baud=300 data=8 parity=N stop=1");
break;
case 600 : strcpy(baudr, "baud=600 data=8 parity=N stop=1");
break;
case 1200 : strcpy(baudr, "baud=1200 data=8 parity=N stop=1");
break;
case 2400 : strcpy(baudr, "baud=2400 data=8 parity=N stop=1");
break;
case 4800 : strcpy(baudr, "baud=4800 data=8 parity=N stop=1");
break;
case 9600 : strcpy(baudr, "baud=9600 data=8 parity=N stop=1");
break;
case 19200 : strcpy(baudr, "baud=19200 data=8 parity=N stop=1");
break;
case 38400 : strcpy(baudr, "baud=38400 data=8 parity=N stop=1");
break;
case 57600 : strcpy(baudr, "baud=57600 data=8 parity=N stop=1");
break;
case 115200 : strcpy(baudr, "baud=115200 data=8 parity=N stop=1");
break;
case 128000 : strcpy(baudr, "baud=128000 data=8 parity=N stop=1");
break;
case 256000 : strcpy(baudr, "baud=256000 data=8 parity=N stop=1");
break;
default : printf(errors, "invalid baudrate: %d", baudrate);
refErrors = errors;
return(false);
}
Cport = CreateFileA(comport,
GENERIC_READ|GENERIC_ReadWRITE,
0, /* no share */
NULL, /* no security */
OPEN_EXISTING,
0, /* no threads */
NULL); /* no templates */
if(Cport == INVALID_HANDLE_VALUE)
{
sprintf(errors, "Unable to open comport. Error code: %ld", GetLastError());
refErrors = errors;
return(false);
}
DCB port_settings;
memset(&port_settings, 0, sizeof(port_settings)); /* clear the new struct */
port_settings.DCBlength = sizeof(port_settings);
//use DTR control if specified. Disabled by default.
port_settings.fDtrControl = useDtrControl ? DTR_CONTROL_ENABLE : DTR_CONTROL_DISABLE;
if(!BuildCommDCBA(baudr, &port_settings))
{
sprintf(errors, "Unable to set comport dcb settings.Error code: %ld", GetLastError());
refErrors = errors;
CloseHandle(Cport);
return(false);
}
if(!SetCommState(Cport, &port_settings))
{
sprintf(errors, "Unable to set comport cfg settings. Com port will be closed. Error code: %ld", GetLastError());
refErrors = errors;
CloseHandle(Cport);
return(false);
}
COMMTIMEOUTS Cptimeouts;
Cptimeouts.ReadIntervalTimeout = MAXDWORD;
Cptimeouts.ReadTotalTimeoutMultiplier = 0;
Cptimeouts.ReadTotalTimeoutConstant = 0;
Cptimeouts.WriteTotalTimeoutMultiplier = 1;
Cptimeouts.WriteTotalTimeoutConstant = 1;
if(!SetCommTimeouts(Cport, &Cptimeouts))
{
sprintf(errors, "Unable to set comport time-out settings. Com port will be closed. Error code: %ld", GetLastError());
refErrors = errors;
CloseHandle(Cport);
return(false);
}
comName = portCOM;
return(true);
}
int PollComport(unsigned char *buf, int size)
{
int n;
if(size > 4096)
size = 4096;
if(!ReadFile(Cport, buf, size, (LPDWORD)((void *)&n), NULL))
{
return (-1);
}else
{
return(n);
}
}
int SendByte(unsigned char byte)
{
int n = 0;
if(WriteFile(Cport, &byte, 1, (LPDWORD)((void *) &n), NULL))
{
return(n);
}else
{
return(0);
}
}
int SendBuf(unsigned char *buf, int size)
{
int n;
if(WriteFile(Cport, buf, size, (LPDWORD)((void *)&n), NULL))
{
return(n);
}else
{
return(-1);
}
}
bool CloseComport()
{
return CloseHandle(Cport);
}
bool isComExists(string portName)
{
COMMCONFIG CommConfig;
DWORD size;
TCHAR strPort[32] = {0};
_stprintf(strPort, _T("%s"), portName.c_str());
size = sizeof CommConfig;
bool result = GetDefaultCommConfig(strPort, &CommConfig, &size);
return (result == true || result != 0 || size > sizeof CommConfig) ? true : false;
}