//------------------------------------------------------------------------- // Function: PnrpUnregister // // Purpose: Unregister the given name from the PNRP cloud // // Arguments: // pwzIdentity : identity string originally used to register the name // pwzName : name to unregister from PNRP // pwzCloud : name of cloud to unregister from, NULL = global cloud // // Returns: HRESULT // HRESULT PnrpUnregister(PCWSTR pwzIdentity, PCWSTR pwzName, PCWSTR pwzCloud) { HRESULT hr = S_OK; PNRPINFO pnrpInfo = {0}; BLOB blPnrpData = {0}; WSAQUERYSET querySet = {0}; INT iRet; // // build the WSAQUERYSET required to unregister // pnrpInfo.dwSize = sizeof(pnrpInfo); pnrpInfo.dwLifetime = REGISTRATION_LIFETIME; pnrpInfo.lpwszIdentity = (PWSTR) pwzIdentity; blPnrpData.cbSize = sizeof(pnrpInfo); blPnrpData.pBlobData = (BYTE*)&pnrpInfo; querySet.dwSize = sizeof(querySet); querySet.dwNameSpace = NS_PNRPNAME; querySet.lpServiceClassId = (LPGUID)&SVCID_PNRPNAME; querySet.lpszServiceInstanceName = (PWSTR) pwzName; querySet.lpszContext = (PWSTR) pwzCloud; querySet.lpBlob = &blPnrpData; // unregister the name with PNRP iRet = WSASetService(&querySet, RNRSERVICE_DELETE, 0); if (iRet != 0) { hr = HRESULT_FROM_WIN32(WSAGetLastError()); } return hr; }
static int unregisterSDPService(ULONG sdpRecordHandle) { WSAQUERYSET wqs; BLOB b; ULONG sdpVersion = BTH_SDP_VERSION; BTHNS_SETBLOB bthNsBlob; memset(&bthNsBlob, 0, sizeof(bthNsBlob)); bthNsBlob.pRecordHandle = &sdpRecordHandle; bthNsBlob.ulRecordLength = sizeof(sdp_rec); bthNsBlob.pSdpVersion = &sdpVersion; b.cbSize = sizeof(bthNsBlob); b.pBlobData = (PBYTE) & bthNsBlob; memset(&wqs, 0, sizeof(WSAQUERYSET)); wqs.dwSize = sizeof(WSAQUERYSET); wqs.dwNameSpace = NS_BTH; wqs.lpBlob = &b; int ret = WSASetService(&wqs, RNRSERVICE_DELETE, 0); if (ret == SOCKET_ERROR) return -1; return 0; }
// Makes this bluetooth "service" visible to anyone else searching static int registerSDPService(ULONG * sdpRecordHandle) { WSAQUERYSET wqs; unsigned char uuid[] = HAGGLE_BLUETOOTH_SDP_UUID; BLOB b; ULONG sdpVersion = BTH_SDP_VERSION; struct sdp_record *sdpRec; struct { BTHNS_SETBLOB bthNsBlob; char data[sizeof(struct sdp_record) - 1]; } rec; *sdpRecordHandle = 0; memset(&rec, 0, sizeof(rec)); rec.bthNsBlob.pRecordHandle = sdpRecordHandle; rec.bthNsBlob.ulRecordLength = sizeof(sdp_rec); rec.bthNsBlob.pSdpVersion = &sdpVersion; sdpRec = (struct sdp_record *) &rec.bthNsBlob.pRecord; /* Intitialize the record with the default values */ memcpy(sdpRec, &sdp_rec, sizeof(sdp_rec)); /* Add our UUID and channel */ sdpRec->len = sizeof(struct sdp_record) - 2; memcpy(sdpRec->uuid, uuid, sizeof(uuid)); sdpRec->channel = RFCOMM_DEFAULT_CHANNEL; b.cbSize = sizeof(rec); b.pBlobData = (PBYTE) & rec; memset(&wqs, 0, sizeof(WSAQUERYSET)); wqs.dwSize = sizeof(WSAQUERYSET); wqs.dwNameSpace = NS_BTH; wqs.lpBlob = &b; int ret = WSASetService(&wqs, RNRSERVICE_REGISTER, 0); if (ret == SOCKET_ERROR) return -1; return 0; }
int RhoBluetoothManager::RegisterService(BYTE *rgbSdpRecord, int cSdpRecord, int iChannelOffset, UCHAR channel) { ULONG recordHandle = 0; struct bigBlob { BTHNS_SETBLOB b; }*pBigBlob; pBigBlob = (bigBlob *)malloc(sizeof(struct bigBlob)+cSdpRecord); ULONG ulSdpVersion = BTH_SDP_VERSION; pBigBlob->b.pRecordHandle = &recordHandle; pBigBlob->b.pSdpVersion = &ulSdpVersion; pBigBlob->b.fSecurity = 0; pBigBlob->b.fOptions = 0; pBigBlob->b.ulRecordLength = cSdpRecord; memcpy (pBigBlob->b.pRecord, rgbSdpRecord, cSdpRecord); pBigBlob->b.pRecord[iChannelOffset] = (unsigned char)channel; BLOB blob; blob.cbSize = sizeof(BTHNS_SETBLOB) + cSdpRecord - 1; blob.pBlobData = (PBYTE) pBigBlob; WSAQUERYSET Service; memset (&Service, 0, sizeof(Service)); Service.dwSize = sizeof(Service); Service.lpBlob = &blob; Service.dwNameSpace = NS_BTH; if (WSASetService(&Service,RNRSERVICE_REGISTER,0) == SOCKET_ERROR) { free(pBigBlob); return WSAGetLastError(); } else { free(pBigBlob); return 0; } }
//------------------------------------------------------------------------- // Function: PnrpRegister // // Purpose: Register the given name in the PNRP cloud // // Arguments: // pwzIdentity : identity string created using PeerIdentityCreate // pwzName : name to register in PNRP, generally the graph id // pwzCloud : name of cloud to register in, NULL = global cloud // pNodeInfo : local node info returned from PeerGraphGetNodeInfo // // Returns: HRESULT // HRESULT PnrpRegister(PCWSTR pwzIdentity, PCWSTR pwzName, PCWSTR pwzCloud, __in PEER_NODE_INFO* pNodeInfo) { HRESULT hr = S_OK; CSADDR_INFO* pCsaAddr = NULL; PNRPINFO pnrpInfo = {0}; BLOB blPnrpData = {0}; WSAQUERYSET querySet = {0}; ULONG nAddrs = 0; ULONG i; INT iRet; // // build a CSADDR_INFO array from the PEER_NODE_INFO // if (pNodeInfo->cAddresses < 1) { // need at least one address to register hr = E_INVALIDARG; } if (SUCCEEDED(hr)) { // do not attempt to register more addresses than PNRP allows if (pNodeInfo->cAddresses > PNRP_MAX_ENDPOINT_ADDRESSES) { nAddrs = PNRP_MAX_ENDPOINT_ADDRESSES; } else { nAddrs = pNodeInfo->cAddresses; } pCsaAddr = (CSADDR_INFO*)malloc(sizeof(CSADDR_INFO) * nAddrs); if (pCsaAddr != NULL) { // copy the addresses from PEER_NODE_INFO into CSADDR_INFO format for (i = 0; i < nAddrs; i++) { pCsaAddr[i].iProtocol = IPPROTO_TCP; pCsaAddr[i].iSocketType = SOCK_STREAM; pCsaAddr[i].LocalAddr.iSockaddrLength = sizeof(SOCKADDR_IN6); pCsaAddr[i].LocalAddr.lpSockaddr = (LPSOCKADDR) &pNodeInfo->pAddresses[i].sin6; } } else { hr = E_OUTOFMEMORY; } } if (SUCCEEDED(hr)) { // // build the WSAQUERYSET required to register // pnrpInfo.dwSize = sizeof(pnrpInfo); pnrpInfo.dwLifetime = REGISTRATION_LIFETIME; pnrpInfo.lpwszIdentity = (PWSTR) pwzIdentity; blPnrpData.cbSize = sizeof(pnrpInfo); blPnrpData.pBlobData = (BYTE*)&pnrpInfo; querySet.dwSize = sizeof(querySet); querySet.dwNameSpace = NS_PNRPNAME; querySet.dwNumberOfCsAddrs = nAddrs; querySet.lpServiceClassId = (LPGUID)&SVCID_PNRPNAME; querySet.lpszServiceInstanceName = (PWSTR) pwzName; querySet.lpszContext = (PWSTR) pwzCloud; querySet.lpszComment = L"GraphChatMember"; querySet.lpcsaBuffer = pCsaAddr; querySet.lpBlob = &blPnrpData; // register the name with PNRP iRet = WSASetService(&querySet, RNRSERVICE_REGISTER, 0); if (iRet != 0) { hr = HRESULT_FROM_WIN32(WSAGetLastError()); } } if (pCsaAddr != NULL) { free(pCsaAddr); } return hr; }
//--------------------------------------------------------------------------- // FUNCTION: BOOL WINAPI CtrlHandler ( DWORD dwEvent ) // Intercept CTRL-C or CTRL-BRK events and cause the server to // initiate shutdown and cleanup. //--------------------------------------------------------------------------- BOOL WINAPI CtrlHandler ( DWORD dwEvent ) { int nRet = 0; int i = 0; WCHAR szGuid[MAX_PATH] = {'\0'}; HRESULT hRet; switch (dwEvent) { case CTRL_C_EVENT: case CTRL_BREAK_EVENT: case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: case CTRL_CLOSE_EVENT: fEndProgram = TRUE; printf("CtrlHandler: cleaning up...\n"); printf("delete service instance...\n"); nRet = WSASetService(&g_QS, RNRSERVICE_DELETE, 0L); if (nRet == SOCKET_ERROR) { printf("WSASetService DELETE error %d\n", WSAGetLastError()); } else printf(" Deleted.\n"); printf("Removing Service class "); if (SUCCEEDED(hRet = StringCchPrintfW(szGuid, sizeof(szGuid)/sizeof(szGuid[0]), L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", g_MyGuid.Data1, g_MyGuid.Data2, g_MyGuid.Data3, g_MyGuid.Data4[0], g_MyGuid.Data4[1], g_MyGuid.Data4[2], g_MyGuid.Data4[3], g_MyGuid.Data4[4], g_MyGuid.Data4[5], g_MyGuid.Data4[6], g_MyGuid.Data4[7] ))) { wprintf(L"%s",szGuid); } printf("... \n"); nRet = WSARemoveServiceClass(&g_MyGuid); if (nRet == SOCKET_ERROR) { printf("WSARemoveServiceClass error %d\n", WSAGetLastError()); } else printf(" Removed.\n"); for (i = 0; i < g_nMaxNumOfSocks; i++) { if ( g_aSock[i] != INVALID_SOCKET ) { closesocket ( g_aSock[i] ); g_aSock[i] = INVALID_SOCKET; } } break; default: // unknown type--better pass it on. return FALSE; } return TRUE; }
//--------------------------------------------------------------------------- // FUNCTION: Advertise(char* pszServerName) // // PURPOSE: Given the name of this service instance "pszServerName", // advertise this instance to the available name spaces. // // RETURNS: // TRUE if succeed otherwise FALSE // //--------------------------------------------------------------------------- BOOL Advertise(char* pszServerName) { int nRet = 0; int i=0; // number of socket created int nNumOfCSAddr = 0; // number of bound socket addresses // Advertizing // Set up the WSAQuery data SecureZeroMemory(&g_QS,sizeof(WSAQUERYSET)); g_QS.dwSize = sizeof(WSAQUERYSET); g_QS.lpszServiceInstanceName = (LPSTR)pszServerName; // service instance name g_QS.lpServiceClassId = &g_MyGuid; // associated service class id g_QS.dwNameSpace = NS_ALL; // advertise to all name spaces g_QS.lpNSProviderId = NULL; g_QS.lpcsaBuffer = g_aCSAddr; // our bound socket addresses g_QS.lpBlob = NULL; // Set up the g_aCSAddr data if (g_fNtds) { SOCKET_ADDRESS_LIST *slist=NULL; struct addrinfo *res=NULL, *resptr=NULL, hints; char *addrbuf=NULL; DWORD dwBytes=0; SecureZeroMemory(&hints,sizeof(hints)); hints.ai_flags = AI_PASSIVE; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; nRet = getaddrinfo(NULL, "0", &hints, &res); if ((nRet != 0) || (res == NULL)) { return FALSE; } resptr = res; while (resptr) { g_aSock[i] = socket(resptr->ai_family, resptr->ai_socktype, resptr->ai_protocol); if (g_aSock[i] == INVALID_SOCKET) { printf("socket error %d\n", WSAGetLastError()); freeaddrinfo(res); return FALSE; } // bind to local host ip addresses and let system to assign a port number nRet = bind ( g_aSock[i], resptr->ai_addr, (int)resptr->ai_addrlen); if ( SOCKET_ERROR == nRet ) { printf("bind error %d\n", WSAGetLastError()); freeaddrinfo(res); return FALSE; } int cb = sizeof(ss_in); if (getsockname(g_aSock[i], (SOCKADDR *) &ss_in, &cb) == SOCKET_ERROR) { printf("getsockname error %d\n", WSAGetLastError()); freeaddrinfo(res); return FALSE; } nRet = WSAIoctl(g_aSock[i], SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, 0, &dwBytes, NULL, NULL); if (nRet == SOCKET_ERROR) { addrbuf = (char *)HeapAlloc(GetProcessHeap(), 0, dwBytes); if (addrbuf == NULL) { freeaddrinfo(res); return FALSE; } nRet = WSAIoctl(g_aSock[i], SIO_ADDRESS_LIST_QUERY, NULL, 0, addrbuf, dwBytes, &dwBytes, NULL, NULL); if (nRet == SOCKET_ERROR) { printf("WSAIoctl failed: %d\n", WSAGetLastError()); HeapFree(GetProcessHeap(), 0, addrbuf); freeaddrinfo(res); return FALSE; } } else { printf("WSAIoctl should have failed!\n"); freeaddrinfo(res); return FALSE; } slist = (SOCKET_ADDRESS_LIST *)addrbuf; if (resptr->ai_family == AF_INET) printf("IPv4 addresses bound...\n"); else if (resptr->ai_family == AF_INET6) printf("IPv6 addresses bound...\n"); else printf("Unknown address family addresses bound...\n"); for (int j = 0; j < slist->iAddressCount ; j++) { if (j >= g_nMaxNumOfCSAddr) { printf("Max. number of socket address (%d) reached. We will not advertise extra ones\n", g_nMaxNumOfCSAddr); break; } // Copy the address over memcpy(&g_aSockAddr[j], slist->Address[j].lpSockaddr, slist->Address[j].iSockaddrLength); // Set the port number our socket is actually bound to SetIpPort(&g_aSockAddr[j],&ss_in); char temp[128] = {'\0'}; GetSockAddrString (&g_aSockAddr[j], slist->Address[j].iSockaddrLength, temp, 128); printf("Address %40s\n", temp); g_aCSAddr[j].iSocketType = SOCK_DGRAM; g_aCSAddr[j].iProtocol = IPPROTO_UDP; g_aCSAddr[j].LocalAddr.lpSockaddr = (struct sockaddr *)&g_aSockAddr[j]; g_aCSAddr[j].LocalAddr.iSockaddrLength = slist->Address[j].iSockaddrLength; g_aCSAddr[j].RemoteAddr.lpSockaddr = (struct sockaddr *)&g_aSockAddr[j]; g_aCSAddr[j].RemoteAddr.iSockaddrLength = slist->Address[j].iSockaddrLength; nNumOfCSAddr++; // increase the number SOCKADDR buffer used } i++; // increase the number of socket created // Go to the next address resptr = resptr->ai_next; // Free the address buffer HeapFree(GetProcessHeap(), 0, addrbuf); addrbuf = NULL; } freeaddrinfo(res); } if (g_fSap && (nNumOfCSAddr < g_nMaxNumOfCSAddr)) { // advertise into the NS_SAP name space if we still have enough // socket address buffer SecureZeroMemory(sa_ipx.sa_netnum,sizeof(sa_ipx.sa_netnum)); SecureZeroMemory(sa_ipx.sa_nodenum,sizeof(sa_ipx.sa_nodenum)); sa_ipx.sa_family = AF_IPX; sa_ipx.sa_socket = 0; g_aSock[i] = socket ( AF_IPX, SOCK_DGRAM, NSPROTO_IPX ); if ( INVALID_SOCKET == g_aSock[i] ) { printf("socket error %d\n", WSAGetLastError()); return FALSE; } nRet = bind ( g_aSock[i], (SOCKADDR *) &sa_ipx, sizeof (sa_ipx) ); if ( SOCKET_ERROR == nRet ) { printf("bind error %d\n", WSAGetLastError()); return FALSE; } //--------------Find out our bound ipx addresses------------ int cb = 0; // size variable int nAdapters = 0; // number of adapters bound with IPX // get the number of adapters cb = sizeof(nAdapters); nRet = getsockopt(g_aSock[i], NSPROTO_IPX, IPX_MAX_ADAPTER_NUM, (char *) &nAdapters, &cb); if (nRet == SOCKET_ERROR) { printf("getsockopt error %d\n", WSAGetLastError()); return FALSE; } SOCKADDR_IPX* pSaIpx = NULL; // a pointer to our current SOCKADDR buffer printf("IPX addresses bound...\n"); for (int nIdx = 0; nIdx < nAdapters; nIdx++) { if (nNumOfCSAddr >= g_nMaxNumOfCSAddr) { printf("Max. number of socket address (%d) reached. We will not advertise extra ones\n", g_nMaxNumOfCSAddr); break; } // get the buffer for this SOCKADDR pSaIpx = (SOCKADDR_IPX *) &g_aSockAddr[nNumOfCSAddr]; if (GetBoundIpxAddr(g_aSock[i], pSaIpx, nIdx) == FALSE) { printf("No valid bound IPX address at adapter index %d\n", nIdx); // since this link is not available, nNumOfCSAddr will reuse the current SOCKADDR buffer continue; } char temp[DEFAULT_STRING_LEN] = {'\0'}; GetSockAddrString (&g_aSockAddr[nNumOfCSAddr], sizeof(SOCKADDR_IPX), temp, DEFAULT_STRING_LEN); printf("%40s\n", temp); g_aCSAddr[nNumOfCSAddr].iSocketType = SOCK_DGRAM; g_aCSAddr[nNumOfCSAddr].iProtocol = NSPROTO_IPX; g_aCSAddr[nNumOfCSAddr].LocalAddr.lpSockaddr = (struct sockaddr *)&g_aSockAddr[nNumOfCSAddr]; g_aCSAddr[nNumOfCSAddr].LocalAddr.iSockaddrLength = sizeof(sa_ipx); g_aCSAddr[nNumOfCSAddr].RemoteAddr.lpSockaddr = (struct sockaddr *)&g_aSockAddr[nNumOfCSAddr]; g_aCSAddr[nNumOfCSAddr].RemoteAddr.iSockaddrLength = sizeof(sa_ipx); nNumOfCSAddr++; } i++; // increase the number of socket created // Note: If g_fNtds is TRUE, this ipx address will be // available from the NTDS name space too. } // update counters g_QS.dwNumberOfCsAddrs = nNumOfCSAddr; g_nNumOfUsedSocks = i; // Call WSASetService printf("Advertise server of instance name: %s ...\n", pszServerName); nRet = WSASetService(&g_QS, RNRSERVICE_REGISTER, 0L); if (nRet == SOCKET_ERROR) { printf("WSASetService error %d\n", WSAGetLastError()); return FALSE; } printf("Wait for client talking to me, hit Ctrl-C to terminate...\n"); return TRUE; }
int BtHandler::startBtServer() { qDebug() << "BtHandler::startBtServer()" << endl; int retCode = 0; WSAQUERYSET wsaQuerySet = {0}; SOCKADDR_BTH sockAddrBthLocal = {0}; int iAddrLen = sizeof(SOCKADDR_BTH); CSADDR_INFO csAddrInfo = {0}; // Open a bluetooth socket using RFCOMM protocol if((serverSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM)) == INVALID_SOCKET) { retCode = WSAGetLastError(); //emit message("Could not create bluetooth socket: %d\n(%s)", retCode, Util::GetLastErrorMessage()); goto EXIT; } // Setting address family to AF_BTH indicates winsock2 to use Bluetooth port sockAddrBthLocal.addressFamily = AF_BTH; sockAddrBthLocal.port = BT_PORT_ANY; // bind() associates a local address and port combination // with the socket just created. This is most useful when // the application is a server that has a well-known port // that clients know about in advance. if(bind(serverSocket, (struct sockaddr *) &sockAddrBthLocal, sizeof(SOCKADDR_BTH)) == SOCKET_ERROR) { retCode = WSAGetLastError(); //emit message("Could not bind bluetooth socket: %d\n(%s)", retCode, Util::GetLastErrorMessage()); goto EXIT; } if(getsockname(serverSocket, (struct sockaddr *)&sockAddrBthLocal, &iAddrLen) == SOCKET_ERROR) { retCode = WSAGetLastError(); //emit message("Could not access bluetooth socket: %d\n(%s)", retCode, Util::GetLastErrorMessage()); goto EXIT; } // CSADDR_INFO csAddrInfo.LocalAddr.iSockaddrLength = sizeof( SOCKADDR_BTH ); csAddrInfo.LocalAddr.lpSockaddr = (LPSOCKADDR)&sockAddrBthLocal; csAddrInfo.RemoteAddr.iSockaddrLength = sizeof( SOCKADDR_BTH ); csAddrInfo.RemoteAddr.lpSockaddr = (LPSOCKADDR)&sockAddrBthLocal; csAddrInfo.iSocketType = SOCK_STREAM; csAddrInfo.iProtocol = BTHPROTO_RFCOMM; // If we got an address, go ahead and advertise it. ZeroMemory(&wsaQuerySet, sizeof(WSAQUERYSET)); wsaQuerySet.dwSize = sizeof(WSAQUERYSET); wsaQuerySet.lpServiceClassId = (LPGUID) &LOG_VIEWS_BT_SERVICE_CLASS_GUID; wsaQuerySet.lpszServiceInstanceName = TEXT("SmartCam Server"); wsaQuerySet.lpszComment = TEXT("Webcam over bluetooth"); wsaQuerySet.dwNameSpace = NS_BTH; wsaQuerySet.dwNumberOfCsAddrs = 1; // Must be 1. wsaQuerySet.lpcsaBuffer = &csAddrInfo; // Required. // As long as we use a blocking accept(), we will have a race // between advertising the service and actually being ready to // accept connections. If we use non-blocking accept, advertise // the service after accept has been called. if(WSASetService(&wsaQuerySet, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR) { retCode = WSAGetLastError(); //emit message("Could not set service on bluetooth socket: %d\n(%s)", retCode, Util::GetLastErrorMessage()); goto EXIT; } // listen() call indicates winsock2 to listen on a given socket for any incoming connection. if(listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) { retCode = WSAGetLastError(); //emit message("Could not listen on bluetooth socket: %d\n(%s)", retCode, Util::GetLastErrorMessage()); goto EXIT; } EXIT: emit btStarted(retCode == 0); return retCode; }
//extern "C"{ int hego() { WSAData wsaData = { 0 }; WSAStartup(MAKEWORD(2, 2), &wsaData); SOCKET listen_sock = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM); if (listen_sock == INVALID_SOCKET) { return -1; } SOCKADDR_BTH sa = { 0 }; sa.addressFamily = AF_BTH; sa.port = BT_PORT_ANY; if (bind(listen_sock, (SOCKADDR *)&sa, sizeof(sa)) == SOCKET_ERROR) { return -1; } int size = sizeof(sa); getsockname(listen_sock, (SOCKADDR *)&sa, &size); CSADDR_INFO info = { 0 }; info.LocalAddr.lpSockaddr = (LPSOCKADDR)&sa; info.LocalAddr.iSockaddrLength = sizeof(sa); info.iSocketType = SOCK_STREAM; info.iProtocol = BTHPROTO_RFCOMM; WSAQUERYSET set = { 0 }; set.dwSize = sizeof(WSAQUERYSET); // Must be set to sizeof(WSAQUERYSET) set.dwOutputFlags = 0; // Not used set.lpszServiceInstanceName = (char*)"Server"; // Recommended. GUID guid;//cc896eaa-d8f0-d97a-c432-0301d6921a54 guid.Data1 = 0xcc896eaa; guid.Data2 = 0xd8f0; guid.Data3 = 0xd97a; guid.Data4[0] = 0xc4; guid.Data4[1] = 0x32; guid.Data4[2] = 0x03; guid.Data4[3] = 0x01; guid.Data4[4] = 0xd6; guid.Data4[5] = 0x92; guid.Data4[6] = 0x1a; guid.Data4[7] = 0x54; printf("%08x-%04x-%04x", guid.Data1, guid.Data2, guid.Data3); int i; printf("-"); for(i = 0; i < sizeof(guid.Data4); i++){ printf("%02x", guid.Data4[i]); if(i == 1) printf("-"); } printf("\n"); set.lpServiceClassId = &guid; // Requred. set.lpVersion = NULL; // Not used. set.lpszComment = NULL; // Optional. set.dwNameSpace = NS_BTH; // Must be NS_BTH. set.lpNSProviderId = NULL; // Not required. set.lpszContext = NULL; // Not used. set.dwNumberOfProtocols = 0; // Not used. set.lpafpProtocols = NULL; // Not used. set.lpszQueryString = NULL; // not used. set.dwNumberOfCsAddrs = 1; // Must be 1. set.lpcsaBuffer = &info; // Pointer to a CSADDR_INFO. set.lpBlob = NULL; // Optional. if (WSASetService(&set, RNRSERVICE_REGISTER, 0) != 0) { return -1; } listen(listen_sock, 0); printf("listen��accept\n"); SOCKADDR_BTH sab2; int ilen = sizeof(sab2); SOCKET socket = accept(listen_sock, (SOCKADDR *)&sab2, &ilen); printf("accept��recv\n"); char buf[1024] = { 0 }; while(0){ int res = recv(socket, buf, sizeof(buf), 0); if (res > 0) printf("%s", buf); if(res == 0)break; } printf("recv��close\n"); closesocket(listen_sock); closesocket(socket); WSACleanup(); return 0; }
ULONG RunServerMode(int iMaxCxnCycles) { ULONG ulRetCode = 0; int iAddrLen = sizeof(SOCKADDR_BTH), iCxnCount = 0, iLengthReceived = 0, iTotalLengthReceived = 0; LPTSTR lptstrThisComputerName = NULL; DWORD dwLenComputerName = MAX_COMPUTERNAME_LENGTH + 1; SOCKET LocalSocket = INVALID_SOCKET, ClientSocket = INVALID_SOCKET; WSAVERSION wsaVersion = { 0 }; WSAQUERYSET wsaQuerySet = { 0 }; SOCKADDR_BTH SockAddrBthLocal = { 0 }; LPCSADDR_INFO lpCSAddrInfo = NULL; BOOL bContinue; char * pszDataBufferIndex = NULL; char szDataBuffer[CXN_TRANSFER_DATA_LENGTH] = { 0 }; // Both of these fixed-size allocations can be on the stack if ((lpCSAddrInfo = (LPCSADDR_INFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSADDR_INFO))) == NULL) { printf("!ERROR! | Unable to allocate memory for CSADDR_INFO\n"); ulRetCode = 1; goto CleanupAndExit; } else printf("HeapAlloc() for CSADDR_INFO (address) is OK!\n"); if ((lptstrThisComputerName = (LPTSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLenComputerName)) == NULL) { printf("!ERROR! | Unable to allocate memory for CSADDR_INFO\n"); ulRetCode = 1; goto CleanupAndExit; } else printf("HeapAlloc() for CSADDR_INFO (local computer name) is OK!\n"); if (!GetComputerName(lptstrThisComputerName, &dwLenComputerName)) { printf("=CRITICAL= | GetComputerName() call failed. WSAGetLastError=[%d]\n", WSAGetLastError()); ulRetCode = 1; goto CleanupAndExit; } else { printf("GetComputerName() is pretty fine!\n"); printf("Local computer name: %S\n", lptstrThisComputerName); } // Open a bluetooth socket using RFCOMM protocol printf("Opening local socket using socket()...\n"); if ((LocalSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM)) == INVALID_SOCKET) { printf("=CRITICAL= | socket() call failed. WSAGetLastError = [%d]\n", WSAGetLastError()); ulRetCode = 1; goto CleanupAndExit; } if ((2 <= g_iOutputLevel) | (LocalSocket != INVALID_SOCKET)) { printf("*INFO* | socket() call succeeded! Socket = [0x%X]\n", LocalSocket); } // Setting address family to AF_BTH indicates winsock2 to use Bluetooth port SockAddrBthLocal.addressFamily = AF_BTH; // Valid ports are 1 - 31 // SockAddrBthLocal.port = BT_PORT_ANY; SockAddrBthLocal.port = 1; // bind() associates a local address and port combination // with the socket just created. This is most useful when // the application is a server that has a well-known port // that clients know about in advance. if (bind(LocalSocket, (struct sockaddr *) &SockAddrBthLocal, sizeof(SOCKADDR_BTH)) == SOCKET_ERROR) { printf("=CRITICAL= | bind() call failed w/socket = [0x%X]. Error=[%d]\n", LocalSocket, WSAGetLastError()); ulRetCode = 1; goto CleanupAndExit; } if ((2 <= g_iOutputLevel) | (bind(LocalSocket, (struct sockaddr *) &SockAddrBthLocal, sizeof(SOCKADDR_BTH)) != SOCKET_ERROR)) { printf("*INFO* | bind() call succeeded!\n"); } if ((ulRetCode = getsockname(LocalSocket, (struct sockaddr *)&SockAddrBthLocal, &iAddrLen)) == SOCKET_ERROR) { printf("=CRITICAL= | getsockname() call failed w/socket = [0x%X]. WSAGetLastError=[%d]\n", LocalSocket, WSAGetLastError()); ulRetCode = 1; goto CleanupAndExit; } else { printf("getsockname() is pretty fine!\n"); printf("Local address: 0x%x\n", SockAddrBthLocal.btAddr); } // CSADDR_INFO lpCSAddrInfo[0].LocalAddr.iSockaddrLength = sizeof(SOCKADDR_BTH); lpCSAddrInfo[0].LocalAddr.lpSockaddr = (LPSOCKADDR)&SockAddrBthLocal; lpCSAddrInfo[0].RemoteAddr.iSockaddrLength = sizeof(SOCKADDR_BTH); lpCSAddrInfo[0].RemoteAddr.lpSockaddr = (LPSOCKADDR)&SockAddrBthLocal; lpCSAddrInfo[0].iSocketType = SOCK_STREAM; lpCSAddrInfo[0].iProtocol = BTHPROTO_RFCOMM; // If we got an address, go ahead and advertise it. ZeroMemory(&wsaQuerySet, sizeof(WSAQUERYSET)); wsaQuerySet.dwSize = sizeof(WSAQUERYSET); wsaQuerySet.lpServiceClassId = (LPGUID)&g_guidServiceClass; // should be something like "Sample Bluetooth Server" wsaQuerySet.lpszServiceInstanceName = lptstrThisComputerName; wsaQuerySet.lpszComment = "Example Service instance registered in the directory service through RnR"; wsaQuerySet.dwNameSpace = NS_BTH; wsaQuerySet.dwNumberOfCsAddrs = 1; // Must be 1. wsaQuerySet.lpcsaBuffer = lpCSAddrInfo; // Required. // As long as we use a blocking accept(), we will have a race // between advertising the service and actually being ready to // accept connections. If we use non-blocking accept, advertise // the service after accept has been called. if (WSASetService(&wsaQuerySet, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR) { printf("=CRITICAL= | WSASetService() call failed. Error=[%d]\n", WSAGetLastError()); ulRetCode = 1; goto CleanupAndExit; } else printf("WSASetService() looks fine!\n"); // listen() call indicates winsock2 to listen on a given socket for any incoming connection. if (listen(LocalSocket, SOMAXCONN) == SOCKET_ERROR) { printf("=CRITICAL= | listen() call failed w/socket = [0x%X]. Error=[%d]\n", LocalSocket, WSAGetLastError()); ulRetCode = 1; goto CleanupAndExit; } if ((2 <= g_iOutputLevel) | (listen(LocalSocket, SOMAXCONN) != SOCKET_ERROR)) { printf("*INFO* | listen() call succeeded!\n"); } for (iCxnCount = 0; (0 == ulRetCode) && ((iCxnCount < iMaxCxnCycles) || (iMaxCxnCycles == 0)); iCxnCount++) { printf("\n"); // accept() call indicates winsock2 to wait for any // incoming connection request from a remote socket. // If there are already some connection requests on the queue, // then accept() extracts the first request and creates a new socket and // returns the handle to this newly created socket. This newly created // socket represents the actual connection that connects the two sockets. if ((ClientSocket = accept(LocalSocket, NULL, NULL)) == INVALID_SOCKET) { printf("=CRITICAL= | accept() call failed. Error=[%d]\n", WSAGetLastError()); ulRetCode = 1; break; // Break out of the for loop } if ((2 <= g_iOutputLevel) | (ClientSocket != INVALID_SOCKET)) { printf("*INFO* | accept() call succeeded. CientSocket = [0x%X]\n", ClientSocket); } // Read data from the incoming stream bContinue = TRUE; pszDataBufferIndex = &szDataBuffer[0]; while (bContinue && (iTotalLengthReceived < CXN_TRANSFER_DATA_LENGTH)) { // recv() call indicates winsock2 to receive data // of an expected length over a given connection. // recv() may not be able to get the entire length // of data at once. In such case the return value, // which specifies the number of bytes received, // can be used to calculate how much more data is // pending and accordingly recv() can be called again. iLengthReceived = recv(ClientSocket, pszDataBufferIndex, (CXN_TRANSFER_DATA_LENGTH - iTotalLengthReceived), 0); switch (iLengthReceived) { case 0: // socket connection has been closed gracefully printf("Socket connection has been closed gracefully!\n"); bContinue = FALSE; break; case SOCKET_ERROR: printf("=CRITICAL= | recv() call failed. Error=[%d]\n", WSAGetLastError()); bContinue = FALSE; ulRetCode = 1; break; default: // most cases when data is being read pszDataBufferIndex += iLengthReceived; iTotalLengthReceived += iLengthReceived; if ((2 <= g_iOutputLevel) | (iLengthReceived != SOCKET_ERROR)) { //printf("*INFO* | Receiving data of length = [%d]. Current Total = [%d]\n", iLengthReceived, iTotalLengthReceived); } break; } } if (ulRetCode == 0) { if (CXN_TRANSFER_DATA_LENGTH != iTotalLengthReceived) { printf("+WARNING+ | Data transfer aborted mid-stream. Expected Length = [%d], Actual Length = [%d]\n", CXN_TRANSFER_DATA_LENGTH, iTotalLengthReceived); } printf("*INFO* | Received following data string from remote device:\n%s\n", szDataBuffer); // Close the connection if (closesocket(ClientSocket) == SOCKET_ERROR) { printf("=CRITICAL= | closesocket() call failed w/socket = [0x%X]. Error=[%d]\n", LocalSocket, WSAGetLastError()); ulRetCode = 1; } else { // Make the connection invalid regardless ClientSocket = INVALID_SOCKET; if ((2 <= g_iOutputLevel) | (closesocket(ClientSocket) != SOCKET_ERROR)) { printf("*INFO* | closesocket() call succeeded w/socket=[0x%X]\n", ClientSocket); } } } } CleanupAndExit: if (INVALID_SOCKET != ClientSocket) { closesocket(ClientSocket); ClientSocket = INVALID_SOCKET; } if (INVALID_SOCKET != LocalSocket) { closesocket(LocalSocket); LocalSocket = INVALID_SOCKET; } if (NULL != lptstrThisComputerName) { HeapFree(GetProcessHeap(), 0, lptstrThisComputerName); lptstrThisComputerName = NULL; } if (NULL != lpCSAddrInfo) { HeapFree(GetProcessHeap(), 0, lpCSAddrInfo); lpCSAddrInfo = NULL; } return ulRetCode; }