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

📄 wtlsmain.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 + -