📄 wdpsuppt.c
字号:
p[3] = (UINT8)type;
p[4] = (UINT8)code;
p[5] = (UINT8)(dst_port >> 8);
p[6] = (UINT8)(dst_port & 0xff);
p[7] = (UINT8)(src_port >> 8);
p[8] = (UINT8)(src_port & 0xff);
p[9] = (is_udcp_msg == SDL_True) ? BEARER_GSM_USSD : BEARER_GSM_SMS; /* Addresstype GSM SMS or GSM USSD */
p[10] = (UINT8)(addr->length);
memcpy (p + 11, addr->data, addr->length);
}
/************************************************************
* Tables of ongoing reassemblies, and rejected reassemblies.
************************************************************/
#define EMPTY_REFNUM 1000
#define MAX_REASSEMBLIES 10
#define MAX_REJECTIONS 20
typedef struct wdp_seg_node_st {
struct wdp_seg_node_st *next;
SDL_Natural segnum;
BYTE *segment;
SDL_Natural length;
SDL_Natural header_length;
} wdp_seg_node;
typedef struct {
SDL_Natural refnum;
DeviceAddress server_addr;
UINT16 portnum;
SDL_Natural total_num_segments;
wdp_seg_node *segments;
} wdp_segtbl_entry;
typedef struct {
SDL_Natural refnum;
DeviceAddress server_addr;
} wdp_rejtbl_entry;
static wdp_segtbl_entry wdp_segtbl[MAX_REASSEMBLIES];
static wdp_rejtbl_entry wdp_rejtbl[MAX_REJECTIONS];
static unsigned int wdp_rejtbl_insert_next = 0;
/*
* Initialize the segment table.
*/
void
wdp_segtbl_init (void)
{
int i;
for (i = 0; i < MAX_REASSEMBLIES; i++) {
wdp_segtbl[i].refnum = EMPTY_REFNUM;
wdp_segtbl[i].total_num_segments = 0;
wdp_segtbl[i].segments = NULL;
}
}
/*
* Delete all entries from the segment table.
*/
void
wdp_segtbl_clear (void)
{
int i;
for (i = 0; i < MAX_REASSEMBLIES; i++) {
wdp_segtbl_delete_entry (i);
}
}
/*
* Initialize the table of rejects, i.e., reassemblies
* that have failed. Segments belonging to such a failed
* reassembly will be discarded upon arrival.
*/
void
wdp_rejtbl_init (void)
{
int i;
for (i = 0; i < MAX_REJECTIONS; i++) {
wdp_rejtbl[i].refnum = EMPTY_REFNUM;
wdp_rejtbl[i].server_addr.length = 0;
}
wdp_rejtbl_insert_next = 0;
}
/*
* Add an element to the table of rejects.
*/
void
wdp_rejtbl_add (SDL_Natural refnum, DeviceAddress server_addr)
{
if (wdp_rejtbl_lookup (refnum, server_addr) == SDL_True) {
return;
}
if (wdp_rejtbl_insert_next == MAX_REJECTIONS) {
wdp_rejtbl_insert_next = 0;
}
wdp_rejtbl[wdp_rejtbl_insert_next].refnum = refnum;
yDef_DeviceAddress (&(wdp_rejtbl[wdp_rejtbl_insert_next].server_addr));
yAssF_DeviceAddress (wdp_rejtbl[wdp_rejtbl_insert_next].server_addr,
server_addr, XASS);
wdp_rejtbl_insert_next++;
}
/*
* Check if a <refnum, server_addr> pair is in the table of rejects.
*/
SDL_Boolean
wdp_rejtbl_lookup (SDL_Natural refnum, DeviceAddress server_addr)
{
int i;
for (i = 0; i < MAX_REJECTIONS; i++) {
if ((wdp_rejtbl[i].refnum == refnum) &&
yEqF_DeviceAddress (wdp_rejtbl[i].server_addr, server_addr)) {
return SDL_True;
}
}
return SDL_False;
}
/*
* Check if a reassembly in the segment table has all its
* segments.
*/
SDL_Boolean
wdp_segtbl_is_complete (SDL_Integer index)
{
UINT16 n = 0;
wdp_seg_node *p = wdp_segtbl[index].segments;
if ((wdp_segtbl[index].refnum == EMPTY_REFNUM) ||
(wdp_segtbl[index].total_num_segments == 0)) {
return SDL_False;
}
while (p) {
n++;
if (n != p->segnum) {
return SDL_False;
}
p = p->next;
}
return (n == wdp_segtbl[index].total_num_segments) ? SDL_True : SDL_False;
}
/*
* Terminate the reassembly at position "index", and insert
* it into the table of rejects.
*/
void
wdp_segtbl_reject (SDL_Integer index)
{
if (wdp_segtbl[index].refnum == EMPTY_REFNUM) {
return;
}
wdp_rejtbl_add (wdp_segtbl[index].refnum, wdp_segtbl[index].server_addr);
wdp_segtbl_delete_entry (index);
}
/*
* Delete the reassembly using client port "portnum".
* Returns the index in the table where it was found,
* or -1 if it's not in the table.
*/
SDL_Integer
wdp_segtbl_delete_port (SDL_Integer portn)
{
UINT16 portnum = (UINT16)portn;
int i;
for (i = 0; i < MAX_REASSEMBLIES; i++) {
if ((wdp_segtbl[i].refnum != EMPTY_REFNUM) &&
(wdp_segtbl[i].portnum == portnum)) {
wdp_segtbl_delete_entry (i);
return i;
}
}
return -1;
}
/*
* Delete the reassembly at position "index" in the table.
*/
void
wdp_segtbl_delete_entry (SDL_Integer index)
{
wdp_seg_node *p;
if (wdp_segtbl[index].refnum == EMPTY_REFNUM) {
return;
}
while ((p = wdp_segtbl[index].segments) != 0) {
wdp_segtbl[index].segments = p->next;
OSConnectorFree (p->segment);
OSConnectorFree (p);
}
wdp_segtbl[index].refnum = EMPTY_REFNUM;
wdp_segtbl[index].portnum = 0;
wdp_segtbl[index].total_num_segments = 0;
wdp_segtbl[index].segments = NULL;
}
/*
* Check if a <refnum, server_addr> pair is in the table
* of reassemblies. Returns the index in the table if
* it was found, and -1 otherwise.
*/
SDL_Integer
wdp_segtbl_lookup (SDL_Natural refnum, DeviceAddress addr,
SDL_Integer *empty_pos)
{
SDL_Integer i, e = -1;
for (i = 0; i < MAX_REASSEMBLIES; i++) {
if ((wdp_segtbl[i].refnum == refnum) &&
yEqF_DeviceAddress (wdp_segtbl[i].server_addr, addr)) {
return i;
}
else if ((e < 0) && (wdp_segtbl[i].refnum == EMPTY_REFNUM)) {
e = i;
}
}
*empty_pos = e;
return -1;
}
/*
* Assemble all the segments of the reassembly at position "index"
* in the table, and turn into a PDU buffer. Also deletes the entry
* from the table.
*/
void
wdp_segtbl_assemble (SDL_Integer index, pdubuf **pb_ptr)
{
wdp_seg_node *p;
UINT16 length = 0;
pdubuf *pb;
BYTE *q;
if (wdp_segtbl[index].refnum == EMPTY_REFNUM) {
*pb_ptr = NULL;
return;
}
for (p = wdp_segtbl[index].segments; p; p = p->next) {
length += p->length - p->header_length;;
}
pb = pdubuf_new (length);
pdubuf_setLength (pb, length);
q = pdubuf_getStart (pb);
for (p = wdp_segtbl[index].segments; p; p = p->next) {
memcpy (q, p->segment + p->header_length, p->length - p->header_length);
q += p->length - p->header_length;
}
wdp_segtbl_delete_entry (index);
*pb_ptr = pb;
}
/*
* Add a segment to the reassembly table.
*/
void
wdp_segtbl_add (SDL_Integer index,
SDL_Natural refnum, DeviceAddress server_addr,
SDL_Integer portn, SDL_Natural total_num_segments,
SDL_Natural segnum,
void *segment, SDL_Natural length, SDL_Natural header_length)
{
UINT16 portnum = (UINT16)portn;
wdp_seg_node *p, *q, *r;
if (wdp_segtbl[index].refnum == EMPTY_REFNUM) {
wdp_segtbl[index].refnum = refnum;
wdp_segtbl[index].server_addr = server_addr;
wdp_segtbl[index].portnum = portnum;
wdp_segtbl[index].total_num_segments = (UINT16)total_num_segments;
wdp_segtbl[index].segments = NULL;
}
for (q = 0, p = wdp_segtbl[index].segments; p; q = p, p = p->next) {
if (p->segnum == segnum) {
/* This segment is a duplicate; deallocate and return. */
OSConnectorFree (segment);
return;
}
if (p->segnum > segnum) {
break;
}
}
/* We have found the correct position */
r = OSConnectorAlloc (sizeof (wdp_seg_node));
r->segment = segment;
r->length = (UINT16)length;
r->segnum = (UINT16)segnum;
r->header_length = (UINT16)header_length;
if (q) {
q->next = r;
}
else {
wdp_segtbl[index].segments = r;
}
r->next = p;
}
/************************************************************
* Saved addresses.
************************************************************/
static DeviceAddress saved_client_addr;
static AuxiliaryAddress saved_smsc_addr;
static AuxiliaryAddress saved_ussdc_addr;
/*
* Initialize the saved addresses.
*/
void
wdp_address_init (void)
{
saved_client_addr.length = 0;
saved_smsc_addr.length = 0;
saved_ussdc_addr.length = 0;
}
/*
* Save an address. The first parameter is a bit mask
* that indicates which address(es) should be saved.
*/
void
wdp_address_save (SDL_Integer type, DeviceAddress *addr,
AuxiliaryAddress *addr2)
{
if (type & WDP_CLIENT_ADDRESS) {
yAssF_DeviceAddress (saved_client_addr, *addr, XASS);
}
if (type & WDP_SMSC_ADDRESS) {
yAssF_AuxiliaryAddress (saved_smsc_addr, *addr2, XASS);
}
if (type & WDP_USSDC_ADDRESS) {
yAssF_AuxiliaryAddress (saved_ussdc_addr, *addr2, XASS);
}
}
/*
* Retrieve a saved address. The first parameter is a bit mask
* that indicates which address(es) should be retrieved.
*/
void
wdp_address_get (SDL_Integer type, DeviceAddress *addr,
AuxiliaryAddress *addr2)
{
if (type & WDP_CLIENT_ADDRESS) {
yAssF_DeviceAddress (*addr, saved_client_addr, XASS);
}
if (type & WDP_SMSC_ADDRESS) {
yAssF_AuxiliaryAddress (*addr2, saved_smsc_addr, XASS);
}
if (type & WDP_USSDC_ADDRESS) {
yAssF_AuxiliaryAddress (*addr2, saved_ussdc_addr, XASS);
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -