⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wtlsmain.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    return 0;
  }
}

/*
 * Check if a received SDU is a clear text Alert message.
 */
INT16
wtls_main_is_cleartext_alert (pdubuf *data)
{
  wap_cvt_t     cvt_obj;
  wtls_record_t rec;

  wap_cvt_init (&cvt_obj, WAP_CVT_DECODE_STATIC,
                pdubuf_getStart (data), pdubuf_getLength (data));
  if (!wtls_cvt_record (&cvt_obj, &rec)) {
    wtls_err_set (ERR_GENERAL, ERR_DECODING, 1,
                  ALERT_LEVEL_CRITICAL, ALERT_DESC_DECODE_ERROR);
    return -1;
  }
  if (((rec.rec_type & RECTYPE_CONTENT_TYPE) == CONTENT_TYPE_ALERT) &&
      ((rec.rec_type & RECTYPE_USE_CS) == 0)) {
    return 0;
  }

  return -1;
}

/*
 * Create a SDU holding a No-Connection Alert, for immediate sending.
 * "dataInd" is the message we just received, for which we have no
 * connection.
 */
SDL_Integer
wtls_main_create_no_connection_alert (TDUnitdataIndType *dataInd,
                                      TDUnitdataReqType *dataReq)
{
  BYTE          *p = pdubuf_getStart (dataInd->UserData);
  UINT16        len = pdubuf_getLength (dataInd->UserData);
  wtls_alert_t  alert;
  wap_cvt_t     cvt_obj;
  wtls_record_t rec;
  BYTE          *buf;
  UINT16        buflen;

  alert.level = ALERT_LEVEL_CRITICAL;
  alert.description = ALERT_DESC_NO_CONNECTION;
  alert.checksum = wtls_alert_compute_checksum (p, len);
  buflen = 6;
  buf = NEWARRAY (BYTE, buflen);
  if (buf == NULL) {
    wtls_err_set (ERR_INTERNAL, ERR_INSUFFICIENT_MEMORY,
                  1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
    return -1;
  }    

  wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE, buf, buflen);
  if (!wtls_cvt_alert (&cvt_obj, &alert)) {
    wtls_err_set (ERR_INTERNAL, ERR_ENCODING, 0,
                  ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
    return -1;
  }

  /* Always use a length field. */
  rec.rec_type = CONTENT_TYPE_ALERT | RECTYPE_SEQNUM | RECTYPE_LENGTH_FIELD;
  rec.seqnum = MAX_SEQNUM;
  rec.length = buflen;
  rec.fragment = buf;
#ifdef LOG_WTLS
  wtls_log_msg (0, "\n--------SENDING SDU--------\n");
  wtls_log_msg (0, "SDU[ =>\n");
  wtls_log_record_brief (&rec);
  wtls_log_msg (0, "]\n");
#endif

  wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE_SIZE, NULL, 0);
  if (!wtls_cvt_record (&cvt_obj, &rec)) {
    wtls_err_set (ERR_INTERNAL, ERR_ENCODING, 0,
                  ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
    return -1;
  }
  buflen = (UINT16)cvt_obj.pos;
  buf = NEWARRAY (BYTE, buflen);
  if (buf == NULL) {
    wtls_err_set (ERR_INTERNAL, ERR_INSUFFICIENT_MEMORY,
                  1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
    return -1;
  }    

  wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE, buf, buflen);
  if (!wtls_cvt_record (&cvt_obj, &rec)) {
    wtls_err_set (ERR_INTERNAL, ERR_ENCODING, 0,
                  ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
    DEALLOC (&buf);
    return -1;
  }
  DEALLOC (&(rec.fragment));

  /* Allocate a PDU buffer. */
  dataReq->UserData = pdubuf_newFromData (buflen, buf);
  pdubuf_setLength (dataReq->UserData, buflen);

  /* Copy addresses from the connection state. */
  yAssF_AddressType (dataReq->SourceAddress, dataInd->DestinationAddress,
                     XASS);
  yAssF_AddressType (dataReq->DestinationAddress, dataInd->SourceAddress,
                     XASS);

  return RET_OK;
}

/*
 * Split an incoming SDU into records, and store them in the connection's
 * list of incoming records.
 */
SDL_Integer
wtls_main_split_SDU (SDL_PId cm_proc, pdubuf *SDU)
{
  list_node     *n = wtls_main_find_node (cm_proc);
  wtls_record_t *rec = NULL;
  wap_cvt_t      cvt_obj;
  BYTE          *p;
  UINT16         start;
  UINT8          content_type;
  UINT8          is_first = 1;

  if ((n == NULL) || (SDU == NULL)) {
    return -1;
  }

#ifdef LOG_WTLS
  wtls_log_msg (0, "\n--------RECEIVED SDU--------\n");
  wtls_log_msg (0, "SDU[ <=\n");
#endif
  wap_cvt_init (&cvt_obj, WAP_CVT_DECODE,
                pdubuf_getStart (SDU), pdubuf_getLength (SDU));

  while (cvt_obj.pos < cvt_obj.length) {
    p = cvt_obj.data + cvt_obj.pos;
    start = (UINT16)cvt_obj.pos;

    rec = NEWARRAY (wtls_record_t, 1);
    if (rec == NULL) {
      wtls_err_set (ERR_INTERNAL, ERR_INSUFFICIENT_MEMORY,
                    1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
      return -1;
    }
    if (!wtls_cvt_record (&cvt_obj, rec)) {
      wtls_err_set (ERR_GENERAL, ERR_DECODING, 1,
                    ALERT_LEVEL_CRITICAL, ALERT_DESC_DECODE_ERROR);
      wtls_rec_delete_record (rec);
      return -1;
    }
    content_type = rec->rec_type & RECTYPE_CONTENT_TYPE;

    /* Check that we have a content type we recognize. */
    if ((content_type != CONTENT_TYPE_CCS) &&
        (content_type != CONTENT_TYPE_ALERT) &&
        (content_type != CONTENT_TYPE_HANDSHAKE) &&
        (content_type != CONTENT_TYPE_DATA)) {
      /* Unknown content type; ignore this record.
       * We cannot trust any information in this record,
       * so we have to assume that the record occupies the entire SDU. */
      wtls_rec_delete_record (rec);
      return -1;
    }
#ifdef LOG_WTLS
    wtls_log_record_brief (rec);
#endif
    rec->is_first = is_first;
    is_first = 0;
    wtls_rec_list_append (rec, &(n->msgs_in));

    /* Compute the Alert checksum. We tentatively accept this record,
     * and hence will use its checksum when we send an Alert. */
    ((wtls_connection_t *)(n->connptr))->read_cksum =
      wtls_alert_compute_checksum (p, (UINT16)(cvt_obj.pos - start));
  }

#ifdef LOG_WTLS
  wtls_log_msg (0, "]\n");
#endif

  return RET_OK;
}

/************************************************************
 * External routines called from other C functions.
 ************************************************************/

/*
 * Store a pointer to the connection record.
 */
void
wtls_main_set_connection_pointer (SDL_PId pid, void *connptr)
{
  list_node *n = wtls_main_find_node (pid);

  if (n == NULL) {
    return;
  }
  n->connptr = connptr;
}

/*
 * Get a pointer to the connection record for the specified SDL process.
 */
void *
wtls_main_get_connection_pointer (SDL_PId pid)
{
  list_node *n = wtls_main_find_node (pid);

  if (n == NULL) {
    return NULL;
  }

  return n->connptr;
}

/*
 * Remove, and return, the first message in the message queue
 * for the indicated Connection Manager process.
 * Returns NULL, in case the queue is empty.
 */
wtls_record_t *
wtls_main_pop_incoming_message (SDL_PId pid)
{
  list_node *n = wtls_main_find_node (pid);

  if (n == NULL) {
    return NULL;
  }
  return wtls_rec_list_pop (&(n->msgs_in));
}

wtls_record_t *
wtls_main_peek_incoming_message (SDL_PId pid)
{
  list_node *n = wtls_main_find_node (pid);

  if (n == NULL) {
    return NULL;
  }
  return n->msgs_in;
}

wtls_record_t *
wtls_main_pop_outbound_message (SDL_PId pid)
{
  list_node *n = wtls_main_find_node (pid);

  if (n == NULL) {
    return NULL;
  }
  return wtls_rec_list_pop (&(n->msgs_out));
}

/*
 * Check if a received PDU is a Hello Request message in clear text,
 * from a source that we can accept.
 * Returns 0 if we should act on this request, -1 otherwise.
 */
SDL_Integer
wtls_main_check_hello_request (pdubuf *pdu)
{
  wap_cvt_t     cvt_obj;
  wtls_record_t rec;
  SDL_Integer   retval = -1;

  wap_cvt_init (&cvt_obj, WAP_CVT_DECODE_STATIC,
                pdubuf_getStart (pdu), pdubuf_getLength (pdu));
  if (!wtls_cvt_record (&cvt_obj, &rec)) {
    return -1;
  }
  if (((rec.rec_type & RECTYPE_CONTENT_TYPE) == CONTENT_TYPE_HANDSHAKE) &&
      ((rec.rec_type & RECTYPE_USE_CS) == 0) &&
      (rec.length == 3) &&
      (rec.fragment[0] == 0) &&
      (rec.fragment[1] == 0) &&
      (rec.fragment[2] == 0)) {
    retval = 0;
  }
  
  return retval;
}

/************************************************************
 * Local functions
 ************************************************************/

/*
 * Return a pointer to the list node with given PId.
 * Returns NULL in case the given PId is not in the list.
 */
static list_node *
wtls_main_find_node (SDL_PId cm_proc)
{
  list_node *n;

  for (n = connection_list; n != NULL; n = n->next) {
    if (n->cm_proc == cm_proc)
      return n;
  }
  
  return NULL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -