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