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

📄 wspprocm.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Copyright (C) Ericsson Mobile Communications AB, 2000.
 * Licensed to AU-System AB.
 * All rights reserved.
 *
 * This software is covered by the license agreement between
 * the end user and AU-System AB, and may be used and copied
 * only in accordance with the terms of the said agreement.
 *
 * Neither Ericsson Mobile Communications AB nor AU-System AB
 * assumes any responsibility or liability for any errors or inaccuracies in
 * this software, or any consequential, incidental or indirect damage arising
 * out of the use of the Generic WAP Client software.
 */
/*
 * wspprocm.c
 *
 * Procedures for WSP Connection oriented.
 *
 * Created by Anders Edenbrandt, May 1999.
 *
 * Revision history:
 *   990915, AED: Changed from using MBM buffers to PDU buffers.
 *   001027, HEAD: Added two functions for SAR.
 *   001208, AED: Simplified by using the new common conversion routines.
 *                Removed debugging code.
 *   001211, AED: New way of handling capabilities.
 *
 */
#include "confvars.h"
#include "ansilibs.h"

#include "wspprocm.h"
#include "pdubuf.h"
#include "wapcvt.h"

#ifndef MIN
#define MIN(x, y)     (((x) < (y)) ? (x) : (y))
#endif


/*
 * The intention was that WSP should allocate a large enough
 * PDU buffer so that the added WTP headers should fit,
 * withouth any new memory allocation. However, with the
 * introduction of SAR, this is only used for class 0 transactions.
 */
#define WTP_MAX_HEADER_SIZE  5


static INT16
wsp_create_capabilities_list (SDL_Natural client_sdu_size,
                              SDL_Natural server_sdu_size,
                              SDL_Octet protocol_options,
                              SDL_Octet method_mor,
                              SDL_Octet push_mor,
                              void **caplist, SDL_Natural *caplen);

static INT16
wsp_check_capabilities_list (wap_cvt_t *obj, SDL_Natural caplen,
                             SDL_Natural *client_sdu_size,
                             SDL_Natural *server_sdu_size,
                             SDL_Octet *protocol_options,
                             SDL_Octet *method_mor,
                             SDL_Octet *push_mor);

/*
 * Extract the fields from a reply PDU.
 * Sets a status value, two VOIDSTAR out-parameters and two integer
 * out-parameters (containing headers and data from the PDU as well as
 * their lengths), and then releases the PDU buffer.
 * Returns FALSE in case of error, in which case the PDU buffer
 * is NOT released.
 * NOTE: it is the caller's responsibility to deallocate the VOIDSTAR buffers
 * (unless the routine returns FALSE).
 */
extern SDL_Boolean
ExtractReplyPDU (pdubuf *pdu,
                 SDL_Octet *Status, VOIDSTAR *Headers, SDL_Natural *HeadLen,
                 VOIDSTAR *Data, SDL_Natural *DataLen)
{
/*
 * The contents of a Reply PDU is the following:
 *     UINT8    PDU type
 *     UINT8    Status
 *     UintVar  Length of content-type and headers fields combined
 *     Octets   Content type
 *     Octets   Headers
 *     Octets   Data
 */
  wap_cvt_t cvt_obj;
  UINT8     pdu_type;

  wap_cvt_init (&cvt_obj, WAP_CVT_DECODE,
                pdubuf_getStart (pdu), pdubuf_getLength (pdu));

  if (!wap_cvt_uint8 (&cvt_obj, &pdu_type) ||
      (pdu_type != REPLY_PDU_TYPE) ||
      !wap_cvt_uint8 (&cvt_obj, Status) ||
      !wap_cvt_uintvar (&cvt_obj, HeadLen))
    return SDL_False;

  if (*HeadLen + cvt_obj.pos > cvt_obj.length)
    return SDL_False;
  *DataLen = cvt_obj.length - cvt_obj.pos - *HeadLen;

  if (!wap_cvt_bytevector (&cvt_obj, *HeadLen, (BYTE **)Headers) ||
      !wap_cvt_bytevector (&cvt_obj, *DataLen, (BYTE **)Data))
    return SDL_False;

  /* Release PDU buffer given as in-parameter. */
  pdubuf_release (pdu);
  
  return SDL_True;
}

