コード例 #1
0
ファイル: discImpl.cpp プロジェクト: Felard/MoSync
int MASdpEnumAttrs(LPBYTE pSDPStream, ULONG streamSize, std::vector<MAUUID>* pUUIDs) {
	//should fill serv.uuids with what we're looking for, if everything went well.
	//GLE(BluetoothSdpEnumAttributes(pSDPStream, streamSize,
	//	BtEnumAttributesCallback, pUUIDs));

	HRESULT hres;
	ISdpStream *pIStream = NULL;
	ISdpRecord **pSdpRecords = NULL;
	// Create a stream object.
	HRES(CoCreateInstance(__uuidof(SdpStream),NULL,CLSCTX_INPROC_SERVER,
		__uuidof(ISdpStream),(LPVOID *) &pIStream));

	// Ensure that the stream is valid and is well formed.
	hres = pIStream->Validate(pSDPStream,streamSize,NULL);
	if(FAILED(hres)) {
		LOG("SdpStream validation failed: 0x%08X\n", hres);
		//not good; we should return a proper MoSync error code, but the current MASdpEnumAttrs
		//interface doesn't allow it.
		return false;
	}

	SdpWalkListener walker(pUUIDs);
#if 0
	HRES(pIStream->Walk(pSDPStream, streamSize, &walker));
	//ISdpNodeContainer::CreateFromStream(
	return true;
#endif

	// Ensure that the sequence of the stream is valid and is well formed.
#if 1
	ULONG numRecords;
	hres = pIStream->VerifySequenceOf(pSDPStream,streamSize,
		SDP_TYPE_SEQUENCE,NULL,&numRecords);
	LOGBT("%i SDP records\n", numRecords);

	if (SUCCEEDED(hres) && numRecords > 0) {
		//Allocate memory for the SDP record buffer.
		pSdpRecords = (ISdpRecord **) CoTaskMemAlloc(sizeof(ISdpRecord*) * (numRecords));
		if (pSdpRecords != NULL) {
			// Retrieve the SDP records from the stream.
			hres = pIStream->RetrieveRecords(pSDPStream, 
				streamSize,pSdpRecords,&numRecords);

			if(SUCCEEDED(hres)) {
				//SdpWalkListener *walkListener = new SdpWalkListener(pUUIDs);
				for(unsigned int i = 0; i < numRecords; i++) {
					LOGBT("SDP Walk %i\n", i);
					pSdpRecords[i]->Walk(&walker);//walkListener);
				}
			}

			CoTaskMemFree(pSdpRecords);
			pSdpRecords = NULL;
			numRecords = 0;
		}
		else 
		{
			LOGBT("Bluetooth Service discovery: Out of Memory\n");
			hres = E_OUTOFMEMORY;
		}	
	} else {
		LOGBT("pIStream->VerifySequenceOf failed\n");
	}
#endif

	return SUCCEEDED(hres);
}
コード例 #2
0
HRESULT FindRFCOMMChannel (unsigned char *pStream, int cStream,
			   unsigned long *nChannel)
{
	ISdpRecord **pRecordArg = NULL;
	int cRecordArg          = 0;
	ISdpStream *pIStream    = NULL;
	HRESULT hr              = 0;
	ULONG ulError           = 0;

	*nChannel = 0;

	hr = CoCreateInstance(__uuidof(SdpStream),NULL,
		CLSCTX_INPROC_SERVER,
		__uuidof(ISdpStream),(LPVOID *)
		&pIStream);

	if ( FAILED(hr) || pIStream == NULL )
		return hr;

	hr = pIStream->Validate (pStream, cStream,&ulError);

	if (SUCCEEDED(hr))
	{
		hr = pIStream->VerifySequenceOf(pStream, cStream,
			SDP_TYPE_SEQUENCE,NULL,
			(ULONG *)&cRecordArg);

		if (SUCCEEDED(hr) && cRecordArg > 0)
		{
			pRecordArg =
				(ISdpRecord **) CoTaskMemAlloc(sizeof(ISdpRecord*)
				* cRecordArg);

			if (pRecordArg != NULL)
			{
				hr =
					pIStream->RetrieveRecords(pStream, cStream,
					pRecordArg,(ULONG *)
					&cRecordArg);

				if ( FAILED(hr) )
				{
					CoTaskMemFree(pRecordArg);
					pRecordArg = NULL;
					cRecordArg = 0;
				}
			}
			else
			{
				hr = E_OUTOFMEMORY;
			}
		}
	}

	if (pIStream != NULL)
	{
		pIStream->Release();
		pIStream = NULL;
	}

	if ( FAILED(hr) )
		return hr;

	for (int i = 0; (*nChannel == 0) && (i < cRecordArg); i++)
	{
		ISdpRecord *pRecord = pRecordArg[i];
		// contains SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST data,
		// if available
		NodeData protocolList;

		if (ERROR_SUCCESS !=
			pRecord->GetAttribute(SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST,
			&protocolList) ||
			(protocolList.type !=
			SDP_TYPE_CONTAINER))
		{
			if (protocolList.type == SDP_TYPE_STRING)
				CoTaskMemFree(protocolList.u.str.val);
			else if (protocolList.type == SDP_TYPE_URL)
				CoTaskMemFree(protocolList.u.url.val);
			continue;
		}

		ISdpNodeContainer *pRecordContainer = protocolList.u.container;
		int cProtocols = 0;
		NodeData protocolDescriptor;

		pRecordContainer->GetNodeCount((DWORD *)&cProtocols);
		for (int j = 0; (nChannel == 0) && (j < cProtocols); j++)
		{
			pRecordContainer->GetNode(j,&protocolDescriptor);

			if (protocolDescriptor.type != SDP_TYPE_CONTAINER)
				continue;

			ISdpNodeContainer *pProtocolContainer =
				protocolDescriptor.u.container;
			int cProtocolAtoms = 0;
			pProtocolContainer->GetNodeCount((DWORD *)&cProtocolAtoms);

			for (int k = 0; (nChannel == 0) && (k < cProtocolAtoms); k++)
			{
				NodeData nodeAtom;
				pProtocolContainer->GetNode(k,&nodeAtom);

				if (IsRfcommUuid(&nodeAtom))
				{
					if (k+1 == cProtocolAtoms)
					{
						// Error: Channel ID should follow RFCOMM uuid
						break;
					}

					NodeData channelID;
					pProtocolContainer->GetNode(k+1,&channelID);

					switch(channelID.specificType)
					{
					case SDP_ST_UINT8:
						*nChannel = channelID.u.uint8;
						break;
					case SDP_ST_INT8:
						*nChannel = channelID.u.int8;
						break;
					case SDP_ST_UINT16:
						*nChannel = channelID.u.uint16;
						break;
					case SDP_ST_INT16:
						*nChannel = channelID.u.int16;
						break;
					case SDP_ST_UINT32:
						*nChannel = channelID.u.uint32;
						break;
					case SDP_ST_INT32:
						*nChannel = channelID.u.int32;
						break;
					default:
						*nChannel = 0;
					}
					break;
				}
			}
		}
		if (protocolList.type == SDP_TYPE_STRING)
			CoTaskMemFree(protocolList.u.str.val);
		else if (protocolList.type == SDP_TYPE_URL)
			CoTaskMemFree(protocolList.u.url.val);
	}

	// cleanup
	for (int i = 0; i < cRecordArg; i++)
		pRecordArg[i]->Release();
	CoTaskMemFree(pRecordArg);

	return (*nChannel != 0) ? S_OK : S_FALSE;
}
コード例 #3
0
ファイル: discImpl.cpp プロジェクト: Felard/MoSync
int handleSdpResponse(std::vector<BtService>* services, LPWSAQUERYSET pQs) {
	//set up SdpStream

	HRESULT hres;
	ISdpStream *pIStream = NULL;
	//ISdpRecord **pSdpRecords = NULL;
	// Create a stream object.
	HRES(CoCreateInstance(__uuidof(SdpStream),NULL,CLSCTX_INPROC_SERVER,
		__uuidof(ISdpStream), (LPVOID *)&pIStream));

	BYTE* pSDPStream = pQs->lpBlob->pBlobData;
	ULONG streamSize = pQs->lpBlob->cbSize;

	DUMPHEX(pSDPStream);
	DUMPHEX(streamSize);
	DUMPHEX(pIStream);

	// Ensure that the stream is valid and is well formed.
	hres = pIStream->Validate(pSDPStream, streamSize, NULL);
	if(FAILED(hres)) {
		LOG("SdpStream validation failed: 0x%08X\n", hres);
		return CONNERR_GENERIC;
	}

	//get list of Records

	int numRecords;
	hres = pIStream->VerifySequenceOf(pSDPStream, streamSize,
		SDP_TYPE_SEQUENCE, NULL, (ULONG*)&numRecords);
	LOGBT("SdpStream verification result: 0x%08X\n", hres);
	if(FAILED(hres) || numRecords<=0) {
		LOG("SdpStream verification failed: 0x%08X, numRecords: %d\n", hres, numRecords);
		return CONNERR_GENERIC;
	}
	LOGBT("%i SDP records\n", numRecords);

	//pSdpRecords = (ISdpRecord **) CoTaskMemAlloc(sizeof(ISdpRecord*) * (numRecords));

	Array<ISdpRecord*> pSdpRecords(numRecords);
	MYASSERT(pSdpRecords != NULL, ERR_OOM);

	// Retrieve the SDP records from the stream.
	hres = pIStream->RetrieveRecords(pSDPStream, streamSize, pSdpRecords.p(), (ULONG *) &numRecords);
	if(FAILED(hres)) {
		LOG("SdpStream retrieval failed: 0x%08X\n", hres);
		return CONNERR_GENERIC;
	}

	//one Service per Record
	//Walk
	//store results in *services

	for(int i = 0; i < numRecords; i++) {
		LOGBT("SDP Walk %i\n", i);
		BtService serv;
		MySdpWalk walk(serv);
		hres = pSdpRecords[i]->Walk(&walk);
		if(FAILED(hres)) {
			LOG("SdpStream walk failed: 0x%08X\n", hres);
			return CONNERR_GENERIC;
		}
		services->push_back(serv);
	}

	return 1;
}