October 23, 2018
Hot Topics:

Object Exchange (OBEX) Protocol Primer

  • December 27, 2005
  • By Alex Gusev
  • Send Email »
  • More Articles »

What OBEX Stands For

According to its name, OBEX stands for OBject EXchange. It allows the devices to exchange standard objects such as files, business cards, and calendar infos. This is a vendor-independent protocol implemented on different OSes, such as Palm OS and Windows CE. The actual OBEX support on a particular mobile device depends on system configuration; in other words, vendors can decide what to put there, but at least the OBEX Push protocol is usually presented because it is supported by an Inbox application.

If you turn to the Windows Mobile area, you now can choose between IrDA and Bluetooth as underlying transports. OBEX does all the transport-specific work for you, so there is no need to worry about such things like BT devices being discovered and so forth. In addition, there are a number of COM interfaces to control OBEX as well as to perform device enumeration:

  • IObex
  • IObex2
  • IObexDevice
  • IHeaderCollection
  • IObexSink
  • IObexService
  • IObexServiceConnection
  • IInboxSink
  • IHeaderEnum
  • IPropertyBagEnum
  • IDeviceEnum
  • IObexCaps

I won't disscuss all of them, but I will cover IObexService, IObexServiceConnection, and IInboxSink; they are used in the article's sample project. Moreover, in many cases you will need Object Push rather than Object Pull, so you will cover only sending data process, leaving it up to the OS to implement receiving operations (or GET in terms of OBEX). You also can implement GET operation at low level—for example, with WinSock—according to OBEX protocol description.


Your entry point to OBEX is the IObex and IObex2 interfaces. A common workflow, therefore, will be as follows:

  • Initialize OBEX
  • Find a connection point and command OBEX to send notifications on the remote device's arrival or departure
  • Enumerate devices
  • Handle OBEX events
  • Perform all required transfers
  • Shut down OBEX

The very first step is to make an initialization. You will assume that IObex2 is supported in your system:

int CObex::InitObex(HWND hWnd)
   HRESULT hr;
   CString sInfo;
   CComPtr<IObex> pObex;
   m_hWnd = hWnd;
   hr = pObex.CoCreateInstance(__uuidof(Obex),NULL,
      sInfo.Format(_T("Failed to initialize Obex interface:
                   hr = 0x%X, err =  0x%Xn"),
                   hr, GetLastError());
      ::SendMessage(m_hWnd, WM_OBEX_INFO,0,(LPARAM)&sInfo);
      return 0;
   hr = pObex->QueryInterface(__uuidof(IObex2),(void**)&m_pObex);
      sInfo.Format(_T("Failed to initialize Obex interface:
                   hr = 0x%X, err =  0x%Xn"),
                   hr, GetLastError());
      ::SendMessage(m_hWnd, WM_OBEX_INFO,0,(LPARAM)&sInfo);
      return 0;
   if (!m_pObex)
      return 0;
   IObexCaps *pObexCaps = NULL;
   hr = m_pObex->QueryInterface(IID_IObexCaps,
                                (LPVOID *)&pObexCaps);
   CCriticalSection csLock;
   IObexSinkImpl *pSink = new IObexSinkImpl(hWnd);
   if (!pSink)
      return 0;
   hr = m_pObex->QueryInterface(IID_IConnectionPointContainer,
                                (LPVOID *)&m_pContainer);
   if (!SUCCEEDED(hr) || (m_pContainer == 0))
      return 0;
   hr = m_pContainer->FindConnectionPoint(IID_IObexSink,
   if (!SUCCEEDED(hr) || (m_pConPoint == 0))
      return 0;
   hr = m_pConPoint->Advise((IUnknown *)pSink, &m_dwCookie);
   if (ERROR_SUCCESS != m_pObex->StartDeviceEnum())
      return 0;
   if(!SUCCEEDED(hr) || (pDeviceEnum == 0))
      return 0;
   return 1;

This code snippet illustrates the entire process: Create all required interfaces, look for connection point, and advise for sink object. Please note that, to receive callback notifications, you have to implement a simple COM-like class. In this sample, it is IObexSinkImpl. All it actually does is to implement the Notify method to pass events to the main application. After all objects are ready, you can start a device lookup. You can collect all devices in range either with a Notify callback or directly by a

CComPtr<IDeviceEnum> pDeviceEnum;
hr = m_pObex->EnumDevices(&pDeviceEnum, GUID_NULL);

call. This function returns the IDeviceEnum interface, which allows you to surf through device enumeration. The last parameter defines a device type to request. You want all devices in range, so sending CLSID_NULL will do. If you want a specific device class, you can do it by sending the appropriate parameter here. The following table lists possible values:

Value Description
CLSID_BthTransport A device that uses Bluetooth to communicate with other devices
CLSID_HeaderCollection The header collection of a device
CLSID_IpTransport A device that uses TCP/IP to communicate with other devices
CLSID_IrdaTransport A device that uses IRdA to communicate with other devices
CLSID_Obex An OBEX-class device
CLSID_PropertyBag The property bag of a device

Page 1 of 3

Comment and Contribute


(Maximum characters: 1200). You have characters left.



Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

By submitting your information, you agree that developer.com may send you developer offers via email, phone and text message, as well as email offers about other products and services that developer believes may be of interest to you. developer will process your information in accordance with the Quinstreet Privacy Policy.


Thanks for your registration, follow us on our social networks to keep up-to-date