Developer

API Reference

IBTImagePullResponder

Brew Release
Brew MP 1.0.2
Description
Bluetooth Basic Imaging Profile version 1.0, Image Pull Responder role
This interface allows application to become a responder in the Image Pull feature defined by Bluetooth BIP specifications.
For more information, refer to http://bluetooth.com/Bluetooth/Technology/Works/BIP.htm
Usage

   
   ===== To create an IBTImagePullResponder object, 
   see instruction in class header file
 
 
   ===== To register signal
   // first create the signals;
   // for example, use ISignalCBFactory_CreateSignal()
   // then register the signals:
   IBTImagePullResponder_OnEventNotify(piBTBIPSrv, piSignal);


   ===== Find out what imaging capabilities the responder object has:
   char* pszCapXML = NULL;
   int nLen = 0;
   IBTImagePullResponder_ReadDefaultCap(piResponder, pszCapXML, nLen, &nLen);
   pszCapXML = MALLOC(nLen);
   if (NULL != pszCapXML)
   {
      IBTImagePullResponder_ReadDefaultCap(piResponder, 
                                           pszCapXML, nLen, &nLen);

      // determine if object's imaging capability is adequate
      // in this example, let's assume application prefers 
      // to handle all requests
      pMe->cFuncToHandle = AEEBTBIP_FUNC_ALL;
      FREEIF(pszCapXML);
   }


   ===== To get an associated IOBEXAuthentication object:
   IBTImagePullResponder_QueryInterface(piResponder, 
                                        AEEIID_IOBEXAuthentication,
                                        (void**)&pMe->piAuth);

   // prepare for authentication initiated by initiator
   IOBEXAuthentication_OnRequest(pMe->piAuth, piAuthReqSig);

   // prepare to initiate authentication; this tells responder object
   // whether incoming connection request should be authenticated
   char szRealm[] = "James Photos";
   IOBEXAuthentication_Config(pMe->piAuth,
                              MIBENUM_CHARSET_US_ASCII,
                              (uint8*)szRealm,
                              STRLEN (szRealm),
                              bUserIDRequired,
                              FALSE, // default access is read-only
                              TRUE); // config data invalid after next operation
   IOBEXAuthentication_OnResponse(pMe->piAuth, piAuthRespSig);

   
   ===== To enable Image Pull Responder:
   FSStatVFSEx stat;
   if ((AEE_SUCCESS == ISHELL_CreateInstance(piShell, AEECLSID_FileSystem2, 
                                             &pMe->piFS)) &&
       (AEE_SUCCESS == IFileSystem2_StatVFS(pMe->piFS, pszMyRootFolder, &stat)))
   {
      IBTImagePullResponder_Enable(
         piResponder, 
         AEEBT_SEC_SM4_MEDIUM,
         stat.qwMaxFSSpace,
         "Image Pull",
         AEEBTBIP_CAP_CAPTURING,   // this is a camera app in this example
         AEEBTBIP_PUSH_NONE);
   }
 
 
   ===== To retrieve and handle events when Event signal is triggered:
   while (IBTImagePullResponder_GetEvent(piResponder, 
                                         &eventData) != AEE_ENOMORE)
   {
      switch (eventData.cEvent)
      {
         case AEEBTBIPR_EV_ENABLED:
         case AEEBTBIPR_EV_DISABLED:
            // check eventData.cResult to see if it was successful
            break;

         case AEEBTBIPR_EV_CONNECT_REQ:
            char* pszRootFolder = NULL;
            // eventData.bdAddr tells who the initiator is
            // prompt user "Accept conn req from ?"
            if ((FALSE != bUserAccept) &&
                (AEEBTBIP_FUNC_NONE != pMe->cFuncToHandle))
            {
               pszRootFolder = pMe->szMyRootFolderName;
            }
            IBTImagePullResponder_AcceptConnection(
               piResponder, 
               bUserAccept,
               pszRootFolder,
               pMe->piFS,
               1000);   // progress report every 1000 bytes of data transferred
            break;

         case AEEBTBIPR_EV_CONNECTED:
         case AEEBTBIPR_EV_DISCONNECTED:
            // check eventData.cResult to see if it was successful
            // eventData.bdAddr tells who the initiator is
            break;

         case AEEBTBIPR_EV_FUNC_REQ:
            appRequestHandler(); // see sample code below
            break;

         case AEEBTBIPR_EV_FUNC_ENDED:
            // eventData.cFunc tells what function was performed
            // check eventData.cResult to see if it was successful
            break;

         case AEEBTBIPR_EV_PROGRESS_REPORT:
            // eventData.cFunc tells what function is being performed
            // eventData.nBytes tells accumulative number of data bytes 
            // pulled from initiator
            break;

         case AEEBTBIPR_EV_EVENT_Q_OVERFLOW:
            // eventData.nSize tells how many events got dropped
            // since previous GetEvent()
            break;
      }
   }
   ISignalCtl_Enable(piSignalCtl); // re-enable signal


   ===== sample appRequestHandler():
   AEEBTBIPImagingReq req;
   if (AEE_SUCCESS == IBTImagePullResponder_GetRequestData(piResponder, &req))
   {
      switch (req.cRequestedFunc)
      {
         case AEEBTBIP_FUNC_GET_CAPABILITIES:
            // assuming buildCapacitiesString() creates a 
            // imaging-capabilities XML string
            buildCapacitiesString(pMe->szMyCaps);
            IBTImagePullResponder_SendCapabilities(piResponder, pMe->szMyCaps);
            break;

         case AEEBTBIP_FUNC_GET_IMAGES_LIST:
            uint8* pDataBuf = MALLOC(req.nDescriptorLen);
            int nTmpSize;
            if ((NULL != pDataBuf) &&
                (AEE_SUCCESS == IBTImagePullResponder_GetDescriptor(
                                  piResponder, pDataBuf, 
                                  req.nDescriptionLen, &nTmpSize)))
            {
               // make a list based on the filtering described in
               // the descriptor, save it to a file, then send to initiator
               IBTImagePullResponder_SendImagesList(
                  piResponder,
                  nNumHandles,
                  pszFiltering,
                  (IPort1*)piListingFile); // file object from which to read
               FREEIF (pDataBuf);
            }
            break;

         case AEEBTBIP_FUNC_GET_IMAGE_PROPERTIES:
            if (FALSE != validHandle(req.handle))
            {
               char* pszProperties = appGetProperties(req.handle));
               IBTImagePullResponder_SendImageProperties(
                  piResponder,
                  pszProperties);
            }
            break;

         case AEEBTBIP_FUNC_GET_IMAGE:
            IFilePort1* piFile = NULL;
            FSStatEx stat;
            if ((NULL != (piImageFile = getFileFromHandle(req.handle))) &&
                (AEE_SUCCESS = IFilePort1_Stat(piFile, &stat)))
            {
               IBTImagePullResponder_SendObject(
                  piResponder,
                  AEEBTBIP_OBJTYPE_IMAGE,
                  (IPort1*)piFile,
                  stat.qwSize);
            }
            else
            {
               IBTImagePullResponder_SendObject(
                  piResponder, AEEBTBIP_OBJTYPE_IMAGE, NULL, 0);
            }
            FREEIF(piFile);
            break;

         case AEEBTBIP_FUNC_GET_LINKED_THUMBNAIL:
         case AEEBTBIP_FUNC_GET_LINKED_ATTACHMENT:
            // handle request same way as AEEBTBIP_FUNC_GET_IMAGE above
            break;

         case AEEBTBIP_FUNC_DELETE_IMAGE:
            result = AEE_ENOSUCH;
            if (NULL != (pszName = getFileNameFromHandle(req.handle)))
            {
               result = IFileSystem2_Unlink(pMe->piFS, pszName);
            }
            IBTImagePullResponder_SendDeleteResult(piResponderl, result);
            FREEIF (pszName);
            break;

         default:
            // object doesn't know what it's doing!
      }
   }

 
   ===== When done with responder object:
   IBTImagePullResponder_ForceDisconnect(piResponder);
   IBTImagePullResponder_Disable(piResponder);
   IBTImagePullResponder_Release(piResponder);

   
  • Follow