예제 #1
0
/**
  * calls link establishment callback
  *
  * This function is  called after P2P RF link establishment
  * or when a new link establishment is requested and the P2P RF link is already established
  */
static void static_PP2PCallLinkEstablishmentCallback(
   tContext * pContext,
   tP2PLink * pP2PLink,
   W_ERROR    nError)
{
   PDebugTrace("static_PP2PCallLinkEstablishmentCallback : hLink %08x - %p %s", pP2PLink->hLink, pP2PLink, PUtilTraceError(nError));

   if (pP2PLink->bEstablishedCalled == W_FALSE)
   {
      /* mark the operation as completed */
      if (pP2PLink->hEstablishOperation != W_NULL_HANDLE)
      {
         PBasicSetOperationCompleted(pContext, pP2PLink->hEstablishOperation);
         pP2PLink->hEstablishOperation = W_NULL_HANDLE;
      }

      if (nError == W_SUCCESS)
      {
         PDFCPostContext3(&pP2PLink->sEstablishmentCC, pP2PLink->hLink, W_SUCCESS);
      }
      else
      {
         PDFCPostContext3(&pP2PLink->sEstablishmentCC, W_NULL_HANDLE, nError);
         PDFCFlushCall(&pP2PLink->sReleaseCC);
      }

      pP2PLink->bEstablishedCalled = W_TRUE;
   }
}
예제 #2
0
/* See header */
void PP2PCallSocketReadCallback(
   tContext    * pContext,
   tP2PSocket  * pP2PSocket,
   uint32_t      nRecvLength,
   W_ERROR       nError,
   uint8_t       nSAP)
{
   PDebugTrace("PP2PCallSocketReadCallback %08x - %p %s", pP2PSocket->sConfig.hSocket, pP2PSocket, PUtilTraceError(nError));

   pP2PSocket->bRecvInProgress = W_FALSE;
   pP2PSocket->pRecvBuffer = null;
   pP2PSocket->nRecvBufferLength = 0;

   if (pP2PSocket->hRecvOperation != W_NULL_HANDLE)
   {
      PBasicSetOperationCompleted(pContext, pP2PSocket->hRecvOperation);
      pP2PSocket->hRecvOperation = W_NULL_HANDLE;
   }

   if (pP2PSocket->sConfig.nType == W_P2P_TYPE_CONNECTIONLESS)
   {
      PDFCPostContext4(&pP2PSocket->sRecvCC, nRecvLength, nError, nSAP);
   }
   else
   {
      PDFCPostContext3(&pP2PSocket->sRecvCC, nRecvLength, nError);
   }
}
예제 #3
0
/**
 * Open a 7816 channel used to exchanged APDU
 *
 * @param[in] pContext The context
 *
 * @param[in] pNDEFConnection The NDEF connection
 */