/*
 * Extract the fields from a Data PDU.
 * Sets a VOIDSTAR out-parameter and one integer out-parameter
 * (containing data from the PDU as well as the length) and then
 * releases the PDU buffer.
 * Returns FALSE in case of error, in which case the PDU buffer
 * is NOT released.
 * NOTE: it is the caller's responsibility to deallocate the VOIDSTAR buffer
 * (unless the routine returns FALSE).
 */
extern SDL_Boolean
ExtractDataPDU (pdubuf *pdu, VOIDSTAR *Data, SDL_Natural *DataLen)
{
/*
 * The contents of a Data PDU is the following:
 *     Octets   Data
 */
  UINT32 pdulen = pdubuf_getLength (pdu);

  *DataLen = pdulen;

  if (pdulen > 0) {
    *Data = OSConnectorAlloc (pdulen);

    if (*Data == NULL) {
      /* Error, no memory available. */
      return SDL_False;
    }
    B_COPYSTRINGN (*Data, pdubuf_getStart (pdu), pdulen);
  }
  else
    *Data = NULL;

  /* Release PDU buffer given as in-parameter. */
  pdubuf_release (pdu);
  
  return SDL_True;
}

/*
 * Extract the fields from a Push PDU.
 * Sets two VOIDSTAR out-parameters and two integer
 * out-parameters (containing headers and data from the PDU as well as
 * their lengths), and then releases the PDU buffer.
 * Returns FALSE in case of error, in which case the PDU buffer
 * is NOT released.
 * NOTE: it is the caller's responsibility to deallocate the VOIDSTAR buffers
 * (unless the routine returns FALSE).
 */
extern SDL_Boolean
ExtractPushPDU (pdubuf *pdu,
                VOIDSTAR *Headers, SDL_Natural *HeadLen,
                VOIDSTAR *Data, SDL_Natural *DataLen)
{
/*
 * The content of a Push PDU is as follows:
 *     UINT8    PDU type
 *     UintVar  Length of content-type and headers fields combined
 *     Octets   Content type
 *     Octets   Headers
 *     Octets   Data
 */
  wap_cvt_t cvt_obj;
  UINT8     pdu_type;

  wap_cvt_init (&cvt_obj, WAP_CVT_DECODE,
                pdubuf_getStart (pdu), pdubuf_getLength (pdu));

  if (!wap_cvt_uint8 (&cvt_obj, &pdu_type) ||
      ((pdu_type != PUSH_PDU_TYPE) &&
       (pdu_type != CONFIRMED_PUSH_PDU_TYPE)) ||
      !wap_cvt_uintvar (&cvt_obj, HeadLen))
    return SDL_False;

  if (*HeadLen + cvt_obj.pos > cvt_obj.length)
    return SDL_False;
  *DataLen = cvt_obj.length - cvt_obj.pos - *HeadLen;

  if (!wap_cvt_bytevector (&cvt_obj, *HeadLen, (BYTE **)Headers) ||
      !wap_cvt_bytevector (&cvt_obj, *DataLen, (BYTE **)Data))
    return SDL_False;

  /* Release PDU buffer given as in-parameter. */
  pdubuf_release (pdu);
  
  return SDL_True;
}


/*
 * Create a PDU for a Connect request.
 * Returns a pointer to a PDU buffer where the relevant data has
 * been placed. Also deallocates the VOIDSTAR buffers that are
 * given as in-parameters (unless the routine returns NULL).
 * Returns NULL in case of error.
 * NOTE: it is the caller's responsibility to deallocate the returned buffer.
 */
