Logo Search packages:      
Sourcecode: pcsc-lite version File versions  Download package

INTERNAL LONG MessageReceiveTimeout ( uint32_t  command,
void *  buffer_void,
uint64_t  buffer_size,
int32_t  filedes,
unsigned long  timeOut 
)

Called by the Client to get the reponse from the server or vice-versa.

Reads the message from the file filedes.

Parameters:
[in]commandone of the pcsc_msg_commands commands
[out]buffer_voidMessage read.
[in]buffer_sizeSize to read
[in]filedesSocket handle.
[in]timeOutTimeout in milliseconds.
Return values:
SCARD_S_SUCCESSSuccess.
SCARD_E_TIMEOUTTimeout.
SCARD_F_COMM_ERRORSocket is closed.
SCARD_F_COMM_ERRORA signal was received.

Definition at line 159 of file winscard_msg.c.

References SCARD_E_TIMEOUT, SCARD_F_COMM_ERROR, SCARD_S_SUCCESS, SCardCheckDaemonAvailability(), and time_sub().

Referenced by SCardGetStatusChange().

{
      char *buffer = buffer_void;

      /* default is success */
      LONG retval = SCARD_S_SUCCESS;

      /* record the time when we started */
      struct timeval start;

      /* how many bytes we must read */
      size_t remaining = buffer_size;

      gettimeofday(&start, NULL);

      /* repeat until we get the whole message */
      while (remaining > 0)
      {
            fd_set read_fd;
            struct timeval timeout, now;
            int selret;
            long delta;

            gettimeofday(&now, NULL);
            delta = time_sub(&now, &start);

            if (delta > timeOut*1000)
            {
                  /* we already timed out */
                  retval = SCARD_E_TIMEOUT;
                  break;
            }

            /* remaining time to wait */
            delta = timeOut*1000 - delta;

            FD_ZERO(&read_fd);
            FD_SET(filedes, &read_fd);

            timeout.tv_sec = delta/1000000;
            timeout.tv_usec = delta - timeout.tv_sec*1000000;

            selret = select(filedes + 1, &read_fd, NULL, NULL, &timeout);

            /* try to read only when socket is readable */
            if (selret > 0)
            {
                  int readed;

                  if (!FD_ISSET(filedes, &read_fd))
                  {
                        /* very strange situation. it should be an assert really */
                        retval = SCARD_F_COMM_ERROR;
                        break;
                  }
                  readed = read(filedes, buffer, remaining);

                  if (readed > 0)
                  {
                        /* we got something */
                        buffer += readed;
                        remaining -= readed;
                  } else if (readed == 0)
                  {
                        /* peer closed the socket */
                        retval = SCARD_F_COMM_ERROR;
                        break;
                  } else
                  {
                        /* we ignore the signals and empty socket situations, all
                         * other errors are fatal */
                        if (errno != EINTR && errno != EAGAIN)
                        {
                              retval = SCARD_F_COMM_ERROR;
                              break;
                        }
                  }
            } else if (selret == 0)
            {
                  /* is the daemon still there? */
                  retval  =  SCardCheckDaemonAvailability();
                  if (retval != SCARD_S_SUCCESS)
                  {
                        /* timeout */
                        break;
                  }

                  /* you need to set the env variable PCSCLITE_DEBUG=0 since
                   * this is logged on the client side and not on the pcscd
                   * side*/
                  Log2(PCSC_LOG_INFO, "Command 0x%X not yet finished", command);
            } else
            {
                  /* we ignore signals, all other errors are fatal */
                  if (errno != EINTR)
                  {
                        Log2(PCSC_LOG_ERROR, "select returns with failure: %s",
                              strerror(errno));
                        retval = SCARD_F_COMM_ERROR;
                        break;
                  }
            }
      }

      return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index