static void static_PNDEFType4OpenChannel(
               tContext* pContext,
               tNDEFConnection* pNDEFConnection,
               tPBasicGenericDataCallbackFunction * pCallback,
               void * pCallbackParameter)
{
   pNDEFConnection->sType.t4.pChannelCallback = pCallback;
   pNDEFConnection->sType.t4.pChannelCallbackParameter = pCallbackParameter;

   if (pNDEFConnection->sType.t4.h7816Channel == W_NULL_HANDLE)
   {
      /* Open a raw channel used to exchange APDU */
      P7816OpenChannelInternal(
         pContext,
         pNDEFConnection->hConnection,
         static_PNDEFType4OpenChannelCompleted,
         pNDEFConnection,
         W_7816_CHANNEL_TYPE_RAW,
         (const uint8_t*)null,
         0);
   }
   else
   {
      /* Channel is already opened. Send result */
      tDFCCallbackContext sCallbackContext;
      PDFCFillCallbackContext(pContext, (tDFCCallback*)static_PNDEFType4OpenChannelCompleted, pNDEFConnection, &sCallbackContext);
      PDFCPostContext3(&sCallbackContext, pNDEFConnection->sType.t4.h7816Channel, W_SUCCESS);
   }
}
예제 #4
0
/* See client API */
void PP2PURILookup(
      tContext * pContext,
      W_HANDLE hLink,
      tPP2PURILookupCompleted * pCallback,
      void * pCallbackParameter,
      const char16_t * pServiceURI)
{
   tDFCCallbackContext * pCallbackContext = (tDFCCallbackContext *) CMemoryAlloc(sizeof(tDFCCallbackContext));
   W_ERROR nError;

   if (pCallbackContext != null)
   {
      PDFCFillCallbackContext(pContext, (tDFCCallback *) pCallback, pCallbackParameter, pCallbackContext);

      if (pServiceURI != null)
      {
         PP2PURILookupDriver(pContext, hLink, static_PP2PURILookupCompleted, pCallbackContext, pServiceURI, PUtilStringLength(pServiceURI) * sizeof(char16_t));
      }
      else
      {
      /* all errors are handled in the driver implementation */
         PP2PURILookupDriver(pContext, hLink, static_PP2PURILookupCompleted, pCallbackContext, null, 0);
      }

      nError = PContextGetLastIoctlError(pContext);

      if (nError != W_SUCCESS)
      {
         tDFCCallbackContext sCallbackContext;
         PDFCFillCallbackContext(pContext, (tDFCCallback *) static_PP2PURILookupCompleted, pCallbackContext, &sCallbackContext);
         PDFCPostContext3(&sCallbackContext, 0, nError);
      }
   }
   else
   {
      tDFCCallbackContext sCallbackContext;

      PDFCFillCallbackContext(pContext, (tDFCCallback *) pCallback, pCallbackParameter, &sCallbackContext);
      PDFCPostContext3(&sCallbackContext, 0, W_ERROR_OUT_OF_RESOURCE);
   }
}
예제 #5
0
static void static_PP2PURILookupCompleted(
      tContext* pContext,
      void * pCallbackParameter,
      uint8_t nDSAP,
      W_ERROR nError )
{
   tDFCCallbackContext * pCallbackContext = (tDFCCallbackContext *) pCallbackParameter;

   PDebugError("static_PP2PURILookupCompleted");

   PDFCPostContext3(pCallbackContext, (uint32_t) nDSAP, nError);
   CMemoryFree(pCallbackContext);
}
예제 #6
0
/* See tWBasicGenericDataCallbackFunction */
static void static_PBPrimeUserExchangeDataCompleted(
            tContext* pContext,
            void *pCallbackParameter,
            uint32_t nDataLength,
            W_ERROR nError)
{


   tPBPrimeUserConnection* pBPrimeUserConnection = (tPBPrimeUserConnection*)pCallbackParameter;

   /* Check if the operation has been cancelled by the user */
   if ( pBPrimeUserConnection->hCurrentOperation != W_NULL_HANDLE )
   {
      /* Check the operation state */
      if ( PBasicGetOperationState(pContext, pBPrimeUserConnection->hCurrentOperation) == P_OPERATION_STATE_CANCELLED)
      {
         PDebugError("static_PBPrimeUserExchangeDataCompleted: Operation is cancelled");
         if(nError == W_SUCCESS)
         {
            nError = W_ERROR_CANCEL;
         }
      }
      else
      {
         PBasicSetOperationCompleted(pContext, pBPrimeUserConnection->hCurrentOperation);
      }

      PHandleClose(pContext, pBPrimeUserConnection->hCurrentOperation);
      pBPrimeUserConnection->hCurrentOperation = W_NULL_HANDLE;
   }

   PHandleClose(pContext, pBPrimeUserConnection->hCurrentDriverOperation);
   pBPrimeUserConnection->hCurrentDriverOperation = W_NULL_HANDLE;

   if(nError != W_SUCCESS)
   {
      PDebugError("static_PBPrimeUserExchangeDataCompleted: Returning %s",
         PUtilTraceError(nError));
      nDataLength = 0;
   }

   /* Send the result */
   PDFCPostContext3(
      &pBPrimeUserConnection->sCallbackContext,
      nDataLength,
      nError );

   /* Release the reference after completion
      May destroy pBPrimeUserConnection */
   PHandleDecrementReferenceCount(pContext, pBPrimeUserConnection);
}
예제 #7
0
/* See WP2PEstablishLink */
W_HANDLE PP2PEstablishLinkDriver1Internal(
   tContext * pContext,
   tPBasicGenericHandleCallbackFunction* pEstablishmentCallback,
   void* pEstablishmentCallbackParameter
 )
{
   tDFCCallbackContext   sCallbackContext;
   tP2PLink            * pP2PLink = null;
   W_ERROR               nError;

   PDFCFillCallbackContext( pContext, (tDFCCallback*)pEstablishmentCallback, pEstablishmentCallbackParameter, & sCallbackContext);

   if (PP2PCheckP2PSupport(pContext) == W_FALSE)
   {
      nError = W_ERROR_RF_PROTOCOL_NOT_SUPPORTED;
      goto error;
   }

   pP2PLink = CMemoryAlloc(sizeof(tP2PLink));

   if (pP2PLink == null)
   {
      nError = W_ERROR_OUT_OF_RESOURCE;
      goto error;
   }

   CMemoryFill(pP2PLink, 0, sizeof(tP2PLink));

   nError = PHandleRegister(pContext, pP2PLink, P_HANDLE_TYPE_P2P_LINK, &pP2PLink->hLink);

   if (nError != W_SUCCESS)
   {
      goto error;
   }

   pP2PLink->sEstablishmentCC = sCallbackContext;

   return pP2PLink->hLink;

error:
   if (pP2PLink != null)
   {
      CMemoryFree(pP2PLink);
   }

   PDFCPostContext3(&sCallbackContext, W_NULL_HANDLE, nError);

   return W_NULL_HANDLE;
}
예제 #8
0
/* See header */
void PP2PCallSocketReadAndWriteCallbacks(
   tContext     * pContext,
   tP2PSocket   * pP2PSocket,
   W_ERROR        nError)
{
   PDebugTrace("static_PP2PCallReadAndWriteCallbacks nError %d", nError);

   /* call the receive callback */
   if (pP2PSocket->bRecvInProgress)
   {
      pP2PSocket->bRecvInProgress = W_FALSE;
      pP2PSocket->pRecvBuffer = null;

      if (pP2PSocket->hRecvOperation != W_NULL_HANDLE)
      {
         PBasicSetOperationCompleted(pContext, pP2PSocket->hRecvOperation);
         pP2PSocket->hRecvOperation = W_NULL_HANDLE;
      }

      PDFCPostContext3(&pP2PSocket->sRecvCC, 0, nError);
   }

   /* call the send callback */
   if (pP2PSocket->bXmitInProgress)
   {
      pP2PSocket->bXmitInProgress = W_FALSE;
      pP2PSocket->pXmitBuffer = null;

      if (pP2PSocket->hXmitOperation != W_NULL_HANDLE)
      {
         PBasicSetOperationCompleted(pContext, pP2PSocket->hXmitOperation);
         pP2PSocket->hXmitOperation = W_NULL_HANDLE;
      }

      PDFCPostContext2(&pP2PSocket->sXmitCC, nError);
   }
}
예제 #9
0
static void static_PBPrimeUserExchangeData(
            tContext* pContext,
            void* pObject,
            tPBasicGenericDataCallbackFunction* pCallback,
            void* pCallbackParameter,
            const uint8_t* pReaderToCardBuffer,
            uint32_t nReaderToCardBufferLength,
            uint8_t* pCardToReaderBuffer,
            uint32_t nCardToReaderBufferMaxLength,
            W_HANDLE* phOperation)
{
   tPBPrimeUserConnection* pBPrimeUserConnection = (tPBPrimeUserConnection*)pObject;
   tDFCCallbackContext sCallbackContext;
   W_ERROR nError = W_SUCCESS;

   PDebugTrace("static_PBPrimeUserExchangeData");

   PDFCFillCallbackContext(
      pContext,
      (tDFCCallback*)pCallback,
      pCallbackParameter,
      &sCallbackContext );

   /* Check if an operation is still pending */
   if ( pBPrimeUserConnection->hCurrentOperation != W_NULL_HANDLE )
   {
      PDebugError("static_PBPrimeUserExchangeData: operation already pending");
      nError = W_ERROR_BAD_STATE;
      goto return_error;
   }

   /* Check the card buffer size */
   if ((nReaderToCardBufferLength == 0) || (pReaderToCardBuffer == null))
   {
      PDebugError("static_PBPrimeUserExchangeData: nReaderToCardBufferLength / pReaderToCardBuffer can not be null");
      nError = W_ERROR_BAD_PARAMETER;
      goto return_error;
   }

   if ( ((pCardToReaderBuffer == null) && (nCardToReaderBufferMaxLength != 0)) ||
        ((pCardToReaderBuffer != null) && (nCardToReaderBufferMaxLength == 0)) )
   {
      PDebugError("static_PBPrimeUserExchangeData: inconsistency between pCardToReaderBuffer and nCardToReaderBufferMaxLength");
      nError = W_ERROR_BAD_PARAMETER;
      goto return_error;
   }

   /* Get an operation handle if needed */
   if((pBPrimeUserConnection->hCurrentOperation = PBasicCreateOperation(
      pContext, static_PBPrimeUserExchangeDataCancel, pBPrimeUserConnection)) == W_NULL_HANDLE)
   {
      PDebugError("static_PBPrimeUserExchangeData: Cannot allocate the operation");
      nError = W_ERROR_OUT_OF_RESOURCE;
      goto return_error;
   }

   if(phOperation != null)
   {
      /* Duplicate the handle to be referenced internally and in the returned handle */
      nError = PHandleDuplicate(pContext, pBPrimeUserConnection->hCurrentOperation, phOperation );
      if(nError != W_SUCCESS)
      {
         PDebugError("static_PBPrimeUserExchangeData: Error returned by PHandleDuplicate()");
         PHandleClose(pContext, pBPrimeUserConnection->hCurrentOperation);
         pBPrimeUserConnection->hCurrentOperation = W_NULL_HANDLE;

         goto return_error;
      }
   }

   pBPrimeUserConnection->hCurrentDriverOperation = PBPrimeDriverExchangeData(
         pContext,
         pBPrimeUserConnection->hDriverConnection,
         static_PBPrimeUserExchangeDataCompleted,
         pBPrimeUserConnection,
         pReaderToCardBuffer,
         nReaderToCardBufferLength,
         pCardToReaderBuffer,
         nCardToReaderBufferMaxLength);

   nError = PContextGetLastIoctlError(pContext);

   if (nError != W_SUCCESS)
   {
      PDebugError("static_PBPrimeUserExchangeData: Error returned by PContextGetLastIoctlError()");
      PHandleClose(pContext, pBPrimeUserConnection->hCurrentOperation);
      pBPrimeUserConnection->hCurrentOperation = W_NULL_HANDLE;

      goto return_error;
   }

   /* Store the callback context */
   pBPrimeUserConnection->sCallbackContext = sCallbackContext;

   /* Increment the reference count to keep the connection object alive
      during the operation.
      The reference count is decreased in static_PBPrimeUserExchangeDataCompleted
      when the NFC HAL operation is completed */
   PHandleIncrementReferenceCount(pBPrimeUserConnection);

   return;

return_error:

   PDebugError("static_PBPrimeUserExchangeData: returning %s", PUtilTraceError(nError));

   PDFCPostContext3(
      &sCallbackContext,
      0,
      nError );
}
예제 #10
0
/**
 * Sends Select Application APDU
 *
 * @param[in] pContext The context
 *
 * @param[in] pNDEFConnection The NDEF connection
 */
