Developer

API Reference

IBTImagePushResponder

Brew Release
Brew MP 1.0.2
Description
Bluetooth Basic Imaging Profile version 1.0, Imaging Responder role
This interface allows application to make use of the Image Push feature defined by Bluetooth BIP specifications. The typical use case is a mobile phone as Image initiator and a wristwatch, or PC, or another mobile phone as Image responder. Depending on the responder's capabilities, images can be pushed for the purpose of storing, printing, or displaying.
For more information, refer to http://bluetooth.com/Bluetooth/Technology/Works/BIP.htm
Usage

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


   ===== Find out what imaging capabilities the responder object has:
   char* pszCapXML = NULL;
   int nLen = 0;
   IBTImagePushResponder_ReadDefaultCap(piResponder, pszCapXML, nLen, &nLen);
   pszCapXML = MALLOC(nLen);
   if (NULL != pszCapXML)
   {
      IBTImagePushResponder_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:
   IBTImagePushResponder_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 PC";
   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 Push Responder:
   FSStatVFSEx stat;
   if ((AEE_SUCCESS == ISHELL_CreateInstance(piShell, AEECLSID_FileSystem2, 
                                             &pMe->piFS)) &&
       (AEE_SUCCESS == IFileSystem2_StatVFS(pMe->piFS, pszMyRootFolder, &stat)))
   {
      IBTImagePushResponder_Enable (
         piResponder, 
         AEEBT_SEC_SM4_MEDIUM,
         stat.qwMaxFSSpace,
         "Image Push - Store",
         AEEBTBIP_CAP_GENERIC_IMAGING,
         AEEBTBIP_PUSH_STORE);   // this responder stores received images
   }
 
 
   ===== To retrieve and handle events when Event signal is triggered:
   while (IBTImagePushResponder_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;
            }
            IBTImagePushResponder_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 == IBTImagePushResponder_GetRequestData(piResponder, &req))
   {
      switch (req.cRequestedFunc)
      {
         case AEEBTBIP_FUNC_GET_CAPABILITIES:
            // assuming appBuildCapacitiesString() creates a 
            // imaging-capabilities XML string
            appBuildCapacitiesString(pMe->szMyCaps);
            IBTImagePushResponder_SendCapabilities(piResponder, pMe->szMyCaps);
            break;

         case AEEBTBIP_FUNC_PUT_IMAGE:
            AEEBTBIPImageHandle handle;
            IFilePort1* piFile = NULL;
            boolean bGetThumbnail = TRUE;
            char* pszName = MALLOC(req.nNameLen);
            uint8* pDataBuf = MALLOC(req.nDataLen);
            int nTmpSize;
            if ((NULL != pDataBuf) &&
                (AEE_SUCCESS = IBTImagePushResponder_PeekData(
                                  piResponder, pDataBuf, 
                                  req.nDataLen, &nTmpSize)))
            {
               if (FALSE != appValidImage(pDataBuf))
               {
                  IBTImagePushResponder_GetName(piResponder, pszName,
                                                req.nNameLen, &nTmpSize);
                  std_makepath(pMe->szRootFolder, pszName,
                               pszName, req.nNameLen);
                  IFileSystem2_Open(pMe->piFS, 
                                    pszName,
                                    FS_CAP_RDWR FS_CAP_CREATE, 
                                    &piFile);
                  if (NULL != piFile)
                  {
                     // assuming appCreateHandle() returns a unique handle
                     appCreateHandle (pszName, &handle);
                     if (FALSE != isThumbnail(pDataBuf))
                     {
                        // image is itself a thumbnail; no need to ask for one
                        bGetThumbnail = FALSE;
                     }
                  }
               }
            }
            IBTImagePushResponder_AcceptImage(
               piResponder, 
               (IPort1*)piFile,
               &handle,
               bGetThumbnail);
            FREEIF(pszName);
            FREEIF(pDataBuf);
            break;

         case AEEBTBIP_FUNC_PUT_LINKED_THUMBNAIL:
            // do something similar to case AEEBTBIP_FUNC_PUT_IMAGE
            // such as, did I ask for thumbnail?  is the handle associated 
            // with it valid?
            IBTImagePushResponder_AcceptThumbnail(
               piResponder, 
               (IPort1*)piThumbnailFile);
            break;

         case AEEBTBIP_FUNC_PUT_LINKED_ATTACHMENT:
            // match req.handle with an image, and perform similar step 
            // as above case to create a open a file to which attachment
            // data will be stored, then accept the request
            IBTImagePushResponder_AcceptAttachment(
               piResponder, 
               (IPort1*)piAttachmentFile);
            break;

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

 
   ===== When done with responder object:
   IBTImagePushResponder_ForceDisconnect (piResponder);
   IBTImagePushResponder_Disable (piResponder);
   IBTImagePushResponder_Release (piResponder);

   
  • Follow