예제 #1
0
파일: tagReader.c 프로젝트: hideout/c-beam
/* TODO : this function hasn't really been tested                */
int
readerGetContactlessStatus(
                            tReaderManager  *pManager,
                            tReader	        *pReader
                          )
{
    DWORD		dwRecvLength;
    BYTE		pbRecvBuffer[20];
    LONG		rv;
    int         i;
    BOOL        automatic;

    /* Duh. If you pass me a NULL pointer then I'm out of here */
    if ( ( pManager == NULL ) || ( pManager->hContext == NULL ) )
       return( SCARD_E_INVALID_PARAMETER );

    automatic = readersSettingBitmapBitTest( pManager, READER_BIT_AUTO );

    if ( automatic )
    {
        /* re-enumerate the readers in the system as it may have changed */
        rv = readersConnect( pManager );
        if ( rv != SCARD_S_SUCCESS )
            return( rv );
    }

    sprintf(messageString, "Requesting contactles status");
    readersLogMessage( pManager, LOG_INFO, 2, messageString);

    /* then check all readers we were ABLE to connect to */
    for ( i = 0; i < pManager->nbReaders; i++ )
    {
        /* check we have connected and have a driver for this reader */
        if ( ( pReader[i].hCard != NULL ) && ( pReader[i].pDriver != NULL ) &&
             ( automatic || readersSettingBitmapNumberTest( pManager, i ) ) )
        {
            dwRecvLength = sizeof(pbRecvBuffer);
            rv = ((tReaderDriver *)(pReader[i].pDriver))->getContactlessStatus(pReader, pbRecvBuffer, &dwRecvLength);

            if ( rv == SCARD_S_SUCCESS )
            {
                if (pManager->libVerbosityLevel)
                {
                    sprintf(messageString, "Reader %d Status: ", i);
                    sPrintBufferHex( (messageString + strlen("Reader %d Status: ") ), dwRecvLength, pbRecvBuffer);
                    readersLogMessage( pManager, LOG_INFO, 2, messageString);

                    sprintf(messageString, "Number of Tags = %d", pbRecvBuffer[4]);
                    readersLogMessage( pManager, LOG_INFO, 2, messageString);
                }
            }
            else
                PCSC_ERROR( pManager, rv, "driver->getConnectlessStatus:");
        }
    }

   return (rv);
}
예제 #2
0
파일: tagReader.c 프로젝트: hideout/c-beam
/************************* READER MANAGER DISCONNECT ***********/
int
readersManagerDisconnect(
                        tReaderManager *pManager
                        )
{
    LONG 		    rv;

    if ( pManager == NULL )
        return( SCARD_E_INVALID_PARAMETER );

    if ( pManager->hContext )
    {
        readersLogMessage( pManager, LOG_INFO, 2, "Disconnecting from pcscd server");

        rv = SCardReleaseContext( (SCARDCONTEXT) (pManager->hContext) );
        if ( rv != SCARD_S_SUCCESS )
            PCSC_ERROR( pManager, rv, "SCardReleaseContext");

        /* libreate memory that was allocated when we connected to manager */
        if (pManager->mszReaders)
        {
            free(pManager->mszReaders);
            pManager->mszReaders = NULL;
        }
    }
    else
        rv = SCARD_E_INVALID_PARAMETER;

    /* now it should be NULL either way */
    pManager->hContext = NULL;

    eventDispatch( PCSCD_DISCONNECT, NULL, 0, pManager );

    return( rv );
}
예제 #3
0
/************************ STOP DAEMON **************/
void stopDaemon( const tReaderManager   *pManager ){
   char		messageString[MAX_LOG_MESSAGE];
   char 	pidString[20];
   int		pid;

   /* open lock file to get PID */
   sprintf(lockFilename, "%s/%s.lock", DEFAULT_LOCK_FILE_DIR, DAEMON_NAME);
   lockFile = open( lockFilename, O_RDONLY, 0 );
   if (lockFile == -1)
   {
      sprintf(messageString, "Could not open lock file %s, exiting", lockFilename);
      readersLogMessage( pManager, LOG_ERR, 0, messageString);
      sprintf(messageString, "Check you have the necessary permission for it");
      readersLogMessage( pManager, LOG_ERR, 0, messageString);
      exit( EXIT_FAILURE );
   }

   /* get the running PID in the lockfile */
   if (read(lockFile, pidString, 19) == -1)
   {
      sprintf(messageString, "Could not read PID from lock file %s, exiting", lockFilename);
      readersLogMessage( pManager, LOG_ERR, 0, messageString);
      exit( EXIT_FAILURE );
   }

   close( lockFile );

   if (sscanf( pidString, "%d\n", &pid ) != 1)
   {
      sprintf(messageString, "Could not read PID from lock file %s, exiting", lockFilename);
      readersLogMessage( pManager, LOG_ERR, 0, messageString);
      exit( EXIT_FAILURE );
   }

   sprintf(messageString, "Stopping daemon with PID = %d", pid );
   readersLogMessage( pManager, LOG_INFO, 1, messageString);

   /* might need to be root for this to work ?  - try and kill nicely*/
   kill (pid, SIGTERM);

   /* TODO else, use a bit more brute force */
   /* check if running? */
   /* remove the lock file myself if I can ! */
   sleep(1);
   remove( lockFilename );
}
예제 #4
0
void daemonTerminate( const tReaderManager *pManager ){

    if ( runningAsDaemon )
    {
        readersLogMessage( pManager, LOG_INFO, 1, "Closing and removing lockfile, closing log. Bye.");

        close( lockFile );
        remove( lockFilename );
    }

}
예제 #5
0
/* make sure we are the only running copy for this reader number */
static void getLockOrDie( const tReaderManager *pManager ){
   char 	pidString[20];
   char		messageString[MAX_LOG_MESSAGE];
   struct flock lock;

   sprintf(lockFilename, "%s/%s.lock", DEFAULT_LOCK_FILE_DIR, DAEMON_NAME );
   lockFile = open( lockFilename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH );
   if ( lockFile == -1 )
   {
      sprintf(messageString,
              "Could not open lock file %s, check permissions or run as root, exiting", lockFilename);
      readersLogMessage( pManager, LOG_ERR, 0, messageString);
      exit( EXIT_FAILURE );
   }

   /* Initialize the flock structure. */
   memset (&lock, 0, sizeof(lock));
   lock.l_type = F_WRLCK;

   /* try and get the lock file, non-blocking */
   if ( fcntl(lockFile, F_SETLK, &lock) == -1 )
   {
      sprintf(messageString, "Could not lock file %s", lockFilename);
      readersLogMessage( pManager, LOG_ERR, 0, messageString);
      sprintf(messageString, "Probably indicates a previous copy is still running or crashed");
      readersLogMessage( pManager, LOG_ERR, 0, messageString);
      sprintf(messageString, "Find PID using \"cat %s\" or \"ps -ef | grep %s\". Exiting.",
             lockFilename, DAEMON_NAME);
      readersLogMessage( pManager, LOG_ERR, 0, messageString);
      exit( EXIT_FAILURE );
   }

   /* store the running PID in the lockfile */
   sprintf( pidString, "%d\n", getpid());
   if (write(lockFile, pidString, strlen(pidString)) != strlen(pidString) )
   {
      sprintf(messageString, "Could not write PID to lock file %s", lockFilename);
      readersLogMessage( pManager, LOG_ERR, 0, messageString);
      exit( EXIT_FAILURE );
   }
}
예제 #6
0
파일: tagReader.c 프로젝트: hideout/c-beam
/************************ READER DISCONNECT ********************/
void
readersDisconnect(
                tReaderManager  *pManager
                   )
{
    LONG    rv;
    int     i;

    /* Duh. If you pass me a NULL pointer then I'm out of here */
    if ( ( pManager == NULL ) || ( pManager->hContext == NULL ) )
       return;

    if ( readersSettingBitmapBitTest( pManager, READER_BIT_AUTO ) )
    {
        /* re-enumerate the readers in the system as it may have changed */
        rv = readersEnumerate( pManager );
        if ( rv != SCARD_S_SUCCESS )
            return;
    }

    /* then check all readers we were ABLE to connect to */
    for ( i = 0; i < pManager->nbReaders; i++ )
    {
        if ( pManager->readers[i].hCard != NULL )
        {
            sprintf(messageString, "Disconnecting from reader %d", i );
            readersLogMessage( pManager, LOG_INFO, 2, messageString);

            rv = SCardDisconnect( (SCARDHANDLE) (pManager->readers[i].hCard), SCARD_UNPOWER_CARD);
            RESET_READER( pManager->readers[i] );

            eventDispatch( READER_DISCONNECT, NULL, i, pManager );

            if ( rv != SCARD_S_SUCCESS )
                PCSC_ERROR( pManager, rv, "SCardDisconnect");
        }
    }
}
예제 #7
0
파일: tagReader.c 프로젝트: hideout/c-beam
/* function allocates the memory for the list you must handle it!*/
int
readersGetTagList(
                tReaderManager  *pManager
                )
{
    LONG		rv = SCARD_S_SUCCESS;
    tTag        *pTags[MAX_NUM_READERS]; /* an array of pointers to tags (that act like arrays) ! */
    int         i, j;
    int         uniqueListIndex;
    BOOL        automatic;
    char        *namePointer;

    /* Duh. If you pass me a NULL pointer then I'm out of here */
    if ( ( pManager == NULL ) || ( pManager->hContext == NULL ) )
       return( SCARD_E_INVALID_PARAMETER );

    automatic = readersSettingBitmapBitTest( pManager, READER_BIT_AUTO );

    if ( automatic )
    {
        /* re-connect the readers in the system as it may have changed */
        rv = readersConnect( pManager );
        if ( rv != SCARD_S_SUCCESS )
            return( rv );
    }

    /* before we start, reset the total count to 0 */
    pManager->tagList.numTags = 0;

    /* for all readers we were connected to PREVIOUSLY or are now after AUTMATIC reconnect */
    for ( i = 0; i < pManager->nbReaders; i++ )
    {
        /* make sure it's initialized, as depending on reader settings we may skip over */
        /* one of these pointers in the array and later try to free an invalid pointer */
        pTags[i] = NULL;
        pManager->readers[i].tagList.numTags = 0;

        /* check we are connected, have a driver and should be reading it */
        if ( ( pManager->readers[i].hCard != NULL ) && ( pManager->readers[i].pDriver != NULL ) &&
             ( automatic || readersSettingBitmapNumberTest( pManager, i ) ) )
        {
            /* I'd normally check if a tag is present using readerGetContactlessStatus() before    */
            /* querying the tag list, but all my testing to date has failed to get the contactless */
            /* status APDU to work, it always returns D5 05 00 00 00 80 90 00 to indicate no tag   */
            /* is present. I have reported this issue to ACS by e-mail - Andrew                    */

            /* allocate the structure for this reader to read tag list into upto max size */
            pTags[i] = (tTag *)malloc( ( ((tReaderDriver *)(pManager->readers[i].pDriver))->maxTags ) * sizeof(tTag) );

            /* call the reader's associated driver's function to read the tag list */
            rv = ((tReaderDriver *)(pManager->readers[i].pDriver))->getTagList( &(pManager->readers[i]), pTags[i] );
            if ( rv != SCARD_S_SUCCESS )
            {
                PCSC_ERROR( pManager, rv, "driver->getTagList():");
                RESET_READER( pManager->readers[i] );
                if ( pTags[i] != NULL )
                    free( pTags[i] );
                pTags[i] = NULL;
            }
            /* accumulate the total number of tags found */
            pManager->tagList.numTags += pManager->readers[i].tagList.numTags;
        }
    }

    /* now mash them all up into one big list */
    pManager->tagList.pTags = NULL; /* for the zero tag case */
    uniqueListIndex = 0;

    if ( pManager->tagList.numTags > 0 )
    {
        pManager->tagList.pTags = (tTag *)malloc( (pManager->tagList.numTags) * sizeof( tTag ) );

        /* copy all the individual lists across into the unique list */
        for( i = 0; i < pManager->nbReaders; i++)
        {
            /* make the pointer in the per-reader structure point to it's parts of the overall list */
            pManager->readers[i].tagList.pTags = &(pManager->tagList.pTags[uniqueListIndex]);

            /* for each of the tags detected in this reader */
            for ( j = 0; j < pManager->readers[i].tagList.numTags; j++ )
            {
                /* copy the tag from the tempory list to the unique one */
                pManager->tagList.pTags[uniqueListIndex] = (pTags[i])[j];

                TAG_TYPE_NAME_FROM_ENUM( pManager->tagList.pTags[uniqueListIndex].tagType, namePointer );

                sprintf(messageString, "Tag ID:   %s\tType: %s", pManager->tagList.pTags[uniqueListIndex].uid, namePointer);

                readersLogMessage( pManager, LOG_INFO, 2, messageString);
                uniqueListIndex++;
            }

            /* free the space allocated for that list, even if it was never filled with anything */
            if ( pTags[i] )
                free( pTags[i] );
        }
    }

    sprintf( messageString, "Total Number of tags: %d", (int)(pManager->tagList.numTags) );
    readersLogMessage( pManager, LOG_INFO, 2, messageString );

   return (rv);
}
예제 #8
0
파일: tagReader.c 프로젝트: hideout/c-beam
/************************* READER CONNECT **********************/
int readersConnect (
                    tReaderManager  *pManager
                 )
{
    LONG 		    rv;
    BOOL			    readerSupported;
    DWORD 		    dwActiveProtocol;
    int              i, num;
    BOOL             automatic;

    /* Duh. If you pass me a NULL pointer then I'm out of here */
    if ( pManager == NULL )
        return( SCARD_E_INVALID_PARAMETER );

    automatic = ( readersSettingBitmapBitTest( pManager, READER_BIT_AUTO ) != 0 );

    if ( automatic )
    {
        /* re-enumerate the readers in the system as it may have changed */
        rv = readersEnumerate( pManager );
        if ( rv != SCARD_S_SUCCESS )
            return( rv );
    }

    if ( pManager->nbReaders == 0 )
        return( SCARD_E_NO_READERS_AVAILABLE );

    /* try and connect to all readers that are present according to readerSetting */
    for ( num = 0; num < pManager->nbReaders; num++ )
    {
        /* if we are not already connected and should be trying then do so */
        if ( ( pManager->readers[num].hCard == NULL) &&
             ( automatic || readersSettingBitmapNumberTest( pManager, num ) ) )
        {
            dwActiveProtocol = -1;
            rv = SCardConnect( (SCARDCONTEXT)(pManager->hContext),
                                pManager->readers[num].name,
                                SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 ,
                                (LPSCARDHANDLE) &(pManager->readers[num].hCard),
                                &dwActiveProtocol);
            if (rv == SCARD_S_SUCCESS)
            {
                eventDispatch( READER_DETECTED, NULL, num, pManager );

                /* Query the drivers in the list until one of them can handle the reader */
                i = 0;
                readerSupported = FALSE;
                /* call the function to check if this driver works with this reader */
                while ( (readerDriverTable[i] != NULL) && (readerSupported == FALSE) )
                    rv = readerDriverTable[i++]->readerCheck( &(pManager->readers[num]), &readerSupported );

                if ( rv != SCARD_S_SUCCESS )
                {
                    RESET_READER( pManager->readers[num] );
                    PCSC_ERROR( pManager, rv, "readerCheck:" );
                    return( rv );
                }

                /* we couldn't find a driver that knows how to handle this reader... */
                if ( ( readerSupported == FALSE) )
                {
                    pManager->readers[num].pDriver = NULL;
                    sprintf(messageString, "Reader (%s) not supported by any known driver", pManager->readers[num].name );
                    readersLogMessage( pManager, LOG_ERR, 0, messageString);
                    return (SCARD_E_UNKNOWN_READER);
                }
                else
                {
                    /* if we got this far then a driver was successfully found, remember it! */
                    pManager->readers[num].pDriver = readerDriverTable[i -1];
                    pManager->readers[num].driverDescriptor = readerDriverTable[i -1]->driverDescriptor;
                    eventDispatch( READER_DETECTED, NULL, num, pManager );

                }
            }
            else
                RESET_READER( pManager->readers[num] );
        }
    }

    return ( SCARD_S_SUCCESS );

}
예제 #9
0
파일: tagReader.c 프로젝트: hideout/c-beam
/*************************** READERS ENUMERATE *****************/
static int
readersEnumerate(
                tReaderManager  *pManager
                )
{

    LONG    rv;
    DWORD   dwReaders;
    char 	*ptr;
    int     i, previousNumReaders;

    /* remember how many readers there used to be */
    previousNumReaders = pManager->nbReaders;

    /* Call with a null buffer to get the number of bytes to allocate */
    rv = SCardListReaders( (SCARDCONTEXT)(pManager->hContext), NULL, NULL, &dwReaders);
    if ( rv != SCARD_S_SUCCESS )
    {
        /* if there are no readers, then zero everything out but don't report an error */
        if ( rv == SCARD_E_NO_READERS_AVAILABLE )
        {
            pManager->nbReaders = 0;

            if ( pManager->mszReaders )
                free( pManager->mszReaders );
            pManager->mszReaders = NULL;

            readersLogMessage( pManager, LOG_INFO, 2, "Found 0 Readers" );
        }
        else
            PCSC_ERROR( pManager, rv, "SCardListReaders");

        return ( rv );
    }

    /* if array already exists, then liberate it and alloc a new one for the */
    /* number of readers reported from SCardListReader */
    if ( pManager->mszReaders )
        free( pManager->mszReaders );
    /* malloc enough memory for dwReader string */
    pManager->mszReaders = malloc(sizeof(char)*dwReaders);

    /* now get the list into the mszReaders array */
    rv = SCardListReaders( (SCARDCONTEXT)(pManager->hContext), NULL, pManager->mszReaders, &dwReaders);
    if (rv != SCARD_S_SUCCESS)
    {
        /* Avoid reporting an error just because no reader is connected */
        if ( rv != SCARD_E_NO_READERS_AVAILABLE )
            PCSC_ERROR( pManager, rv, "SCardListReaders");
        return (rv);
    }

    /* Extract readers from the null separated string and get the total
        * number of readers */
    pManager->nbReaders = 0;
    ptr = pManager->mszReaders;
    while (*ptr != '\0')
    {
        ptr += strlen(ptr)+1;
        (pManager->nbReaders)++;
    }

    sprintf(messageString, "Found %d Readers", pManager->nbReaders);
    readersLogMessage( pManager, LOG_INFO, 2, messageString);

    /* fill the array of readers with pointers to the appropriate point */
    /* in the long mszReaders multi-string */
    pManager->nbReaders = 0;
    ptr = pManager->mszReaders;
    while (*ptr != '\0')
    {
        sprintf(messageString, "Reader [%d]: %s", pManager->nbReaders, ptr);
        readersLogMessage( pManager, LOG_INFO, 3, messageString);
        pManager->readers[pManager->nbReaders].name = ptr;
        ptr += strlen(ptr)+1;
        (pManager->nbReaders)++;
    }

    /* if we have fewer readers than we used to then zero out the "lost ones" */
    if ( pManager->nbReaders < previousNumReaders )
       for ( i = pManager->nbReaders; i < previousNumReaders; i++ )
          RESET_READER( pManager->readers[i] );

    return( SCARD_S_SUCCESS );

}
예제 #10
0
/************************ READER CHECK ***************************/
LONG   acr122UReaderCheck(
    tReader   *pReader,
    BOOL      *pReaderSupported
)
{
    static  char     pbReader[MAX_READERNAME] = "";

    DWORD  dwAtrLen, dwReaderLen, dwState, dwProt;
    DWORD  dwRecvLength;
    BYTE   pbAtr[MAX_ATR_SIZE] = "";
    int    i;
    LONG   rv;
    BYTE	  pbRecvBuffer[MAX_FIRMWARE_STRING_LENGTH];

    *pReaderSupported = FALSE;

    /* First check the name reported by pcscd to see if it's possible supported */
    for (i = 0; (i < SUPPORTED_READER_NAME_ARRAY_COUNT) & (*pReaderSupported == FALSE) ; i++)
    {
        if ( strncmp( pReader->name, SUPPORTED_READER_NAME_ARRAY[i],
                      sizeof(SUPPORTED_READER_NAME_ARRAY[i])-1) == 0 )
            *pReaderSupported = TRUE;
    }

    /* If even the name is not supported, then we're done */
    if ( *pReaderSupported == FALSE )
        return (SCARD_S_SUCCESS );

    /* just because the name was OK, doesn't mean it'll actually work! */
    *pReaderSupported = FALSE;

    /* Get firmware version and check it's really a ACR122* */
    dwRecvLength = sizeof(pbRecvBuffer);
    rv = apduSend(pReader->hCard, APDU_GET_READER_FIRMWARE,
                  sizeof(APDU_GET_READER_FIRMWARE),
                  pbRecvBuffer, &dwRecvLength);
    if (rv != SCARD_S_SUCCESS)
        return (rv);

    /* Search the list of supported firmware versions (reader versions) */
    /* to check we are compatible with it - or have tested with it      */

    /* NULL terminate the BYTE array for subsequent string compares */
    pbRecvBuffer[dwRecvLength] = '\0';

    for (i = 0; (i < SUPPORTED_READER_FIRMWARE_ARRAY_COUNT) & (*pReaderSupported == FALSE) ; i++)
    {
        if ( strncmp( ((char *)pbRecvBuffer), SUPPORTED_READER_FIRMWARE_ARRAY[i],
                      sizeof(SUPPORTED_READER_FIRMWARE_ARRAY[i])-1) == 0 )
            *pReaderSupported = TRUE;
    }

    /* if we didn't find that we support it, then we're done */
    if ( *pReaderSupported == FALSE )
        return( SCARD_S_SUCCESS ); /* no actual communication errors to report */

    /* If we got this far then the general name and specific firmware version is supported */
    /* Get ATR so we can tell if there is a SAM in the reader */
    dwAtrLen = sizeof(pbAtr);
    dwReaderLen = sizeof(pbReader);
    SCardStatus( (SCARDHANDLE) (pReader->hCard), pbReader, &dwReaderLen, &dwState, &dwProt, pbAtr, &dwAtrLen);

    dwRecvLength = sizeof(pbRecvBuffer);
    rv = apduSend(pReader->hCard, APDU_SET_RETRY, sizeof(APDU_SET_RETRY),
                  pbRecvBuffer, &dwRecvLength);
    if (rv != SCARD_S_SUCCESS)
        return (rv);

    /* get card status ATR first two bytes = ACS_NO_SAM= '3B00' */
    if ( (pbAtr[SW1] != 0x3B) || (pbAtr[SW2] != 0x00) )
    {
        dwRecvLength = sizeof(pbRecvBuffer);
        rv = apduSend(pReader->hCard, APDU_GET_SAM_SERIAL,
                      sizeof(APDU_GET_SAM_SERIAL),
                      pbRecvBuffer, &dwRecvLength);
        if (rv == SCARD_S_SUCCESS)
        {
            sPrintBufferHex(pReader->SAM_serial, dwRecvLength, pbRecvBuffer);
#if 0
            sprintf(messageString, "SAM Serial: %s", pReader->SAM_serial);
            readersLogMessage(LOG_INFO, 1, messageString);
#endif
        }
        else
            return (rv);

        dwRecvLength = sizeof(pbRecvBuffer);
        rv = apduSend(pReader->hCard, APDU_GET_SAM_ID, sizeof(APDU_GET_SAM_ID),
                      pbRecvBuffer, &dwRecvLength);
        if (rv == SCARD_S_SUCCESS)
        {
            sPrintBufferHex(pReader->SAM_id, dwRecvLength, pbRecvBuffer);
#if 0
            sprintf(messageString, "SAM ID: %s", pReader->SAM_id);
            readersLogMessage(LOG_INFO, 1, messageString);
#endif
        }
        else
            return( rv );

        pReader->SAM = TRUE;
    }

    /* Turning RATS off thus a JCOP tag will be detected as emulating a DESFIRE */
    apduSend(pReader->hCard, APDU_RATS_14443_4_OFF, sizeof(APDU_RATS_14443_4_OFF), pbRecvBuffer, &dwRecvLength);

    return( SCARD_S_SUCCESS );

}
예제 #11
0
/**************************** APDU SEND ************************/
static LONG
apduSend (
    tCardHandle     hCard,
    const BYTE    	*apdu,
    DWORD			apduLength,
    BYTE			*pbRecvBuffer,
    DWORD			*dwRecvLength
)
{
    LONG 			rv;
    SCARD_IO_REQUEST 	pioRecvPci;
    BYTE 			pbSendBuffer[40];
    DWORD 			dwSendLength = 0;
    DWORD			rBufferMax;
    BOOL			psuedoAPDU = FALSE;


    /* remember the size of the input buffer passed to us, so we don't exceed */
    rBufferMax = *dwRecvLength;

    /* The special psuedo APDU's to talk to a tag, need to have their */
    /* response read back in two chunks, using GET_RESPONSE for the second */
    if (apdu[0] == 0xd4)
    {
        psuedoAPDU = TRUE;
        /* prepend the DIRECT_TRANSMIT APDU  */
        memcpy(pbSendBuffer, APDU_DIRECT_TRANSMIT, sizeof(APDU_DIRECT_TRANSMIT));

        /* then a byte that tells it the length of the psuedo APDU to follow */
        pbSendBuffer[sizeof(APDU_DIRECT_TRANSMIT)] = (BYTE)apduLength;

        dwSendLength += (sizeof(APDU_DIRECT_TRANSMIT) + 1);
    }

    /* Add the APDU that was requested to be sent and increase length to send */
    memcpy((pbSendBuffer + dwSendLength), apdu, apduLength);
    dwSendLength += apduLength;

#if 0
    sprintf(messageString, "APDU: ");
    sPrintBufferHex((messageString + strlen("APDU: ")), dwSendLength, pbSendBuffer);
    readersLogMessage( pManager, LOG_INFO, 3, messageString);
#endif

    rv = SCardTransmit((SCARDHANDLE) hCard,
                       pioSendPci, pbSendBuffer, dwSendLength,
                       &pioRecvPci, pbRecvBuffer, dwRecvLength);

    /* if it was a psuedo APDU then we need to get the response */
    if ( (rv == SCARD_S_SUCCESS) && psuedoAPDU )
    {
#if 0
        sprintf(messageString, "Received: ");
        sPrintBufferHex((messageString + strlen("Received: ")), *dwRecvLength, pbRecvBuffer);
        readersLogMessage(LOG_INFO, 3, messageString);
#endif

        /* command went OK? */
        if (pbRecvBuffer[SW1] != SW1_SUCCESS)
        {
#if 0
            sprintf(messageString, "APDU failed: SW1 = %02X", pbRecvBuffer[SW1]);
            readersLogMessage(LOG_ERR, 0, messageString);
#endif
            return ( SCARD_F_COMM_ERROR );
        }

        /* are their response bytes to get? */
        if (pbRecvBuffer[SW2] > 0)
        {
#if 0
            sprintf(messageString, "Requesting Response Data (%d)",
                    pbRecvBuffer[SW2]);
            readersLogMessage(LOG_INFO, 3, messageString);
#endif

            /* copy the get_response APDU into the first bytes */
            memcpy(pbSendBuffer, APDU_GET_RESPONSE, sizeof(APDU_GET_RESPONSE));

            /* the second response byte tells us how many bytes are pending */
            /* add that value at the end of the GET_RESPONSE APDU */
            pbSendBuffer[sizeof(APDU_GET_RESPONSE)] = pbRecvBuffer[SW2];
            dwSendLength = sizeof(APDU_GET_RESPONSE) + 1;

            /* specify the maximum size of the buffer that was passed in */
            *dwRecvLength = rBufferMax;

            rv = SCardTransmit((SCARDCONTEXT)hCard, pioSendPci, pbSendBuffer,
                               dwSendLength, &pioRecvPci, pbRecvBuffer, dwRecvLength );
#if 0
            PCSC_ERROR(rv, "SCardTransmit");
            sprintf(messageString, "Received: ");
            sPrintBufferHex(messageString, rBufferMax, pbRecvBuffer);
            readersLogMessage(LOG_INFO, 3, messageString);
#endif
        }
        else
            *dwRecvLength = 0;
    }

    return(rv);

}
예제 #12
0
/************************ DAEMONIZE *************************/
void daemonize( tReaderManager *pManager ){
   int		pid;
   char		messageString[MAX_LOG_MESSAGE];

   /* fork a copy of myself */
   pid = fork();
   if ( pid < 0 )
   { /* fork error */
      sprintf(messageString, "Error forking daemon %s, exiting", DAEMON_NAME);
      readersLogMessage( pManager, LOG_ERR, 0, messageString);
      exit( EXIT_FAILURE );
   }

   if ( pid > 0 )
   { /* fork worked, this is the parent process so exit */
      sprintf(messageString, "Started daemon %s with PID=%d, see /var/log/syslog",
              DAEMON_NAME, pid );
      readersLogMessage( pManager, LOG_INFO, 1, messageString);
      exit( EXIT_FAILURE );
   }

   /* from here on I must be a successfully forked child */
   runningAsDaemon = TRUE;

   /* tell the library we are now going to be calling it from a daemon */
   readersSetOptions( pManager, IGNORE_OPTION, runningAsDaemon );

   /* set umask for creating files */
   umask(0);

   /* start logging --> /var/log/syslog on my system */
   openlog(DAEMON_NAME, LOG_PID, LOG_DAEMON);

   /* get a new process group for daemon */
   if ( setsid() < 0 )
   {
      sprintf(messageString, "Error creating new SID for daemon process %s with PID=%d, see in /var/log/syslog", DAEMON_NAME, pid );
      readersLogMessage( pManager, LOG_ERR, 0, messageString);
      exit( EXIT_FAILURE );
   }

   /* change working directory to / */
   if ( (chdir("/")) < 0 )
      exit( EXIT_FAILURE );

   /* These following lines to close open filedescriptors are recommended for daemons, but it      */
   /* seems to cause problems for executing some xternal scripts with system() so they are avoided */
#if 0
   /* close unneeded descriptions in the deamon child process */
   for (i = getdtablesize(); i >= 0; i--)
      close( i );

   /* close stdio */
   close ( STDIN_FILENO );
   close ( STDOUT_FILENO );
   close ( STDERR_FILENO );
#endif

   /* make sure Iḿ the only one reading from this reader */
   getLockOrDie( pManager );

   /* ignore TTY related signales */
   signal( SIGTSTP, SIG_IGN );
   signal( SIGTTOU, SIG_IGN );
   signal( SIGTTIN, SIG_IGN );

   sprintf(messageString, "Daemon Started" );
   readersLogMessage( pManager, LOG_INFO, 1, messageString);
}