Пример #1
0
int receiveMessage(int sock, void *message, int maxLength, unsigned long timeout)
{
  unsigned long val;
  long timeout_s;
  long timeout_us;
  int bytesReceived;

  if (sock < 0) {  // invalid socket number.
    return -1;
  }

  // set a receive timeout
  val = timeout + 100;
  setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &val, sizeof(unsigned long));

  timeout_s = timeout / 1000;
  timeout_us = (timeout - (timeout_s*1000)) * 1000;

  bytesReceived = 0;

  switch (recvfromTimeOut(sock, timeout_s, timeout_us)) {
    case 0:   // timed out
    case -1:  // error
      return -1;
      break;
    default:  // got a reply
      bytesReceived = recv(sock, message, maxLength, 0);
      break;
  }
  return bytesReceived;
}
Пример #2
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  char address [1024] ;
  char port [1024] ;
  char key [1024] ;

  struct addrinfo servHints ;
  struct addrinfo *servInfo ;

  int status ;

  enum {IN_HOST, IN_PORT, IN_KEY} ;
  enum {OUT_GO} ;

  if (nin != 3) {
    mexErrMsgTxt("Three arguments required") ;
  }

  if (mxGetString(in[IN_HOST], address, sizeof(address))) {
    mexErrMsgTxt("HOST must be a string") ;
  }
  if (mxGetString(in[IN_PORT], port, sizeof(port))) {
    mexErrMsgTxt("PORT must be a string") ;
  }
  if (mxGetString(in[IN_KEY], key, sizeof(key))) {
    mexErrMsgTxt("KEY must be a string") ;
  }

  /* IN address of server */
  memset(&servHints, 0, sizeof(servHints));
  servHints.ai_family   = AF_INET ; /* AF_UNSPEC */
  servHints.ai_socktype = SOCK_DGRAM ;

  status = getaddrinfo(address, port, &servHints, &servInfo) ;

  if (status) {
    mexPrintf(gai_strerror(status)) ;
    mexErrMsgTxt("getaddrinfo") ;
  }

#if 1
  {
    struct addrinfo *p ;
    for(p = servInfo ; p != NULL ; p = p->ai_next) {
      void *addr;
      char *ipver;
      char ipstr[INET6_ADDRSTRLEN];
      int port ;

      /* get the pointer to the address itself,
       * different fields in IPv4 and IPv6: */
      if (p->ai_family == AF_INET) { /* IPv4 */
        struct sockaddr_in *ipv4 = (struct sockaddr_in *) p->ai_addr ;
        addr = &(ipv4->sin_addr);
        port = ntohs(ipv4->sin_port) ;
        ipver = "IPv4";
      } else { /* IPv6 */
        struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
        addr = &(ipv6->sin6_addr);
        port = ntohs(ipv6->sin6_port) ;
        ipver = "IPv6";
      }

      /* convert the IP to a string and print it: */
      inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
      mexPrintf("  %s: %s (port %d)\n", ipver, ipstr, port);
    }
  }
#endif

  {
    char answer [1024] ;
    int unsigned answerLength = sizeof(answer) ;
    int answerRecvLength ;
    int clientSocket ;
    socklen_t fromLength = sizeof(struct sockaddr_in) ;
    int numAttemptsLeft = 5 ;

    memset(answer, 0, answerLength) ;

    clientSocket = socket(servInfo->ai_family,
                          servInfo->ai_socktype,
                          servInfo->ai_protocol) ;

    if (clientSocket < 0) {
      mexErrMsgTxt("socket()") ;
    }

    while (numAttemptsLeft -- > 0) {

      status = sendto(clientSocket,
                      key,
                      strlen(key),
                      0,
                      servInfo->ai_addr,
                      sizeof(struct sockaddr_in)) ;

      status = recvfromTimeOut(clientSocket, 5, 0) ;

      if (status < 0) break ;
      if (status == 0) {
        mexPrintf("Resending request due to timeout (%d left)\n", 
                  numAttemptsLeft) ;
        continue ;
      }

      answerRecvLength = recvfrom(clientSocket,
                                  answer,
                                  answerLength,
                                  0,
                                  servInfo->ai_addr,
                                  &fromLength) ;
      break ;
      /* mexPrintf("answ %d: '%s'\n", answerRecvLength, answer) ; */
    }

    close(clientSocket) ;
    out[OUT_GO] = mxCreateLogicalScalar(strcmp(answer, "stop") != 0) ;
  }

  freeaddrinfo(servInfo) ;
}
Пример #3
0
int discoverDevice(EthernetDeviceInfo *device_info, uint16_t productID)
{
  EthernetDeviceInfo device;  // a MCC device that responded
  struct sockaddr_in sendaddr;
  struct sockaddr_in recvaddr;
  struct sockaddr_in remoteaddr;
  int sock;
  int broadcast;
  unsigned char msg[64];
  bool finished = false;   
  int nfound = 0;            // number of matched devices found
  socklen_t remoteaddrSize;
  int BytesReceived;

  // create the socket
  if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    perror("discoverDevice: Error in creating socket");
    return -1;
  }
  // set the broadcast option
  broadcast = 1;
  if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0) {
    perror("discoverDevice: Error setting socket options");
    close(sock);
    return -1;
  }
  // set up the send and receive addresses
  memset(&sendaddr, 0, sizeof(sendaddr));
  sendaddr.sin_family = AF_INET;
  sendaddr.sin_addr.s_addr = INADDR_BROADCAST;
  sendaddr.sin_port = htons(DISCOVER_PORT);
  
  memset(&recvaddr, 0, sizeof(recvaddr));
  recvaddr.sin_family = AF_INET;
  recvaddr.sin_addr.s_addr = INADDR_ANY;
  recvaddr.sin_port = htons(DISCOVER_PORT);

  // bind the socket for receive
  if (bind(sock, (struct sockaddr*)&recvaddr, sizeof(recvaddr)) < 0) {
    perror("discoverDevice: Error binding port");
    close(sock);
    return -1;
  }

  // send a broadcast discover datagram
  msg[0] = 'D';
  if (sendto(sock, msg, 1, 0, (struct sockaddr*)&sendaddr, sizeof(sendaddr)) != 1) {
    perror("discoverDevice: sendto failed");
    close(sock);
    return -1;
  }

  // look for replies (including the original broadcast)
  while (!finished) {
    switch (recvfromTimeOut(sock, 1, 0)) {
      case 0:
        // timed out
        finished = true;
        break;
      case -1:
        // error
        printf("Error from recvfromTimeOut\n");
        finished = true;
        close(sock);
        return -1;
        break;
      default:
       // got a reply
        remoteaddrSize = sizeof(remoteaddr);
        BytesReceived = recvfrom(sock, msg, 64, 0, (struct sockaddr*)&remoteaddr, &remoteaddrSize);
        if ((BytesReceived == 64) && (msg[0] == 'D')) {
	  memcpy(device.MAC, &msg[1], 6);
	  memcpy(&device.ProductID, &msg[7], 2);
	  memcpy(&device.FirmwareVersion, &msg[9], 2);
	  memcpy(device.NetBIOS_Name, &msg[11], 16);
	  memcpy(&device.CommandPort, &msg[27], 2);
	  memcpy(&device.Status, &msg[33], 2);
	  memcpy(&device.RemoteHost.sin_addr, &msg[35], 4);
	  memcpy(&device.BootloaderVersion, &msg[39], 2);
	  memcpy(&device.Address, &remoteaddr, sizeof(remoteaddr));
          if (device.ProductID == productID) {  // check for match
	    memcpy(device_info, &device, sizeof(EthernetDeviceInfo));
	    nfound++;
	  }
	}
	break;
    }
  }
  close(sock);
  return nfound;
}
Пример #4
0
int openDevice(uint32_t addr, uint32_t connectCode)
{
  int sock;
  struct sockaddr_in sendaddr;
  unsigned char msg[64];
  int bytesReceived;

  // open the UDP socket
  if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    perror("openDevice: Error creating socket.");
      return -1;
  }

  // set up the send address
  memset(&sendaddr, 0, sizeof(sendaddr));
  sendaddr.sin_family = AF_INET;
  sendaddr.sin_addr.s_addr = addr;
  sendaddr.sin_port = htons(DISCOVER_PORT);

  if (connect(sock, (const struct sockaddr*) &sendaddr, sizeof(sendaddr)) < 0) {
    perror("openDevice: error in connect.");
    close(sock);
    return -1;
  }
 
  // send the connect message
  msg[0] = 'C';
  memcpy(&msg[1], &connectCode, 4);
  if (send(sock, msg, 5, 0) < 0) {
    perror("openDevice: Error in send.");
    close(sock);
    return -1;
  }

  // look for a reply
  switch (recvfromTimeOut(sock, 1, 0)) {
    case 0:  // timed out
    case -1: //  error    
      close (sock);
      return -1;
      break;
    default:  // got a reply
      bytesReceived = recv(sock, msg, 64, 0);
      if ((bytesReceived == 2) && (msg[0] = 'C') && (msg[1] == 0)) {
	break;
      } else {
	close(sock);
	return -1;
      }
      break;
  }
  close(sock);   // finished with the UDP portion

  if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
    perror("openDevice: error creating TCP socket.");
    return -1;
  }

  // set up the send address
  memset(&sendaddr, 0, sizeof(sendaddr));
  sendaddr.sin_family = AF_INET;
  sendaddr.sin_addr.s_addr = addr;
  sendaddr.sin_port = htons(COMMAND_PORT);

  // create a tcp connection
  if ((connect(sock, (const struct sockaddr*) &sendaddr, sizeof(sendaddr))) < 0) {
      perror("openDevice: can not connect to device.");
      close(sock);
      return -1;
  }
    return sock;
}