.: Links :.

Home | Forums | Desert Computer Agents

.: VC++ Widcomm Tutorial :.
By Nicholas A. Hall

 
There are about 5 Main Bluetooth Stacks for Windows Currently known as
1: Widcomm Stack
2: Microsoft Stack
3: Toshiba Stack
4: EtherMind stack
5: BlueSoleil

	You may look up a description at Wiki
for futher information. Now lets get started. A Huge number of people on the internet are requesting how to get
1: RSSI Value from any of these stacks
2: Get Distance of Bluetooth Device

Well which one of these do? All of them support RSSI one way or another, BUT only for mostly Mobile systems such as
Windows Mobile 6/CE. What about Desktop/laptop? The only one I have found that supports RSSI Via Desktop/Laptop is
WIDCOMM on Windows XP SP2/3. Ive taken the time to help the public with sample code to get started and get on their
way to bluetooth programming.

A couple of things are required to start testing.

Microsoft Visual Studio 6.0 C++

You need the SDK which is now free
http://www.broadcom.com/support/bluetooth/sdk.php

Driver for WIDCOMM Device's
http://www.broadcom.com/support/bluetooth/update.php

Need this for BluetoothAPI.h, you need thing to program bluetooth in general
Windows® Server 2003 SP1 Platform SDK Web Install

WIDCOMM requires MFC <--- Why dident they tell us this in the SDK Manuel?

A Broadcom WIDCOMM Chipset Dongel
http://www.frys.com/product/5756272
that's the f8t016, they also have the f8t013 for $9.90 no rebate
Any F8t Series should work perfectly fine but there are others!

And perhaps a Headset to use or something of the sort to connect to and send information.

Now lets get started, Once you've installed all the Software you can run Microsoft VS 6 C++

One opened, Click File -> New -> MFC AppWizard (exe), Then enter in a Project name. Proceed by
clicking "OK"

"MFC AppWizard - Step 1" will appear, We need to change this to a "Dialog based" project.

Then click "Finished" Enless you want to customize further, Which is not needed.

You are then greeted with a Dialog Box to start created your first Widcomm Bluetooth Application.
First thing we need to do is start adding all of our librarys we downloaded and installed so our
project can use them to talk to the bluetooth device.

Click Project -> Settings -> "Project Settings Will Appear" -> Click Drop-down box "Settings For" -> 
Select "All Configurations" -> Click C/C++ -> "Locate Preprocessor definitions" -> Add ",_BTWLIB"

In the end it should look like this "WIN32,_DEBUG,_WINDOWS,_AFXDLL,_MBCS,_BTWLIB"

Then Click "Link" Tab -> "Locate Category:" -> Switch to "Customize", Then Check "Force file output"

Now lets add the Directories. Click "OK" to close and save settings for our "Project Settings"

Now back into our main project click "Tools" -> "Options" -> "Directories" then add to the "Include files"
"C:\PROGRAM FILES\WIDCOMM\BTW DK\SDK\INC"
"C:\PROGRAM FILES\MICROSOFT PLATFORM SDK\INCLUDE"

Click Select "Library files" from the "Show directories for:" Drop-Down box, then add
"C:\PROGRAM FILES\WIDCOMM\BTW DK\SDK\RELEASE"
"C:\PROGRAM FILES\MICROSOFT PLATFORM SDK\LIB"

Then click "OK" to save the settings.

Go to "ClassView"

You shoudl see 3 Classes Under your Project
CAboutDlg
C(ProjectName)App
C(ProjectName)Dlg
then your Globals. Double Click C(ProjectName)Dlg Your View should now be
// (ProjectName)Dlg.h : header file
//

#if !defined(AFX_L2CAPDLG_H__444B25A1_1A66_4F9B_BC0F_DC2286602D73__INCLUDED_)
#define AFX_L2CAPDLG_H__444B25A1_1A66_4F9B_BC0F_DC2286602D73__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/////////////////////////////////////////////////////////////////////////////
// (ProjectName)Dlg dialog