extern pdubuf *
CreateConnectPDU (SConnectReqType *SConnectReqData)
{
/*
 * A Connect PDU has the following contents:
 *    UINT8    PDU type
 *    UINT8    WSP Protocol Version
 *    UintVar  Length of the Capabilities field
 *    UintVar  Length of the Headers field
 *    Octets   Capabilities
 *    Octets   Headers
 */
  wap_cvt_t cvt_obj;
  UINT8     pdu_type = CONNECT_PDU_TYPE;
  UINT8     protocol_version = WSP_PROTOCOL_VERSION;
  BYTE     *caplist = NULL;
  UINT32    caplen;     /* Length of capabilities */
  UINT32    headlen;    /* Length of header */
  UINT32    pdulen;     /* Calculated length of PDU */
  pdubuf   *pdu;        /* PDU buffer */

  if (!wsp_create_capabilities_list (SConnectReqData->ClientSDUSize,
                                     SConnectReqData->ServerSDUSize,
                                     SConnectReqData->ProtocolOptions,
                                     SConnectReqData->MethodMOR,
                                     SConnectReqData->PushMOR,
                                     &caplist, &caplen)) {
    return NULL;
  }
                                    
  headlen = SConnectReqData->HeadersLen;

  wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE_SIZE, NULL, 0);
  if (!wap_cvt_uint8 (&cvt_obj, &pdu_type) ||
      !wap_cvt_uint8 (&cvt_obj, &protocol_version) ||
      !wap_cvt_uintvar (&cvt_obj, &caplen) ||
      !wap_cvt_uintvar (&cvt_obj, &headlen) ||
      !wap_cvt_bytevector (&cvt_obj, caplen, NULL) ||
      !wap_cvt_bytevector (&cvt_obj, headlen, NULL))
    return NULL;
      
  pdulen = cvt_obj.pos;

  /* Get new PDU buffer, of size PDUlen */
  if ((pdu = pdubuf_new ((UINT16)(pdulen + WTP_MAX_HEADER_SIZE))) == NULL) {
    /* Error, no buffers available. */
    return NULL;
  }
  pdubuf_setLength (pdu, (UINT16)pdulen);

  /* Place PDU type, protocol version, capabilities length, headers length,
     capabilities and headers in the PDU. */
  wap_cvt_init (&cvt_obj, WAP_CVT_ENCODE,
                pdubuf_getStart (pdu), pdubuf_getLength (pdu));
  if (!wap_cvt_uint8 (&cvt_obj, &pdu_type) ||
      !wap_cvt_uint8 (&cvt_obj, &protocol_version) ||
      !wap_cvt_uintvar (&cvt_obj, &caplen) ||
      !wap_cvt_uintvar (&cvt_obj, &headlen) ||
      !wap_cvt_bytevector (&cvt_obj, caplen, &caplist) ||
      !wap_cvt_bytevector (&cvt_obj, headlen,
                           (BYTE **)&SConnectReqData->ClientHeaders))
    return NULL;

  /* Release buffer given as in-parameter. */
  DEALLOC (&caplist);
  DEALLOC (&SConnectReqData->ClientHeaders);

  return pdu;
}

/*
 * Extract the fields from a Connect Reply PDU.
 * Sets a session ID value and fields in the SConnectCnfType structure
 * representing capabilities and headers as well as their lengths,
 * and then releases the PDU buffer.
 * Returns FALSE in case of error, in which case the PDU buffer
 * is NOT released.
 * NOTE: it is the caller's responsibility to deallocate the VOIDSTAR buffers
 * (unless the routine returns FALSE).
 */
extern SDL_Boolean
ExtractConnectReplyPDU (pdubuf *pdu,
                        SDL_Natural *ServerSessionId,
                        SConnectCnfType *SConnectCnfData)
{
/*
 * A Connect Reply PDU has the following content:
 *     UINT8     PDU type
 *     UintVar   Server session ID
 *     UintVar   Length of capabilities field
 *     UintVar   Length of headers field
 *     Octets    Capabilities
 *     Octets    Headers
 */
  wap_cvt_t cvt_obj;
  UINT8     pdu_type;
  UINT32    caplen;

  wap_cvt_init (&cvt_obj, WAP_CVT_DECODE,
                pdubuf_getStart (pdu), pdubuf_getLength (pdu));

  if (!wap_cvt_uint8 (&cvt_obj, &pdu_type) ||
      (pdu_type != CONNECTREPLY_PDU_TYPE) ||
      !wap_cvt_uintvar (&cvt_obj, ServerSessionId) ||
      !wap_cvt_uintvar (&cvt_obj, &caplen) ||
      !wap_cvt_uintvar (&cvt_obj, &SConnectCnfData->HeadersLen))
    return SDL_False;

  if ((caplen + SConnectCnfData->HeadersLen + cvt_obj.pos) > cvt_obj.length)
    return SDL_False;

  if (!wsp_check_capabilities_list (&cvt_obj, caplen,
                                    &SConnectCnfData->ClientSDUSize,

⌨️ 快捷键说明

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