static void static_PNDEFType4SelectApplication(
               tContext* pContext,
               tNDEFConnection* pNDEFConnection,
               tPBasicGenericDataCallbackFunction * pCallback,
               void * pCallbackParameter)
{

   pNDEFConnection->sType.t4.pCCCache = PCacheConnectionGetBuffer(pContext, P_NDEF_4_CC_CACHE_ID, 0, &pNDEFConnection->sType.t4.nCCCacheLength);
   pNDEFConnection->sType.t4.pNDEFCache = PCacheConnectionGetBuffer(pContext, P_NDEF_4_NDEF_CACHE_ID, 0, &pNDEFConnection->sType.t4.nNDEFCacheLength);

   if ((pNDEFConnection->sType.t4.pCCCache == null) || (pNDEFConnection->sType.t4.pNDEFCache == null))
   {
         /* NFC Type 4 Tag v2.0 specific commands (with optional Le byte) */
      static const uint8_t aSelectApplicationv20[]    = { P_7816SM_CLA, P_7816SM_INS_SELECT, P_7816SM_P1_SELECT_AID, P_7816SM_P2_SELECT_AID, 0x07, 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01, 0x00 };

      /* NFC Type 4 Tag v1.0 specific commands (with non-standard Le byte) */
      static const uint8_t aSelectApplicationv10[]    = { P_7816SM_CLA, P_7816SM_INS_SELECT, P_7816SM_P1_SELECT_AID, P_7816SM_P2_SELECT_AID, 0x07, 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00, 0x00 };

      const uint8_t * pSelectApplication;
      uint8_t nCommandLength = 0;

      PDebugTrace("static_PNDEFType4SelectApplication");

      switch (pNDEFConnection->sType.t4.nVariant)
      {
         case P_NDEF_4_VERSION_20:
            pSelectApplication = aSelectApplicationv20;
            nCommandLength = sizeof(aSelectApplicationv20);
            break;

         case P_NDEF_4_VERSION_20_NON_STANDARD:
            pSelectApplication = aSelectApplicationv20;
            nCommandLength = sizeof(aSelectApplicationv20) - 1;
            break;

         case P_NDEF_4_VERSION_10:
            pSelectApplication = aSelectApplicationv10;
            nCommandLength = sizeof (aSelectApplicationv10) - 1;
            break;

         case P_NDEF_4_VERSION_10_NON_STANDARD:
            pSelectApplication = aSelectApplicationv10;
            nCommandLength = sizeof (aSelectApplicationv10);
            break;

         default:
            PDebugError("static_PNDEFType4SelectApplication : invalid tag type");
            return;
      }

      /* Send the command */
      P7816ExchangeApduInternal(
               pContext,
               pNDEFConnection->sType.t4.h7816Channel,
               pCallback,
               pCallbackParameter,
               pSelectApplication,
               nCommandLength,
               pNDEFConnection->pReceivedBuffer,
               pNDEFConnection->nBufferLength);
   }
   else
   {
      tDFCCallbackContext sCallbackContext;

      PDebugTrace("static_PNDEFType4SelectApplication : skipping select due to cache existence");

      pNDEFConnection->pReceivedBuffer[0] = 0x90;
      pNDEFConnection->pReceivedBuffer[1] = 0x00;

      PDFCFillCallbackContext(pContext, (tDFCCallback *) pCallback, pCallbackParameter, &sCallbackContext);
      PDFCPostContext3(&sCallbackContext, 2, W_SUCCESS);
   }
}