class (ProjectName)Dlg : public CDialog
{
// Construction
public:
	...
	...
	...
//CODE
We need to subclass this to inhaite our Bluetooth Commands, Change it by appending public CBtIf class C(ProjectName)Dlg : public CDialog, public CBtIf then after add

#include "btwlib.h"  //Widcomm Stack
#include 
#pragma comment(lib, "version.lib")
#pragma comment(lib, "Ws2_32.lib")

to the top. Your end result is this

// (ProjectName)Dlg.h : header file
//
#include "btwlib.h"  //Widcomm Stack
#include 
#pragma comment(lib, "version.lib")
#pragma comment(lib, "Ws2_32.lib")

#if !defined(AFX_L2CAPDLG_H__444B25A1_1A66_4F9B_BC0F_DC2286602D73__INCLUDED_)
#define AFX_L2CAPDLG_H__444B25A1_1A66_4F9B_BC0F_DC2286602D73__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/////////////////////////////////////////////////////////////////////////////
// (ProjectName)Dlg dialog

class (ProjectName)Dlg : public CDialog, public CBtIf
{
// Construction
public:
	...
	...
	...
//CODE

Now once done we need to do some error correcting, Proceed by pressing 'F5' then confirming the build and await the errors.... You should get something like this [Quote] Error executing cl.exe. L2CAP.exe - 24 error(s), 1 warning(s) [/Quote] [Quote] --------------------Configuration: L2CAP - Win32 Debug-------------------- Compiling... L2CAPDlg.cpp c:\program files\microsoft platform sdk\include\bluetoothapis.h(1176) : error C2146: syntax error : missing ';' before identifier 'type' c:\program files\microsoft platform sdk\include\bluetoothapis.h(1176) : error C2501: 'SDP_TYPE' : missing storage-class or type specifiers c:\program files\microsoft platform sdk\include\bluetoothapis.h(1176) : error C2501: 'type' : missing storage-class or type specifiers c:\program files\microsoft platform sdk\include\bluetoothapis.h(1181) : error C2146: syntax error : missing ';' before identifier 'specificType' c:\program files\microsoft platform sdk\include\bluetoothapis.h(1181) : error C2501: 'SDP_SPECIFICTYPE' : missing storage-class or type specifiers c:\program files\microsoft platform sdk\include\bluetoothapis.h(1181) : error C2501: 'specificType' : missing storage-class or type specifiers c:\program files\microsoft platform sdk\include\bluetoothapis.h(1190) : error C2146: syntax error : missing ';' before identifier 'int128' c:\program files\microsoft platform sdk\include\bluetoothapis.h(1190) : error C2501: 'SDP_LARGE_INTEGER_16' : missing storage-class or type specifiers c:\program files\microsoft platform sdk\include\bluetoothapis.h(1190) : error C2501: 'int128' : missing storage-class or type specifiers c:\program files\microsoft platform sdk\include\bluetoothapis.h(1197) : error C2146: syntax error : missing ';' before identifier 'uint128' c:\program files\microsoft platform sdk\include\bluetoothapis.h(1197) : error C2501: 'SDP_ULARGE_INTEGER_16' : missing storage-class or type specifiers c:\program files\microsoft platform sdk\include\bluetoothapis.h(1197) : error C2501: 'uint128' : missing storage-class or type specifiers C:\Documents and Settings\MAP\My Documents\Visual Studio 6.0\MFC\L2CAP\L2CAPDlg.cpp(176) : warning C4805: '==' : unsafe mix of type 'int' and type 'const bool' in operation Generating Code... Compiling... L2CAP.cpp c:\program files\microsoft platform sdk\include\bluetoothapis.h(1176) : error C2146: syntax error : missing ';' before identifier 'type' c:\program files\microsoft platform sdk\include\bluetoothapis.h(1176) : error C2501: 'SDP_TYPE' : missing storage-class or type specifiers c:\program files\microsoft platform sdk\include\bluetoothapis.h(1176) : error C2501: 'type' : missing storage-class or type specifiers c:\program files\microsoft platform sdk\include\bluetoothapis.h(1181) : error C2146: syntax error : missing ';' before identifier 'specificType' c:\program files\microsoft platform sdk\include\bluetoothapis.h(1181) : error C2501: 'SDP_SPECIFICTYPE' : missing storage-class or type specifiers c:\program files\microsoft platform sdk\include\bluetoothapis.h(1181) : error C2501: 'specificType' : missing storage-class or type specifiers c:\program files\microsoft platform sdk\include\bluetoothapis.h(1190) : error C2146: syntax error : missing ';' before identifier 'int128' c:\program files\microsoft platform sdk\include\bluetoothapis.h(1190) : error C2501: 'SDP_LARGE_INTEGER_16' : missing storage-class or type specifiers c:\program files\microsoft platform sdk\include\bluetoothapis.h(1190) : error C2501: 'int128' : missing storage-class or type specifiers c:\program files\microsoft platform sdk\include\bluetoothapis.h(1197) : error C2146: syntax error : missing ';' before identifier 'uint128' c:\program files\microsoft platform sdk\include\bluetoothapis.h(1197) : error C2501: 'SDP_ULARGE_INTEGER_16' : missing storage-class or type specifiers c:\program files\microsoft platform sdk\include\bluetoothapis.h(1197) : error C2501: 'uint128' : missing storage-class or type specifiers Generating Code... Error executing cl.exe. L2CAP.exe - 24 error(s), 1 warning(s) [/Quote] You need to comment out 4 linesn in bluetoothapis.h then click File -> Save the changes The four lines are as follows

//SDP_TYPE type;
//SDP_SPECIFICTYPE specificType;
//SDP_LARGE_INTEGER_16 int128;        // specificType == SDP_ST_INT128
//SDP_ULARGE_INTEGER_16 uint128;      // specificType == SDP_ST_UINT128

Compile again and you should also get this error [Quote] LINK : fatal error LNK1104: cannot open file "..\..\sdk\release\WidcommSdklib.lib" [/Quote] This error is due to btwlib.h including librarys from a path that does not exist on our system and needs to be changed from
/////////////////////////////////////////////////////////////////////////////
//
//  Name        BtwLib.h
//  $Header:
//
//  Function    this file facilitates linking the SDK library and including
//  			other SDK headers
//
//  Date                 Modification
//  ----------------------------------
//  09/11/2003    HZ   Create
//
//  Copyright (c) 2000-2006, Broadcom Corporation, All Rights Reserved.
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#if (_MSC_FULL_VER >= 140050727)
    // use this lib for VS2005 wchar definition 
    // Note: using _MSC_VER >= 1400 is not sufficient, MSFT VC++ 6.0 under AMD64 
    // configuration February 2003 Platform SDK, the compiler (incorrectly) identifies
    // itself as 1400, so this is the accurate method.
    //
    // See Programmer's Guide - must redistribute btwapi.dll to use BtWdSdkLib.lib on
    // older BTW stack targets
    #ifdef _WIN64
        #pragma comment(lib, "..\\..\\sdk\\release\\x64\\BtWdSdkLib.lib")
    #else
        #pragma comment(lib, "..\\..\\sdk\\release\\BtWdSdkLib.lib")
    #endif
#else
    // use this for previous compilers
    #ifdef _WIN64
        #pragma comment(lib, "..\\..\\sdk\\release\\amd64\\WidcommSdklib.lib")
    #else
        #pragma comment(lib, "..\\..\\sdk\\release\\WidcommSdklib.lib")
    #endif
#endif

#include "BtIfDefinitions.h"
#include "BtIfClasses.h"
to
/////////////////////////////////////////////////////////////////////////////
//
//  Name        BtwLib.h
//  $Header:
//
//  Function    this file facilitates linking the SDK library and including
//  			other SDK headers
//
//  Date                 Modification
//  ----------------------------------
//  09/11/2003    HZ   Create
//
//  Copyright (c) 2000-2006, Broadcom Corporation, All Rights Reserved.
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#if (_MSC_FULL_VER >= 140050727)
    // use this lib for VS2005 wchar definition 
    // Note: using _MSC_VER >= 1400 is not sufficient, MSFT VC++ 6.0 under AMD64 
    // configuration February 2003 Platform SDK, the compiler (incorrectly) identifies
    // itself as 1400, so this is the accurate method.
    //
    // See Programmer's Guide - must redistribute btwapi.dll to use BtWdSdkLib.lib on
    // older BTW stack targets
    #ifdef _WIN64
        #pragma comment(lib, "..\\..\\sdk\\release\\x64\\BtWdSdkLib.lib")
    #else
        #pragma comment(lib, "C:\\Program Files\\Widcomm\\BTW DK\\SDK\\Release\\BtWdSdkLib.lib")
    #endif
#else
    // use this for previous compilers
    #ifdef _WIN64
        #pragma comment(lib, "..\\..\\sdk\\release\\amd64\\WidcommSdklib.lib")
    #else
        #pragma comment(lib, "C:\\Program Files\\Widcomm\\BTW DK\\SDK\\Release\\WidcommSdklib.lib")
    #endif
#endif

#include "BtIfDefinitions.h"
#include "BtIfClasses.h"
Try building your project now and it should build just fine! Keep in mind that when you call certin Bluetooth commands YOUR COMPUTER SHOULD NOT HANG 100%! I've had this before I reinstalled my OS then when I ran the same code I got [Quote] Unhandled exception in L2CAP.exe: 0xC0000005: Access Violation. [/Quote] And if your getting that too I recommend the same due to unknown reasons! Now go to your resource view and add 2 buttons Start Inquiry Get Conn stats Double Click the buttons to add the events and code Under "Start Inquiry add"

// TODO: Add your control notification handler code here
	if (StartInquiry() == true)
	{
		OutputDebugString("Starting To Inquiry"); 
		StartInquiry();
	}
	else
	{
		OutputDebugString("Starting To Inquiry FAILED!"); 
	}

Now in the (ProjectName)Dlg.h you need to receive events to work with bluetooth This code needs to be inserted between

// (ProjectName)Dlg.h : header file
//
#include "btwlib.h"  //Widcomm Stack
#include 
#pragma comment(lib, "version.lib")
#pragma comment(lib, "Ws2_32.lib")

#if !defined(AFX_L2CAPDLG_H__444B25A1_1A66_4F9B_BC0F_DC2286602D73__INCLUDED_)
#define AFX_L2CAPDLG_H__444B25A1_1A66_4F9B_BC0F_DC2286602D73__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/////////////////////////////////////////////////////////////////////////////
// CL2CAPDlg dialog

class (ProjectName)Dlg : public CDialog, public CBtIf
{
// Construction
public:
	(ProjectName)Dlg(CWnd* pParent = NULL);	// standard constructor

// Dialog Data
	//{{AFX_DATA(CL2CAPDlg)
	enum { IDD = IDD_L2CAP_DIALOG };
		// NOTE: the ClassWizard will add data members here
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CL2CAPDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
	//}}AFX_VIRTUAL

And

// Implementation
protected:
	HICON m_hIcon;

