2
votes

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

  1. can't send and read bytes to virtual BT serial port.
  2. 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:

  1. Should I connect to 2 ports, write bytes to "outgoing" and listen on "incoming" port?
  2. What should I change in my code to resolve my problem?
  3. 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;
}
1

1 Answers

1
votes

You cannot read/send that way with Microsoft Bluetooth Stack: you have to use Sockets and all Bth* functions/structures described in MSDN. Trying to use the COM ports won't do the trick! "Incoming" port is created for a server-like use: you are waiting incoming connections for nearby devices (properly paired to you) "Outgoing" port is created for a client-like use: you are 'calling' a nearby device to connect to it. But, anyway, you should use 'sockets' and use them pretty much like a 'server' or a 'client' application; You can start from here: The Bluetooth Socket in Window