Ejemplo n.º 1
0
int m600_read_card(unsigned int count, m600_cardfn_t on_card, void* ctx)
{
  static const m600_request_t req = M600_REQ_READ_CARD;
  m600_reply_t rep;
  size_t size;
  int error;

  for (; count; --count)
    {
      error = serial_write(&handle, &req, sizeof(req), &size);
      if (error == -1 || size != sizeof(req))
	return -1;

      if (wait_for_read() == -1)
	return -1;

      error = serial_readn(&handle, (void*)&rep, sizeof(rep));
      if (error == -1)
	return -1;

      if (on_card(rep.card_data, rep.alarms, ctx) == -1)
	break;
    }

  return 0;
}
Ejemplo n.º 2
0
Socket *IPv4Socket::accept(bool nonblocking) {
    //fudeb("Socket::accept(s:%d)", sock_);
    LOG_DEBUG((use_rs_ ? "RDMA" : "TCP"));
    int asock = 0;
    while (!stop_) {
        if (nonblocking_) {
            wait_for_read();
        }
        asock = rs_accept(sock_, 0, 0);
        if (asock >= 0)
            break;
        LOG_WARN("accept encountered " << strerror(errno));
        if (asock < 0 && errno != EAGAIN && errno != EINTR
#ifndef _WIN32
                && errno != ECONNABORTED && errno != EPROTO
#endif
           ) {
            throw IOException("accept", "", getErrorNumber());
        }

    }
    if (stop_) {
        return 0;
    }

    uint16_t remote_port = 0;
    char str[INET_ADDRSTRLEN];

    struct sockaddr_in clientaddr;
    socklen_t addrlen = sizeof(clientaddr);
    int res = rs_getpeername(asock, (struct sockaddr *) &clientaddr, &addrlen);
    if (res < 0) {
        throw IOException("Socket::accept() Failed to find peer IP/port", "",
                          res);
    }
    char * buf = inet_ntoa(clientaddr.sin_addr);
    if (buf != 0) {
        str[0] = 0;
#pragma warning( push )
#pragma warning( disable: 4996) // we use strncpy in a safe way
        strncpy(str, buf, INET_ADDRSTRLEN);
#pragma warning( pop )
        LOG_DEBUG("IPv4 Client address is " << str);
        LOG_DEBUG("Client port is " << ntohs(clientaddr.sin_port));
    } else {
        throw IOException(
            "Socket::accept() Failure to resolve remote peer for accepted connection");
    }

    remote_port = ntohs(clientaddr.sin_port);

    Socket *asock2 = new IPv4Socket(this, asock, sock_type_, str, remote_port);
    if (nonblocking) {
        asock2->setNonBlocking();
    }
    // TODO make sendbuffersize
    // asock2->setSendbufferssize(32 * 1024);
    return asock2;
}
Ejemplo n.º 3
0
int m600_read_alarms(m600_alarms_t* alarms)
{
  static const m600_request_t req = M600_REQ_READ_ALARMS;
  m600_reply_t rep;
  size_t size;
  int error;

  error = serial_write(&handle, &req, sizeof(req), &size);
  if (error == -1 || size != sizeof(req))
    return -1;

  if (wait_for_read() == -1)
    return -1;

  error = serial_readn(&handle, (void*)&rep, sizeof(rep));
  if (error == -1)
    return -1;

  *alarms = rep.alarms;

  return 0;
}
Ejemplo n.º 4
0
size_t network::stream_read(
    network::socket_t const &sockfd,
    void                    *buffer,
    size_t                   buffer_size,
    size_t                   buffer_offset,
    bool                    *out_disconnected,
    int                     *out_error /* = NULL */)
{
    char *buf = (char*) buffer      + buffer_offset;
    int   nba = (int)  (buffer_size - buffer_offset);
    int   res = -1;

    LLSOCKET_SET_ERROR_RESULT(0);

    if (buffer           == NULL   ||
        buffer_size      == 0      ||
        out_disconnected == NULL   ||
        buffer_offset    >= buffer_size)
    {
        // invalid parameter. return immediately.
        if (out_disconnected != NULL) *out_disconnected = false;
        return 0;
    }

    // ideally this loop only executes once, but if the OS buffers fill up
    // we may need to re-try the receive operation multiple times.
    size_t retry_count = 0;
    bool   try_recv    = true;
    while (try_recv)
    {
        if (retry_count >= LLSOCKET_MAX_RETRIES)
        {
            // this socket has exceeded its retry count. disconnect it.
            network::stream_shutdown(sockfd, NULL, NULL);
            *out_disconnected = true;
            return 0;
        }

        // assume the receive operation will succeed:
        try_recv = false;

        // read as much data as possible from the socket:
        res = recv(sockfd, buf, nba, 0);
        if  (!network::socket_error(res))
        {
            if (res != 0)
            {
                *out_disconnected = false;
                return (size_t) res;
            }
            else
            {
                // the socket was shutdown gracefully.
                network::stream_shutdown(sockfd, NULL, NULL);
                *out_disconnected = true;
                return 0;
            }
        }

#if defined(_WIN32) || defined(_WIN64)
        // an error occurred. try to determine whether we are still connected.
        int     err = WSAGetLastError();
        switch (err)
        {
            case WSAEWOULDBLOCK:
                {
                    // no data is available to read on the socket.
                    // this is not actually an error.
                    *out_disconnected = false;
                }
                return 0;

            case WSAENOBUFS:     // ENOBUFS
                {
                    // insufficient resources available in the system to
                    // perform the operation. we'll wait (in select()) for
                    // a bit to see if the socket becomes readable again;
                    // otherwise, the socket is shutdown.
                    if (wait_for_read(sockfd, LLSOCKET_WAIT_TIMEOUT_USEC))
                    {
                        // the socket is available again. retry.
                        try_recv = true;
                        retry_count++;
                        continue; // back to the loop start
                    }
                    else
                    {
                        // the wait timed out. disconnect the socket.
                        network::stream_shutdown(sockfd, NULL, NULL);
                        LLSOCKET_SET_ERROR_RESULT(err);
                        *out_disconnected = true;
                    }
                }
                return 0;

            case WSANOTINITIALISED:
            case WSAENETDOWN:
            case WSAENOTCONN:
            case WSAENETRESET:
            case WSAENOTSOCK:
            case WSAESHUTDOWN:
            case WSAECONNABORTED:
            case WSAETIMEDOUT:
            case WSAECONNRESET:
                {
                    // we were either never connected, or the connection has
                    // somehow been terminated in a non-graceful way.
                    network::stream_shutdown(sockfd, NULL, NULL);
                    LLSOCKET_SET_ERROR_RESULT(err);
                    *out_disconnected = true;
                }
                return 0;

            default:
                {
                    // an error occurred; try again.
                    try_recv = true;
                    retry_count++;
                }
                break;
        }
#else
        // an error occurred. try to determine whether we are still connected.
        int     err = errno;
        switch (err)
        {
            case EWOULDBLOCK:
                {
                    // no data is available to read on the socket.
                    // this is not actually an error.
                    *out_disconnected = false;
                }
                return 0;

            case ENOBUFS:
                {
                    // insufficient resources available in the system to
                    // perform the operation. we'll wait (in select()) for
                    // a bit to see if the socket becomes readable again;
                    // otherwise, the socket is shutdown.
                    if (wait_for_read(sockfd, LLSOCKET_WAIT_TIMEOUT_USEC))
                    {
                        // the socket is available again. retry.
                        try_recv = true;
                        retry_count++;
                        continue; // back to the loop start
                    }
                    else
                    {
                        // the wait timed out. disconnect the socket.
                        network::stream_shutdown(sockfd, NULL, NULL);
                        LLSOCKET_SET_ERROR_RESULT(err);
                        *out_disconnected = true;
                    }
                }
                return 0;

            case EBADF:
            case ECONNRESET:
            case ENOTCONN:
            case ENOTSOCK:
            case ETIMEDOUT:
                {
                    // we were either never connected, or the connection has
                    // somehow been terminated in a non-graceful way.
                    network::stream_shutdown(sockfd, NULL, NULL);
                    LLSOCKET_SET_ERROR_RESULT(err);
                    *out_disconnected = true;
                }
                return 0;

            default:
                {
                    // an error occurred; try again.
                    try_recv = true;
                    retry_count++;
                }
                break;
        }
#endif
    }
    // no data was received.
    return 0;
}