	// Generated message map functions
	//{{AFX_MSG(CL2CAPDlg)
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	afx_msg void OnStart();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_L2CAPDLG_H__444B25A1_1A66_4F9B_BC0F_DC2286602D73__INCLUDED_)


BLUETOOTH_DEVICE_INFO	btDevInfo;

//For Discovery
int    i, nRecs;
CSdpDiscoveryRec		m_sdpRecs[16];
CRfCommIf * MyRF;
CRfCommPort * ComPort;
void C(ProjectName)Dlg::OnDeviceResponded(BD_ADDR bda,DEV_CLASS devClass,BD_NAME bdName,BOOL bConnected)
		{
			memset(&btDevInfo, 0, sizeof(btDevInfo));
			btDevInfo.dwSize     = sizeof(BLUETOOTH_DEVICE_INFO);
			btDevInfo.fConnected = bConnected; 
			memcpy(btDevInfo.Address.rgBytes, bda, BD_ADDR_LEN);
			// Set the device class
			btDevInfo.ulClassofDevice = ((ULONG)devClass[0] << 16) + ((ULONG)devClass[1] <<  8) + devClass[2]; 

			MultiByteToWideChar(CP_ACP, 0, (const char*)bdName,BD_NAME_LEN,btDevInfo.szName, BD_NAME_LEN); 

			OutputDebugString("OnDeviceResponded\r\n");
			OutputDebugString("Connected: ");
			if (bConnected == true) {OutputDebugString("True\r\n");} else {OutputDebugString("False\r\n");}
			
			OutputDebugString("Device Name: ");
			OutputDebugString((LPCSTR)bdName);
			OutputDebugString("\r\n");

			CString strDevClass;
            		CString strAddress; 

			strDevClass.Format("%X", btDevInfo.ulClassofDevice);

			OutputDebugString("Class Of Device: ");
			OutputDebugString(strDevClass);
			OutputDebugString("\r\n");

			strAddress.Format("%02X:%02X:%02X:%02X:%02X:%02X",
                              btDevInfo.Address.rgBytes[0],
                              btDevInfo.Address.rgBytes[1],
                              btDevInfo.Address.rgBytes[2],
                              btDevInfo.Address.rgBytes[3],
                              btDevInfo.Address.rgBytes[4],
                              btDevInfo.Address.rgBytes[5]); 

			OutputDebugString("BTAddr: ");
			OutputDebugString(strAddress);
			OutputDebugString("\r\n");
			
			StartDiscovery(btDevInfo.Address.rgBytes, NULL); 
		} 

void C(ProjectName)Dlg::OnInquiryComplete(BOOL bSuccess, short nResponses)
		{
			OutputDebugString("OnInquiryComplete\r\n");
		}

void C(ProjectName)Dlg::OnDiscoveryComplete()
		{
			nRecs = ReadDiscoveryRecords(btDevInfo.Address.rgBytes,16, m_sdpRecs, NULL);

			OutputDebugString("-------Service Names-------\r\n");

			for(i = 0; i < nRecs; ++i)
			{
				CString strGuid;
				GUID    guid    = m_sdpRecs[i].m_service_guid;
				UINT8   channel;

				OutputDebugString(m_sdpRecs[i].m_service_name);
				OutputDebugString("\r\n");

				strGuid.Format("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
					guid.Data1, guid.Data2, guid.Data3,
					guid.Data4[0],
					guid.Data4[1],
					guid.Data4[2],
					guid.Data4[3],
					guid.Data4[4],
					guid.Data4[5],
					guid.Data4[6],
					guid.Data4[7]);

				OutputDebugString("GUID: ");
				OutputDebugString(strGuid);
				OutputDebugString("\r\n");

				UINT16 PSM;

				if(m_sdpRecs[i].FindL2CapPsm(&PSM))
				{
					CString strPSM;

					strPSM.Format("%d", PSM);
					OutputDebugString("L2CAP PSM: ");
					OutputDebugString(strPSM);
					OutputDebugString("\r\n\r\n");
				}

				if(m_sdpRecs[i].FindRFCommScn(&channel))
				{
					CString strChannel;

					strChannel.Format("%d", channel);
					OutputDebugString("RFCOMM Channel: ");
					OutputDebugString(strChannel);
					OutputDebugString("\r\n\r\n");

					if (channel==1)
					{

						if ( SUCCESS == Bond(btDevInfo.Address.rgBytes, "0000")) 
						{ 
							OutputDebugString("Bonded\r\n"); 
						} 
				
						//CRfCommConn MyRFControl;
						MyRF = new CRfCommIf;

						if (!MyRF->AssignScnValue(&guid)) 
						{ 
							OutputDebugString("Failed To Set ScnValue"); 
							return;
						}

						UINT8 sec_level = BTM_SEC_OUT_AUTHENTICATE;//BTM_SEC_NONE;

						if (!MyRF->SetSecurityLevel((char *)m_sdpRecs[i].m_service_name, sec_level, false)) 
						{ 
							WBtRc err = GetExtendedError(); 
							OutputDebugString("Failed To Set Security Level\r\n"); 
							return;
						}

						ComPort = new CRfCommPort;
						if (! ComPort->OpenClient(MyRF->GetScn(), btDevInfo.Address.rgBytes)) 
						{ 
							OutputDebugString("Failed To Connect RFCOMM"); 
							return; 
						}

						OutputDebugString("Connected!");

					}
				}

			}
			
			OutputDebugString("----END OF Service Names----\r\n\r\n");

			return; 
		}

This right here will work

.: Links :.

Home | Forums | Desert Computer Agents