title: Sending bytes to Bluetooth through system virtual serial port
body: <p>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. </p>
  
  <h2>My problems</h2>
  
  <ol>
  <li>can't send and read bytes to virtual BT serial port.</li>
  <li>I use "GetDefaultCommConfig" to check if serial port is active. It's works for usb UART connection but sometimes fail for virtual ports.</li>
  </ol>
  
  <h2>My questions:</h2>
  
  <ol>
  <li>Should I connect to 2 ports, write bytes to "outgoing" and listen on
  "incoming" port?</li>
  <li>What should I change in my code to resolve my problem?</li>
  <li>Why windows create 2 serial ports for Bluetooth?</li>
  </ol>
  
  <p>Code:</p>
  
  <pre><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 &amp;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(&amp;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, &amp;port_settings))
      {
          sprintf(errors, "Unable to set comport dcb settings.Error code: %ld", GetLastError());
  
          refErrors = errors;
          CloseHandle(Cport);
  
          return(false);
      }
  
      if(!SetCommState(Cport, &amp;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, &amp;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 &gt; 4096)
          size = 4096;
  
      if(!ReadFile(Cport, buf, size, (LPDWORD)((void *)&amp;n), NULL))
      {
          return (-1);
      }else
      {
          return(n);
      }
  }
  
  
  int SendByte(unsigned char byte)
  {
      int n = 0;
  
      if(WriteFile(Cport, &amp;byte, 1, (LPDWORD)((void *) &amp;n), NULL))
      {
          return(n);
      }else
      {
          return(0);
      }
  }
  
  
  int SendBuf(unsigned char *buf, int size)
  {
      int n;
  
      if(WriteFile(Cport, buf, size, (LPDWORD)((void *)&amp;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, &amp;CommConfig, &amp;size);
  
      return (result == true || result != 0  || size &gt; sizeof CommConfig) ? true : false;
  }
  </code></pre>