📄 wspprocm.c
字号:
/*
* 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 + -