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

📄 wdpsuppt.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.
 */
/*
 * wdpsuppt.c
 *
 * Created by Anders Edenbrandt, Wed Aug 16 12:43:53 2000.
 *
 * Revision history:
 *
 */
#include "wdpsuppt.h"
#include "cmmnrsrc.h"
#include "capiclnt.h"
#include "sdl_cfgw.h"

/************************************************************
 * Routines that handle the port table, i.e.,
 * a table holding information about current connections.
 ************************************************************/
typedef struct st_port_table_node {
  struct st_port_table_node *next;
  UINT16                     portnum;
  SDL_PId                    pid;
  SDL_Natural                config;
  SDL_Octet                  bearer;
  SDL_Octet                  view_id;
  SDL_Octet                  channel_id;
} port_table_t;

static port_table_t *port_table = 0;

/*
 * Initialize the port table.
 */
void
wdp_porttbl_init (void)
{
  port_table = 0;
  #ifdef CONFIG_PUSH
  #ifdef CONFIG_WTLS
    wdp_porttbl_update (2949, XPTID_WTLS_Main, MODE_CL_WTLS, 0, 0, 0);
  #endif
  #endif
}

/*
 * Remove all elements from the port table.
 */
void
wdp_porttbl_clear (void)
{
  while (port_table) {
    port_table_t *pn = port_table;

    port_table = port_table->next;
    OSConnectorFree (pn);
  }
}

/*
 * Locate an entry in the port table.
 */
static port_table_t *
wdp_porttbl_find (UINT16 portnum)
{
  port_table_t *pn;

  for (pn = port_table; pn; pn = pn->next) {
    if (pn->portnum == portnum) {
      break;
    }
  }

  return pn;
}

/*
 * Add or update an element in the port table.
 */
void
wdp_porttbl_update (SDL_Integer portn, SDL_PId pid,
                    SDL_Natural config, SDL_Octet bearer,
                    SDL_Octet view_id, SDL_Octet channel_id)
{
  port_table_t *pn;
  UINT16       portnum = (UINT16)portn;

  pn = wdp_porttbl_find (portnum);
  if (!pn) {
    pn = OSConnectorAlloc (sizeof (port_table_t));
    pn->next = port_table;
    port_table = pn;
    pn->portnum = portnum;
  }
  pn->pid = pid;
  pn->config = config;
  pn->bearer = bearer;
  pn->view_id = view_id;
  pn->channel_id = channel_id;
}

/*
 * Delete the element with the specified port number
 * from the port table.
 */
void
wdp_porttbl_delete (SDL_Integer portn)
{
  port_table_t *pn, *qn;
  UINT16       portnum = (UINT16)portn;

  for (qn = 0, pn = port_table; pn; qn = pn, pn = pn->next) {
    if (pn->portnum == portnum) {
      break;
    }
  }
  if (!pn) {
    return;
  }
  if (qn) {
    qn->next = pn->next;
  }
  else {
    port_table = pn->next;
  }
  OSConnectorFree (pn);
}

/*
 * Retrieve values from the port table, stored under
 * the specified port number.
 * Returns SDL_True if the port number was found,
 * and SDL_False otherwise.
 */
SDL_Boolean
wdp_porttbl_lookup (SDL_Integer portn, SDL_PId *pid,
                    SDL_Natural *config, SDL_Octet *bearer,
                    SDL_Octet *view_id, SDL_Octet *channel_id)
{
  port_table_t *pn;
  UINT16       portnum = (UINT16)portn;

  pn = wdp_porttbl_find (portnum);

  if (!pn) {
    return SDL_False;
  }
  *pid = pn->pid;
  *config = pn->config;
  *bearer = pn->bearer;
  *view_id = pn->view_id;
  *channel_id = pn->channel_id;

  return SDL_True;
}

#ifdef CONFIG_SMS
/************************************************************
 * Message building and parsing.
 ************************************************************/

#define SEGMENTED_HEADER_SIZE      12
#define NONSEGMENTED_HEADER_SIZE    7

/*
 * Construct an SMS segment holding the first "length" bytes
 * in the given PDU buffer.
 * The result is stored in "segment" and "seglen".
 */
void
wdp_segment_build (pdubuf *pb, SDL_Integer length,
                   SDL_Integer dst_port, SDL_Integer src_port,
                   SDL_Natural refnum, SDL_Natural total_num_segments,
                   SDL_Natural segnum,
                   void** segment, SDL_Natural *seglen)
{
  BYTE *ptr;

  if (total_num_segments > 1) {
    *seglen = length + SEGMENTED_HEADER_SIZE;
    *segment = OSConnectorAlloc (*seglen);
    ptr = (BYTE *)*segment;
    ptr[0] = 11;
    ptr[1] = IE_ID_PORT_NUMBER;
    ptr[2] = 4;
    ptr[3] = (UINT8)(dst_port >> 8);
    ptr[4] = (UINT8)(dst_port & 0xff);
    ptr[5] = (UINT8)(src_port >> 8);
    ptr[6] = (UINT8)(src_port & 0xff);
    ptr[7] = IE_ID_SAR_SHORT;
    ptr[8] = 3;
    ptr[9] = (BYTE)refnum;
    ptr[10] = (BYTE)total_num_segments;
    ptr[11] = (BYTE)segnum;

    memcpy (ptr + SEGMENTED_HEADER_SIZE, pdubuf_getStart (pb), length);
  }
  else {
    *seglen = length + NONSEGMENTED_HEADER_SIZE;
    *segment = OSConnectorAlloc (*seglen);
    ptr = (BYTE *)*segment;
    ptr[0] = 6;
    ptr[1] = IE_ID_PORT_NUMBER;
    ptr[2] = 4;
    ptr[3] = (UINT8)(dst_port >> 8);
    ptr[4] = (UINT8)(dst_port & 0xff);
    ptr[5] = (UINT8)(src_port >> 8);
    ptr[6] = (UINT8)(src_port & 0xff);

    memcpy (ptr + NONSEGMENTED_HEADER_SIZE, pdubuf_getStart (pb), length);
  }
}

/*
 * Extract values from a User Data Header.
 * Returns SDL_True if the extraction succeeded, and
 * SDL_False otherwise.
 */
SDL_Boolean
wdp_UDH_extract (void *segment, SDL_Natural length,
                 SDL_Boolean *is_segmented,
                 SDL_Natural *header_length,
                 SDL_Integer *dst_port, SDL_Integer *src_port,
                 SDL_Natural *refnum, SDL_Natural *total_num_segments,
                 SDL_Natural *segnum,
                 SDL_Boolean *has_WCMP,
                 void **WCMP_ptr, SDL_Natural *WCMP_length)
{
  BYTE   *p = segment;
  UINT16 i;
  UINT16 portnum, tmp;

  if (length <= 0) {
    return SDL_False;
  }
  *header_length = (UINT16)p[0] + 1;
  if (length < *header_length) {
    return SDL_False;
  }
  *is_segmented = SDL_False;
  *has_WCMP = SDL_False;

  for (i = 1; i < *header_length;) {
    switch (p[i]) {
    case IE_ID_PORT_NUMBER:
      if (i + 5 >= *header_length) {
        return SDL_False;
      }
      if (p[i + 1] != 4) {
        return SDL_False;
      }
      portnum = p[i + 2];
      portnum <<= 8;
      portnum |= p[i + 3];
      *dst_port = (SDL_Integer)portnum;

      portnum = p[i + 4];
      portnum <<= 8;
      portnum |= p[i + 5];
      *src_port = (SDL_Integer)portnum;

      i += 6;
      break;

    case IE_ID_SAR_SHORT:
      if (i + 4 >= *header_length) {
        return SDL_False;
      }
      if (p[i + 1] != 3) {
        return SDL_False;
      }
      *is_segmented = SDL_True;
      *refnum = (p[i + 2] & 0xff);
      *total_num_segments = (p[i + 3] & 0xff);
      *segnum = (p[i + 4] & 0xff);
      i += 5;
      break;

    case IE_ID_SAR_LONG:
      if (i + 5 >= *header_length) {
        return SDL_False;
      }
      if (p[i + 1] != 4) {
        return SDL_False;
      }
      *is_segmented = SDL_True;
      tmp = p[i + 2];
      tmp <<= 8;
      tmp |= p[i + 3];
      *refnum = tmp;
      *total_num_segments = (p[i + 4] & 0xff);
      *segnum = (p[i + 5] & 0xff);
      i += 6;
      break;

    case IE_ID_WCMP:
      if (i + 1 >= *header_length) {
        return SDL_False;
      }
      *has_WCMP = SDL_True;
      *WCMP_ptr = &(p[i + 2]);
      *WCMP_length = (SDL_Integer)(p[i + 1] & 0xff);
      i += p[i + 1] + 2;
      break;

    default:
      /* Unknown IE Identifier, skip past it. */
      if (i + 1 >= *header_length) {
        return SDL_False;
      }
      i += p[i] + 2;
      break;
    }
  }

  return SDL_True;
}

/*
 * Construct a WCMP message.
 */
void
wdp_wcmp_build_msg (SDL_Octet type, SDL_Octet code,
                    SDL_Integer dst_port, SDL_Integer src_port,
                    DeviceAddress *addr,
                    void *old_msg, SDL_Natural old_msg_length,
                    void **msg, SDL_Natural *msg_length,
					SDL_Boolean is_udcp_msg)
{
  BYTE  *p;
  UINT8 IE_length, package_length;

  if (type == WCMP_MESSAGE_TOO_BIG) {
    IE_length = (UINT8)(6 + 2 + addr->length + 2);
    package_length = 2 + IE_length;
	*msg_length = package_length + 1;
    p = *msg = OSConnectorAlloc (*msg_length);
    p[addr->length + 11] = (MaxPDUsize >> 8) & 0xff;
    p[addr->length + 12] = (MaxPDUsize & 0xff);
  }
  else if (type == WCMP_DESTINATION_UNREACHABLE) {
    IE_length = (UINT8)(6 + 2 + addr->length);
    package_length = 2 + IE_length;
    *msg_length = package_length + 1;
    p = *msg = OSConnectorAlloc (*msg_length);
  }
  else if (type == WCMP_ECHO_REPLY) {
    IE_length = (UINT8)old_msg_length;
    package_length = 2 + IE_length;
    *msg_length = package_length + 1;
    p = *msg = OSConnectorAlloc (*msg_length);
    memcpy (p + 3, old_msg, old_msg_length);
    p[0] = package_length;
    p[1] = 9;
    p[2] = IE_length;
    p[3] = WCMP_ECHO_REPLY;
    return;
  }
  else {
    *msg = NULL;
    *msg_length = 0;
    return;
  }
  p[0] = package_length;
  p[1] = 9;
  p[2] = (UINT8)IE_length;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -