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

📄 wdpsuppt.c

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