示例#1
0
/**
 * Encode a BFCP message with variable arguments
 *
 * @param mb      Mbuf to encode into
 * @param prim    BFCP Primitive
 * @param confid  Conference ID
 * @param tid     Transaction ID
 * @param userid  User ID
 * @param attrc   Number of attributes
 * @param ap      Variable argument of attributes
 *
 * @return 0 if success, otherwise errorcode
 */
int bfcp_msg_vencode(struct mbuf *mb, enum bfcp_prim prim,
		     uint32_t confid, uint16_t tid, uint16_t userid,
		     uint32_t attrc, va_list ap)
{
	size_t start;
	uint32_t i;
	uint16_t len;
	int err = 0;

	if (!mb)
		return EINVAL;

	start = mb->pos;
	mb->pos += BFCP_HDR_SIZE;

	for (i=0; i<attrc; i++) {

		uint16_t type = va_arg(ap, int);
		const void *v = va_arg(ap, const void *);
		bool mand = false;

		if (!v)
			continue;

		err = bfcp_attr_encode(mb, mand, type, v);
		if (err)
			return err;
	}

	/* header */
	len = (mb->pos - start - BFCP_HDR_SIZE) / 4;
	mb->pos = start;
	err = bfcp_hdr_encode(mb, prim, len, confid, tid, userid);

	mb->pos = mb->end;

	return err;
}
示例#2
0
int build_msg_fragments( std::vector<mbuf_t*> &fragBufs, mbuf_t *msgBuf, size_t maxMsgSize )
{
  assert(kHeaderWithFragSize < maxMsgSize);

  int err = 0;
  size_t bufSize = msgBuf->end;
  if (bufSize < maxMsgSize)
  {
    fragBufs.push_back(msgBuf);
    mem_ref(msgBuf);
  }
  else
  {
    size_t start = msgBuf->pos;

    size_t payloadSize = bufSize - kHeaderSize;
    size_t maxFragPayloadSize = (maxMsgSize - kHeaderWithFragSize) & ~0x3;
    size_t fragmentCount = 
      (payloadSize + maxFragPayloadSize - 1) / maxFragPayloadSize;

    std::vector<mbuf_t*> bufs;
    bufs.reserve(fragmentCount);
    
    bfcp_hdr_t header;
    err = bfcp_hdr_decode(&header, msgBuf);
    assert(!err);
    assert(!header.f);

    size_t remainPayloadSize = payloadSize;
    for (size_t i = 0; i < fragmentCount; ++i)
    {
      mbuf_t *buf = mbuf_alloc(maxMsgSize);
      if (!buf)
      {
        err = ENOMEM;
        break;
      }
      bufs.push_back(buf);

      header.f = 1;
      header.fragoffset = i * maxFragPayloadSize / 4;
      size_t actualPayloadSize = (std::min)(maxFragPayloadSize, remainPayloadSize);
      header.fraglen = actualPayloadSize / 4;
      remainPayloadSize -= actualPayloadSize;
      err = bfcp_hdr_encode(buf, &header);
      if (err) break;

      mbuf_write_mem(buf, msgBuf->buf + msgBuf->pos, actualPayloadSize);
      msgBuf->pos += actualPayloadSize;
    }
    if (err)
    {
      for (auto buf : bufs)
      {
        mem_deref(buf);
      }
    }
    else
    {
      assert(msgBuf->pos == msgBuf->end);
      msgBuf->pos = start;
      fragBufs.insert(fragBufs.end(), bufs.begin(), bufs.end());
    }
  }
  return err;
}