WINCE 5.0 蓝牙SOCKET


2010-09-28 16:29:41|  分类: 默认分类 |  标签:编程  |举报|字号 订阅

//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/**
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.


Abstract:
 Windows CE Bluetooth application sample

**/
#include <windows.h>
#include <winsock.h>
#include <ws2bth.h>
#include <bt_sdp.h>
#include <bthapi.h>
#include <bt_api.h>

#include <winioctl.h>
#include <console.h>

#define BIGBUF 66000

#define SDP_RECORD_SIZE 0x0000003f

#undef WSAGetLastError
#define WSAGetLastError() GetLastError()

int GetDI (WCHAR **pp, unsigned int *pi) {
 while (**pp == ' ')
  ++*pp;

 int iDig = 0;
 *pi = 0;
 while (iswdigit (**pp)) {
  int c = **pp;

  c = c - '0';

  if ((c < 0) || (c > 9))
   return FALSE;

  *pi = *pi * 10 + c;

  ++*pp;

  ++iDig;
 }

 if ((iDig <= 0) || (iDig > 10))
  return FALSE;

 return TRUE;
}

int GetBA (WCHAR **pp, BT_ADDR *pba) {
 while (**pp == ' ')
  ++*pp;

 for (int i = 0 ; i < 4 ; ++i, ++*pp) {
  if (! iswxdigit (**pp))
   return FALSE;

  int c = **pp;
  if (c >= 'a')
   c = c - 'a' + 0xa;
  else if (c >= 'A')
   c = c - 'A' + 0xa;
  else c = c - '0';

  if ((c < 0) || (c > 16))
   return FALSE;

  *pba = *pba * 16 + c;
 }

 for (i = 0 ; i < 8 ; ++i, ++*pp) {
  if (! iswxdigit (**pp))
   return FALSE;

  int c = **pp;
  if (c >= 'a')
   c = c - 'a' + 0xa;
  else if (c >= 'A')
   c = c - 'A' + 0xa;
  else c = c - '0';

  if ((c < 0) || (c > 16))
   return FALSE;

  *pba = *pba * 16 + c;
 }

 if ((**pp != ' ') && (**pp != '\0'))
  return FALSE;

 return TRUE;
}


#define BPR  8

int GetUx (WCHAR **pp, void *pRes, int nDigs) {
 while (**pp == ' ')
  ++*pp;
 if (**pp != '0')
  return FALSE;
 ++*pp;
 if (**pp != 'x')
  return FALSE;

 ++*pp;

 int iDig = 0;
 int iRes = 0;
 while (iswxdigit (**pp)) {
  int c = **pp;
  if (c >= 'a')
   c = c - 'a' + 0xa;
  else if (c >= 'A')
   c = c - 'A' + 0xa;
  else c = c - '0';

  if ((c < 0) || (c > 16))
   return FALSE;

  iRes = iRes * 16 + c;

  ++*pp;

  ++iDig;
 }

 if (iDig > nDigs)
  return FALSE;

 switch (nDigs) {
 case 2:
  *(unsigned char *)pRes = (unsigned char)iRes;
  break;
 case 4:
  *(unsigned short *)pRes = (unsigned short)iRes;
  break;
 case 8:
  *(unsigned int *)pRes = (unsigned int)iRes;
  break;
 }

 return TRUE;
}

void DumpBuff (WCHAR *szLineHeader, unsigned char *lpBuffer, unsigned int cBuffer) {
 WCHAR szLine[5 + 7 + 2 + 4 * BPR];

 for (int i = 0 ; i < (int)cBuffer ; i += BPR) {
  int bpr = cBuffer - i;
  if (bpr > BPR)
   bpr = BPR;

  wsprintf (szLine, L"%04x ", i);
  WCHAR *p = szLine + wcslen (szLine);

  for (int j = 0 ; j < bpr ; ++j) {
   WCHAR c = (lpBuffer[i + j] >> 4) & 0xf;
   if (c > 9) c += L'a' - 10; else c += L'0';
   *p++ = c;
   c = lpBuffer[i + j] & 0xf;
   if (c > 9) c += L'a' - 10; else c += L'0';
   *p++ = c;
   *p++ = L' ';
  }

  for ( ; j < BPR ; ++j) {
   *p++ = L' ';
   *p++ = L' ';
   *p++ = L' ';
  }

  *p++ = L' ';
  *p++ = L' ';
  *p++ = L' ';
  *p++ = L'|';
  *p++ = L' ';
  *p++ = L' ';
  *p++ = L' ';

  for (j = 0 ; j < bpr ; ++j) {
   WCHAR c = lpBuffer[i + j];
   if ((c < L' ') || (c >= 127))
    c = L'.';

   *p++ = c;
  }

  for ( ; j < BPR ; ++j) {
   *p++ = L' ';
  }

  *p++ = L'\n';
  *p++ = L'\0';

  wprintf (L"%s %s", szLineHeader ? szLineHeader : L"", szLine);
 }
}

int wmain (int argc, WCHAR **argv) {
 BT_ADDR b;
 unsigned int channel = 0;
 WCHAR *arg2 = argv[2];
 WCHAR *arg3 = argv[3];
 WCHAR *arg4 = argv[4];
 WCHAR *arg5 = argv[5];
 unsigned int success = 0;
 int namelen;

 WSADATA wsd;
 if (WSAStartup (MAKEWORD(1,1), &wsd)) {
  wprintf (L"Initialization of socket subsystem failed! Error = %d\n", WSAGetLastError ());
  return 0;
 }

 if ((argc == 6) && (wcsicmp (argv[1], L"client") == 0) && GetBA(&arg2, &b)) {
  SOCKET s = socket (AF_BT, SOCK_STREAM, BTHPROTO_RFCOMM);
  if (s == INVALID_SOCKET) {
   wprintf (L"socket failed, error %d\n", WSAGetLastError ());
   return 0;
  }

  SOCKADDR_BTH sa;
  memset (&sa, 0, sizeof(sa));

  sa.addressFamily = AF_BT;

  sa.btAddr = b;

  success = GetDI(&arg3, &channel);
  sa.port = channel & 0xff;

  int size = 0;
  int chunk = 0;

  if (success)
   success = GetDI(&arg4, (unsigned int *)&size);

  size &= ~1;
  if (success)
   success = GetDI(&arg5, (unsigned int *)&chunk);

  if ((! success) || (size <= 0) || (chunk <= 0)) {
   wprintf(L"Invalid format for Channel or size specified\n");
   closesocket(s);
  } else {
   wprintf (L"Connecting to %04x%08x 0x%02x\n", GET_NAP(b), GET_SAP(b), channel & 0xff);

   if (connect (s, (SOCKADDR *)&sa, sizeof(sa))) {
    wprintf (L"Connect failed, error = %d\n", WSAGetLastError ());
    closesocket (s);
    return 0;
   }

   SOCKADDR_BTH sa3;
   namelen = sizeof(sa3);
   if (0 == getsockname(s, (SOCKADDR *)&sa3, &namelen))
    wprintf (L"Socket s:localname<%04x%08x> connecting on port %d(0x%x)...\n", GET_NAP(sa3.btAddr), GET_SAP(sa3.btAddr), sa3.port, sa3.port);

   namelen = sizeof(sa3);
   if (!getpeername(s, (SOCKADDR *)&sa3, &namelen))
    wprintf (L"Socket s:peername<%04x%08x> connecting on port %d(0x%x)...\n", GET_NAP(sa3.btAddr), GET_SAP(sa3.btAddr), sa3.port, sa3.port);

   wprintf (L"Established connection with %04x%08x 0x%02x\n", GET_NAP(b), GET_SAP(b), channel & 0xff);

   char *pbuf = (char *)malloc (size);
   if (pbuf) {

    int iTicks0 = GetTickCount ();

    send (s, (char *)&size, sizeof (size), 0);

    unsigned char *p = (unsigned char *)pbuf;
    for (int i = 0 ; i < size/2; ++i) {
     *p++ = (char)(i & 0xff);
     *p++ = (char)((i >> 8) & 0xff);
    }

    int isent = 0;
    while (isent < size) {
     if (chunk > size - isent)
      chunk = size - isent;

     int c = send (s, pbuf + isent, chunk, 0);

     if (c == SOCKET_ERROR) {
      wprintf (L"Error %d\n", GetLastError ());
      break;
     }

     isent += c;
     wprintf (L"Sent %d bytes (%d total)\n", c, isent);
    }

    int iTicks1 = GetTickCount ();

    if (iTicks1 != iTicks0)
     wprintf (L"Sent total %d bytes in %d seconds (%d bps)\n", size, (iTicks1 - iTicks0) / 1000, 8000*size / (iTicks1 - iTicks0));

    free (pbuf);
   }

   closesocket (s);
  }
 } else if (((argc == 3) || (argc == 4)) && (wcsicmp (argv[1], L"server") == 0)) {
  SOCKET server = socket (AF_BT, SOCK_STREAM, BTHPROTO_RFCOMM);
  if (server  == INVALID_SOCKET) {
   wprintf (L"socket failed, error %d\n", WSAGetLastError ());
   return 0;
  }

  DWORD dwSleep = 0;

  if (argc == 4)
   GetDI (&arg3, (unsigned int *)&dwSleep);

  SOCKADDR_BTH sa;
  memset (&sa, 0, sizeof(sa));

  sa.addressFamily = AF_BT;

  success = GetDI (&arg2, &channel);

  if (success) {
   sa.port = channel & 0xff;

   wprintf (L"binding to 0x%02x\n", channel & 0xff);

   if (bind (server, (SOCKADDR *)&sa, sizeof(sa))) {
    wprintf (L"Bind failed, error = %d\n", WSAGetLastError ());
    closesocket (server);
    return 0;
   }

   namelen = sizeof(sa);
   if (getsockname(server, (SOCKADDR *)&sa, &namelen)) {
    wprintf(L"getsockname failed, error = %d\n", WSAGetLastError());
    closesocket (server);
    return 0;
   }

   wprintf (L"localhost<%04x%08x> listening on port %d(0x%x)...\n", GET_NAP(sa.btAddr), GET_SAP(sa.btAddr), sa.port, sa.port);

   if (listen (server, 5)) {
    wprintf (L"Listen failed, error = %d\n", WSAGetLastError ());
    return 0;
   }


   SOCKADDR_BTH sa2;
   int size = sizeof(sa2);

   wprintf (L"Accepting...\n");

   SOCKET s2 = accept (server, (SOCKADDR *)&sa2, &size);

   if (s2 != INVALID_SOCKET) {
    if (size != sizeof(sa2))
     wprintf (L"Sockaddr size is %d, not %d which was expected!\n", size, sizeof(sa2));

    BT_ADDR b2 = sa2.btAddr;
    int channel2 = sa2.port;

    SOCKADDR_BTH sa3;
    namelen = sizeof(sa3);
    if (!getsockname(s2, (SOCKADDR *)&sa3, &namelen))
     wprintf (L"Socket s2:localname<%04x%08x> connecting on port %d(0x%x)...\n", GET_NAP(sa3.btAddr), GET_SAP(sa3.btAddr), sa3.port, sa3.port);

    namelen = sizeof(sa3);
    if (!getpeername(s2, (SOCKADDR *)&sa3, &namelen))
     wprintf (L"Socket s2:peername<%04x%08x> connecting on port %d(0x%x)...\n", GET_NAP(sa3.btAddr), GET_SAP(sa3.btAddr), sa3.port, sa3.port);
 
    wprintf (L"Connection accepted. Family %d Address %04x%08x Channel 0x%02x\n", sa2.addressFamily, GET_NAP(b2), GET_SAP(b2), channel2);
    size = 0;
    if ((recv (s2, (char *)&size, sizeof(size), 0) == sizeof(size)) && ((size & 1) == 0) && (size > 0)) {
     wprintf (L"Receiving %d bytes\n", size);

     char *pbuf = (char *)malloc (size);
     if (pbuf) {
      int ilastreport = 0;
      int irecv = 0;

      int iTicks0 = GetTickCount ();

      while (irecv < size) {
       if (dwSleep)
        Sleep(dwSleep);
       int c = recv (s2, pbuf + irecv, size - irecv, 0);
       if (c == SOCKET_ERROR) {
        wprintf (L"Error %d\n", GetLastError ());
        break;
       }

       int ierr = FALSE;

       int i1 = irecv / 2;
       int i2 = (irecv + c) / 2;

       unsigned char *p = (unsigned char *)(pbuf + i1 * 2);
       for (int i  = i1 ; i < i2 ; ++i) {
        if (*p++ != (unsigned char)(i & 0xff)) {
         ierr = 1;
         break;
        }

        if (*p++ != (unsigned char)((i >> 8) & 0xff)) {
         ierr = 2;
         break;
        }
       }

       if (ierr) {
        --p;
        wprintf (L"Detected error at byte %d in total stream!\n", p - (unsigned char *)pbuf);
        wprintf (L"Have: 0x%02x, want 0x%02x\n", *p, ierr == 1 ? (unsigned char)(i & 0xff) : (unsigned char)((i >> 8) & 0xff));
        wprintf (L"Offset in current buffer : %d\n", p - (unsigned char *)(pbuf + irecv));
        DumpBuff (L"Error>", (unsigned char *)(pbuf + irecv), c);

        break;
       }

       irecv += c;

       while (irecv - ilastreport > 10*1024) {
        wprintf (L"Got %d bytes\n", ilastreport);
        ilastreport += 10*1024;
       }

       if (c == 0)
        break;
      }

      if (irecv == size) {
       int iTicks1 = GetTickCount ();

       if (iTicks1 != iTicks0)
        wprintf (L"Received total %d bytes in %d seconds (%d bps)\n", size, (iTicks1 - iTicks0) / 1000, 8000*size / (iTicks1 - iTicks0));

       wprintf (L"Got all buffer, verifying!\n");
       unsigned char *p = (unsigned char *)pbuf;
       int ierr = FALSE;
       for (int i = 0 ; i < size/2; ++i) {
        if (*p++ != (unsigned char)(i & 0xff)) {
         ierr = TRUE;
         break;
        }

        if (*p++ != (unsigned char)((i >> 8) & 0xff)) {
         ierr = TRUE;
         break;
        }
       }

       if (ierr) {
        int c1 = 128;
        int c2 = 128;

        if ((char *)p - pbuf < 128)
         c1 = (char *)p - pbuf;
        if (pbuf + irecv - (char *)p < 128)
         c2 = pbuf + irecv - (char *)p - 1;

        DumpBuff (L"Error buffer", p - c1, c1 + c2);
       }
      } else
       wprintf (L"Only got %d bytes\n", irecv);

      free (pbuf);
     } else
      wprintf (L"Couldn't alloc %d bytes\n", size);
    } else
     wprintf (L"Didn't get the size properly\n");

    closesocket (s2);
   }

   closesocket (server);
   wprintf (L"Exiting....\n");
  } else
   wprintf (L"Incorrect syntax\n");

  closesocket (server);
 } else {
  wprintf (L"Usage: %s {server <channel> [sleep_between-recv_in_ms]| client <target bt_addr> <channel> <total> <chunksize>}\n", argv[0]);
  return 1;
 }

 return 0;
}

你可能感兴趣的:(WINCE 5.0 蓝牙SOCKET)