📄 mcpdu.c
字号:
/*
* Copyright (C) Obigo AB, 2002-2005.
* All rights reserved.
*
* This software is covered by the license agreement between
* the end user and Obigo AB, and may be
* used and copied only in accordance with the terms of the
* said agreement.
*
* Obigo AB assumes no 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 software.
*
*/
#include "cansilib.h"
#include "cmnconf.h"
#include "cmntypes.h"
#include "aapicmn.h"
#include "gmem.h"
#include "mmstypes.h"
#include "mmsconf.h"
#include "aapimms.h"
#include "msig.h"
#include "mmem.h"
#include "mcpdu.h"
#include "mcpost.h"
#include "mmpduc.h"
#define OCTET_SIZE 1
#define POS_TYPE_TAG 0
#define POS_TYPE_DATA 1
#define SHORT_FLAG (unsigned char)0x80
#define UINTVAR_MAX_LENGTH 5
#define TRANSACTION_ID_DEFAULT ((char *)"0")
#define ALLOWED_STRING_CHAR_LIMIT (unsigned char)128
#define MIN_PDU_LENGTH 6
static unsigned char *skipApplicationHeaderString(unsigned char *pos, unsigned long length);
static unsigned char *skipContentType(unsigned char *pos, unsigned long length);
void *cnvLongIntegerToUint32( void *from, UINT32 *to, unsigned long size)
{
UINT32 tmp = 0L;
unsigned char *ptr = (unsigned char *)from;
int len = *ptr;
*to = 0;
if (len == 0 && size >= 0)
{
return ++ptr;
}
else if (len > 4 || (unsigned long)len > size)
{
return NULL;
}
do
{
tmp += *++ptr;
if (--len > 0)
{
tmp <<= 8;
}
} while (len > 0);
*to = tmp;
return ++ptr;
}
void *cnvIntegerToUint32( void *from, UINT32 *to, unsigned long size)
{
UINT8 *ptr = (UINT8 *)from;
if (IS_SHORT_INTEGER(*ptr))
{
*to = (UINT32)SKIP_HIGH_BIT(*ptr);
++ptr;
}
else if (IS_LONG_INTEGER(*ptr))
{
ptr = cnvLongIntegerToUint32( from, to, size);
}
else
{
MMS_LOG_I(("%s(%d): Integer-value invalid.\n", __FILE__, __LINE__));
ptr = NULL;
}
return ptr;
}
void *cnvShortIntegerToUchar( void *from, unsigned char *to, unsigned long size)
{
unsigned char *ptr = (unsigned char *)from;
if (size < 1)
{
*to = 0;
return NULL;
}
*to = SKIP_HIGH_BIT(*ptr);
return ++ptr;
}
void *cnvUcharToShortInteger( unsigned char from, void *to, unsigned long size)
{
unsigned char *ptr = (unsigned char *)to;
if (size < 1)
{
return NULL;
}
*ptr++ = SET_HIGH_BIT(from);
return ptr;
}
void *cnvUint32ToInteger( UINT32 from, void *to, unsigned long size)
{
if (IS_POSSIBLE_SHORT_INTEGER(from))
{
return cnvUcharToShortInteger( (UINT8)from, to, size);
}
else
{
return cnvUint32ToLongInteger( from, to, size);
}
}
void *cnvUint32ToLongInteger( UINT32 from, void *to, unsigned long size)
{
UINT8 len = cnvLenLongInteger(from);
unsigned char *ptr = (unsigned char *)to;
if (len > size)
{
return NULL;
}
*ptr++ = len;
for (; len > 0; --len)
{
*ptr++ = (UINT8)((from >> ((len - 1) * 8)) & 0xff);
}
return ptr;
}
void *cnvUint32ToUintvar( UINT32 from, void *to, unsigned long size)
{
UINT8 len = cnvLenUintvar(from);
unsigned char b;
unsigned char *ptr = (unsigned char *)to;
if (len > size)
{
return NULL;
}
for (; len > 0; --len)
{
b = (UINT8)((from >> ((len - 1) * 7)) & 0x7f);
if (len > 1)
{
b = SET_HIGH_BIT(b);
}
*ptr++ = b;
}
return ptr;
}
void *cnvUint32ToValueLength( UINT32 from, void *to, unsigned long size)
{
unsigned char *ptr = (unsigned char *)to;
if (size < 1)
{
ptr = NULL;
}
else if (from < LENGTH_QUOTE)
{
*ptr++ = (unsigned char)from;
}
else if (size < 2)
{
ptr = NULL;
}
else
{
*ptr++ = LENGTH_QUOTE;
ptr = (unsigned char *)cnvUint32ToUintvar( from, ptr, size - 1);
}
return ptr;
}
void *cnvUintvarToUint32( void *from, UINT32 *to, unsigned long size)
{
UINT32 n = 0;
int i = 0;
unsigned char *ptr = (unsigned char *)from;
unsigned char b;
do
{
if (i >= UINTVAR_MAX_LENGTH || (unsigned long)i >= size)
{
*to = 0;
return NULL;
}
b = *ptr++;
n <<= 7;
n |= (b & 0x7f);
++i;
} while (b > 0x7f);
*to = n;
return ptr;
}
void *cnvValueLengthToUint32( void *from, UINT32 *to, unsigned long size)
{
unsigned char *ptr = (unsigned char *)from;
if (size < 1)
{
*to = 0;
ptr = NULL;
}
else if (*ptr < LENGTH_QUOTE)
{
*to = (UINT32)*ptr++;
}
else
{
ptr = (unsigned char *)cnvUintvarToUint32( ptr + OCTET_SIZE, to, size);
}
return ptr;
}
UINT8 cnvLenUintvar(UINT32 n)
{
if (n < 0x80)
{
return 1;
}
else if (n < 0x4000)
{
return 2;
}
else if (n < 0x200000)
{
return 3;
}
else if (n < 0x10000000)
{
return 4;
}
else
{
return 5;
}
}
UINT8 cnvLenLongInteger(UINT32 n)
{
if (n < 0x100)
{
return 1;
}
else if (n < 0x10000)
{
return 2;
}
else if (n < 0x1000000)
{
return 3;
}
else
{
return 4;
}
}
void *mmsGetBody( void *data, unsigned long size)
{
unsigned char *offset = (unsigned char *)data;
unsigned char *start = (unsigned char *)data;
while ( offset != NULL && (unsigned long)(offset - start) < size)
{
if (SKIP_HIGH_BIT(*offset) == MMS_CONTENT_TYPE)
{
++offset;
offset = skipContentType( offset, (unsigned long)(start - offset) + size);
return (unsigned long)(offset - start) >= size ? NULL : offset;
}
offset = mmsPduNextTag( offset, (unsigned long)(start - offset) + size);
}
return NULL;
}
CMN_BOOL mmsPduAppend( void *header, unsigned long size, unsigned long *length,
MmsHeaderTag tag, unsigned long valueSize, MmsHeaderValue value)
{
unsigned char *from;
unsigned char *to;
unsigned long remainingSize = size - *length;
CMN_BOOL ret = TRUE;
if (*length > size || remainingSize <= 1 || remainingSize < valueSize)
{
return FALSE;
}
to = &((unsigned char *)header)[*length];
*to++ = SET_HIGH_BIT(tag);
--remainingSize;
++*length;
switch (tag)
{
case MMS_BCC :
case MMS_CC :
case MMS_CONTENT_TYPE :
case MMS_FROM :
case MMS_SUBJECT :
case MMS_TO :
case X_MMS_CONTENT_LOCATION :
case X_MMS_DELIVERY_TIME :
case X_MMS_ELEMENT_DESCRIPTOR :
case X_MMS_EXPIRY :
case X_MMS_MBOX_QUOTAS :
case X_MMS_MBOX_TOTALS :
case X_MMS_MESSAGE_CLASS :
case X_MMS_MESSAGE_COUNT :
case X_MMS_MM_FLAGS :
case X_MMS_PREVIOUSLY_SENT_BY :
case X_MMS_PREVIOUSLY_SENT_DATE :
case X_MMS_REPLY_CHARGING_DEADLINE :
case X_MMS_RESPONSE_STATUS :
case X_MMS_RESPONSE_TEXT :
case X_MMS_RETRIEVE_TEXT :
case X_MMS_STORE_STATUS_TEXT :
from = (unsigned char *)value.raw.aVoidPtr;
memcpy( to, from, valueSize);
*length += valueSize;
break;
case MMS_MESSAGE_ID :
case X_MMS_TRANSACTION_ID :
case X_MMS_REPLY_CHARGING_ID :
from = (unsigned char *)value.raw.aCharPtr;
memcpy( to, from, valueSize);
*length += valueSize;
break;
case X_MMS_LIMIT :
case X_MMS_START :
from = to;
if ((to = (unsigned char *)cnvUint32ToInteger( value.raw.aUint32,
to, remainingSize)) == NULL || from > to)
{
MMS_LOG_I(("%s(%d): Integer-value conversion failed (%d,%d).\n",
__FILE__, __LINE__, (int)from, (int)to));
ret = FALSE;
}
else
{
*length += (unsigned long)(to - from);
}
break;
case MMS_DATE :
case X_MMS_MESSAGE_SIZE :
case X_MMS_REPLY_CHARGING_SIZE :
from = to;
if ((to = (unsigned char *)cnvUint32ToLongInteger( value.raw.aUint32,
to, remainingSize)) == NULL || from > to)
{
MMS_LOG_I(("%s(%d): Long-integer conversion failed (%d,%d).\n",
__FILE__, __LINE__, (int)from, (int)to));
ret = FALSE;
}
else
{
*length += (unsigned long)(to - from);
}
break;
case X_MMS_DELIVERY_REPORT :
case X_MMS_DISTRIBUTION_INDICATOR :
case X_MMS_MESSAGE_TYPE :
case X_MMS_PRIORITY :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -