📄 wtlsmain.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.
*/
/*
* wtlsmain.c
*
* Created by Anders Edenbrandt, Wed Jun 02 07:57:08 1999.
*
* Revision history:
* 001012, AED: Changed how records are logged.
*
*/
#include "wtlsdef.h"
typedef struct ln_st {
struct ln_st *next;
SDL_PId cm_proc;
SDL_PId rec_proc;
AddressType src_addr;
AddressType dst_addr;
void *connptr;
wtls_record_t *msgs_out;
wtls_record_t *msgs_in;
UINT8 close_on_done;
SDL_Natural portnum;
SDL_Integer path;
} list_node;
static list_node *connection_list;
/************************************************************
* Forward declaration of 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 pid);
/************************************************************
* External routines called from SDL.
************************************************************/
/*
* Initialize the WTLS_Main SDL process.
*/
void
wtls_main_init (void)
{
connection_list = NULL;
}
/*
* Terminate the WTLS_Main SDL process.
*/
void
wtls_main_terminate (void)
{
while (connection_list != NULL) {
(void)wtls_main_pop_connection ();
}
}
/*
* Add a new element to the list of known connection quadruples.
*/
SDL_Integer
wtls_main_new_connection (SDL_PId cm_proc, SDL_PId rec_proc,
AddressType *src_addr, AddressType *dst_addr)
{
list_node *n = NEWARRAY (list_node, 1);
if (n == NULL) {
wtls_err_set (ERR_INTERNAL, ERR_INSUFFICIENT_MEMORY,
0, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
return -1;
}
n->cm_proc = cm_proc;
n->rec_proc = rec_proc;
yDef_AddressType (&(n->src_addr));
yDef_AddressType (&(n->dst_addr));
yAssF_AddressType (n->src_addr, *src_addr, XASS);
yAssF_AddressType (n->dst_addr, *dst_addr, XASS);
n->msgs_in = NULL;
n->msgs_out = NULL;
n->close_on_done = 0;
n->next = connection_list;
connection_list = n;
return RET_OK;
}
/*
* Delete an element from our list of known connection
* quadruples, and also free its message queue.
*/
SDL_Integer
wtls_main_delete_connection (SDL_PId cm_proc)
{
list_node *n, *p;
p = NULL;
for (n = connection_list; n; p = n, n = n->next) {
if (n->cm_proc == cm_proc) {
if (p != NULL)
p->next = n->next;
else
connection_list = n->next;
wtls_rec_list_delete (&(n->msgs_in));
wtls_rec_list_delete (&(n->msgs_out));
DEALLOC (&n);
break;
}
}
return RET_OK;
}
/*
* Remove the first element in our list of known
* connection quadruples, and free its message queues.
* Returns the SDL_PId of the removed connection,
* or xNULLPID if the list is empty.
*/
SDL_PId
wtls_main_pop_connection (void)
{
list_node *n = connection_list;
SDL_PId p;
if (n == NULL) {
return xNULLPID;
}
p = n->cm_proc;
connection_list = n->next;
wtls_rec_list_delete (&(n->msgs_in));
wtls_rec_list_delete (&(n->msgs_out));
DEALLOC (&n);
return p;
}
/*
* Return the SDL_PId of the connection with the given
* address quadruple.
* Returns xNULLPID if the connection is not in our list
* of known connections.
*/
SDL_PId
wtls_main_find_connection (AddressType *src_addr, AddressType *dst_addr,
SDL_PId *rec_proc)
{
list_node *n;
for (n = connection_list; n != NULL; n = n->next) {
if ((n->src_addr.PortNumber == src_addr->PortNumber) &&
(n->dst_addr.PortNumber == dst_addr->PortNumber) &&
yEqF_DeviceAddress (n->src_addr.Address, src_addr->Address) &&
yEqF_DeviceAddress (n->dst_addr.Address, dst_addr->Address)) {
*rec_proc = n->rec_proc;
return n->cm_proc;
}
}
return xNULLPID;
}
/*
* Return the SDL_PId of the connection with the given
* source port number.
* Returns xNULLPID if the connection is not in our list
* of known connections.
*/
SDL_PId
wtls_main_find_connection_by_port (SDL_Natural portnum)
{
list_node *n;
for (n = connection_list; n != NULL; n = n->next) {
if ((SDL_Natural)n->src_addr.PortNumber == portnum) {
return n->cm_proc;
}
}
return xNULLPID;
}
void
wtls_main_set_close_on_done (SDL_PId cm_proc,
SDL_Natural portnum,
SDL_Integer path)
{
list_node *n = wtls_main_find_node (cm_proc);
if (n == NULL) {
return;
}
n->close_on_done = 1;
n->portnum = portnum;
n->path = path;
}
SDL_Boolean
wtls_main_get_close_on_done (SDL_PId cm_proc,
SDL_Natural *portnum,
SDL_Integer *path)
{
list_node *n = wtls_main_find_node (cm_proc);
if (n == NULL) {
return SDL_False;
}
if (n->close_on_done) {
*portnum = n->portnum;
*path = n->path;
return SDL_True;
}
else {
return SDL_False;
}
}
/*
* Add a new outbound message to the message queue of the
* indicated Connection Manager process.
*/
SDL_Integer
wtls_main_append_message (SDL_PId cm_proc, pdubuf *msg)
{
list_node *n = wtls_main_find_node (cm_proc);
wtls_record_t *rec;
if (n == NULL) {
wtls_err_set (ERR_INTERNAL, ERR_MISSING_CONNECTION_NODE,
1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
return -1;
}
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;
}
/* Always use a length field. */
rec->rec_type = CONTENT_TYPE_DATA | RECTYPE_LENGTH_FIELD;
rec->length = pdubuf_getLength (msg);
if (msg->currpos == 0) {
rec->fragment = pdubuf_getStart (msg);
DEALLOC (&msg);
}
else {
rec->fragment = NEWARRAY (BYTE, rec->length);
if (rec->fragment == NULL) {
wtls_err_set (ERR_INTERNAL, ERR_INSUFFICIENT_MEMORY,
1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
return -1;
}
B_COPYSTRINGN (rec->fragment, pdubuf_getStart (msg), rec->length);
pdubuf_release (msg);
}
wtls_rec_list_append (rec, &(n->msgs_out));
return RET_OK;
}
/*
* Check if we have an active Connection Manager process
* with the given PId. Returns 0 if we the process exists
* and we have not sent it a TerminateReq signal,
* and -1 otherwise.
*/
SDL_Integer
wtls_main_check_pid (SDL_PId pid)
{
list_node *n;
for (n = connection_list; n != NULL; n = n->next) {
if (((n->cm_proc == pid) || (n->rec_proc == pid)) &&
(n->close_on_done == 0))
break;
}
if (n == NULL) {
return -1;
}
else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -