Object Exchange (OBEX) Protocol Primer
Responding to OBEX Notifications
After the device discovering query has started, your application can get notified upon the connection and disconnection events. You may respond to such notifications; for example, by showing the device list and storing device info:
LRESULT CObexSampleDlg::OnObexEvent(WPARAM wParam, LPARAM lParam) { int i; HRESULT hr; TCHAR szDevStr[128]; POBEXDEVICEINFO pFoundDev; OBEXDEVICEINFO diDev; memset (&diDev, 0, sizeof (diDev)); IPropertyBag *pDeviceBag = (IPropertyBag *)lParam; VARIANT var; VariantInit (&var); hr = pDeviceBag->Read(_T("Name"), &var, NULL); if (SUCCEEDED(hr)) { diDev.dwFlags |= DEV_FLAG_NAME; lstrcpy (diDev.szName, var.bstrVal); } VariantClear(&var); hr = pDeviceBag->Read(_T("Address"), &var, NULL); if (SUCCEEDED(hr)) { diDev.dwFlags |= DEV_FLAG_ADDRESS; if (var.vt == VT_BSTR) lstrcpy (diDev.szAddr, var.bstrVal); else if (var.vt == VT_I4) _stprintf (diDev.szAddr, _T("%08x"), var.ulVal); else diDev.dwFlags &= ~DEV_FLAG_ADDRESS; } VariantClear(&var); hr = pDeviceBag->Read(_T("Port"), &var, NULL); if (SUCCEEDED(hr)) { diDev.dwFlags |= DEV_FLAG_PORT; if (var.vt == VT_BSTR) lstrcpy (diDev.szAddr, var.bstrVal); else if (var.vt == VT_I4) _stprintf (diDev.szAddr, _T("%08x"), var.ulVal); else diDev.dwFlags &= ~DEV_FLAG_PORT; } VariantClear(&var); hr = pDeviceBag->Read(_T("Transport"), &var, NULL); if (SUCCEEDED(hr)) { if (var.vt == VT_BSTR) { TCHAR szTran[40]; memset (szTran, 0, sizeof (szTran)); wcsncpy (szTran, var.bstrVal, 38); wcslwr (szTran); LPOLESTR lpszIrDATransport = NULL; LPOLESTR lpszBthTransport = NULL; if ( SUCCEEDED(StringFromCLSID(CLSID_IrdaTransport, &lpszIrDATransport)) && SUCCEEDED(StringFromCLSID(CLSID_BthTransport, &lpszBthTransport)) ) { if (wcsicmp (lpszIrDATransport, szTran) == 0) diDev.dwFlags |= DEV_TRANS_IRDA; else if (wcsicmp (lpszBthTransport, szTran) == 0) diDev.dwFlags |= DEV_TRANS_BTOOTH; } if ( lpszIrDATransport ) CoTaskMemFree(lpszIrDATransport); if ( lpszBthTransport ) CoTaskMemFree(lpszBthTransport); } } VariantClear(&var); hr = pDeviceBag->Read (TEXT("ServiceUUID"), &var, NULL); if (SUCCEEDED(hr)) { TCHAR lpszIr[40]; TCHAR lpszFtp[40]; TCHAR lpszObjPush[40]; if (var.vt == VT_BSTR) { CString sServiceUUID = CComBSTR(var.bstrVal); memset(lpszIr,0,sizeof(lpszIr)); memset(lpszObjPush,0,sizeof(lpszObjPush)); memset(lpszFtp,0,sizeof(lpszFtp)); StringFromGUID2(IrMCSyncServiceClass_UUID, lpszIr,sizeof(lpszIr)/sizeof(TCHAR)); StringFromGUID2(OBEXObjectPushServiceClass_UUID, lpszObjPush, sizeof(lpszObjPush)/sizeof(TCHAR)); StringFromGUID2(OBEXFileTransferServiceClass_UUID, lpszFtp,sizeof(lpszFtp)/sizeof(TCHAR)); if ( sServiceUUID.CompareNoCase(lpszIr) == 0 ) { diDev.dwFlags |= (DEV_FLAG_UUID | DEV_SERVICE_IRMCSYNC); } else if ( sServiceUUID.CompareNoCase(lpszObjPush) == 0 ) { diDev.dwFlags |= (DEV_FLAG_UUID | DEV_SERVICE_OBJPUSH); } else if ( sServiceUUID.CompareNoCase(lpszFtp) == 0 ) { diDev.dwFlags |= (DEV_FLAG_UUID | DEV_SERVICE_FTP); } } } VariantClear(&var); diDev.pDevBag = pDeviceBag; lstrcpy (szDevStr, diDev.szName); lstrcat (szDevStr, _T(" ")); if (diDev.dwFlags & DEV_SERVICE_OBJPUSH) lstrcat (szDevStr, _T("Object Push")); else if (diDev.dwFlags & DEV_SERVICE_FTP) lstrcat (szDevStr, _T("FTP")); else if (diDev.dwFlags & DEV_SERVICE_IRMCSYNC) lstrcat (szDevStr, _T("IrMC Sync")); else if (diDev.dwFlags & DEV_TRANS_IRDA) lstrcat (szDevStr, _T("IrDA")); pFoundDev = m_oObex.FindDevInfo (pDeviceBag); switch ((int)wParam) { case OE_DEVICE_ARRIVAL: if (pFoundDev->pDevBag) break; memcpy (pFoundDev, &diDev, sizeof (diDev)); i = m_DevList.AddString(szDevStr); m_DevList.SetItemDataPtr(i,pFoundDev); break; case OE_DEVICE_UPDATE: i = LB_ERR; memcpy (pFoundDev, &diDev, sizeof (diDev)); if (pFoundDev->pDevBag) { i = FindDevInList(pFoundDev); pFoundDev->pDevBag->Release(); } if (LB_ERR != i) m_DevList.DeleteString(i); i = m_DevList.InsertString(i,szDevStr); m_DevList.SetItemDataPtr(i,pFoundDev); break; case OE_DISCONNECT: case OE_DEVICE_DEPARTURE: if (pFoundDev->pDevBag == 0) break; i = FindDevInList(pFoundDev); if (LB_ERR != i) m_DevList.DeleteString(i); pFoundDev->pDevBag->Release(); pFoundDev->pDevBag = 0; break; case OE_QUERY_PASSWORD: break; } return 0; }
Your callback implementation postsan IPropertyBag object in lParam. You can read various remote device properties such as Name, Address, and so forth via this interface, as shown in above sample.
Page 2 of 3