int WebSocketTcp::framePackage()

in nlsCppSdk/transport/webSocketTcp.cpp [491:584]


int WebSocketTcp::framePackage(WebSocketHeaderType::OpCodeType codeType,
                               const uint8_t* buffer, size_t length,
                               uint8_t** frame, size_t* frameSize) {
  bool useMask = true;
  const uint8_t masKingKey[4] = {0x12, 0x34, 0x56, 0x78};
  const int headlen = 2 + (length >= 126 ? 2 : 0) + (length >= 65536 ? 6 : 0) +
                      (useMask ? 4 : 0);

  uint8_t* header =
      (uint8_t*)calloc(headlen, sizeof(uint8_t));  // new uint8_t[headlen];
  if (header == NULL) {
    LOG_ERROR("WsTcp(%p) calloc header failed.", this);
    return -(MallocFailed);
  }

  header[0] = 0x80 | codeType;

  if (length < 126) {
    header[1] = (length & 0xff) | (useMask ? 0x80 : 0);
    if (useMask) {
      header[2] = masKingKey[0];
      header[3] = masKingKey[1];
      header[4] = masKingKey[2];
      header[5] = masKingKey[3];
    }
  } else if (length < 65536) {
    header[1] = 126 | (useMask ? 0x80 : 0);
    header[2] = (length >> 8) & 0xff;
    header[3] = (length >> 0) & 0xff;
    if (useMask) {
      header[4] = masKingKey[0];
      header[5] = masKingKey[1];
      header[6] = masKingKey[2];
      header[7] = masKingKey[3];
    }
  } else {  // TODO: run coverage testing here
    header[1] = 127 | (useMask ? 0x80 : 0);
    header[2] = ((uint64_t)length >> 56) & 0xff;
    header[3] = ((uint64_t)length >> 48) & 0xff;
    header[4] = ((uint64_t)length >> 40) & 0xff;
    header[5] = ((uint64_t)length >> 32) & 0xff;
    header[6] = ((uint64_t)length >> 24) & 0xff;
    header[7] = ((uint64_t)length >> 16) & 0xff;
    header[8] = ((uint64_t)length >> 8) & 0xff;
    header[9] = ((uint64_t)length >> 0) & 0xff;
    if (useMask) {
      header[10] = masKingKey[0];
      header[11] = masKingKey[1];
      header[12] = masKingKey[2];
      header[13] = masKingKey[3];
    }
  }

  // N.B. - tmpBuffer will keep growing until it can be transmitted over the
  // socket: uint8_t * tmpBuffer = new uint8_t[headlen + length];
  // memset(tmpBuffer, 0, sizeof(uint8_t) * (headlen + length));
  // memcpy(tmpBuffer, header, headlen);
  // memcpy(tmpBuffer + headlen, (uint8_t*)buffer, length);

  *frameSize = (headlen + length);
  *frame = (uint8_t*)calloc(*frameSize, sizeof(uint8_t));
  if (*frame == NULL) {
    LOG_ERROR("WsTcp(%p) calloc frame failed.", this);
    free(header);
    return -(MallocFailed);
  }
  memcpy(*frame, header, headlen);
  if (buffer && length > 0) {
    memcpy(*frame + headlen, (uint8_t*)buffer, length);
  }

#ifdef OPU_DEBUG
  std::ofstream ofs;
  ofs.open("./out.opus", std::ios::out | std::ios::app | std::ios::binary);
  if (ofs.is_open() && buffer) {
    ofs.write((const char*)buffer, length);
    ofs.flush();
    ofs.close();
  }
#endif

  // LOG_DEBUG("framePackage Receive Data: %d ", *frameSize);

  if (useMask) {
    for (size_t i = 0; i != length; ++i) {
      *(*frame + headlen + length - length + i) ^= masKingKey[i & 0x3];
    }
  }

  free(header);
  header = NULL;

  return Success;
}