bool AsioDrivers::loadDriver(char *name)
{
	char dname[64];
	unsigned long newID;

	for(long i = 0; i < getNumFragments(); i++)
	{
		if(getName(i, dname) && !strcmp(name, dname))
		{
			if(newInstance(i, &newID))
			{
				if(resolveASIO(newID))
				{
					if(connID != -1)
						removeInstance(curIndex, connID);
					curIndex = i;
					connID = newID;
					return true;
				}
			}
			break;
		}
	}
	return false;
}
Example #2
0
int SendTextIMPacket::putContents(unsigned char *buf) 
{
	int pos=0;

	//multi-fragment information
	buf[pos++] = numFragments;
	buf[pos++] = seqFragments;
	memcpy(buf+pos, &messageID, 2);
	pos+=2;
	
	bool hasImage = false;
	std::string str2send = EvaUtil::convertToSend(message, &hasImage);

	buf[pos++] = hasImage?QQ_IM_IMAGE_REPLY:replyType; // auto-reply or not

	memcpy(buf+pos, str2send.c_str(), str2send.length());
	pos += str2send.length();

	if (getNumFragments() == (getSeqOfFragments() + 1))
	{
		buf[pos++] = 0x20; //  a space, witch is needed in the last fragment
		setMessageID(getMessageID() + 1);
	}
	buf[pos++] = 0x00;    //  C style string terminator
	
	buf[pos++] = fontFlag;
	buf[pos++] = red;
	buf[pos++] = green;
	buf[pos++] = blue;
	
	buf[pos++] = 0;
	
	short tmpEncoding = htons(encoding);  // encoding for text
	memcpy(buf+pos,&tmpEncoding, 2);
	pos+=2;
	
	int len = fontName.length();     // font name
	memcpy(buf+pos, fontName.c_str(), len);
        pos+=len;
 
	buf[pos++] = 0x0D;   // an Enter
	
	return pos;
}
long AsioDrivers::getDriverNames(char **names, long maxDrivers)
{
	for(long i = 0; i < getNumFragments() && i < maxDrivers; i++)
		getName(i, names[i]);
	return getNumFragments() < maxDrivers ? getNumFragments() : maxDrivers;
}
Example #4
0
bool LcmTunnel::send_lcm_messages(std::deque<TunnelLcmMessage *> &msgQueue, uint32_t bytesInQueue)
{
  if (udp_fd >= 0) {
    if (server_udp_port <= 0)
      return true; //connection hasn't been setup yet.

    udp_send_seqno++;//increment the sequence counter
    udp_send_seqno = udp_send_seqno % SEQNO_WRAP_VAL;
    if (verbose)
      printf("sending %d bytes from %d lcm messages\n", bytesInQueue, static_cast<int> (msgQueue.size()));

    uint32_t msgSize = bytesInQueue;
    int nfragments = getNumFragments(msgSize);
    if ((tunnel_params->fec <= 0 && nfragments > MAX_NUM_FRAGMENTS) || (tunnel_params->fec > 0 && nfragments
        > MAX_NUM_FRAGMENTS / tunnel_params->fec)) {
      uint32_t maxMsgSize;
      if (tunnel_params->fec > 0)
        maxMsgSize = MAX_PAYLOAD_BYTES_PER_FRAGMENT * MAX_NUM_FRAGMENTS / tunnel_params->fec;
      else
        maxMsgSize = MAX_PAYLOAD_BYTES_PER_FRAGMENT * MAX_NUM_FRAGMENTS;
      fprintf(stderr,
          "WARNING! Queue contains more than the max message size of %d bytes... we're WAY behind, dropping msgs\n",
          maxMsgSize);
      while (msgSize < maxMsgSize) {
        //drop messages
        TunnelLcmMessage * drop_msg = msgQueue.front();
        msgQueue.pop_front();
        msgSize -= drop_msg->encoded_size;
        delete drop_msg;
      }
    }
    //put the entire queue into 1 big buffer
    uint8_t * msgBuf = (uint8_t *) malloc(msgSize * sizeof(uint8_t));
    uint32_t msgBufOffset = 0;
    while (!msgQueue.empty()) {
      TunnelLcmMessage * msg = msgQueue.front();
      msgQueue.pop_front();
      lcm_tunnel_sub_msg_t_encode(msgBuf, msgBufOffset, msgSize - msgBufOffset, msg->sub_msg);
      msgBufOffset += msg->encoded_size;
      delete msg;
    }
    assert(msgBufOffset==msgSize);

    if (tunnel_params->fec < 1 || nfragments < MIN_NUM_FRAGMENTS_FOR_FEC) { //don't use FEC
      int sendRepeats = 1;
      if (fabs(tunnel_params->fec) > 1) { //fec <0 means always send duplicates
        sendRepeats = (int) ceil(fabs(tunnel_params->fec)); //send ceil of the fec rate times
      }
      for (int r = 0; r < sendRepeats; r++) {
        msgBufOffset = 0;
        for (int i = 0; i < nfragments; i++) {
          lcm_tunnel_udp_msg_t msg;
          msg.seqno = udp_send_seqno;
          msg.fragno = i;
          msg.payload_size = msgSize;

          msg.data_size = MIN(MAX_PAYLOAD_BYTES_PER_FRAGMENT, msgSize - msgBufOffset);
          msg.data = msgBuf + msgBufOffset;

          msgBufOffset += msg.data_size;

          int msg_sz = lcm_tunnel_udp_msg_t_encoded_size(&msg);
          uint8_t msg_buf[msg_sz];
          lcm_tunnel_udp_msg_t_encode(msg_buf, 0, msg_sz, &msg);
          //          printf("sending: %d, %d / %d\n", msg.seqno, msg.fragment, msg.nfrags);
          int send_status = send(udp_fd, msg_buf, msg_sz, 0);
          //          fprintf(stderr,"sent packet\n");
          checkUDPSendStatus(send_status);
        }
      }
    }
    else { //use tunnel error correction to send
      ldpc_enc_wrapper * ldpc_enc = new ldpc_enc_wrapper(msgBuf, msgSize, MAX_PAYLOAD_BYTES_PER_FRAGMENT,
          tunnel_params->fec);

      lcm_tunnel_udp_msg_t msg;
      msg.seqno = udp_send_seqno;
      msg.payload_size = msgSize;

      //      printf("sending: %d, %d / %d\n", recv_udp_msg->seqno, recv_udp_msg->fragment, recv_udp_msg->nfrags);

      int enc_done = 0;
      while (!enc_done) {
        uint8_t data_buf[MAX_PAYLOAD_BYTES_PER_FRAGMENT];
        msg.data_size = MAX_PAYLOAD_BYTES_PER_FRAGMENT;
        msg.data = data_buf;
        enc_done = ldpc_enc->getNextPacket(msg.data, &msg.fragno);

        int msg_sz = lcm_tunnel_udp_msg_t_encoded_size(&msg);
        uint8_t msg_buf[msg_sz];
        lcm_tunnel_udp_msg_t_encode(msg_buf, 0, msg_sz, &msg);
        //          printf("sending: %d, %d / %d\n", msg.seqno, msg.fragment, msg.nfrags);
        int send_status = send(udp_fd, msg_buf, msg_sz, 0);
        checkUDPSendStatus(send_status);
      }
      //          printf("finished encoding and sending packet %d for channel: %s\n",recv_udp_msg->seqno,channel);
      delete ldpc_enc;
    }
    free(msgBuf);
  }
  else {
    int cfd = ssocket_get_fd(tcp_sock);
    assert(cfd>0);

    while (!msgQueue.empty()) {
      TunnelLcmMessage * msg = msgQueue.front();
      msgQueue.pop_front();

      int64_t now = _timestamp_now();
      double age_ms = (now - msg->recv_utime) * 1.0e-3;
      if (tunnel_params->tcp_max_age_ms > 0 && age_ms > tunnel_params->tcp_max_age_ms) {
        // message has been queued up for too long.  Drop it.
        if (verbose)
          fprintf(stderr, "%s message too old (age = %d, param = %d), dropping.\n", msg->sub_msg->channel,
              (int) age_ms, tunnel_params->tcp_max_age_ms);
      }
      else {
        // send channel
        int chan_len = strlen(msg->sub_msg->channel);
        uint32_t chan_len_n = htonl(chan_len);
        if (4 != _fileutils_write_fully(cfd, &chan_len_n, 4)) {
          delete msg;
          return false;
        }
        if (chan_len != _fileutils_write_fully(cfd, msg->sub_msg->channel, chan_len)) {
          delete msg;
          return false;
        }

        // send data
        int data_size_n = htonl(msg->sub_msg->data_size);
        if (4 != _fileutils_write_fully(cfd, &data_size_n, 4)) {
          delete msg;
          return false;
        }
        if (msg->sub_msg->data_size != _fileutils_write_fully(cfd, msg->sub_msg->data, msg->sub_msg->data_size)) {
          delete msg;
          return false;
        }
      }
      if (verbose)
        printf("Sent \"%s\".\n", msg->sub_msg->channel);
      delete msg;
    }
  }

  return true;
}
Example #5
0
int LcmTunnel::on_udp_data(GIOChannel * source, GIOCondition cond, void *user_data)
{
  LcmTunnel * self = (LcmTunnel*) user_data;

  uint8_t recv_buffer[65535];

  int recv_status = recv(self->udp_fd, recv_buffer, 65535, 0);

  if (recv_status < 0) {
    perror("recv error: ");
    return TRUE;
    //    LcmTunnelServer::disconnectClient(self);
  }

  lcm_tunnel_udp_msg_t * recv_udp_msg = (lcm_tunnel_udp_msg_t *) calloc(1, sizeof(lcm_tunnel_udp_msg_t));
  int decode_ret = lcm_tunnel_udp_msg_t_decode(recv_buffer, 0, recv_status, recv_udp_msg);
  if (decode_ret < 0) {
    lcm_tunnel_disconnect_msg_t disc_msg;
    decode_ret = lcm_tunnel_disconnect_msg_t_decode(recv_buffer, 0, recv_status, &disc_msg);
    if (decode_ret >= 0) {
      fprintf(stderr, "Received a disconnect message... disconnecting!\n");
      LcmTunnelServer::disconnectClient(self);
    }
    else {
      fprintf(stderr, "Received Corrupted UDP packet!\n");
    }

  }

  //  printf("received: %d, %d / %d\n", recv_udp_msg->seqno, recv_udp_msg->fragment, recv_udp_msg->nfrags);


  if (self->verbose, recv_udp_msg->seqno < self->cur_seqno) {
    printf("Got Out of order packet!\n");
  }

  // start of a new message?
  if (recv_udp_msg->seqno > self->cur_seqno || recv_udp_msg->seqno < (int32_t) self->cur_seqno - SEQNO_WRAP_GAP) { //handle wrap-around with second part
    if (!self->message_complete && self->cur_seqno > 0 || recv_udp_msg->seqno > (self->cur_seqno + 1)) {
      printf("packets %d to %d dropped! with %d of %d fragments received, ", self->cur_seqno, recv_udp_msg->seqno - 1,
          self->numFragsRec, self->nfrags);
      if (self->tunnel_params->fec > 1 && self->nfrags >= MIN_NUM_FRAGMENTS_FOR_FEC) {
        printf("was FECed\n");
      }
      else
        printf("not FECed\n");
    }
    self->cur_seqno = recv_udp_msg->seqno;
    self->nfrags = getNumFragments(recv_udp_msg->payload_size);
    self->numFragsRec = 0;
    //increase the recFlags buffers
    if (self->recFlags_sz < self->nfrags) {
      self->recFlags_sz = self->nfrags;
      self->recFlags = (char *) realloc(self->recFlags, self->recFlags_sz);
    }
    memset(self->recFlags, 0, self->recFlags_sz); //mark all frags as unreceived
    self->completeTo_fragno = 0;
    self->fragment_buf_offset = 0;

    int messageSize = recv_udp_msg->payload_size;
    // increase buffer size if needed, also make enough space for the channel in case we're using FEC
    if (self->buf_sz < messageSize) {
      self->buf = (char *) realloc(self->buf, messageSize);
      self->buf_sz = messageSize;
    }

    //create a new FEC decoder
    if (self->ldpc_dec != NULL) {
      delete self->ldpc_dec; //delete the old one if we haven't already
      self->ldpc_dec = NULL;
    }
    if (self->tunnel_params->fec > 1 && self->nfrags >= MIN_NUM_FRAGMENTS_FOR_FEC) {
      //allocate the new one
      self->ldpc_dec = new ldpc_dec_wrapper(messageSize, MAX_PAYLOAD_BYTES_PER_FRAGMENT, self->tunnel_params->fec);
    }
    self->message_complete = 0;
  }

  if (!self->message_complete && recv_udp_msg->seqno == self->cur_seqno && getNumFragments(recv_udp_msg->payload_size)
      == self->nfrags) {
    self->numFragsRec++;
    if (self->tunnel_params->fec < 1 || self->nfrags < MIN_NUM_FRAGMENTS_FOR_FEC) { //we're not using FEC for this message
      // have we already received this fragment?
      if (recv_udp_msg->fragno < self->nfrags && !self->recFlags[recv_udp_msg->fragno]) {
        self->recFlags[recv_udp_msg->fragno] = 1;

        //copy everything to the app->buf
        int64_t pos_start = recv_udp_msg->fragno * MAX_PAYLOAD_BYTES_PER_FRAGMENT;
        int64_t pos_end = MIN(recv_udp_msg->payload_size, (recv_udp_msg->fragno + 1) * MAX_PAYLOAD_BYTES_PER_FRAGMENT);
        int64_t curPayloadSize = pos_end - pos_start;
        assert(recv_udp_msg->data_size==curPayloadSize);
        memcpy(self->buf + pos_start, recv_udp_msg->data, curPayloadSize);

        self->message_complete = 1;
        for (int i = self->completeTo_fragno; i < self->nfrags; i++) {
          if (!self->recFlags[i]) {
            self->message_complete = 0;
            break;
          }
          else
            self->completeTo_fragno = i;
        }

        if (self->message_complete) {
          //publish all the lcm messages in the buffer
          self->publishLcmMessagesInBuf(recv_udp_msg->payload_size);
        }

      }
      else if (self->verbose) {
        printf("ignoring udp packet\n");
        //        printf("seqno: %d (%d)  fragment: %d (%d) nfrags: %d (%d)\n",
        //                recv_udp_msg->seqno, app->cur_seqno,
        //                recv_udp_msg->fragment, app->expected_fragno,
        //                recv_udp_msg->nfrags, app->nfrags);
      }
    }
    else { //we're using FEC
      int dec_done = self->ldpc_dec->processPacket(recv_udp_msg->data, recv_udp_msg->fragno);
      if (dec_done != 0) {
        if (dec_done == 1) {
          check_ret(self->ldpc_dec->getObject((uint8_t*) self->buf));
          //publish all the lcm messages in the buffer
          self->publishLcmMessagesInBuf(recv_udp_msg->payload_size);
        }
        else {
          fprintf(stderr, "ldpc got all the sent packets, but couldn't reconstruct... this shouldn't happen!\n");
        }
        self->message_complete = 1;
        delete self->ldpc_dec; //we're all done, so we can delete it
        self->ldpc_dec = NULL;
      }
    }
  }
  else if (self->verbose && !self->message_complete) {
    //    if (!self->message_complete && recv_udp_msg->seqno == self->cur_seqno && recv_udp_msg->nfrags == self->nfrags) {
    printf("ignoring udp packet seqno=%d, nfrag =%d, \t self-> seqno=%d, nfrags=%d\n", recv_udp_msg->seqno,
        getNumFragments(recv_udp_msg->payload_size), self->cur_seqno, self->nfrags);
  }

  lcm_tunnel_udp_msg_t_destroy(recv_udp_msg);

  return TRUE;
}