自主协议库编译通过

This commit is contained in:
lnk
2026-06-15 15:48:16 +08:00
parent d3579a2aa7
commit 7205cb5cb9
621 changed files with 224958 additions and 48 deletions

2268
mmslib/ositcps/acse2dec.c Normal file

File diff suppressed because it is too large Load Diff

522
mmslib/ositcps/acse2dib.c Normal file
View File

@@ -0,0 +1,522 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 2003 - 2003, All Rights Reserved */
/* */
/* MODULE NAME : acse2dib.c */
/* PRODUCT(S) : MMS-LITE */
/* */
/* MODULE DESCRIPTION : Address matching functions. */
/* */
/* NOTE: !!! If changes are made to this file the same changes */
/* have to be made in the marb_dib.c (MMS-EASE). */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 03/28/05 JRB 03 Del suicacse header. */
/* 06/16/03 EJV 02 Renamed m_match.c to acse2dib.c */
/* 06/02/03 MDE 01 Created */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#include "acse2.h"
/************************************************************************/
/* For debug version, use a static pointer to avoid duplication of */
/* __FILE__ strings. */
/************************************************************************/
#ifdef DEBUG_SISCO
static ST_CHAR *thisFileName = __FILE__;
#endif
/************************************************************************/
/* Internal Functions */
static ST_VOID _dib_match_ap_title (DIB_MATCH_CTRL *matchCtrl,
ST_INT *matchLevel,
ST_BOOLEAN ind_pres, MMS_OBJ_ID *ind_apTitle,
ST_BOOLEAN dib_pres, MMS_OBJ_ID *dib_apTitle);
static ST_VOID _dib_match_ae_int (DIB_MATCH_CTRL *matchCtrl,
ST_INT *matchLevel,
ST_BOOLEAN ind_pres, ST_INT32 ind_val,
ST_BOOLEAN dib_pres, ST_INT32 dib_val,
ST_CHAR *itemText);
static ST_VOID _dib_match_mem (ST_INT *matchLevel,
ST_INT ind_sel_len, ST_UCHAR *ind_sel,
ST_INT dib_sel_len, ST_UCHAR *dib_sel,
ST_CHAR *sel_text);
static ST_VOID _dib_match_ae_present_flag (DIB_MATCH_CTRL *matchCtrl,
ST_INT *matchLevelIo,
ST_CHAR *aeElText,
ST_BOOLEAN dibPres,
ST_BOOLEAN remotePres,
ST_BOOLEAN *doCompareOut);
/************************************************************************/
/* ml_match_remote_ar */
/************************************************************************/
ST_RET dib_match_remote_ar (DIB_MATCH_CTRL *matchCtrl,
AARQ_APDU *aarq, DIB_ENTRY **dib_entry_out)
{
ST_INT i;
DIB_ENTRY *de;
DIB_ENTRY *closeDe;
ST_INT remMatch;
ACSELOG_DIB0 ("Matching Remote AR");
closeDe = NULL;
for (i = 0; i < num_rem_dib_entries; ++i)
{
de = &rem_dib_table[i];
ACSELOG_DIB1C (" Remote AR '%s'", de->name);
remMatch = dib_cmp_remote_addr (matchCtrl, aarq, de);
if (remMatch == DIB_MATCH_EXACT)
{
*dib_entry_out = de;
ACSELOG_DIB1C ("Exact Match: '%s'", de->name);
return (SD_SUCCESS);
}
if (remMatch == DIB_MATCH_CLOSE && closeDe == NULL)
closeDe = de;
}
if (closeDe != NULL)
{
*dib_entry_out = closeDe;
ACSELOG_DIB1C ("Close Match: '%s'", closeDe->name);
return (SD_SUCCESS);
}
return (SD_FAILURE);
}
/************************************************************************/
/* dib_match_local_ar */
/************************************************************************/
ST_RET dib_match_local_ar (DIB_MATCH_CTRL *matchCtrl,
AARQ_APDU *aarq, DIB_ENTRY **dib_entry_out)
{
ST_INT i;
DIB_ENTRY *de;
DIB_ENTRY *closeDe;
ST_INT locMatch;
ACSELOG_DIB0 ("Matching Local AR");
closeDe = NULL;
for (i = 0; i < num_loc_dib_entries; ++i)
{
de = &loc_dib_table[i];
ACSELOG_DIB1C (" Local AR '%s'", de->name);
locMatch = dib_cmp_local_addr (matchCtrl,aarq, de);
if (locMatch == DIB_MATCH_EXACT)
{
ACSELOG_DIB1C ("Exact Match: '%s'", de->name);
*dib_entry_out = de;
return (SD_SUCCESS);
}
if (locMatch == DIB_MATCH_CLOSE && closeDe == NULL)
closeDe = de;
}
if (closeDe != NULL)
{
ACSELOG_DIB1C ("Close Match: '%s'", de->name);
*dib_entry_out = closeDe;
return (SD_SUCCESS);
}
return (SD_FAILURE);
}
/************************************************************************/
/************************************************************************/
/* dib_cmp_local_addr */
/************************************************************************/
ST_INT dib_cmp_local_addr (DIB_MATCH_CTRL *matchCtrl,
AARQ_APDU *aarq, DIB_ENTRY *dib_entry)
{
ST_INT matchLevel;
/* The best we can do ... */
matchLevel = DIB_MATCH_EXACT;
/* Compare local network address with dib entry */
#if 0
if (matchCtrl->match_net_addr)
{
if (aarq->transport == TCP)
{
_dib_match_mem (&matchLevel,
strlen (aarq->ip_addr), aarq->ip_addr,
strlen (dib_entry->ip_addr), dib_entry->ip_addr,
"Local IP Address");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
else if (aarq->transport == TP4)
{
_dib_match_mem (&matchLevel,
aarq->net_addr_len,aarq->net_addr,
dib_entry->net_addr_len, dib_entry->net_addr,
"Local Network Address");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
else
{
ACSELOG_ERR1 ("Transport type problem: %d", aarq->transport);
return (DIB_MATCH_NOT);
}
}
#endif
/* Compare selectors with dib entry */
/* PSEL */
if (matchCtrl->match_psel)
{
_dib_match_mem (&matchLevel, aarq->called_paddr.psel_len, aarq->called_paddr.psel,
dib_entry->pres_addr.psel_len, dib_entry->pres_addr.psel,
"PSEL");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
/* SSEL */
if (matchCtrl->match_ssel)
{
_dib_match_mem (&matchLevel, aarq->called_paddr.ssel_len, aarq->called_paddr.ssel,
dib_entry->pres_addr.ssel_len, dib_entry->pres_addr.ssel,
"SSEL");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
/* TSEL */
if (matchCtrl->match_tsel)
{
_dib_match_mem (&matchLevel, aarq->called_paddr.tsel_len, aarq->called_paddr.tsel,
dib_entry->pres_addr.tsel_len, dib_entry->pres_addr.tsel,
"TSEL");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
/* Now compare AE Titles */
/* AP Title */
if (matchCtrl->match_ap_title)
{
_dib_match_ap_title (matchCtrl,&matchLevel,
aarq->called_ae_title.AP_title_pres, &aarq->called_ae_title.AP_title,
dib_entry->AP_title_pres, &dib_entry->AP_title);
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
/* AE Qualifier */
if (matchCtrl->match_ae_qualifier)
{
_dib_match_ae_int (matchCtrl, &matchLevel,
aarq->called_ae_title.AE_qual_pres, aarq->called_ae_title.AE_qual,
dib_entry->AE_qual_pres, dib_entry->AE_qual,
"AE Qualifier");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
/* AP Invoke ID */
if (matchCtrl->match_ap_invoke)
{
_dib_match_ae_int (matchCtrl, &matchLevel,
aarq->called_ae_title.AP_inv_id_pres, aarq->called_ae_title.AP_inv_id,
dib_entry->AP_inv_id_pres, dib_entry->AP_invoke_id,
"AP invoke ID");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
/* AE Invoke ID */
if (matchCtrl->match_ae_invoke)
{
_dib_match_ae_int (matchCtrl, &matchLevel,
aarq->called_ae_title.AE_inv_id_pres, aarq->called_ae_title.AE_inv_id,
dib_entry->AE_inv_id_pres, dib_entry->AE_invoke_id,
"AE invoke ID");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
return (matchLevel); /* exact */
}
/************************************************************************/
/* dib_cmp_remote_addr */
/************************************************************************/
ST_INT dib_cmp_remote_addr (DIB_MATCH_CTRL *matchCtrl,
AARQ_APDU *aarq, DIB_ENTRY *dib_entry)
{
ST_INT matchLevel;
/* The best we can do ... */
matchLevel = DIB_MATCH_EXACT;
/* Compare partner network address with dib entry */
#if 0
if (matchCtrl->match_net_addr)
{
if (aarq->transport == TCP)
{
_dib_match_mem (&matchLevel,
strlen (aarq->part_ip_addr), aarq->part_ip_addr,
strlen (dib_entry->ip_addr), dib_entry->ip_addr,
"Remote IP Address");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
else if (aarq->transport == TP4)
{
_dib_match_mem (&matchLevel,
aarq->part_net_addr_len,aarq->part_net_addr,
dib_entry->net_addr_len, dib_entry->net_addr,
"Remote Network Address");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
else
{
ACSELOG_ERR1 ("Transport type problem: %d", aarq->transport);
return (DIB_MATCH_NOT);
}
}
#endif
/* Compare selectors with dib entry */
/* PSEL */
if (matchCtrl->match_psel)
{
_dib_match_mem (&matchLevel, aarq->calling_paddr.psel_len, aarq->calling_paddr.psel,
dib_entry->pres_addr.psel_len, dib_entry->pres_addr.psel,
"PSEL");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
/* SSEL */
if (matchCtrl->match_ssel)
{
_dib_match_mem (&matchLevel, aarq->calling_paddr.ssel_len, aarq->calling_paddr.ssel,
dib_entry->pres_addr.ssel_len, dib_entry->pres_addr.ssel,
"SSEL");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
/* TSEL */
if (matchCtrl->match_tsel)
{
_dib_match_mem (&matchLevel, aarq->calling_paddr.tsel_len, aarq->calling_paddr.tsel,
dib_entry->pres_addr.tsel_len, dib_entry->pres_addr.tsel,
"TSEL");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
/* Now compare AE Titles */
/* AP Title */
if (matchCtrl->match_ap_title)
{
_dib_match_ap_title (matchCtrl, &matchLevel,
aarq->calling_ae_title.AP_title_pres, &aarq->calling_ae_title.AP_title,
dib_entry->AP_title_pres, &dib_entry->AP_title);
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
/* AE Qualifier */
if (matchCtrl->match_ae_qualifier)
{
_dib_match_ae_int (matchCtrl, &matchLevel,
aarq->calling_ae_title.AE_qual_pres, aarq->calling_ae_title.AE_qual,
dib_entry->AE_qual_pres, dib_entry->AE_qual,
"AE Qualifier");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
/* AP Invoke ID */
if (matchCtrl->match_ap_invoke)
{
_dib_match_ae_int (matchCtrl, &matchLevel,
aarq->calling_ae_title.AP_inv_id_pres, aarq->calling_ae_title.AP_inv_id,
dib_entry->AP_inv_id_pres, dib_entry->AP_invoke_id,
"AP invoke ID");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
/* AE Invoke ID */
if (matchCtrl->match_ae_invoke)
{
_dib_match_ae_int (matchCtrl, &matchLevel,
aarq->calling_ae_title.AE_inv_id_pres, aarq->calling_ae_title.AE_inv_id,
dib_entry->AE_inv_id_pres, dib_entry->AE_invoke_id,
"AE invoke ID");
if (matchLevel == DIB_MATCH_NOT)
return (DIB_MATCH_NOT);
}
return (matchLevel);
}
/************************************************************************/
/* _dib_match_ap_title */
/************************************************************************/
/* Set match level to DIB_MATCH_NOT, or leave alone */
static ST_VOID _dib_match_ap_title (DIB_MATCH_CTRL *matchCtrl,
ST_INT *matchLevel,
ST_BOOLEAN ind_pres, MMS_OBJ_ID *ind_apTitle,
ST_BOOLEAN dib_pres, MMS_OBJ_ID *dib_apTitle)
{
ST_CHAR *itemText = "AP Title";
ST_BOOLEAN doCompare;
_dib_match_ae_present_flag (matchCtrl, matchLevel, itemText, dib_pres,
ind_pres, &doCompare);
/* See if we need to compare */
if (doCompare)
{
if (asn1_objidcmp (ind_apTitle, dib_apTitle))
{
ACSELOG_DIB1C (" %s mismatch", itemText);
*matchLevel = DIB_MATCH_NOT;
return;
}
}
}
/************************************************************************/
/* _dib_match_ae_int */
/************************************************************************/
/* Set match level to DIB_MATCH_NOT, or leave alone */
static ST_VOID _dib_match_ae_int (DIB_MATCH_CTRL *matchCtrl, ST_INT *matchLevel,
ST_BOOLEAN ind_pres, ST_INT32 ind_val,
ST_BOOLEAN dib_pres, ST_INT32 dib_val,
ST_CHAR *itemText)
{
ST_BOOLEAN doCompare;
_dib_match_ae_present_flag (matchCtrl, matchLevel, itemText, dib_pres,
ind_pres, &doCompare);
/* OK, we matched, see if we need to compare */
if (doCompare)
{
if (ind_val != dib_val)
{
ACSELOG_DIB1C (" %s mismatch", itemText);
*matchLevel = DIB_MATCH_NOT;
return;
}
}
}
/************************************************************************/
/* _dib_match_mem */
/************************************************************************/
/* Set match level to DIB_MATCH_NOT, or leave alone */
static ST_VOID _dib_match_mem (ST_INT *matchLevel,
ST_INT ind_sel_len, ST_UCHAR *ind_sel,
ST_INT dib_sel_len, ST_UCHAR *dib_sel,
ST_CHAR *sel_text)
{
/* See if the selectors match */
if (ind_sel_len == dib_sel_len &&
!memcmp (ind_sel, dib_sel, ind_sel_len))
{
return;
}
ACSELOG_DIB1C (" %s mismatch", sel_text);
*matchLevel = DIB_MATCH_NOT;
return;
}
/************************************************************************/
/* _dib_match_ae_present_flag */
/************************************************************************/
/* Set match level to DIB_MATCH_CLOSE or DIB_MATCH_NOT, or leave alone */
static ST_VOID _dib_match_ae_present_flag (DIB_MATCH_CTRL *matchCtrl,
ST_INT *matchLevelIo,
ST_CHAR *aeElText,
ST_BOOLEAN dibPres,
ST_BOOLEAN remotePres,
ST_BOOLEAN *doCompareOut)
{
/* If the remote sent the parameter and it is in the DIB, SUCCESS */
if (dibPres == remotePres)
{
*doCompareOut = dibPres; /* If it is present, then compare it */
return;
}
*doCompareOut = SD_FALSE; /* Can't compare */
/* OK, this is more complicated. We need to find out what the mismatch */
/* is and what the user wants to do about it. */
if (!remotePres)
{
if (matchCtrl->match_allow_missing_ae_elements)
{
ACSELOG_DIB1C (" Remote did not send: %s, ignoring", aeElText);
if (*matchLevelIo == DIB_MATCH_EXACT)
*matchLevelIo = DIB_MATCH_CLOSE;
}
else
{
ACSELOG_DIB1C (" Remote did not send required: %s", aeElText);
*matchLevelIo = DIB_MATCH_NOT;
}
}
if (remotePres)
{
if (matchCtrl->match_allow_extra_ae_elements)
{
ACSELOG_DIB1C (" Remote sent unexpected: %s, ignoring", aeElText);
if (*matchLevelIo == DIB_MATCH_EXACT)
*matchLevelIo = DIB_MATCH_CLOSE;
}
else
{
ACSELOG_DIB1C (" Remote sent unexpected: %s", aeElText);
*matchLevelIo = DIB_MATCH_NOT;
}
}
}

1334
mmslib/ositcps/acse2enc.c Normal file

File diff suppressed because it is too large Load Diff

39
mmslib/ositcps/acse2var.c Normal file
View File

@@ -0,0 +1,39 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1995 All Rights Reserved */
/* */
/* MODULE NAME : acse2var.c */
/* PRODUCT(S) : */
/* */
/* MODULE DESCRIPTION : */
/* Global variables for ACSE component. Used by both connection- */
/* oriented ACSE and connectionless ACSE. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 09/13/99 MDE 08 Added SD_CONST modifiers */
/* 07/14/99 JRB 07 Add ACSE Password Authentication obj id. */
/* 07/10/98 JRB 06 Add *_obj_id so CO and CL ACSE can share. */
/* 11/15/96 JRB 05 Move acse_debug_sel to acse2enc.c */
/* 05/02/96 KCR 04 Initialized acse_debug_sel to make sure it */
/* is pulled into OS/2 library */
/* 04/17/96 JRB 03 Del acse_sLogCtrl, use sLogCtrl (slog.c) now */
/* 03/26/96 MDE 02 Chg define to PLAIN_DOS. */
/* 10/30/95 JRB 01 Created */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#include "asn1defs.h"
/* NOTE: we only support ISO MMS Abstract Syntax. No more MAP MMS. */
SD_CONST MMS_OBJ_ID mms_obj_id = {5,{1,0,9506,2,1}}; /* ISO MMS Abstract Syntax*/
SD_CONST MMS_OBJ_ID acse_obj_id = {5,{2,2,1,0,1}}; /* ACSE Abstract Syntax*/
SD_CONST MMS_OBJ_ID asn1_obj_id = {3,{2,1,1}}; /* ASN.1 Transfer Syntax*/
SD_CONST MMS_OBJ_ID a_auth_password_obj_id = {4,{2,2,3,1}}; /* ACSE Authent. - Password*/

246
mmslib/ositcps/checksum.c Normal file
View File

@@ -0,0 +1,246 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1996, All Rights Reserved. */
/* */
/* PROPRIETARY AND CONFIDENTIAL */
/* */
/* MODULE NAME : checksum.c */
/* PRODUCT(S) : Lean-T Stack */
/* */
/* MODULE DESCRIPTION : */
/* This module implements the computation of checksum */
/* using the algorithm defined in Annex B of the ISO 8073 */
/* or in the ISO 8473. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* checksum_insert */
/* checksum_verified */
/* */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 05/27/97 JRB 7.00 MMSEASE 7.0 release. */
/* 05/12/97 JRB 03 ch*_verified chk c0. Was checking c1 twice. */
/* Clean up data types. */
/* Clarify casting computing x,y in ch*_insert. */
/* 05/07/97 JRB 02 Changed non-ANSI "%hu" to "%u". */
/* 06/17/96 EJV 01 Created */
/************************************************************************/
#if 0
/* this file is not neccessary when printf will be replaced with slog */
#include <stdio.h>
#endif
#include "glbtypes.h"
#include "checksum.h"
static ST_VOID get_checksum_c0_c1 (ST_UCHAR *buf, ST_UINT16 buf_len,
ST_UCHAR *pC0, ST_UCHAR *pC1);
/************************************************************************/
/* checksum_insert */
/*----------------------------------------------------------------------*/
/* This function computes and inserts the 2 byte checksum into a PDU */
/* buffer at specified position (and position+1). */
/* The checksum algorithm is described in ISO 8473 (CLNP) and */
/* ISO 8073 (Transport protocol). */
/* Note that the maximum len of TPDU in ISO 8073 is 8192 bytes. */
/* */
/* Parameters: */
/* ST_UCHAR *buf Ptr to encoding buffer on which checksum*/
/* will be computed. */
/* ST_UINT16 buf_len Length of the buffer (PDU). */
/* ST_UINT16 position Position of checksum's first byte in buf*/
/* (position=0 if checksum is the first */
/* byte in buffer). */
/* */
/* Return: */
/* ST_VOID none */
/************************************************************************/
ST_VOID checksum_insert (ST_UCHAR *buf, ST_UINT16 buf_len, ST_UINT16 position)
{
ST_UCHAR c0, c1;
ST_LONG x, y; /* the checksum's first and second byte */
ST_UINT16 sum_pos; /* this is the position of checksum first byte */
/* in the PDU as specified by algorithm, first */
/* byte position is 1 not 0. */
sum_pos = position+1;
/* make sure the checksum bytes are cleared */
buf [position] = buf [position+1] = 0;
get_checksum_c0_c1 (buf, buf_len, &c0, &c1);
#if 0
/* LIZ substitute the printf with slogging */
printf ("\n Checksum computation: c0=0x%2.2X=%u, c1=0x%2.2X=%u",
(ST_UINT) c0, (ST_UINT) c0, (ST_UINT) c1, (ST_UINT) c1);
#endif
x = ((ST_LONG) (buf_len-sum_pos) * (ST_LONG) c0 - (ST_LONG) c1) % 255L;
y = ((ST_LONG) c1 - (ST_LONG) (buf_len-sum_pos+1) * (ST_LONG) c0) % 255L;
buf [position] = (ST_UCHAR) (x <= 0L ? x+255L : x);
buf [position+1] = (ST_UCHAR) (y <= 0L ? y+255L : y);
#if 0
/* LIZ substitute the printf with slogging */
printf ("\n Checksum computation: buf[%u]=%u, buf[%u]=%u",
position, (ST_UINT) buf[position],
position+1,(ST_UINT) buf[position+1]);
#endif
}
/************************************************************************/
/* checksum_verified */
/*----------------------------------------------------------------------*/
/* This function verifies the checksum of a PDU. */
/* The checksum algorithm is described in ISO 8473 (CLNP) and */
/* ISO 8073 (Transport protocol). */
/* Note that the maximum len of TPDU in ISO 8073 is 8192 bytes. */
/* */
/* Parameters: */
/* ST_UCHAR *buf Ptr to encoding buffer on which checksum*/
/* will be computed. */
/* ST_UINT16 buf_len Length of the buffer (PDU). */
/* ST_UINT16 position Position of checksum's first byte in buf*/
/* (position=0 if checksum is the first */
/* byte in buffer), used only for CLNP. */
/* ST_BOOLEAN clnp_csum If SD_TRUE the CLNP checksum will be */
/* verified, if SD_FALSE the Transport Prot. */
/* checksum will be verified. */
/* */
/* Return: */
/* ST_BOOLEAN SD_TRUE if verification of checksum is */
/* successful; */
/* SD_FALSE if verification failed. */
/************************************************************************/
ST_BOOLEAN checksum_verified (ST_UCHAR *buf, ST_UINT16 buf_len, ST_UINT16 position,
ST_BOOLEAN clnp_csum)
{
ST_BOOLEAN checksum_correct;
ST_UCHAR c0, c1;
checksum_correct = SD_FALSE;
if (clnp_csum)
{
if (buf [position] != 0 && buf [position+1] != 0)
{
/* if both bytes in checksum are not 0 then we have to compute the */
/* checksum */
get_checksum_c0_c1 (buf, buf_len, &c0, &c1);
#if 0
/* LIZ substitute the printf with slogging */
printf ("\n Checksum verification: c0=0x%2.2X=%u, c1=0x%2.2X=%u",
(ST_UINT) c0, (ST_UINT) c0, (ST_UINT) c1, (ST_UINT) c1);
#endif
if (c0 == 0 && c1 == 0)
checksum_correct = SD_TRUE;
}
else if (buf [position] == 0 && buf [position+1] == 0)
{
/* if both bytes in checksum are 0 then the checksum should be */
/* ignored, and is considered as correct. */
checksum_correct = SD_TRUE;
}
/* if one byte (but not both bytes) in checksum is 0 then the */
/* checksum is invalid. */
}
else
{
/* transport protocol checksum */
get_checksum_c0_c1 (buf, buf_len, &c0, &c1);
if (c0 == 0 && c1 == 0)
checksum_correct = SD_TRUE;
}
return (checksum_correct);
}
/************************************************************************/
/* get_checksum_c0_c1 */
/*----------------------------------------------------------------------*/
/* This function computes the checksum values C0 and C1 described in */
/* ISO 8473 (CLNP) and ISO 8073 (Transport protocol). */
/* Note that the maximum len of TPDU in ISO 8073 is 8192 bytes. */
/* To avoid overflow of long values c0 or c1 when the buffer len is */
/* greater then 4096 the values c0 and c1 are computed in two stages. */
/* */
/* Parameters: */
/* ST_UCHAR *buf Ptr to encoding buffer on which checksum*/
/* will be computed. */
/* ST_UINT16 buf_len Length of the buffer (TPDU). */
/* ST_UCHAR *pC0 Pointer where to return the computed C0.*/
/* ST_UCHAR *pC1 Pointer where to return the computed C1.*/
/* */
/* Return: */
/* ST_VOID none */
/************************************************************************/
static ST_VOID get_checksum_c0_c1 (ST_UCHAR *buf, ST_UINT16 buf_len,
ST_UCHAR *pC0, ST_UCHAR *pC1)
{
ST_ULONG c0, c1;
c0 = c1 = 0L;
while (buf_len-- > 0)
{
c0 = c0 + (ST_ULONG) *(buf++);
c1 = c1 + c0;
/* if the buf_len > 4096 there is risk of overflowing, so we take */
/* modulus at 4096 bytes to bring the c0 and c1 numbers down */
if (buf_len == 4096)
{
c0 = c0 % 255L;
c1 = c1 % 255L;
}
}
*pC0 = (ST_UCHAR) (c0 % 255L);
*pC1 = (ST_UCHAR) (c1 % 255L);
/* the code below can substitute the code above if long 32-bit values */
/* are not available with given compiler. */
#if 0
ST_UINT16 c0,c1;
c0 = c1 = 0;
while (buf_len-- > 0)
{
c0 += (ST_UINT16) *(buf++);
if (c0 >= 255)
{
++c0; /* this two lines are equvalen to mod 255 */
c0 &= 0x00ff;
}
c1 += c0;
if (c1 >= 255)
{
++c1;
c1 &= 0x00ff;
}
}
*pC0 = (ST_UCHAR) c0;
*pC1 = (ST_UCHAR) c1;
#endif
}

488
mmslib/ositcps/copp_dec.c Normal file
View File

@@ -0,0 +1,488 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1997-2002, All Rights Reserved */
/* */
/* PROPRIETARY AND CONFIDENTIAL */
/* */
/* MODULE NAME : copp_dec.c */
/* PRODUCT(S) : MOSI Stack (over TP4) */
/* */
/* MODULE DESCRIPTION : */
/* This file implements decoding of most confirm/indication*/
/* functions. */
/* */
/* For information see the: */
/* ISO 8822 "Information processing systems - Open Systems */
/* Interconnection - Connection oriented presentation service */
/* definition. */
/* ISO 8823 "Information processing systems - Open Systems */
/* Interconnection - Connection oriented presentation protocol */
/* specification. */
/* */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* u_cosp_bind_cnf */
/* u_cosp_unbind_cnf */
/* */
/* u_cosp_rel_cnf_pos */
/* u_cosp_rel_ind */
/* u_cosp_p_abort_ind */
/* u_cosp_data_ind */
/* */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 02/26/09 JRB 12 Fix to handle PDV len=0 or User-data len=0. */
/* 04/28/08 GLB 11 Removed CALLED_ONLY and CALLING_ONLY */
/* 01/02/02 JRB 10 Converted to use ASN1R (re-entrant ASN1) */
/* 04/24/01 JRB 09 Allow octet-aligned PDV. Don't think it's */
/* legal but some stacks (ONE?) may use it. */
/* 02/21/01 JRB 08 Fix previous change. Was checking wrong byte */
/* in PDU for Indef Len. Use global flag instead*/
/* 12/20/00 JRB 07 asn1_skip_elmnt doesn't work for indef len */
/* encoding. Use "parse_next" instead. */
/* 08/13/98 JRB 06 Lint cleanup. */
/* 03/18/98 JRB 05 Use defines (not variables) for ASN1 errors. */
/* 02/20/98 JRB 04 Chg abort_reason & event_id to ST_INT8. */
/* 12/22/97 JRB 03 Use ST_INT8. */
/* 05/27/97 JRB 7.00 MMSEASE 7.0 release. */
/* 03/19/97 JRB 02 Add "CALLING" support. General cleanup. */
/* 02/27/97 JRB 01 Created */
/************************************************************************/
#ifdef DEBUG_SISCO
static char *thisFileName = __FILE__;
#endif
#include "glbtypes.h"
#include "sysincs.h"
#include "mem_chk.h"
#include "asn1defs.h"
#include "acse2.h"
#include "copp.h"
#include "cosp_usr.h"
/* START_p_user_data used by everyone, so proto in include */
/* START_pdv_list used by everyone, so proto in include */
static ST_VOID decode_pdv_tsn (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_pdv_pci (ASN1_DEC_CTXT *aCtx);
static ST_VOID START_pdv (ASN1_DEC_CTXT *aCtx);
static ST_VOID parse_next_done (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_pdv (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_pdv_list (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_p_user_data (ASN1_DEC_CTXT *aCtx);
/************************************************************************/
/* Global Variables */
/************************************************************************/
ST_CHAR expected_pdv_pci;
ST_UCHAR *pdv_data_ptr;
ST_INT pdv_data_len;
ST_BOOLEAN p_user_data_is_outer; /* Is P-User-data outermost constr?*/
/* SD_TRUE or SD_FALSE */
/************************************************************************/
/* u_cosp_bind_cnf */
/************************************************************************/
ST_VOID u_cosp_bind_cnf (ST_LONG user_bind_id, ST_LONG cosp_bind_id, ST_RET result)
{
COPP_LOG_DEC3 ("P-BIND.cnf: copp_user_bind_id =0x%08X copp_bind_id =%9ld result =%d",
user_bind_id, cosp_bind_id, result);
u_copp_bind_cnf (user_bind_id, cosp_bind_id, result);
}
/************************************************************************/
/* u_cosp_unbind_cnf */
/************************************************************************/
ST_VOID u_cosp_unbind_cnf (ST_LONG user_bind_id)
{
COPP_LOG_DEC1 ("P-UNBIND.cnf: copp_user_bind_id =0x%08X", user_bind_id);
u_copp_unbind_cnf (user_bind_id);
}
/* See "coppdcp.c" for "u_cosp_con_cnf_pos" function. */
/* See "coppdcpr.c" for "u_cosp_con_cnf_neg" function. */
/************************************************************************/
/* u_cosp_rel_cnf_pos */
/*----------------------------------------------------------------------*/
/* This USER function is called by the SS-Provider to indicate positive */
/* result of the release operation. */
/* */
/* Parameters: */
/* acse_conn Pointer to connection info */
/* */
/* Return: */
/* ST_VOID */
/************************************************************************/
ST_VOID u_cosp_rel_cnf_pos (ACSE_CONN *acse_conn)
{
ST_INT8 abort_reason;
ASN1_DEC_CTXT localDecCtx; /* For readability, use "aCtx" to access this.*/
ASN1_DEC_CTXT *aCtx = &localDecCtx;
memset (aCtx, 0, sizeof (ASN1_DEC_CTXT)); /* CRITICAL: start clean */
if (acse_conn->copp_state != COPP_STATE_CONNECTED)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot process S-RELEASE.cnf+ (Illegal state=%d)",
acse_conn->copp_state);
return;
}
aCtx->asn1r_decode_method = ASN1_TAG_METHOD; /* Use asn1_tag method for decoding. */
aCtx->asn1r_decode_done_fun = asn1r_done_err; /* done function = error fun */
aCtx->asn1r_err_fun = NULL; /* set up error detected fun */
/* Clean out old stuff from structure. */
decode_acse_conn = acse_conn; /* Save in global so asn1r_decode_asn1 (aCtx, */
/* can fill it in. */
/* Set the PCI to be used during P-User-Data decode. */
expected_pdv_pci = decode_acse_conn->pciacse;
p_user_data_is_outer = SD_TRUE; /* P-User-data IS outermost constr. */
/* CRITICAL: Init APDU ptr & len. Changed only if APDU found in msg. */
acse_conn->apdu_ptr = NULL;
acse_conn->apdu_len = 0;
/* CRITICAL: Init global PDV ptr & len. Changed only if PDV found in msg.*/
pdv_data_ptr = NULL;
pdv_data_len = 0;
/* Call 'asn1r_decode_asn1 (aCtx,' to parse the message. */
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
asn1r_decode_asn1 (aCtx, acse_conn->ppdu_ptr,acse_conn->ppdu_len);
if (aCtx->asn1r_pdu_dec_err != NO_DECODE_ERR)
{
COPP_LOG_ERR1 ("COPP-ERROR: ASN.1 decode of S-Release.cnf failed, err=%d", aCtx->asn1r_pdu_dec_err);
abort_reason = 1; /* unrecognized-ppdu */
/* Don't send ARP PPDU. COSP already thinks we're released. */
/* Pass P-P-Abort.ind to COPP-user. */
u_copp_p_abort_ind (acse_conn, abort_reason);
}
else
{
COPP_LOG_DEC2 ("P-RELEASE.cnf+: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_DECC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_DECH (acse_conn->apdu_len, acse_conn->apdu_ptr);
if (acse_conn->cr)
{
acse_conn->cr = SD_FALSE;
acse_conn->rl = SD_FALSE; /* and stay in COPP_STATE_CONNECTED */
}
else
acse_conn->copp_state = COPP_STATE_IDLE;
u_copp_rel_cnf_pos (acse_conn);
}
}
/* See "coppdcp.c" for "u_cosp_con_ind" function. */
/************************************************************************/
/* u_cosp_rel_ind */
/*----------------------------------------------------------------------*/
/* This USER function is called by the SS-Provider to indicate that a */
/* remote node wishes to release a connection. */
/* */
/* Parameters: */
/* ACSE_CONN *acse_conn Pointer to connection info */
/* */
/* Return: */
/* ST_VOID */
/************************************************************************/
ST_VOID u_cosp_rel_ind (ACSE_CONN *acse_conn)
{
ST_INT8 abort_reason;
ST_INT8 event_id;
ASN1_DEC_CTXT localDecCtx; /* For readability, use "aCtx" to access this.*/
ASN1_DEC_CTXT *aCtx = &localDecCtx;
memset (aCtx, 0, sizeof (ASN1_DEC_CTXT)); /* CRITICAL: start clean */
if (acse_conn->copp_state != COPP_STATE_CONNECTED)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot process S-RELEASE.ind (Illegal state=%d)",
acse_conn->copp_state);
return;
}
/* Set release collision flags. */
if (acse_conn->rl)
acse_conn->cr = SD_TRUE;
acse_conn->rl = SD_TRUE;
aCtx->asn1r_decode_method = ASN1_TAG_METHOD; /* Use asn1_tag method for decoding. */
aCtx->asn1r_decode_done_fun = asn1r_done_err; /* done function = error fun */
aCtx->asn1r_err_fun = NULL; /* set up error detected fun */
/* Clean out old stuff from structure. */
decode_acse_conn = acse_conn; /* Save in global so asn1r_decode_asn1 (aCtx, */
/* can fill it in. */
/* Set the PCI to be used during P-User-Data decode. */
expected_pdv_pci = decode_acse_conn->pciacse;
p_user_data_is_outer = SD_TRUE; /* P-User-data IS outermost constr. */
/* CRITICAL: Init APDU ptr & len. Changed only if APDU found in msg. */
acse_conn->apdu_ptr = NULL;
acse_conn->apdu_len = 0;
/* CRITICAL: Init global PDV ptr & len. Changed only if PDV found in msg.*/
pdv_data_ptr = NULL;
pdv_data_len = 0;
/* Call 'asn1r_decode_asn1 (aCtx,' to parse the message. */
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
asn1r_decode_asn1 (aCtx, acse_conn->ppdu_ptr,acse_conn->ppdu_len);
if (aCtx->asn1r_pdu_dec_err != NO_DECODE_ERR)
{
COPP_LOG_ERR1 ("COPP-ERROR: ASN.1 decode of S-Release.ind failed, err=%d", aCtx->asn1r_pdu_dec_err);
acse_conn->copp_state = COPP_STATE_IDLE;
abort_reason = 1; /* unrecognized-ppdu */
event_id = 14; /* s-release-indication */
/* Encode and send ARP PPDU. */
copp_p_abort_req (acse_conn, abort_reason, event_id);
/* Pass P-P-Abort.ind to COPP-user. */
u_copp_p_abort_ind (acse_conn, abort_reason);
}
else
{
COPP_LOG_DEC2 ("P-RELEASE.ind: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_DECC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_DECH (acse_conn->apdu_len, acse_conn->apdu_ptr);
u_copp_rel_ind (acse_conn);
}
}
/************************************************************************/
/* u_cosp_p_abort_ind */
/*----------------------------------------------------------------------*/
/* This USER function is called by the SS-Provider to indicate that a */
/* connection has been aborted by SS-provider (local or remote). */
/* */
/* Parameters: */
/* ACSE_CONN *acse_con Pointer to connection info */
/* ST_INT reason see def reasons COSP_P_AB_IND_... above */
/* */
/* Return: */
/* ST_VOID */
/************************************************************************/
ST_VOID u_cosp_p_abort_ind (ACSE_CONN *acse_conn, ST_INT reason)
{
if (acse_conn->copp_state == COPP_STATE_IDLE)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot process S-P-ABORT.ind (Illegal state=%d)",
acse_conn->copp_state);
return;
}
COPP_LOG_DEC3 ("P-P-ABORT.ind: acse_conn_id =0x%08X user_conn_id =%4ld reason =%d",
acse_conn, acse_conn->user_conn_id, reason + 0x100);
acse_conn->copp_state = COPP_STATE_IDLE;
u_copp_p_abort_ind (acse_conn, reason + 0x100);
}
/************************************************************************/
/* u_cosp_data_ind */
/*----------------------------------------------------------------------*/
/* This USER function is called by the SS-Provider to indicate that a */
/* data SPDU has been received. */
/* */
/* Parameters: */
/* ACSE_CONN *acse_conn Pointer to connection info */
/* */
/* Return: */
/* ST_VOID */
/************************************************************************/
ST_VOID u_cosp_data_ind (ACSE_CONN *acse_conn)
{
ST_INT8 abort_reason;
ST_INT8 event_id;
ASN1_DEC_CTXT localDecCtx; /* For readability, use "aCtx" to access this.*/
ASN1_DEC_CTXT *aCtx = &localDecCtx;
memset (aCtx, 0, sizeof (ASN1_DEC_CTXT)); /* CRITICAL: start clean */
if (acse_conn->copp_state != COPP_STATE_CONNECTED)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot process S-DATA.ind (Illegal state=%d)",
acse_conn->copp_state);
return;
}
aCtx->asn1r_decode_method = ASN1_TAG_METHOD; /* Use asn1_tag method for decoding. */
aCtx->asn1r_decode_done_fun = asn1r_done_err; /* done function = error fun */
aCtx->asn1r_err_fun = NULL; /* set up error detected fun */
/* Clean out old stuff from structure. */
decode_acse_conn = acse_conn; /* Save in global so asn1r_decode_asn1 (aCtx, */
/* can fill it in. */
/* Set the PCI to be used during P-User-Data decode. */
expected_pdv_pci = decode_acse_conn->pcimms;
p_user_data_is_outer = SD_TRUE; /* P-User-data IS outermost constr. */
/* CRITICAL: Init APDU ptr & len. Changed only if APDU found in msg. */
acse_conn->apdu_ptr = NULL;
acse_conn->apdu_len = 0;
/* CRITICAL: Init global PDV ptr & len. Changed only if PDV found in msg.*/
pdv_data_ptr = NULL;
pdv_data_len = 0;
/* Call 'asn1r_decode_asn1 (aCtx,' to parse the message. */
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
asn1r_decode_asn1 (aCtx, acse_conn->ppdu_ptr,acse_conn->ppdu_len);
if (aCtx->asn1r_pdu_dec_err != NO_DECODE_ERR)
{
COPP_LOG_ERR1 ("COPP-ERROR: ASN.1 decode of S-Data.ind failed, err=%d", aCtx->asn1r_pdu_dec_err);
abort_reason = 1; /* unrecognized-ppdu */
event_id = -1; /* Unlisted */
/* Encode and send ARP PPDU. */
copp_p_abort_req (acse_conn, abort_reason, event_id);
/* Pass P-P-Abort.ind to COPP-user. */
u_copp_p_abort_ind (acse_conn, abort_reason);
}
else
{
COPP_LOG_DEC2 ("P-DATA.ind: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_DECC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_DECH (acse_conn->apdu_len, acse_conn->apdu_ptr);
u_copp_data_ind (acse_conn);
}
}
/*======================================================*/
/* ASN.1 DECODE FUNCTIONS FOR P-USER-DATA */
/* */
/* Used for CP, CPA, CPR, ARU, DT, or REL decode. */
/*======================================================*/
/************************************************************************/
/* START_p_user_data */
/************************************************************************/
ST_VOID START_p_user_data (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, UNI|CONSTR,SEQ_CODE,START_pdv_list);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_p_user_data;
}
/************************************************************************/
/* START_pdv_list */
/* ACSE also uses this function to decode "EXTERNAL". Although defined */
/* independently, it's encoding is same as "PDV-list". */
/************************************************************************/
ST_VOID START_pdv_list (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, UNI,OBJ_ID_CODE,decode_pdv_tsn);
ASN1R_TAG_ADD (aCtx, UNI,INT_CODE,decode_pdv_pci);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_pdv_list;
}
/************************************************************************/
/* decode_pdv_tsn */
/************************************************************************/
static ST_VOID decode_pdv_tsn (ASN1_DEC_CTXT *aCtx)
{
MMS_OBJ_ID tsn;
if (asn1r_get_objid (aCtx, tsn.comps,&tsn.num_comps))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
if (asn1_objidcmp (&tsn, &asn1_obj_id) != 0)
{ /* TSN better be ASN1 */
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BITSTR);
return;
}
ASN1R_TAG_ADD (aCtx, UNI,INT_CODE,decode_pdv_pci);
}
/************************************************************************/
/* decode_pdv_pci */
/************************************************************************/
static ST_VOID decode_pdv_pci (ASN1_DEC_CTXT *aCtx)
{
ST_INT8 pci;
if (asn1r_get_i8 (aCtx, &pci))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
if (pci != expected_pdv_pci)
{ /* Not the pci we're expecting. */
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BITSTR);
return;
}
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,0,START_pdv); /* Must be single-ASN1-type */
/* Octet-aligned doesn't appear to be legal, but some stacks (ONE?) */
/* may use it. To be friendly, let's accept it. */
ASN1R_TAG_ADD (aCtx, CTX,1,START_pdv); /* Allow octet-aligned */
}
/************************************************************************/
/* START_pdv */
/************************************************************************/
static ST_VOID START_pdv (ASN1_DEC_CTXT *aCtx)
{
/* Should now point to PDV data. Save until decode done. */
pdv_data_ptr = aCtx->asn1r_field_ptr;
/* If this is indefinite length encoding, use "asn1r_parse_next (aCtx,". */
/* If "normal" encoding, use "asn1_skip_elmnt" (faster). */
if (aCtx->asn1r_indef_flag)
{ /* indefinite length encoding */
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_pdv;
asn1r_parse_next (aCtx, parse_next_done);
}
else
{ /* "normal" encoding */
pdv_data_len = aCtx->asn1r_elmnt_len;
asn1_skip_elmnt (aCtx); /* Done decoding PPDU. Let ACSE decode rest. */
}
}
/************************************************************************/
/* parse_next_done */
/* Only used for indefinite length encoding. */
/************************************************************************/
static ST_VOID parse_next_done (ASN1_DEC_CTXT *aCtx)
{ /* called when "asn1r_parse_next (aCtx," is done */
}
/************************************************************************/
/* END_pdv */
/* Only used for indefinite length encoding. */
/************************************************************************/
static ST_VOID END_pdv (ASN1_DEC_CTXT *aCtx)
{
pdv_data_len = aCtx->asn1r_field_ptr - pdv_data_ptr - 2; /* -2 strips 00 00*/
}
/************************************************************************/
/* END_pdv_list */
/************************************************************************/
static ST_VOID END_pdv_list (ASN1_DEC_CTXT *aCtx)
{
}
/************************************************************************/
/* END_p_user_data */
/************************************************************************/
static ST_VOID END_p_user_data (ASN1_DEC_CTXT *aCtx)
{
decode_acse_conn->apdu_ptr = pdv_data_ptr;
decode_acse_conn->apdu_len = pdv_data_len;
if (p_user_data_is_outer) /* Is P-User-data outermost constr? */
aCtx->asn1r_decode_done_fun = NULL; /* done decoding */
}

660
mmslib/ositcps/copp_enc.c Normal file
View File

@@ -0,0 +1,660 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1997-2002, All Rights Reserved */
/* */
/* PROPRIETARY AND CONFIDENTIAL */
/* */
/* MODULE NAME : copp_enc.c */
/* PRODUCT(S) : MOSI Stack (over TP4) */
/* */
/* MODULE DESCRIPTION : */
/* This file implements binding and encoding functions */
/* of the COPP protocol. */
/* */
/* For information see the: */
/* ISO 8822 "Information processing systems - Open Systems */
/* Interconnection - Connection oriented presentation service */
/* definition. */
/* ISO 8823 "Information processing systems - Open Systems */
/* Interconnection - Connection oriented presentation protocol */
/* specification. */
/* */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* copp_bind */
/* copp_unbind */
/* */
/* copp_con_req */
/* copp_con_rsp_pos */
/* copp_con_rsp_neg */
/* */
/* copp_rel_req */
/* copp_rel_rsp_pos */
/* */
/* copp_u_abort_req */
/* */
/* copp_data_req */
/* */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 04/28/08 GLB 07 Removed CALLED_ONLY and CALLING_ONLY */
/* 01/02/02 JRB 06 Converted to use ASN1R (re-entrant ASN1) */
/* 06/17/98 JRB 05 Allow second call to copp_bind if PSEL same. */
/* Use new error codes. */
/* 02/20/98 JRB 04 Cast wr_i8 arg. Chg abort_reason to ST_INT8. */
/* 12/22/97 JRB 03 Use ST_INT8. */
/* 05/27/97 JRB 7.00 MMSEASE 7.0 release. */
/* 03/19/97 JRB 02 Add "CALLING" support. General cleanup. */
/* 02/27/97 JRB 01 Created */
/************************************************************************/
#ifdef DEBUG_SISCO
static char *thisFileName = __FILE__;
#endif
#include "glbtypes.h"
#include "sysincs.h"
#include "mem_chk.h"
#include "asn1defs.h"
#include "acse2.h"
#include "copp.h"
#include "cosp_usr.h"
ST_BOOLEAN copp_bind_called; /* flag to tell if copp_bind was called */
ST_UCHAR only_loc_psel [1+MAX_PSEL_LEN]; /* Local len & PSEL */
/************************************************************************/
/* copp_bind */
/************************************************************************/
ST_RET copp_bind (ST_LONG user_bind_id, PRES_ADDR *pres_addr,
ST_INT sharable, ST_INT max_conns)
{
ST_INT ret = SD_SUCCESS;
COPP_LOG_ENC1 ("P-BIND.req: copp_user_bind_id =0x%08X", user_bind_id);
if (!copp_bind_called)
{
/* Make sure Local PSEL len is legal before copying. */
if (pres_addr->psel_len <= sizeof (only_loc_psel)-1)
{
/* Save Local PSEL (only do memcpy if len != 0). */
if ((only_loc_psel [0] = (ST_UCHAR) pres_addr->psel_len) != 0)
memcpy (&only_loc_psel [1], pres_addr->psel, pres_addr->psel_len);
}
else
{
COPP_LOG_ERR1 ("COPP-ERROR: P-BIND.req: Invalid length=%d of PSEL.",
pres_addr->psel_len);
ret = COPP_ERR_INV_PSEL; /* invalid local PSEL */
}
}
else
{ /* Second Bind. Only allow it if the PSEL is the same. */
if (only_loc_psel [0] != (ST_UCHAR) pres_addr->psel_len ||
(pres_addr->psel_len != 0 &&
memcmp (&only_loc_psel [1], pres_addr->psel, pres_addr->psel_len)))
{
COPP_LOG_ERR0 ("COPP-ERROR: Cannot BIND to different PSEL");
ret = COPP_ERR_INV_PSEL; /* invalid local PSEL */
}
}
/* Call cosp_bind. */
if (ret == SD_SUCCESS)
ret = cosp_bind (user_bind_id, pres_addr, sharable, max_conns);
/* If successful, set called flag. Otherwise, treat next bind like first.*/
if (ret == SD_SUCCESS)
copp_bind_called = SD_TRUE;
return (ret);
}
/************************************************************************/
/* copp_unbind */
/************************************************************************/
ST_RET copp_unbind (ST_LONG copp_bind_id)
{
COPP_LOG_ENC1 ("P-UNBIND.req: copp_bind_id =%9ld", copp_bind_id);
return (cosp_unbind (copp_bind_id));
}
/************************************************************************/
/* copp_con_req */
/************************************************************************/
ST_RET copp_con_req (ST_LONG copp_bind_id, ACSE_CONN *acse_conn, PRES_ADDR *rem_addr)
{
/* WARNING: this hardcoding assumes that ACSE pci always equals 1 */
/* and MMS pci always equals 3 when we send P-CONNECT.req. */
/* These must be set in a_associate_req before any encoding. */
static ST_UCHAR hc_definition_list [] =
{
0x30, 0x0f, 0x02, 0x01, 0x01, 0x06, 0x04, 0x52, 0x01, 0x00, 0x01,
0x30, 0x04, 0x06, 0x02, 0x51, 0x01,
0x30, 0x10, 0x02, 0x01, 0x03, 0x06, 0x05, 0x28, 0xca, 0x22, 0x02, 0x01,
0x30, 0x04, 0x06, 0x02, 0x51, 0x01
};
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
/* DEBUG: should we check the copp_bind_id????? */
COPP_LOG_ENC2 ("P-CONNECT.req: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_ENCC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_ENCH (acse_conn->apdu_len, acse_conn->apdu_ptr);
if (acse_conn->copp_state != COPP_STATE_IDLE)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot send P-CONNECT.req (Illegal state=%d)",
acse_conn->copp_state);
return (COPP_ERR_INV_STATE);
}
acse_conn->cr = SD_FALSE;
acse_conn->rl = SD_FALSE;
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start CP SET */
asn1r_strt_constr (aCtx); /* start enclosed SEQUENCE */
asn1r_strt_constr (aCtx); /* start P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_strt_constr (aCtx); /* start single-ASN1-type */
/* Fake out ACSE encoding. Already encoded into cosp_buf. */
aCtx->asn1r_field_ptr -= acse_conn->apdu_len;
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish single-ASN1-type */
asn1r_wr_i8 (aCtx, acse_conn->pciacse); /* PCI for ACSE */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
/* Do not encode Transfer syntax name. We know it is ASN1. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 1,APP,DEF); /* finish P-User-data (fully-encoded) */
/* Hardcode Presentation-requirements (kernel only). */
*aCtx->asn1r_field_ptr-- = 0x00;
*aCtx->asn1r_field_ptr-- = 0x06;
*aCtx->asn1r_field_ptr-- = 0x02;
*aCtx->asn1r_field_ptr-- = 0x88;
/* 2 P-contexts: ACSE and MMS, and they both have a TSN of ASN1, */
/* so we can hardcode this. */
/* WARNING: this hardcoding assumes that ACSE pci always equals 1 */
/* and MMS pci always equals 3 when we send P-CONNECT.req. */
/* These must be set in a_associate_req before any encoding. */
asn1r_strt_constr (aCtx); /* start P-context-def-list. */
aCtx->asn1r_field_ptr -= sizeof (hc_definition_list);
memcpy (aCtx->asn1r_field_ptr + 1, hc_definition_list, sizeof (hc_definition_list));
asn1r_fin_constr (aCtx, 4,CTX,DEF); /* finish P-context-def-list. */
/* Encode Called-p-selector. */
aCtx->asn1r_field_ptr -= rem_addr->psel_len;
memcpy (aCtx->asn1r_field_ptr + 1, rem_addr->psel, rem_addr->psel_len);
*aCtx->asn1r_field_ptr-- = rem_addr->psel_len;
*aCtx->asn1r_field_ptr-- = 0x82; /* Tag for Called-p-selector */
/* Encode Calling-p-selector. */
aCtx->asn1r_field_ptr -= (only_loc_psel[0]+1);
memcpy (aCtx->asn1r_field_ptr + 1, only_loc_psel, only_loc_psel[0]+1);
*aCtx->asn1r_field_ptr-- = 0x81; /* Tag for Calling-p-selector */
/* Protocol-version defaults to version-1, so don't encode. */
asn1r_fin_constr (aCtx, 2,CTX,DEF); /* finish enclosed SEQUENCE */
/* Hard-code Mode. Always "normal-mode". */
*aCtx->asn1r_field_ptr-- = 0x01;
*aCtx->asn1r_field_ptr-- = 0x01;
*aCtx->asn1r_field_ptr-- = 0x80;
*aCtx->asn1r_field_ptr-- = 0x03;
*aCtx->asn1r_field_ptr-- = 0xA0;
asn1r_fin_constr (aCtx, SET_CODE,UNI,DEF); /* finish CPA SET */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
acse_conn->copp_state = COPP_STATE_AWAIT_CPA;
/* Pass to COSP. */
return (cosp_con_req (copp_bind_id, rem_addr, acse_conn));
}
/************************************************************************/
/* copp_rel_req */
/************************************************************************/
ST_RET copp_rel_req (ACSE_CONN *acse_conn)
{
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
COPP_LOG_ENC2 ("P-RELEASE.req: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_ENCC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_ENCH (acse_conn->apdu_len, acse_conn->apdu_ptr);
if (acse_conn->copp_state != COPP_STATE_CONNECTED)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot send P-RELEASE.req (Illegal state=%d)",
acse_conn->copp_state);
return (COPP_ERR_INV_STATE);
}
/* Set release collision flags. */
if (acse_conn->rl)
acse_conn->cr = SD_TRUE;
acse_conn->rl = SD_TRUE;
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_strt_constr (aCtx); /* start single-ASN1-type */
/* Fake out ACSE encoding. Already encoded into cosp_buf. */
aCtx->asn1r_field_ptr -= acse_conn->apdu_len;
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish single-ASN1-type */
asn1r_wr_i8 (aCtx, acse_conn->pciacse); /* PCI for ACSE */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
/* Do not encode Transfer syntax name. We know it is ASN1. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 1,APP,DEF); /* finish P-User-data (fully-encoded) */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
return (cosp_rel_req (acse_conn));
}
/************************************************************************/
/* copp_con_rsp_pos */
/* Encode and send CPA PPDU. */
/************************************************************************/
ST_RET copp_con_rsp_pos (ACSE_CONN *acse_conn)
{
static ST_UCHAR hc_result_list [] =
{
0x30, 0x07, 0x80, 0x01, 0x00, 0x81, 0x02, 0x51, 0x01,
0x30, 0x07, 0x80, 0x01, 0x00, 0x81, 0x02, 0x51, 0x01
};
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
COPP_LOG_ENC2 ("P-CONNECT.rsp+: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_ENCC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_ENCH (acse_conn->apdu_len, acse_conn->apdu_ptr);
if (acse_conn->copp_state != COPP_STATE_AWAIT_CON_RSP)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot send P-CONNECT.rsp+ (Illegal state=%d)",
acse_conn->copp_state);
return (COPP_ERR_INV_STATE);
}
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start CPA SET */
asn1r_strt_constr (aCtx); /* start enclosed SEQUENCE */
asn1r_strt_constr (aCtx); /* start P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_strt_constr (aCtx); /* start single-ASN1-type */
/* Fake out ACSE encoding. Already encoded into cosp_buf. */
aCtx->asn1r_field_ptr -= acse_conn->apdu_len;
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish single-ASN1-type */
asn1r_wr_i8 (aCtx, acse_conn->pciacse); /* PCI for ACSE */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
/* Do not encode Transfer syntax name. We know it is ASN1. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 1,APP,DEF); /* finish P-User-data (fully-encoded) */
/* Hardcode Presentation-requirements (kernel only). */
*aCtx->asn1r_field_ptr-- = 0x00;
*aCtx->asn1r_field_ptr-- = 0x06;
*aCtx->asn1r_field_ptr-- = 0x02;
*aCtx->asn1r_field_ptr-- = 0x88;
/* Hey, I like this. We only accept connections if there are */
/* 2 P-contexts: ACSE and MMS, and they both have a TSN of ASN1, */
/* so we can hardcode this. */
asn1r_strt_constr (aCtx); /* start P-context-def-result-list. */
aCtx->asn1r_field_ptr -= sizeof (hc_result_list);
memcpy (aCtx->asn1r_field_ptr + 1, hc_result_list, sizeof (hc_result_list));
asn1r_fin_constr (aCtx, 5,CTX,DEF); /* finish P-context-def-result-list. */
/* Encode Responding-p-selector. */
aCtx->asn1r_field_ptr -= (only_loc_psel[0]+1);
memcpy (aCtx->asn1r_field_ptr + 1, only_loc_psel, only_loc_psel[0]+1);
*aCtx->asn1r_field_ptr-- = 0x83; /* Tag for Responding-p-selector */
/* Protocol-version defaults to version-1, so don't encode. */
asn1r_fin_constr (aCtx, 2,CTX,DEF); /* finish enclosed SEQUENCE */
/* Hard-code Mode. Always "normal-mode". */
*aCtx->asn1r_field_ptr-- = 0x01;
*aCtx->asn1r_field_ptr-- = 0x01;
*aCtx->asn1r_field_ptr-- = 0x80;
*aCtx->asn1r_field_ptr-- = 0x03;
*aCtx->asn1r_field_ptr-- = 0xA0;
asn1r_fin_constr (aCtx, SET_CODE,UNI,DEF); /* finish CPA SET */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
acse_conn->copp_state = COPP_STATE_CONNECTED;
/* Pass to COSP. */
return (cosp_con_rsp_pos (acse_conn));
}
/************************************************************************/
/* copp_con_rsp_neg */
/* Encode and send CPR PPDU. */
/* If "provider_reason" < 0, this is "user-reject", else this is */
/* "provider-reject" and the value of "provider_reason" will be */
/* encoded in the "Provider-reason" parameter of the PPDU. */
/************************************************************************/
ST_RET copp_con_rsp_neg (ACSE_CONN *acse_conn, ST_INT provider_reason)
{
ST_INT j;
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
COPP_LOG_ENC3 ("P-CONNECT.rsp-: acse_conn_id =0x%08X user_conn_id =%4ld reason =%d",
acse_conn, acse_conn->user_conn_id, provider_reason);
if (provider_reason < 0)
{ /* user-reject: must have User-data */
COPP_LOG_ENCC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_ENCH (acse_conn->apdu_len, acse_conn->apdu_ptr);
}
if (provider_reason < 0 && acse_conn->copp_state != COPP_STATE_AWAIT_CON_RSP)
{ /* If from user, must be in "await P-CONrsp" state. */
COPP_LOG_ERR1 ("COPP-ERROR: Cannot send P-CONNECT.rsp- (Illegal state=%d)",
acse_conn->copp_state);
return (COPP_ERR_INV_STATE);
}
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start CPR SEQUENCE */
if (provider_reason < 0)
{ /* user-reject: encode P-User-data */
asn1r_strt_constr (aCtx); /* start P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_strt_constr (aCtx); /* start single-ASN1-type */
/* Fake out ACSE encoding. Already encoded into cosp_buf. */
aCtx->asn1r_field_ptr -= acse_conn->apdu_len;
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish single-ASN1-type */
asn1r_wr_i8 (aCtx, acse_conn->pciacse); /* PCI for ACSE */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
/* Do not encode Transfer syntax name. We know it is ASN1. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 1,APP,DEF); /* finish P-User-data (fully-encoded) */
} /* end "if (provider_reason < 0)" */
if (provider_reason >= 0)
{ /* provider-reject: encode Provider-reason */
asn1r_wr_i8 (aCtx, (ST_INT8) provider_reason); /* Provider-reason */
asn1r_fin_prim (aCtx, 10,CTX);
}
if (provider_reason == PROV_REASON_DEFAULT_CONTEXT)
{ /* Hardcode "Default-context-result = 2" (provider rejection) */
*aCtx->asn1r_field_ptr-- = 0x02;
*aCtx->asn1r_field_ptr-- = 0x01;
*aCtx->asn1r_field_ptr-- = 0x87;
}
/* If P-contexts proposed, just accept all of them. */
/* We're rejecting the connect anyway, so it doesn't matter. */
if (acse_conn->num_ctxt)
{
asn1r_strt_constr (aCtx); /* start P-context-def-result-list. */
for (j = 0; j < acse_conn->num_ctxt; j++)
{
asn1r_strt_constr (aCtx); /* start SEQUENCE */
/* DEBUG: would be better to encode same TSN they sent. */
*aCtx->asn1r_field_ptr-- = 0x01; /* Hardcode Transfer-syntax-name = ASN.1*/
*aCtx->asn1r_field_ptr-- = 0x51;
*aCtx->asn1r_field_ptr-- = 0x02;
*aCtx->asn1r_field_ptr-- = 0x81;
*aCtx->asn1r_field_ptr-- = 0x00; /* Hardcode "Result=0" (acceptance) */
*aCtx->asn1r_field_ptr-- = 0x01;
*aCtx->asn1r_field_ptr-- = 0x80;
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
}
asn1r_fin_constr (aCtx, 5,CTX,DEF); /* finish P-context-def-result-list. */
}
/* Encode Responding-p-selector. */
aCtx->asn1r_field_ptr -= (only_loc_psel[0]+1);
memcpy (aCtx->asn1r_field_ptr + 1, only_loc_psel, only_loc_psel[0]+1);
*aCtx->asn1r_field_ptr-- = 0x83; /* Tag for Responding-p-selector */
/* Protocol-version defaults to version-1, so don't encode. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish CPR SEQUENCE */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
acse_conn->copp_state = COPP_STATE_IDLE;
/* Pass to COSP. */
return (cosp_con_rsp_neg (acse_conn, COSP_CON_RSP_U_IN_UDATA));
}
/************************************************************************/
/* copp_rel_rsp_pos */
/************************************************************************/
ST_RET copp_rel_rsp_pos (ACSE_CONN *acse_conn)
{
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
COPP_LOG_ENC2 ("P-RELEASE.rsp+: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_ENCC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_ENCH (acse_conn->apdu_len, acse_conn->apdu_ptr);
if (acse_conn->copp_state != COPP_STATE_CONNECTED)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot send P-RELEASE.rsp+ (Illegal state=%d)",
acse_conn->copp_state);
return (COPP_ERR_INV_STATE);
}
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_strt_constr (aCtx); /* start single-ASN1-type */
/* Fake out ACSE encoding. Already encoded into cosp_buf. */
aCtx->asn1r_field_ptr -= acse_conn->apdu_len;
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish single-ASN1-type */
asn1r_wr_i8 (aCtx, acse_conn->pciacse); /* PCI for ACSE */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
/* Do not encode Transfer syntax name. We know it is ASN1. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 1,APP,DEF); /* finish P-User-data (fully-encoded) */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
if (acse_conn->cr)
{
acse_conn->cr = SD_FALSE;
acse_conn->rl = SD_FALSE; /* and stay in COPP_STATE_CONNECTED */
}
else
acse_conn->copp_state = COPP_STATE_IDLE;
return (cosp_rel_rsp_pos (acse_conn));
}
/************************************************************************/
/* copp_u_abort_req */
/************************************************************************/
ST_RET copp_u_abort_req (ACSE_CONN *acse_conn)
{
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
COPP_LOG_ENC2 ("P-U-ABORT.req: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_ENCC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_ENCH (acse_conn->apdu_len, acse_conn->apdu_ptr);
if (acse_conn->copp_state == COPP_STATE_IDLE)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot send P-U-ABORT.req (Illegal state=%d)",
acse_conn->copp_state);
return (COPP_ERR_INV_STATE);
}
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start ARU */
asn1r_strt_constr (aCtx); /* start P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_strt_constr (aCtx); /* start single-ASN1-type */
/* Fake out ACSE encoding. Already encoded into cosp_buf. */
aCtx->asn1r_field_ptr -= acse_conn->apdu_len;
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish single-ASN1-type */
asn1r_wr_i8 (aCtx, acse_conn->pciacse); /* PCI for ACSE */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
/* Do not encode Transfer syntax name. We know it is ASN1. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 1,APP,DEF); /* finish P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start P-context-identifier-list */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_wr_objid (aCtx, asn1_obj_id.comps,
asn1_obj_id.num_comps); /* Transfer syntax name (i.e. ASN1)*/
asn1r_fin_prim (aCtx, OBJ_ID_CODE,UNI);
asn1r_wr_i8 (aCtx, acse_conn->pciacse); /* PCI for ACSE */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish P-context-identifier-list */
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish ARU */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
acse_conn->copp_state = COPP_STATE_IDLE;
return (cosp_u_abort_req (acse_conn));
}
/************************************************************************/
/* copp_data_req */
/************************************************************************/
ST_RET copp_data_req (ACSE_CONN *acse_conn)
{
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
COPP_LOG_ENC2 ("P-DATA.req: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_ENCC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_ENCH (acse_conn->apdu_len, acse_conn->apdu_ptr);
if (acse_conn->copp_state != COPP_STATE_CONNECTED)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot send P-DATA.req (Illegal state=%d)",
acse_conn->copp_state);
return (COPP_ERR_INV_STATE);
}
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_strt_constr (aCtx); /* start single-ASN1-type */
/* Fake out ACSE encoding. Already encoded into cosp_buf. */
aCtx->asn1r_field_ptr -= acse_conn->apdu_len;
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish single-ASN1-type */
asn1r_wr_i8 (aCtx, acse_conn->pcimms); /* PCI for MMS */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
/* Do not encode Transfer syntax name. We know it is ASN1. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 1,APP,DEF); /* finish P-User-data (fully-encoded) */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
return (cosp_data_req (acse_conn));
}
/************************************************************************/
/* copp_p_abort_req */
/* Encode and send ARP PPDU (i.e. P-P-Abort.req). */
/* This function only called by the COPP-provider (not by COPP-user). */
/* Parameters: */
/* ACSE_CONN *acse_conn Pointer to connection info */
/* ST_INT8 abort_reason Abort-reason to send in ARP */
/* ST_INT8 event_id Event-identifier to send in ARP */
/* If -1, don't send it. */
/************************************************************************/
ST_VOID copp_p_abort_req (ACSE_CONN *acse_conn, ST_INT8 abort_reason, ST_INT8 event_id)
{
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
COPP_LOG_ENC4 ("P-P-ABORT.req: acse_conn_id =0x%08X user_conn_id =%4ld reason =%d event_id =%d",
acse_conn, acse_conn->user_conn_id, (ST_INT) abort_reason, (ST_INT) event_id);
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start ARP SEQUENCE */
if (event_id != -1)
{
asn1r_wr_i8 (aCtx, event_id); /* Event-identifier */
asn1r_fin_prim (aCtx, 1,CTX);
}
asn1r_wr_i8 (aCtx, abort_reason); /* Abort-reason */
asn1r_fin_prim (aCtx, 0,CTX);
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish ARP SEQUENCE */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
/* Pass ARP to COSP. */
cosp_u_abort_req (acse_conn);
}

280
mmslib/ositcps/coppdaru.c Normal file
View File

@@ -0,0 +1,280 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1997-2002, All Rights Reserved */
/* */
/* PROPRIETARY AND CONFIDENTIAL */
/* */
/* MODULE NAME : coppdaru.c */
/* PRODUCT(S) : MOSI Stack (over TP4) */
/* */
/* MODULE DESCRIPTION : */
/* This file implements decoding of U-ABORT indication. */
/* */
/* For information see the: */
/* ISO 8822 "Information processing systems - Open Systems */
/* Interconnection - Connection oriented presentation service */
/* definition. */
/* ISO 8823 "Information processing systems - Open Systems */
/* Interconnection - Connection oriented presentation protocol */
/* specification. */
/* */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* u_cosp_u_abort_ind */
/* */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 02/26/09 JRB 07 Fix to handle PDV len=0 or User-data len=0. */
/* 01/30/06 GLB 06 Integrated porting changes for VMS */
/* 01/02/02 JRB 05 Converted to use ASN1R (re-entrant ASN1) */
/* 03/18/98 JRB 04 Use defines (not variables) for ASN1 errors. */
/* 12/22/97 JRB 03 Use ST_INT8. */
/* 05/27/97 JRB 7.00 MMSEASE 7.0 release. */
/* 03/19/97 JRB 02 General cleanup. */
/* 02/27/97 JRB 01 Created */
/************************************************************************/
#ifdef DEBUG_SISCO
static char *thisFileName = __FILE__;
#endif
#include "glbtypes.h"
#include "sysincs.h"
#include "mem_chk.h"
#include "asn1defs.h"
#include "acse2.h"
#include "copp.h"
#include "cosp_usr.h"
/************************************************************************/
/* Global Variables */
/************************************************************************/
/* Structure for tracking ARP/ARU decode. */
typedef struct
{
#define COPP_U_ABORT 0 /* Use to set "abort_type" */
#define COPP_P_ABORT 1 /* Use to set "abort_type" */
ST_INT8 abort_type;
ST_INT8 abort_reason;
ST_INT8 event_id;
} DECODE_ARX;
static DECODE_ARX decode_arx;
static ST_VOID START_aru (ASN1_DEC_CTXT *aCtx);
static ST_VOID START_pc_identifier_list (ASN1_DEC_CTXT *aCtx);
static ST_VOID START_sequence (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_pci (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_tsn (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_sequence (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_pc_identifier_list (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_aru (ASN1_DEC_CTXT *aCtx);
static ST_VOID START_arp (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_abort_reason (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_event_id (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_arp (ASN1_DEC_CTXT *aCtx);
/************************************************************************/
/* u_cosp_u_abort_ind */
/*----------------------------------------------------------------------*/
/* This USER function is called by the SS-Provider to indicate that a */
/* connection has been aborted by remote SS-user. */
/* */
/* Parameters: */
/* ACSE_CONN *acse_conn Pointer to connection info */
/* */
/* Return: */
/* ST_VOID */
/************************************************************************/
ST_VOID u_cosp_u_abort_ind (ACSE_CONN *acse_conn)
{
ASN1_DEC_CTXT localDecCtx; /* For readability, use "aCtx" to access this.*/
ASN1_DEC_CTXT *aCtx = &localDecCtx;
memset (aCtx, 0, sizeof (ASN1_DEC_CTXT)); /* CRITICAL: start clean */
if (acse_conn->copp_state == COPP_STATE_IDLE)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot process S-U-ABORT.ind (Illegal state=%d)",
acse_conn->copp_state);
return;
}
aCtx->asn1r_decode_method = ASN1_TAG_METHOD; /* Use asn1_tag method for decoding. */
aCtx->asn1r_decode_done_fun = asn1r_done_err; /* done function = error fun */
aCtx->asn1r_err_fun = NULL; /* set up error detected fun */
decode_acse_conn = acse_conn; /* Save in global so asn1r_decode_asn1 (aCtx, */
/* can fill it in. */
/* Set the PCI to be used during P-User-Data decode. */
expected_pdv_pci = decode_acse_conn->pciacse;
p_user_data_is_outer = SD_FALSE; /* P-User-data IS NOT outermost constr. */
/* CRITICAL: Init APDU ptr & len. Changed only if APDU found in msg. */
acse_conn->apdu_ptr = NULL;
acse_conn->apdu_len = 0;
/* CRITICAL: Init global PDV ptr & len. Changed only if PDV found in msg.*/
pdv_data_ptr = NULL;
pdv_data_len = 0;
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,0,START_aru);
ASN1R_TAG_ADD (aCtx, UNI|CONSTR,SEQ_CODE,START_arp);
asn1r_decode_asn1 (aCtx, acse_conn->ppdu_ptr,acse_conn->ppdu_len);
if (aCtx->asn1r_pdu_dec_err != NO_DECODE_ERR)
{ /* DECODE FAILED */
/* Couldn't decode ARP or ARU, so pass up as P-P-Abort.ind with */
/* reason = unrecognized-ppdu */
decode_arx.abort_reason = 1; /* unrecognized-ppdu. */
COPP_LOG_ERR1 ("COPP-ERROR: ASN.1 decode of S-U-Abort.ind failed, err=%d", aCtx->asn1r_pdu_dec_err);
COPP_LOG_DEC3 ("P-P-ABORT.ind: acse_conn_id =0x%08X user_conn_id =%4ld reason =%d",
acse_conn, acse_conn->user_conn_id, decode_arx.abort_reason);
u_copp_p_abort_ind (acse_conn, decode_arx.abort_reason);
}
else
{ /* DECODE SUCCESSFUL */
if (decode_arx.abort_type == COPP_U_ABORT)
{ /* This is P-U-Abort */
COPP_LOG_DEC2 ("P-U-ABORT.ind: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_DECC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_DECH (acse_conn->apdu_len, acse_conn->apdu_ptr);
u_copp_u_abort_ind (acse_conn);
}
else
{ /* This is P-P-Abort */
COPP_LOG_DEC4 ("P-P-ABORT.ind: acse_conn_id =0x%08X user_conn_id =%4ld reason =%d, event_id =%d",
acse_conn, acse_conn->user_conn_id, decode_arx.abort_reason, decode_arx.event_id);
u_copp_p_abort_ind (acse_conn, decode_arx.abort_reason);
}
}
acse_conn->copp_state = COPP_STATE_IDLE; /* No matter what. */
}
/************************************************************************/
/* START_aru */
/************************************************************************/
static ST_VOID START_aru (ASN1_DEC_CTXT *aCtx)
{
decode_arx.abort_type = COPP_U_ABORT; /* Set type to U-Abort */
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,0,START_pc_identifier_list);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_aru;
}
/************************************************************************/
/* START_pc_identifier_list */
/************************************************************************/
static ST_VOID START_pc_identifier_list (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, UNI|CONSTR,SEQ_CODE,START_sequence);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_pc_identifier_list;
}
/************************************************************************/
/* START_sequence */
/************************************************************************/
static ST_VOID START_sequence (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, UNI,INT_CODE,decode_pci);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_sequence;
}
/************************************************************************/
/* decode_pci */
/************************************************************************/
static ST_VOID decode_pci (ASN1_DEC_CTXT *aCtx)
{
ST_INT8 pci;
if (asn1r_get_i8 (aCtx, &pci))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
ASN1R_TAG_ADD (aCtx, UNI,OBJ_ID_CODE,decode_tsn);
}
/************************************************************************/
/* decode_tsn */
/************************************************************************/
static ST_VOID decode_tsn (ASN1_DEC_CTXT *aCtx)
{
MMS_OBJ_ID tsn;
if (asn1r_get_objid (aCtx, tsn.comps,&tsn.num_comps))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
if (asn1_objidcmp (&tsn, (MMS_OBJ_ID *) &asn1_obj_id) != 0)
{ /* TSN better be ASN1 */
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BITSTR);
return;
}
}
/************************************************************************/
/* END_sequence */
/************************************************************************/
static ST_VOID END_sequence (ASN1_DEC_CTXT *aCtx)
{
/* May be another context. */
ASN1R_TAG_ADD (aCtx, UNI|CONSTR,SEQ_CODE,START_sequence);
}
/************************************************************************/
/* END_pc_identifier_list */
/************************************************************************/
static ST_VOID END_pc_identifier_list (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
}
/************************************************************************/
/* END_aru */
/************************************************************************/
static ST_VOID END_aru (ASN1_DEC_CTXT *aCtx)
{
aCtx->asn1r_decode_done_fun = NULL; /* done decoding */
}
/************************************************************************/
/* START_arp */
/************************************************************************/
static ST_VOID START_arp (ASN1_DEC_CTXT *aCtx)
{
decode_arx.abort_type = COPP_P_ABORT; /* Set type to P-Abort */
ASN1R_TAG_ADD (aCtx, CTX,0,decode_abort_reason);
ASN1R_TAG_ADD (aCtx, CTX,1,decode_event_id);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_arp;
}
/************************************************************************/
/* decode_abort_reason */
/************************************************************************/
static ST_VOID decode_abort_reason (ASN1_DEC_CTXT *aCtx)
{
if (asn1r_get_i8 (aCtx, &decode_arx.abort_reason))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
ASN1R_TAG_ADD (aCtx, CTX,1,decode_event_id);
}
/************************************************************************/
/* decode_event_id */
/************************************************************************/
static ST_VOID decode_event_id (ASN1_DEC_CTXT *aCtx)
{
if (asn1r_get_i8 (aCtx, &decode_arx.event_id))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
}
/************************************************************************/
/* END_arp */
/************************************************************************/
static ST_VOID END_arp (ASN1_DEC_CTXT *aCtx)
{
aCtx->asn1r_decode_done_fun = NULL; /* done decoding */
}

767
mmslib/ositcps/coppdcp.c Normal file
View File

@@ -0,0 +1,767 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1997-2002, All Rights Reserved */
/* */
/* PROPRIETARY AND CONFIDENTIAL */
/* */
/* MODULE NAME : coppdcp.c */
/* PRODUCT(S) : MOSI Stack (over TP4) */
/* */
/* MODULE DESCRIPTION : */
/* This file implements decoding of CP and CPA PPDUs. */
/* */
/* For information see the: */
/* ISO 8822 "Information processing systems - Open Systems */
/* Interconnection - Connection oriented presentation service */
/* definition. */
/* ISO 8823 "Information processing systems - Open Systems */
/* Interconnection - Connection oriented presentation protocol */
/* specification. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* u_cosp_con_ind */
/* u_cosp_con_cnf_pos */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 02/26/09 JRB 17 Fix to handle PDV len=0 or User-data len=0. */
/* 10/23/08 JRB 16 Del unused variable. */
/* 10/08/08 JRB 15 Fix PSEL decode (didn't work if len > 127). */
/* 04/28/08 GLB 14 Removed CALLED_ONLY and CALLING_ONLY */
/* 01/30/06 GLB 13 Integrated porting changes for VMS */
/* 08/01/03 JRB 12 Elim compiler warning. */
/* 06/24/03 JRB 11 Init psels before decode to avoid crash */
/* when sender does not send psels. */
/* 03/31/03 JRB 10 asn1r_get_bitstr: add max_bits arg. */
/* 01/02/02 JRB 09 Converted to use ASN1R (re-entrant ASN1) */
/* 10/10/01 JRB 08 asn1_skip_elmnt doesn't work for indef len */
/* encoding. Use "parse_next" instead. */
/* 05/09/01 JRB 07 On P-CONNECT.ind, save PSELs in ACSE_CONN. */
/* 02/02/99 JRB 06 BUG FIX: Decode "prov_reas" in "Result-list" */
/* even if no TSN (see decode_result). */
/* 03/18/98 JRB 05 Use defines (not variables) for ASN1 errors. */
/* 02/20/98 JRB 04 Chg abort_reason & event_id to ST_INT8. */
/* 12/22/97 JRB 03 Use ST_INT8. */
/* 05/27/97 JRB 7.00 MMSEASE 7.0 release. */
/* 03/19/97 JRB 02 Add "CALLING" support. General cleanup. */
/* 02/27/97 JRB 01 Created */
/************************************************************************/
#ifdef DEBUG_SISCO
static char *thisFileName = __FILE__;
#endif
#include "glbtypes.h"
#include "sysincs.h"
#include "mem_chk.h"
#include "asn1defs.h"
#include "acse2.h"
#include "copp.h"
#include "cosp_usr.h"
/************************************************************************/
/* Global Variables */
/************************************************************************/
/* Structure for tracking this decode. */
typedef struct
{
#define PPDU_TYPE_CP 0 /* This is a CP PPDU. */
#define PPDU_TYPE_CPA 1 /* This is a CPA PPDU. */
ST_INT ppdu_type; /* PPDU_TYPE_CP or PPDU_TYPE_CPA */
ST_UCHAR version_bit_str;
ST_UCHAR calling_psel [MAX_PSEL_LEN+1];
ST_UCHAR called_psel [MAX_PSEL_LEN+1];
ST_UCHAR responding_psel[MAX_PSEL_LEN+1];
ST_INT num_ctxt;
ST_BOOLEAN bad_pc_deflist; /* SD_TRUE if anything we don't like in pc_deflist*/
ST_BOOLEAN def_ctxt_proposed;
ST_INT8 mode;
ST_BOOLEAN pres_req_present;
ST_UCHAR pres_req [1];
ST_BOOLEAN user_ses_req_present;
ST_UCHAR user_sess_req [2];
ST_BOOLEAN send_negative_resp; /* if set, send negative response */
ST_INT negative_resp_reason; /* reason to send in negative response */
} DECODE_CP;
static DECODE_CP decode_cp;
static ST_INT8 pci; /* PCI rcvd in P-context-def-list */
static ST_VOID START_p_cp (ASN1_DEC_CTXT *aCtx);
static ST_VOID START_mode (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_mode2 (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_mode (ASN1_DEC_CTXT *aCtx);
static ST_VOID START_p_cp_sequence (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_version (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_calling_psel (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_called_psel (ASN1_DEC_CTXT *aCtx);
static ST_VOID START_pc_deflist (ASN1_DEC_CTXT *aCtx);
static ST_VOID START_context (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_pci (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_asn (ASN1_DEC_CTXT *aCtx);
static ST_VOID START_tsn_list (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_tsn (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_tsn_list (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_context (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_pc_deflist (ASN1_DEC_CTXT *aCtx);
static ST_VOID START_def_ctxt_name (ASN1_DEC_CTXT *aCtx);
static ST_VOID parse_next_done (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_def_ctxt_name (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_pres_req (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_user_sess_req (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_p_cp_sequence (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_p_cp (ASN1_DEC_CTXT *aCtx);
/* Functions used only for CPA decode */
static ST_VOID decode_responding_psel (ASN1_DEC_CTXT *aCtx);
static ST_VOID START_pc_def_result_list (ASN1_DEC_CTXT *aCtx);
static ST_VOID START_result_seq (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_result (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_tsn2 (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_result_list_prov_reas (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_result_seq (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_pc_def_result_list (ASN1_DEC_CTXT *aCtx);
/* All code dealing with "*_psel" (here and in other modules) assumes */
/* length fits in first byte of PSEL. */
/* NOTE: Longer PSELs should never be needed, and if another app sends */
/* one, this code gracefully refuses the connection. */
#if MAX_PSEL_LEN > 127
#error This code will not work because (MAX_PSEL_LEN > 127). Length must fit in first byte of psel.
#endif
/************************************************************************/
/* u_cosp_con_ind */
/*----------------------------------------------------------------------*/
/* This USER function is called by the SS-Provider to indicate that a */
/* remote node wishes to establish a connection. */
/* */
/* Parameters: */
/* ST_LONG user_bind_id SS-User's id for this binding. */
/* ACSE_CONN *con Pointer to connection info */
/* */
/* Return: */
/* ST_VOID */
/************************************************************************/
ST_VOID u_cosp_con_ind (ST_LONG user_bind_id, ACSE_CONN *acse_conn)
{
ST_INT8 abort_reason;
ST_INT8 event_id;
ASN1_DEC_CTXT localDecCtx; /* For readability, use "aCtx" to access this.*/
ASN1_DEC_CTXT *aCtx = &localDecCtx;
memset (aCtx, 0, sizeof (ASN1_DEC_CTXT)); /* CRITICAL: start clean */
if (acse_conn->copp_state != COPP_STATE_IDLE)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot process S-CONNECT.ind (Illegal state=%d)",
acse_conn->copp_state);
return;
}
aCtx->asn1r_decode_method = ASN1_TAG_METHOD; /* Use asn1_tag method for decoding. */
aCtx->asn1r_decode_done_fun = asn1r_done_err; /* done function = error fun */
aCtx->asn1r_err_fun = NULL; /* set up error detected fun */
/* Clean out old stuff from structure. */
memset (&decode_cp, 0, sizeof (decode_cp));
decode_cp.ppdu_type = PPDU_TYPE_CP;
decode_cp.version_bit_str = 0x80; /* Default to "version1". */
/* CRITICAL: memset above initializes "decode_cp.*_psel[0]=0" */
/* (i.e. length=0) in case they are NOT received in CP. */
decode_acse_conn = acse_conn; /* Save in global so asn1r_decode_asn1 (aCtx, */
/* can fill it in. */
/* WARNING: expected_pdv_pci MUST BE SET before START_p_user_data */
/* is called (by asn1r_decode_asn1 (aCtx,). Don't know it yet, so don't set here. */
p_user_data_is_outer = SD_FALSE; /* P-User-data IS NOT outermost constr. */
/* CRITICAL: Init APDU ptr & len. Changed only if APDU found in msg. */
acse_conn->apdu_ptr = NULL;
acse_conn->apdu_len = 0;
/* CRITICAL: Init global PDV ptr & len. Changed only if PDV found in msg.*/
pdv_data_ptr = NULL;
pdv_data_len = 0;
/* Call 'asn1r_decode_asn1 (aCtx,' to parse the message. */
ASN1R_TAG_ADD (aCtx, UNI|CONSTR,SET_CODE,START_p_cp);
asn1r_decode_asn1 (aCtx, acse_conn->ppdu_ptr,acse_conn->ppdu_len);
if (aCtx->asn1r_pdu_dec_err != NO_DECODE_ERR)
{
COPP_LOG_ERR1 ("COPP-ERROR: ASN.1 decode of S-Connect.ind failed, err=%d", aCtx->asn1r_pdu_dec_err);
abort_reason = 1; /* unrecognized-ppdu */
event_id = -1; /* Unlisted */
/* Encode and send ARP PPDU. */
copp_p_abort_req (acse_conn, abort_reason, event_id);
/* DON'T pass P-P-Abort.ind to COPP-user. User doesn't know about conn.*/
}
else if (decode_cp.send_negative_resp)
{
/* Flag was set during decode to trigger negative response, so send it.*/
copp_con_rsp_neg (acse_conn, decode_cp.negative_resp_reason);
}
else if (decode_cp.version_bit_str != 0x80)
{ /* Must be version1: Bit 0 of bitstr (high bit) set */
COPP_LOG_ERR0 ("COPP-ERROR: P-CONNECT.ind contains illegal P-version.");
copp_con_rsp_neg (acse_conn, PROV_REASON_VERSION);
}
else if (decode_cp.def_ctxt_proposed)
{
COPP_LOG_ERR0 ("COPP-ERROR: P-CONNECT.ind contains unsupported P-default-context.");
copp_con_rsp_neg (acse_conn, PROV_REASON_DEFAULT_CONTEXT);
}
else if (memcmp (decode_cp.called_psel, only_loc_psel, only_loc_psel [0]+1))
{ /* Called PSEL must be one that is bound. */
COPP_LOG_ERR0 ("COPP-ERROR: P-CONNECT.ind contains invalid Called-P-address.");
copp_con_rsp_neg (acse_conn, PROV_REASON_CALLED_PRES_ADDR);
}
else if (decode_cp.bad_pc_deflist)
{ /* Something we can't handle in pc_deflist. */
COPP_LOG_ERR0 ("COPP-ERROR: P-CONNECT.ind contains illegal PC-deflist.");
copp_con_rsp_neg (acse_conn, PROV_REASON_LOCAL_LIMIT);
}
else
{
COPP_LOG_DEC1 ("P-CONNECT.ind: acse_conn_id =0x%08X", acse_conn);
COPP_LOG_DECC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_DECH (acse_conn->apdu_len, acse_conn->apdu_ptr);
acse_conn->copp_state = COPP_STATE_AWAIT_CON_RSP;
/* Save called_psel, calling_psel in acse_conn. */
/* Will NEVER be too long, because len checked above. */
memcpy (acse_conn->loc_psel, decode_cp.called_psel, decode_cp.called_psel [0]+1);
memcpy (acse_conn->rem_psel, decode_cp.calling_psel, decode_cp.calling_psel [0]+1);
u_copp_con_ind (user_bind_id, acse_conn);
}
}
/************************************************************************/
/* u_cosp_con_cnf_pos */
/*----------------------------------------------------------------------*/
/* This USER function is called by the SS-Provider to indicate that */
/* the connection has been established. */
/* */
/* Parameters: */
/* acse_conn Pointer to connection info */
/* */
/* Return: */
/* ST_VOID */
/************************************************************************/
ST_VOID u_cosp_con_cnf_pos (ACSE_CONN *acse_conn)
{
ST_INT8 abort_reason;
ST_INT8 event_id;
ASN1_DEC_CTXT localDecCtx; /* For readability, use "aCtx" to access this.*/
ASN1_DEC_CTXT *aCtx = &localDecCtx;
memset (aCtx, 0, sizeof (ASN1_DEC_CTXT)); /* CRITICAL: start clean */
if (acse_conn->copp_state != COPP_STATE_AWAIT_CPA)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot process S-CONNECT.cnf+ (Illegal state=%d)",
acse_conn->copp_state);
return;
}
aCtx->asn1r_decode_method = ASN1_TAG_METHOD; /* Use asn1_tag method for decoding. */
aCtx->asn1r_decode_done_fun = asn1r_done_err; /* done function = error fun */
aCtx->asn1r_err_fun = NULL; /* set up error detected fun */
/* Clean out old stuff from structure. */
memset (&decode_cp, 0, sizeof (decode_cp));
decode_cp.ppdu_type = PPDU_TYPE_CPA;
decode_cp.version_bit_str = 0x80; /* Default to "version1". */
/* CRITICAL: memset above initializes "decode_cp.*_psel[0]=0" */
/* (i.e. length=0) in case they are NOT received in CPA. */
decode_acse_conn = acse_conn; /* Save in global so asn1r_decode_asn1 (aCtx, */
/* can fill it in. */
/* WARNING: expected_pdv_pci MUST BE SET before START_p_user_data */
/* is called (by asn1r_decode_asn1 (aCtx,). SET IT NOW. */
expected_pdv_pci = acse_conn->pciacse;
p_user_data_is_outer = SD_FALSE; /* P-User-data IS NOT outermost constr. */
/* CRITICAL: Init APDU ptr & len. Changed only if APDU found in msg. */
acse_conn->apdu_ptr = NULL;
acse_conn->apdu_len = 0;
/* CRITICAL: Init global PDV ptr & len. Changed only if PDV found in msg.*/
pdv_data_ptr = NULL;
pdv_data_len = 0;
/* Call 'asn1r_decode_asn1 (aCtx,' to parse the message. */
ASN1R_TAG_ADD (aCtx, UNI|CONSTR,SET_CODE,START_p_cp);
asn1r_decode_asn1 (aCtx, acse_conn->ppdu_ptr,acse_conn->ppdu_len);
if (aCtx->asn1r_pdu_dec_err != NO_DECODE_ERR)
{
COPP_LOG_ERR1 ("COPP-ERROR: ASN.1 decode of S-Connect.cnf+ failed, err=%d", aCtx->asn1r_pdu_dec_err);
acse_conn->copp_state = COPP_STATE_IDLE;
abort_reason = 1; /* unrecognized-ppdu */
event_id = -1; /* Unlisted */
/* Encode and send ARP PPDU. */
copp_p_abort_req (acse_conn, abort_reason, event_id);
/* Pass P-P-Abort.ind to COPP-user. */
u_copp_p_abort_ind (acse_conn, abort_reason);
}
else if (decode_cp.version_bit_str != 0x80 || decode_cp.bad_pc_deflist)
{ /* Must be version1: Bit 0 of bitstr (high bit) set */
COPP_LOG_ERR1 ("COPP-ERROR: Unsupported version in CPA received for conn %d",
acse_conn->user_conn_id);
acse_conn->copp_state = COPP_STATE_IDLE;
abort_reason = 6; /* invalid-ppdu-parameter-value */
event_id = 1; /* cpa-PPDU */
/* Encode and send ARP PPDU. */
copp_p_abort_req (acse_conn, abort_reason, event_id);
/* Pass P-P-Abort.ind to COPP-user. */
u_copp_p_abort_ind (acse_conn, abort_reason);
}
else
{
COPP_LOG_DEC2 ("P-CONNECT.cnf+: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_DECC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_DECH (acse_conn->apdu_len, acse_conn->apdu_ptr);
acse_conn->copp_state = COPP_STATE_CONNECTED;
u_copp_con_cnf (acse_conn, P_CON_RESULT_ACCEPT, 0);
}
}
/*======================================================*/
/* FUNCTIONS BELOW USED FOR BOTH */
/* "CP" AND "CPA" DECODE */
/*======================================================*/
/************************************************************************/
/* START_p_cp */
/************************************************************************/
static ST_VOID START_p_cp (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,0,START_mode);
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,2,START_p_cp_sequence);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_p_cp;
}
/************************************************************************/
/* START_mode */
/************************************************************************/
static ST_VOID START_mode (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, CTX,0,decode_mode2);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_mode;
}
/************************************************************************/
/* decode_mode2 */
/************************************************************************/
static ST_VOID decode_mode2 (ASN1_DEC_CTXT *aCtx)
{
if (asn1r_get_i8 (aCtx, &decode_cp.mode) || decode_cp.mode != 1) /* Not "normal" mode. Give up. */
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
}
/************************************************************************/
/* END_mode */
/************************************************************************/
static ST_VOID END_mode (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,2,START_p_cp_sequence);
}
/************************************************************************/
/* START_p_cp_sequence */
/************************************************************************/
static ST_VOID START_p_cp_sequence (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, CTX,0,decode_version);
if (decode_cp.ppdu_type == PPDU_TYPE_CP)
{ /* This is CP PPDU */
ASN1R_TAG_ADD (aCtx, CTX,1,decode_calling_psel);
ASN1R_TAG_ADD (aCtx, CTX,2,decode_called_psel);
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,4,START_pc_deflist);
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,6,START_def_ctxt_name);
}
else
{ /* This is CPA PPDU */
ASN1R_TAG_ADD (aCtx, CTX,3,decode_responding_psel);
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,5,START_pc_def_result_list);
}
ASN1R_TAG_ADD (aCtx, CTX,8,decode_pres_req);
ASN1R_TAG_ADD (aCtx, CTX,9,decode_user_sess_req);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_p_cp_sequence;
}
/************************************************************************/
/* decode_version */
/************************************************************************/
static ST_VOID decode_version (ASN1_DEC_CTXT *aCtx)
{
asn1r_get_bitstr (aCtx, &decode_cp.version_bit_str, 8);
if (decode_cp.ppdu_type == PPDU_TYPE_CP)
{ /* This is CP PPDU */
ASN1R_TAG_ADD (aCtx, CTX,1,decode_calling_psel);
ASN1R_TAG_ADD (aCtx, CTX,2,decode_called_psel);
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,4,START_pc_deflist);
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,6,START_def_ctxt_name);
}
else
{ /* This is CPA PPDU */
ASN1R_TAG_ADD (aCtx, CTX,3,decode_responding_psel);
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,5,START_pc_def_result_list);
}
ASN1R_TAG_ADD (aCtx, CTX,8,decode_pres_req);
ASN1R_TAG_ADD (aCtx, CTX,9,decode_user_sess_req);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
}
/************************************************************************/
/* decode_calling_psel */
/************************************************************************/
static ST_VOID decode_calling_psel (ASN1_DEC_CTXT *aCtx)
{
/* If len within limit, copy psel to decode structure. */
/* If not, set flag to send negative response. */
if (aCtx->asn1r_elmnt_len <= MAX_PSEL_LEN)
{
decode_cp.calling_psel [0] = aCtx->asn1r_elmnt_len;
memcpy (&decode_cp.calling_psel [1], aCtx->asn1r_field_ptr, aCtx->asn1r_elmnt_len);
}
else
{
COPP_LOG_ERR2 ("P-CONNECT.ind: Calling PSEL len=%d exceeds max=%d",
aCtx->asn1r_elmnt_len, MAX_PSEL_LEN);
decode_cp.send_negative_resp = SD_TRUE; /* send negative response*/
decode_cp.negative_resp_reason = PROV_REASON_LOCAL_LIMIT;
}
/* Primitive CAN'T be indef len, so asn1_skip_elmnt is safe here. */
asn1_skip_elmnt (aCtx); /* Don't bother decoding it. */
ASN1R_TAG_ADD (aCtx, CTX,2,decode_called_psel);
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,4,START_pc_deflist);
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,6,START_def_ctxt_name);
ASN1R_TAG_ADD (aCtx, CTX,8,decode_pres_req);
ASN1R_TAG_ADD (aCtx, CTX,9,decode_user_sess_req);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
}
/************************************************************************/
/* decode_called_psel */
/************************************************************************/
static ST_VOID decode_called_psel (ASN1_DEC_CTXT *aCtx)
{
/* If len within limit, copy psel to decode structure. */
/* If not, set flag to send negative response. */
if (aCtx->asn1r_elmnt_len <= MAX_PSEL_LEN)
{
decode_cp.called_psel [0] = aCtx->asn1r_elmnt_len; /* first byte is len*/
memcpy (&decode_cp.called_psel [1], aCtx->asn1r_field_ptr, aCtx->asn1r_elmnt_len);
}
else
{
COPP_LOG_ERR2 ("P-CONNECT.ind: Called PSEL len=%d exceeds max=%d",
aCtx->asn1r_elmnt_len, MAX_PSEL_LEN);
decode_cp.send_negative_resp = SD_TRUE; /* send negative response*/
decode_cp.negative_resp_reason = PROV_REASON_LOCAL_LIMIT;
}
/* Primitive CAN'T be indef len, so asn1_skip_elmnt is safe here. */
asn1_skip_elmnt (aCtx); /* Don't bother decoding it. */
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,4,START_pc_deflist);
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,6,START_def_ctxt_name);
ASN1R_TAG_ADD (aCtx, CTX,8,decode_pres_req);
ASN1R_TAG_ADD (aCtx, CTX,9,decode_user_sess_req);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
}
/************************************************************************/
/* START_pc_deflist */
/************************************************************************/
static ST_VOID START_pc_deflist (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, UNI|CONSTR,SEQ_CODE,START_context);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_pc_deflist;
}
/************************************************************************/
/* START_context */
/************************************************************************/
static ST_VOID START_context (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, UNI,INT_CODE,decode_pci);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_context;
}
/************************************************************************/
/* decode_pci */
/************************************************************************/
static ST_VOID decode_pci (ASN1_DEC_CTXT *aCtx)
{
if (asn1r_get_i8 (aCtx, &pci))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
ASN1R_TAG_ADD (aCtx, UNI,OBJ_ID_CODE,decode_asn);
}
/************************************************************************/
/* decode_asn */
/************************************************************************/
static ST_VOID decode_asn (ASN1_DEC_CTXT *aCtx)
{
MMS_OBJ_ID asn;
if (asn1r_get_objid (aCtx, asn.comps,&asn.num_comps))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
if (asn1_objidcmp (&asn, (MMS_OBJ_ID *) &mms_obj_id) == 0)
decode_acse_conn->pcimms = pci;
else if (asn1_objidcmp (&asn, (MMS_OBJ_ID *) &acse_obj_id) == 0)
decode_acse_conn->pciacse = pci;
else
{ /* Unrecognized Abstract Syntax. Must be "ACSE" or "ISO MMS". */
decode_cp.bad_pc_deflist = SD_TRUE;
}
ASN1R_TAG_ADD (aCtx, UNI|CONSTR,SEQ_CODE,START_tsn_list);
}
/************************************************************************/
/* START_tsn_list */
/************************************************************************/
static ST_VOID START_tsn_list (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, UNI,OBJ_ID_CODE,decode_tsn);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_tsn_list;
}
/************************************************************************/
/* decode_tsn */
/************************************************************************/
static ST_VOID decode_tsn (ASN1_DEC_CTXT *aCtx)
{
MMS_OBJ_ID tsn;
if (asn1r_get_objid (aCtx, tsn.comps,&tsn.num_comps))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
if (asn1_objidcmp (&tsn, (MMS_OBJ_ID *) &asn1_obj_id) != 0)
{ /* TSN better be ASN1 */
decode_cp.bad_pc_deflist = SD_TRUE;
}
/* DEBUG: we don't support multiple TSN so no ASN1R_TAG_ADD (aCtx, here. */
/* Should end up in END_tsn_list after this. */
}
/************************************************************************/
/* END_tsn_list */
/************************************************************************/
static ST_VOID END_tsn_list (ASN1_DEC_CTXT *aCtx)
{
return;
}
/************************************************************************/
/* END_context */
/************************************************************************/
static ST_VOID END_context (ASN1_DEC_CTXT *aCtx)
{
decode_acse_conn->num_ctxt++;
/* May be another context. */
ASN1R_TAG_ADD (aCtx, UNI|CONSTR,SEQ_CODE,START_context);
}
/************************************************************************/
/* END_pc_deflist */
/************************************************************************/
static ST_VOID END_pc_deflist (ASN1_DEC_CTXT *aCtx)
{
/* Set the PCI to be used during P-User-Data decode. */
/* WARNING: this must be done here because we don't know what it is */
/* beforehand. */
expected_pdv_pci = decode_acse_conn->pciacse;
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,6,START_def_ctxt_name);
ASN1R_TAG_ADD (aCtx, CTX,8,decode_pres_req);
ASN1R_TAG_ADD (aCtx, CTX,9,decode_user_sess_req);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
}
/************************************************************************/
/* START_def_ctxt_name */
/* Default-context-name. If this is present, we will refuse this */
/* connection so don't bother decoding it. */
/************************************************************************/
static ST_VOID START_def_ctxt_name (ASN1_DEC_CTXT *aCtx)
{
decode_cp.def_ctxt_proposed = SD_TRUE;
/* Don't bother decoding it. Use asn1r_parse_next (aCtx, to skip over it. */
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_def_ctxt_name;
asn1r_parse_next (aCtx, parse_next_done);
}
/************************************************************************/
/* parse_next_done */
/************************************************************************/
static ST_VOID parse_next_done (ASN1_DEC_CTXT *aCtx)
{ /* called when "asn1r_parse_next (aCtx," is done */
}
/************************************************************************/
/* END_def_ctxt_name */
/************************************************************************/
static ST_VOID END_def_ctxt_name (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, CTX,8,decode_pres_req);
ASN1R_TAG_ADD (aCtx, CTX,9,decode_user_sess_req);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
}
/************************************************************************/
/* decode_pres_req */
/************************************************************************/
static ST_VOID decode_pres_req (ASN1_DEC_CTXT *aCtx)
{
decode_cp.pres_req_present = SD_TRUE;
asn1r_get_bitstr (aCtx, decode_cp.pres_req, 8);
ASN1R_TAG_ADD (aCtx, CTX,9,decode_user_sess_req);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
}
/************************************************************************/
/* decode_user_sess_req */
/************************************************************************/
static ST_VOID decode_user_sess_req (ASN1_DEC_CTXT *aCtx)
{
decode_cp.user_ses_req_present = SD_TRUE;
asn1r_get_bitstr (aCtx, decode_cp.user_sess_req, 16);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
}
/************************************************************************/
/* END_p_cp_sequence */
/************************************************************************/
static ST_VOID END_p_cp_sequence (ASN1_DEC_CTXT *aCtx)
{ /* Somebody might encode "mode" after "p_cp_sequence". */
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,0,START_mode);
}
/************************************************************************/
/* END_p_cp */
/************************************************************************/
static ST_VOID END_p_cp (ASN1_DEC_CTXT *aCtx)
{
aCtx->asn1r_decode_done_fun = NULL; /* done decoding */
}
/*======================================================*/
/* FUNCTIONS BELOW USED ONLY FOR "CPA" DECODE */
/* */
/*======================================================*/
/************************************************************************/
/* decode_responding_psel */
/* NOTE: Responding PSEL not used, so if can't decode, just ignore it. */
/************************************************************************/
static ST_VOID decode_responding_psel (ASN1_DEC_CTXT *aCtx)
{
/* If len within limit, copy psel to decode structure. */
/* If not, just log & ignore (responding PSEL not usually needed). */
if (aCtx->asn1r_elmnt_len <= MAX_PSEL_LEN)
{
decode_cp.responding_psel [0] = aCtx->asn1r_elmnt_len;
memcpy (&decode_cp.responding_psel [1], aCtx->asn1r_field_ptr, aCtx->asn1r_elmnt_len);
}
else
COPP_LOG_DEC2 ("P-CONNECT.cnf+: Responding PSEL len=%d exceeds max=%d. Ignored.",
aCtx->asn1r_elmnt_len, MAX_PSEL_LEN);
/* Primitive CAN'T be indef len, so asn1_skip_elmnt is safe here. */
asn1_skip_elmnt (aCtx); /* Don't bother decoding it. */
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,5,START_pc_def_result_list);
ASN1R_TAG_ADD (aCtx, CTX,8,decode_pres_req);
ASN1R_TAG_ADD (aCtx, CTX,9,decode_user_sess_req);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
}
/************************************************************************/
/* START_pc_def_result_list */
/************************************************************************/
static ST_VOID START_pc_def_result_list (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, UNI|CONSTR,SEQ_CODE,START_result_seq);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_pc_def_result_list;
}
/************************************************************************/
/* START_result_seq */
/************************************************************************/
static ST_VOID START_result_seq (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, CTX,0,decode_result);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_result_seq;
}
/************************************************************************/
/* decode_result */
/************************************************************************/
static ST_VOID decode_result (ASN1_DEC_CTXT *aCtx)
{
ST_INT8 result;
if (asn1r_get_i8 (aCtx, &result))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
if (result != 0)
{ /* P-Context rejected. We can't handle any rejection so set flag.*/
decode_cp.bad_pc_deflist = SD_TRUE;
}
ASN1R_TAG_ADD (aCtx, CTX,1,decode_tsn2);
ASN1R_TAG_ADD (aCtx, CTX,2,decode_result_list_prov_reas);
}
/************************************************************************/
/* decode_tsn2 */
/* NOTE: This is essentially same as decode_tsn used in the CP decode */
/* except for the different ASN1R_TAG_ADD (aCtx, at the end. In either case */
/* if we receive any TSN that is not ASN.1 (this is the only */
/* TSN we will ever accept or propose) we set the flag */
/* decode_cp.bad_pc_deflist = SD_TRUE */
/************************************************************************/
static ST_VOID decode_tsn2 (ASN1_DEC_CTXT *aCtx)
{
MMS_OBJ_ID tsn;
if (asn1r_get_objid (aCtx, tsn.comps,&tsn.num_comps))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
if (asn1_objidcmp (&tsn, (MMS_OBJ_ID *) &asn1_obj_id) != 0)
{ /* TSN better be ASN1 */
decode_cp.bad_pc_deflist = SD_TRUE;
}
ASN1R_TAG_ADD (aCtx, CTX,2,decode_result_list_prov_reas);
}
/************************************************************************/
/* decode_result_list_prov_reas */
/* NOTE: Decode but don't save value, because no real use for it. */
/************************************************************************/
static ST_VOID decode_result_list_prov_reas (ASN1_DEC_CTXT *aCtx)
{
ST_INT8 result_list_prov_reas;
if (asn1r_get_i8 (aCtx, &result_list_prov_reas))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
}
/************************************************************************/
/* END_result_seq */
/************************************************************************/
static ST_VOID END_result_seq (ASN1_DEC_CTXT *aCtx)
{
decode_acse_conn->num_ctxt++;
/* May be another "result sequence". */
ASN1R_TAG_ADD (aCtx, UNI|CONSTR,SEQ_CODE,START_result_seq);
}
/************************************************************************/
/* END_pc_def_result_list */
/************************************************************************/
static ST_VOID END_pc_def_result_list (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, CTX,8,decode_pres_req);
ASN1R_TAG_ADD (aCtx, CTX,9,decode_user_sess_req);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
}

401
mmslib/ositcps/coppdcpr.c Normal file
View File

@@ -0,0 +1,401 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1997-2002, All Rights Reserved */
/* */
/* PROPRIETARY AND CONFIDENTIAL */
/* */
/* MODULE NAME : coppdcpr.c */
/* PRODUCT(S) : MOSI Stack (over TP4) */
/* */
/* MODULE DESCRIPTION : */
/* This file implements decoding of CPR PPDU. */
/* */
/* For information see the: */
/* ISO 8822 "Information processing systems - Open Systems */
/* Interconnection - Connection oriented presentation service */
/* definition. */
/* ISO 8823 "Information processing systems - Open Systems */
/* Interconnection - Connection oriented presentation protocol */
/* specification. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* u_cosp_con_cnf_neg */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 02/26/09 JRB 11 Fix to handle PDV len=0 or User-data len=0. */
/* 10/08/08 JRB 10 Fix PSEL decode (didn't work if len > 127). */
/* 04/28/08 GLB 09 Removed CALLED_ONLY. */
/* 03/31/03 JRB 08 asn1r_get_bitstr: add max_bits arg. */
/* 01/02/02 JRB 07 Converted to use ASN1R (re-entrant ASN1) */
/* 10/09/01 JRB 06 asn1_skip_elmnt doesn't work for indef len */
/* encoding. Use "parse_next" instead. */
/* 02/02/99 JRB 05 BUG FIX: Decode "prov_reas" in "Result-list" */
/* even if no TSN (see decode_result). */
/* 02/02/99 JRB 04 Allow User-data with Prov-reason but ignore. */
/* 03/18/98 JRB 03 Use defines (not variables) for ASN1 errors. */
/* 12/22/97 JRB 02 Use ST_INT8. */
/* 05/27/97 JRB 7.00 MMSEASE 7.0 release. */
/* 03/19/97 JRB 01 Created */
/************************************************************************/
#ifdef DEBUG_SISCO
static char *thisFileName = __FILE__;
#endif
#include "glbtypes.h"
#include "sysincs.h"
#include "mem_chk.h"
#include "asn1defs.h"
#include "acse2.h"
#include "copp.h"
#include "cosp_usr.h"
/* Define illegal value for "provider_reason". Init to this before */
/* decode. If still equals this after decode, it was not encoded in PDU.*/
#define CPR_PROVIDER_REASON_NOT_ENCODED -1
/************************************************************************/
/* Global Variables */
/************************************************************************/
/* Structure for tracking this decode. */
typedef struct
{
ST_UCHAR version_bit_str;
ST_UCHAR responding_psel [MAX_PSEL_LEN+1];
ST_INT num_ctxt;
ST_BOOLEAN bad_pc_deflist; /* SD_TRUE if anything we don't like in pc_deflist*/
ST_INT8 default_context_result;
ST_INT8 provider_reason;
} CPR_INFO;
static CPR_INFO cpr_info;
static ST_VOID START_p_cpr (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_version (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_responding_psel (ASN1_DEC_CTXT *aCtx);
static ST_VOID START_pc_def_result_list (ASN1_DEC_CTXT *aCtx);
static ST_VOID START_result_seq (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_result (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_tsn2 (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_result_list_prov_reas (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_result_seq (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_pc_def_result_list (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_default_context_result (ASN1_DEC_CTXT *aCtx);
static ST_VOID decode_provider_reason (ASN1_DEC_CTXT *aCtx);
static ST_VOID SKIP_p_user_data (ASN1_DEC_CTXT *aCtx);
static ST_VOID parse_next_done (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_skip_p_user_data (ASN1_DEC_CTXT *aCtx);
static ST_VOID END_p_cpr (ASN1_DEC_CTXT *aCtx);
/************************************************************************/
/* u_cosp_con_cnf_neg */
/*----------------------------------------------------------------------*/
/* This USER function is called by the SS-Provider to indicate the */
/* connection has been rejected by remote. */
/* */
/* Parameters: */
/* acse_conn Pointer to connection info */
/* result see def results COSP_CON_CNF_... above */
/* reason see def reasons COSP_CON_CNF_... above */
/* */
/* Return: */
/* ST_VOID */
/************************************************************************/
ST_VOID u_cosp_con_cnf_neg (ACSE_CONN *acse_conn, ST_INT result, ST_INT reason)
{
ST_INT8 abort_reason;
ASN1_DEC_CTXT localDecCtx; /* For readability, use "aCtx" to access this.*/
ASN1_DEC_CTXT *aCtx = &localDecCtx;
memset (aCtx, 0, sizeof (ASN1_DEC_CTXT)); /* CRITICAL: start clean */
if (acse_conn->copp_state != COPP_STATE_AWAIT_CPA)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot process S-CONNECT.cnf- (Illegal state=%d)",
acse_conn->copp_state);
return;
}
aCtx->asn1r_decode_method = ASN1_TAG_METHOD; /* Use asn1_tag method for decoding. */
aCtx->asn1r_decode_done_fun = asn1r_done_err; /* done function = error fun */
aCtx->asn1r_err_fun = NULL; /* set up error detected fun */
/* Clean out old stuff from structure. */
memset (&cpr_info, 0, sizeof (cpr_info));
cpr_info.version_bit_str = 0x80; /* Default to "version1". */
cpr_info.provider_reason = CPR_PROVIDER_REASON_NOT_ENCODED;
/* CRITICAL: memset above initializes "cpr_info.responding_psel[0]=0" */
/* (i.e. length=0) in case it is NOT received in CPR. */
decode_acse_conn = acse_conn; /* Save in global so asn1r_decode_asn1 (aCtx, */
/* can fill it in. */
/* WARNING: expected_pdv_pci MUST BE SET before START_p_user_data */
/* is called (by asn1r_decode_asn1 (aCtx,). SET IT NOW. */
expected_pdv_pci = acse_conn->pciacse;
p_user_data_is_outer = SD_FALSE; /* P-User-data IS NOT outermost constr. */
/* CRITICAL: Init APDU ptr & len. Changed only if APDU found in msg. */
acse_conn->apdu_ptr = NULL;
acse_conn->apdu_len = 0;
/* CRITICAL: Init global PDV ptr & len. Changed only if PDV found in msg.*/
pdv_data_ptr = NULL;
pdv_data_len = 0;
/* Call 'asn1r_decode_asn1 (aCtx,' to parse the message. */
ASN1R_TAG_ADD (aCtx, UNI|CONSTR,SEQ_CODE,START_p_cpr);
asn1r_decode_asn1 (aCtx, acse_conn->ppdu_ptr,acse_conn->ppdu_len);
if (aCtx->asn1r_pdu_dec_err != NO_DECODE_ERR)
{
COPP_LOG_ERR1 ("COPP-ERROR: ASN.1 decode of S-Connect.cnf- failed, err=%d", aCtx->asn1r_pdu_dec_err);
abort_reason = 1; /* unrecognized-ppdu */
/* Don't send ARP PPDU. Remote node is already rejecting connect. */
/* Pass P-P-Abort.ind to COPP-user. */
u_copp_p_abort_ind (acse_conn, abort_reason);
}
else if (cpr_info.version_bit_str != 0x80)
{ /* Must be version1: Bit 0 of bitstr (high bit) set */
COPP_LOG_ERR1 ("COPP-ERROR: Unsupported version in CPR received for conn %d",
acse_conn->user_conn_id);
abort_reason = 6; /* invalid-ppdu-parameter-value */
/* Don't send ARP PPDU. Remote node is already rejecting connect. */
/* Pass P-P-Abort.ind to COPP-user. */
u_copp_p_abort_ind (acse_conn, abort_reason);
}
else if (cpr_info.provider_reason != CPR_PROVIDER_REASON_NOT_ENCODED)
{ /* Provider reject */
COPP_LOG_DEC2 ("P-CONNECT.cnf-: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_DECC1 ("Provider-reason = %d. No P-user-data.",
cpr_info.provider_reason);
/* NOTE: there is no User-data with this one. */
u_copp_con_cnf (acse_conn, P_CON_RESULT_PROVIDER_REJ,
cpr_info.provider_reason);
}
else if (cpr_info.bad_pc_deflist)
{
COPP_LOG_ERR1 ("COPP-ERROR: Unsupported P-context in CPR received for conn %d",
acse_conn->user_conn_id);
abort_reason = 6; /* invalid-ppdu-parameter-value */
/* Don't send ARP PPDU. Remote node is already rejecting connect. */
/* Pass P-P-Abort.ind to COPP-user. */
u_copp_p_abort_ind (acse_conn, abort_reason);
}
else
{ /* User reject */
COPP_LOG_DEC2 ("P-CONNECT.cnf-: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_DECC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_DECH (acse_conn->apdu_len, acse_conn->apdu_ptr);
u_copp_con_cnf (acse_conn, P_CON_RESULT_USER_REJ, 0);
}
acse_conn->copp_state = COPP_STATE_IDLE; /* No matter what */
}
/*======================================================*/
/* FUNCTIONS BELOW USED FOR "CPR" DECODE */
/* */
/*======================================================*/
/************************************************************************/
/* START_p_cpr */
/************************************************************************/
static ST_VOID START_p_cpr (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, CTX,0,decode_version);
ASN1R_TAG_ADD (aCtx, CTX,3,decode_responding_psel);
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,5,START_pc_def_result_list);
ASN1R_TAG_ADD (aCtx, CTX,7,decode_default_context_result);
ASN1R_TAG_ADD (aCtx, CTX,10,decode_provider_reason);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_p_cpr;
}
/************************************************************************/
/* decode_version */
/************************************************************************/
static ST_VOID decode_version (ASN1_DEC_CTXT *aCtx)
{
asn1r_get_bitstr (aCtx, &cpr_info.version_bit_str, 8);
ASN1R_TAG_ADD (aCtx, CTX,3,decode_responding_psel);
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,5,START_pc_def_result_list);
ASN1R_TAG_ADD (aCtx, CTX,7,decode_default_context_result);
ASN1R_TAG_ADD (aCtx, CTX,10,decode_provider_reason);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
}
/************************************************************************/
/* decode_responding_psel */
/* NOTE: Responding PSEL not used, so if can't decode, just ignore it. */
/************************************************************************/
static ST_VOID decode_responding_psel (ASN1_DEC_CTXT *aCtx)
{
/* If len within limit, copy psel to decode structure. */
/* If not, just log & ignore (responding PSEL not usually needed). */
if (aCtx->asn1r_elmnt_len <= MAX_PSEL_LEN)
{
cpr_info.responding_psel [0] = aCtx->asn1r_elmnt_len; /* first byte is len*/
memcpy (&cpr_info.responding_psel [1], aCtx->asn1r_field_ptr, aCtx->asn1r_elmnt_len);
}
else
COPP_LOG_DEC2 ("P-CONNECT.cnf-: Responding PSEL len=%d exceeds max=%d. Ignored.",
aCtx->asn1r_elmnt_len, MAX_PSEL_LEN);
/* Primitive CAN'T be indef len, so asn1_skip_elmnt is safe here. */
asn1_skip_elmnt (aCtx); /* Don't bother decoding it. */
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,5,START_pc_def_result_list);
ASN1R_TAG_ADD (aCtx, CTX,7,decode_default_context_result);
ASN1R_TAG_ADD (aCtx, CTX,10,decode_provider_reason);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
}
/************************************************************************/
/* START_pc_def_result_list */
/************************************************************************/
static ST_VOID START_pc_def_result_list (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, UNI|CONSTR,SEQ_CODE,START_result_seq);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_pc_def_result_list;
}
/************************************************************************/
/* START_result_seq */
/************************************************************************/
static ST_VOID START_result_seq (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, CTX,0,decode_result);
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_result_seq;
}
/************************************************************************/
/* decode_result */
/************************************************************************/
static ST_VOID decode_result (ASN1_DEC_CTXT *aCtx)
{
ST_INT8 result;
if (asn1r_get_i8 (aCtx, &result))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
if (result != 0)
{ /* P-Context rejected. We can't handle any rejection so set flag.*/
cpr_info.bad_pc_deflist = SD_TRUE;
}
ASN1R_TAG_ADD (aCtx, CTX,1,decode_tsn2);
ASN1R_TAG_ADD (aCtx, CTX,2,decode_result_list_prov_reas);
}
/************************************************************************/
/* decode_tsn2 */
/* NOTE: This is essentially same as decode_tsn used in the CP decode */
/* except for the different ASN1R_TAG_ADD (aCtx, at the end. In either case */
/* if we receive any TSN that is not ASN.1 (this is the only */
/* TSN we will ever accept or propose) we set the flag */
/* cpr_info.bad_pc_deflist = SD_TRUE */
/************************************************************************/
static ST_VOID decode_tsn2 (ASN1_DEC_CTXT *aCtx)
{
MMS_OBJ_ID tsn;
if (asn1r_get_objid (aCtx, tsn.comps,&tsn.num_comps))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
if (asn1_objidcmp (&tsn, &asn1_obj_id) != 0)
{ /* TSN better be ASN1 */
cpr_info.bad_pc_deflist = SD_TRUE;
}
ASN1R_TAG_ADD (aCtx, CTX,2,decode_result_list_prov_reas);
}
/************************************************************************/
/* decode_result_list_prov_reas */
/* NOTE: Decode but don't save value, because no real use for it. */
/************************************************************************/
static ST_VOID decode_result_list_prov_reas (ASN1_DEC_CTXT *aCtx)
{
ST_INT8 result_list_prov_reas;
if (asn1r_get_i8 (aCtx, &result_list_prov_reas))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
}
/************************************************************************/
/* END_result_seq */
/************************************************************************/
static ST_VOID END_result_seq (ASN1_DEC_CTXT *aCtx)
{
decode_acse_conn->num_ctxt++;
/* May be another "result sequence". */
ASN1R_TAG_ADD (aCtx, UNI|CONSTR,SEQ_CODE,START_result_seq);
}
/************************************************************************/
/* END_pc_def_result_list */
/************************************************************************/
static ST_VOID END_pc_def_result_list (ASN1_DEC_CTXT *aCtx)
{
ASN1R_TAG_ADD (aCtx, CTX,7,decode_default_context_result);
ASN1R_TAG_ADD (aCtx, CTX,10,decode_provider_reason);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
}
/************************************************************************/
/* decode_default_context_result */
/************************************************************************/
static ST_VOID decode_default_context_result (ASN1_DEC_CTXT *aCtx)
{ /* Ignore value, because we never proposed Default-context-name.*/
if (asn1r_get_i8 (aCtx, &cpr_info.default_context_result))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
ASN1R_TAG_ADD (aCtx, CTX,10,decode_provider_reason);
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,START_p_user_data);
}
/************************************************************************/
/* decode_provider_reason */
/************************************************************************/
static ST_VOID decode_provider_reason (ASN1_DEC_CTXT *aCtx)
{
if (asn1r_get_i8 (aCtx, &cpr_info.provider_reason))
{
asn1r_set_dec_err (aCtx, ASN1E_INVALID_BOOLEAN);
return;
}
/* Marben sends bad p_user_data in this case. Skip over it. */
COPP_LOG_DEC0 ("WARNING: Ignoring P-user-data received on CPR.");
ASN1R_TAG_ADD (aCtx, APP|CONSTR,1,SKIP_p_user_data);
}
/************************************************************************/
/* SKIP_p_user_data */
/************************************************************************/
ST_VOID SKIP_p_user_data (ASN1_DEC_CTXT *aCtx)
{
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = END_skip_p_user_data;
asn1r_parse_next (aCtx, parse_next_done);
}
/************************************************************************/
/* parse_next_done */
/************************************************************************/
static ST_VOID parse_next_done (ASN1_DEC_CTXT *aCtx)
{ /* called when "asn1r_parse_next (aCtx," is done */
}
/************************************************************************/
/* END_skip_p_user_data */
/************************************************************************/
static ST_VOID END_skip_p_user_data (ASN1_DEC_CTXT *aCtx)
{
}
/************************************************************************/
/* END_p_cpr */
/************************************************************************/
static ST_VOID END_p_cpr (ASN1_DEC_CTXT *aCtx)
{
aCtx->asn1r_decode_done_fun = NULL; /* done decoding */
}

1090
mmslib/ositcps/cosp_dec.c Normal file

File diff suppressed because it is too large Load Diff

812
mmslib/ositcps/cosp_enc.c Normal file
View File

@@ -0,0 +1,812 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1997, All Rights Reserved */
/* */
/* PROPRIETARY AND CONFIDENTIAL */
/* */
/* MODULE NAME : cosp_enc.c */
/* PRODUCT(S) : MOSI Stack (over TP4) */
/* */
/* MODULE DESCRIPTION : */
/* This file implements the encoding of COSP SPDUs. */
/* */
/* NOTE: Implementation restrictions: */
/* Non-segmenting COSP, */
/* Transport connections are not reused. */
/* */
/* For information see the: */
/* ISO 8326 "Information processing systems - Open Systems */
/* Interconnection - Basic connection oriented session service */
/* definition. */
/* ISO 8327 "Information processing systems - Open Systems */
/* Interconnection - Basic connection oriented session protocol */
/* specification. */
/* ISO 8327/ADD.2 (Draft for Version2). */
/* */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* cosp_envelope_len */
/* cosp_enc_cn_ac */
/* cosp_enc_rf */
/* cosp_enc_fn_dn */
/* cosp_enc_ab */
/* cosp_enc_dt */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 06/02/04 JRB 10 cosp_enc_dt: do NOT restrict user data len. */
/* 07/16/02 JRB 09 Clean up & fix comments in cosp_enc_cn_ac. */
/* 06/05/02 JRB 08 Send Calling SSEL on connect request. */
/* 09/12/01 JRB 07 Reverse last change (not needed). */
/* 08/01/01 JRB 06 Del rem_addr arg from cosp_enc_cn_ac. */
/* 04/12/00 JRB 05 Lint cleanup. */
/* 09/13/99 MDE 04 Added SD_CONST modifiers */
/* 08/13/98 JRB 03 Lint cleanup. */
/* 05/27/97 JRB 7.00 MMSEASE 7.0 release. */
/* 03/20/97 EJV 02 Enhanced logging. */
/* 01/17/97 EJV 01 Created */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#ifdef DEBUG_SISCO
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__; /* Define for SLOG mechanism */
#endif
#include "acse2.h"
#include "cosp_log.h"
#include "cosp.h"
#include "cosp_usr.h"
/*----------------------------------------------*/
/* Fixed encoding for CONNECT / ACCEPT SPDU: */
/* Connect/Accept PGI: */
/* - extended concatination not supported, */
/* - COSP Version2 supported */
/* Session User Requirements PI: */
/* - duplex functional unit (FU) supported */
/*----------------------------------------------*/
static ST_UCHAR cosp_cn_ac_fixed [12] = {
5, /* CN-AC PGI code */
6, /* CN-AC PGI len */
/* Protocol Option PI: */
19, /* PI code */
1, /* PI len */
0, /* 0 if rcv extended concatinat. not supported*/
/* Version Number PI: */
22, /* PI code */
1, /* PI len */
COSP_VER2, /* we supporting Version2 */
/* Session User Requirements PI: */
20, /* PI code */
2, /* PI len */
0, /* bits 9-16 are 0 */
2}; /* bits 1-8 (only bit2=1 duplex FU supported) */
/*----------------------------------------------*/
/* Fixed encoding for REFUSE SPDU: */
/* Session User Requirements PI: */
/* - duplex functional unit (FU) supported */
/* COSP Version PI: */
/* - Version2 supported */
/*----------------------------------------------*/
static ST_UCHAR cosp_rf_fixed [7] = {
/* Session User Requirements PI: */
20, /* PI code */
2, /* PI len */
0, /* bits 9-16 are 0 */
2, /* bits 1-8 (only bit2=1 duplex FU supported) */
/* Version Number PI: */
22, /* PI code */
1, /* PI len */
COSP_VER2}; /* we supporting Version2 */
static ST_UINT cosp_enc_len (ST_UINT16 len, ST_UCHAR *buf);
/************************************************************************/
/* cosp_envelope_len */
/*----------------------------------------------------------------------*/
/* Function to compute the number of envelope bytes needed to encode */
/* a SPDU. The returned length does not include the SS-user data length.*/
/* */
/* Parameters: */
/* ACSE_CONN *con Connection info parameters */
/* ST_UINT rem_ssel_len Remote SSEL length */
/* ST_UCHAR spdu_type One of COSP_SI_... from cosp.h */
/* */
/* Return: */
/* ST_UINT Length of SPDU envelope encoding */
/************************************************************************/
ST_UINT cosp_envelope_len (ACSE_CONN *con, ST_UINT rem_ssel_len, ST_UCHAR spdu_type)
{
ST_UINT enc_len;
ST_UINT udata_len;
udata_len = con->ppdu_len;
enc_len = 0;
switch (spdu_type)
{
case COSP_SI_CONNECT:
enc_len =
2+6 /* Connect/Accept PGI */
+ 2+2 /* Ses User Requirem. PI*/
+ (cosp_only_ssel[0] != 0 ? 2+cosp_only_ssel[0] : 0)/* Calling SSEL*/
+ (rem_ssel_len != 0 ? 2+rem_ssel_len : 0)/* Called SSEL */
+ (udata_len > 0 ? 2 : 0) /* 1 PI code, 1 len */
+ (udata_len > 254 ? 2 : 0); /* add 2 bytes for len */
break;
case COSP_SI_ACCEPT:
enc_len =
2+6 /* Connect/Accept PGI */
+ 2+2 /* Ses User Requirem. PI*/
+ (udata_len > 0 ? 2 : 0) /* 1 PI code, 1 len */
+ (udata_len > 254 ? 2 : 0); /* add 2 bytes for len */
break;
case COSP_SI_REFUSE:
enc_len =
2+2 /* Ses User Requirem. PI*/
+ 2+1 /* Supported Version PI */
+ 2+1 /* 1 PI code, 1 len, 1 Reason Code*/
+ (udata_len > 254 ? 2 : 0); /* add 2 bytes for len */
break;
case COSP_SI_FINISH:
case COSP_SI_DISCON:
enc_len =
(udata_len > 0 ? 2 : 0) /* 1 PI code, 1 len */
+ (udata_len > 254 ? 2 : 0); /* addl 2 bytes for len */
break;
case COSP_SI_ABORT:
enc_len =
2+1 /* TP Disconnect PI */
+ (udata_len > 0 ? 2 : 0) /* 1 PI code, 1 len */
+ (udata_len > 254 ? 2 : 0); /* add 2 bytes for len */
break;
case COSP_SI_DATA:
/* We send Give Token SPDU concatinated with the DT (basic concatination) */
enc_len = 2; /* (SI=01,LI=0) token functionality not used */
break;
default:
COSP_LOG_ERR1 ("COSP-ERROR: Encoding: Invalid PDU type = %d", spdu_type);
break;
}
/* add bytes for params len (none in DT) */
if (spdu_type == COSP_SI_DATA)
/* in DT we do not send any parameters but we have to send the LI=0 */
enc_len += 1; /* 1 byte for len */
else
{
/* all udata is encoded in a parameter */
if (enc_len + udata_len > 254)
enc_len += 3; /* 3 bytes for len */
else
enc_len += 1; /* 1 byte for len */
}
/* add byte for SPDU code */
enc_len += 1;
return (enc_len);
}
/************************************************************************/
/* cosp_enc_cn_ac */
/*----------------------------------------------------------------------*/
/* Function to encode a CONNECT or ACCEPT SPDU. */
/* This function assumed that there is enough place in the enc_buf for */
/* the CN or AC SPDU encoding. The function cosp_envelope_len can be */
/* used to compute exact envelope encoding length. */
/* Note that this function assumes that the SS-user data (CP / CPA PPDU)*/
/* has been already copied into the enc_buf in proper position. */
/* */
/* Parameters: */
/* ACSE_CONN *con Connection info parameters */
/* PRES_ADDR *rem_addr Remote Address (needed only for CN) */
/* char **spdu_ptr Pointer where to return pointer to SPDU */
/* ST_UINT *spdu_len Pointer where to return the SPDU len */
/* ST_UCHAR spdu_type COSP_SI_CONNECT or COSP_SI_ACCEPT */
/* */
/* Return: */
/* SD_SUCCESS (0) if successful */
/* error code otherwise */
/************************************************************************/
ST_RET cosp_enc_cn_ac (ACSE_CONN *con, PRES_ADDR *rem_addr,
char **spdu_ptr, ST_UINT *spdu_len,
ST_UCHAR spdu_type)
{
ST_UINT envelope_len;
ST_UINT udata_len;
ST_UINT udata_max_len;
ST_UCHAR ssel_len;
ST_UCHAR *ssel;
ST_UCHAR *enc_buf;
ST_UINT enc_len;
ST_UINT idx;
/*------------------------------------------------------------*/
/* make sure data len is OK (User Data presence is mandatory) */
/*------------------------------------------------------------*/
udata_len = con->ppdu_len;
if (rem_addr)
envelope_len = cosp_envelope_len (con, rem_addr->ssel_len, spdu_type);
else
envelope_len = cosp_envelope_len (con, 0, spdu_type);
if (spdu_type == COSP_SI_CONNECT)
udata_max_len = COSP_MAX_UDATA_CON;
else
udata_max_len = COSP_MAX_UDATA; /* for ACCEPT SPDU */
if (udata_len == 0 || udata_len > udata_max_len)
{
COSP_LOG_ERR2 ("COSP-ERROR: Encoding CN/AC: Invalid User Data length=%u (0<length<=%u).",
udata_len, udata_max_len);
return (COSP_ERR_INV_UDATA_LEN);
}
/* set the pointer to beginning of encoding in the buffer (global buf)*/
enc_buf = con->ppdu_ptr - envelope_len;
if (enc_buf < cosp_buf)
{
COSP_LOG_ERR0 ("COSP-ERROR: Encoding CN/AC: Invalid pointer to Global Encoding Buffer.");
return (COSP_ERR_INV_POINTER);
}
idx = 0;
/*--------------------------------------------*/
/* Encode CN or AC code and total SPDU len */
/*--------------------------------------------*/
/* SPDU length to encode does not include 1 byte for SPDU code and */
/* 1 or 3 bytes for total len */
if (envelope_len-2 + udata_len <= 254)
enc_len = envelope_len-2 + udata_len; /* len enc on 1 byte */
else
enc_len = envelope_len-4 + udata_len; /* len enc on 3 bytes */
enc_buf [idx++] = spdu_type;
idx += cosp_enc_len ((ST_UINT16) enc_len, &enc_buf [idx]);
/*--------------------------------------------*/
/* no Connection Identifier PGI encoded */
/*--------------------------------------------*/
/*--------------------------------------------*/
/* encode Connect/Accept PGI: */
/* - extended concatination not supported, */
/* - COSP Version2 supported */
/* encode Session User Requirements PI: */
/* - duplex functional unit (FU) supported */
/*--------------------------------------------*/
memcpy (&enc_buf [idx], cosp_cn_ac_fixed, sizeof (cosp_cn_ac_fixed));
idx += sizeof (cosp_cn_ac_fixed);
/*----------------------------------------------*/
/* encode Calling SSEL - (CN only) */
/*----------------------------------------------*/
ssel_len = 0;
ssel = NULL; /* Just to avoid "uninitialized" warning. */
if (spdu_type == COSP_SI_CONNECT)
{
/* Calling SSEL - optional (only if needed) */
ssel_len = cosp_only_ssel [0];
ssel = &cosp_only_ssel [1];
}
if (ssel_len > 0)
{
enc_buf [idx++] = 51; /* encode PI code */
enc_buf [idx++] = ssel_len; /* encode PI len */
memcpy (&enc_buf [idx], ssel, (ST_UINT) ssel_len);
idx += ssel_len;
}
/*------------------------------------*/
/* encode Called/Responding SSEL (CN only) */
/*------------------------------------*/
ssel_len = 0;
ssel = NULL; /* Just to avoid "uninitialized" warning. */
if (spdu_type == COSP_SI_CONNECT && rem_addr != NULL)
{
/* Called SSEL - mandatory */
ssel_len = (ST_UCHAR) rem_addr->ssel_len;
ssel = (ST_UCHAR *) rem_addr->ssel;
}
if (ssel_len > 0)
{
enc_buf [idx++] = 52; /* PI code */
enc_buf [idx++] = ssel_len; /* PI len */
memcpy (&enc_buf [idx], ssel, (ST_UINT) ssel_len);
idx += ssel_len;
}
/*--------------------------------------------------------------------*/
/* encode User Data (length only), SS-user Data should be already */
/* in the enc_buf (in proper position). */
/*--------------------------------------------------------------------*/
if (spdu_type == COSP_SI_CONNECT)
{
if (udata_len <= 512)
enc_buf [idx++] = 193; /* encode PGI code */
else
enc_buf [idx++] = 194; /* if 512 < udata_len <= 10240)*/
}
else
{
/* ACCEPT SPDU */
enc_buf [idx++] = 193; /* encode PGI code */
}
idx += cosp_enc_len ((ST_UINT16) udata_len, &enc_buf [idx]);
/* udata should be already in enc_buf */
/*-----------------------------------------------*/
/* set values to be returned to calling function */
/*-----------------------------------------------*/
*spdu_len = envelope_len + udata_len;
*spdu_ptr = (char *) enc_buf;
return (SD_SUCCESS);
}
/************************************************************************/
/* cosp_enc_rf */
/*----------------------------------------------------------------------*/
/* Function to encode a REFUSE SPDU. */
/* This function assumed that there is enough place in the enc_buf for */
/* the RF SPDU encoding. The function cosp_envelope_len can be used */
/* to compute exact envelope encoding length. */
/* Note that this function assumes that the SS-user data (refuse reason)*/
/* has been already copied into the enc_buf in proper position. */
/* */
/* Parameters: */
/* ACSE_CONN *con Connection info parameters */
/* charE **spdu_ptr Pointer where to return pointer to SPDU */
/* ST_UINT *spdu_len Pointer where to return the SPDU len */
/* ST_UCHAR reason Reason code for refuse */
/* */
/* Return: */
/* SD_SUCCESS (0) if successful */
/* error code otherwise */
/************************************************************************/
ST_RET cosp_enc_rf (ACSE_CONN *con, char **spdu_ptr, ST_UINT *spdu_len,
ST_UCHAR reason)
{
ST_UINT envelope_len;
ST_UINT udata_len;
ST_UCHAR *enc_buf;
ST_UINT enc_len;
ST_UINT idx;
/*--------------------------------------------*/
/* make sure data len is OK */
/*--------------------------------------------*/
udata_len = con->ppdu_len;
envelope_len = cosp_envelope_len (con, 0, COSP_SI_REFUSE);
if (udata_len > COSP_MAX_UDATA)
{
COSP_LOG_ERR2 ("COSP-ERROR: Encoding RF: Invalid User Data length=%u (length<=%u).",
udata_len, COSP_MAX_UDATA);
return (COSP_ERR_INV_UDATA_LEN);
}
/* set the pointer to beginning of encoding in the buffer (global buf)*/
enc_buf = con->ppdu_ptr - envelope_len;
if (enc_buf < cosp_buf)
{
COSP_LOG_ERR0 ("COSP-ERROR: Encoding RF: Invalid pointer to Global Encoding Buffer.");
return (COSP_ERR_INV_POINTER);
}
idx = 0;
/*------------------------------------*/
/* Encode RF code and total SPDU len */
/*------------------------------------*/
/* SPDU length to encode does not include 1 byte for SPDU code and */
/* 1 or 3 bytes for total len */
if (envelope_len-2 + udata_len <= 254)
enc_len = envelope_len-2 + udata_len; /* len enc on 1 byte */
else
enc_len = envelope_len-4 + udata_len; /* len enc on 3 bytes */
enc_buf [idx++] = COSP_SI_REFUSE;
idx += cosp_enc_len ((ST_UINT16) enc_len, &enc_buf [idx]);
/*--------------------------------------------*/
/* no Connection Identifier PGI encoded */
/*--------------------------------------------*/
/*--------------------------------------------*/
/* encode Session User Requirements PI: */
/* - duplex functional unit (FU) supported */
/* encode COSP Version PI: */
/* - Version2 supported */
/*--------------------------------------------*/
memcpy (&enc_buf [idx], cosp_rf_fixed, sizeof (cosp_rf_fixed));
idx += sizeof (cosp_rf_fixed);
/*--------------------------------------------------------------------*/
/* encode Reason Code. SS-user Data (if any) should be already in the */
/* enc_buf (in proper position). */
/*--------------------------------------------------------------------*/
enc_buf [idx++] = 50; /* PI code */
idx += cosp_enc_len ((ST_UINT16) (udata_len+1), &enc_buf [idx]); /* len */
enc_buf [idx++] = reason; /* Reason code */
/* udata may follow if reason=COSP_RF_REASON_U_REJECT */
/*-----------------------------------------------*/
/* set values to be returned to calling function */
/*-----------------------------------------------*/
*spdu_len = envelope_len + udata_len;
*spdu_ptr = (char *) enc_buf;
return (SD_SUCCESS);
}
/************************************************************************/
/* cosp_enc_fn_dn */
/*----------------------------------------------------------------------*/
/* Function to encode a FINISH or DISCONNECT SPDU. */
/* This function assumed that there is enough place in the enc_buf for */
/* the FN or DN SPDU encoding. The function cosp_envelope_len can be */
/* used to compute exact envelope encoding length. */
/* Note that this function assumes that the SS-user data (RLRQ or RLRE */
/* APDU) have been already copied into the enc_buf in proper position. */
/* */
/* Parameters: */
/* ACSE_CONN *con Connection info parameters */
/* char **spdu_ptr Pointer where to return pointer to SPDU */
/* ST_UINT *spdu_len Pointer where to return the SPDU len */
/* ST_UCHAR spdu_type COSP_SI_FINISH or COSP_SI_DISCON */
/* */
/* Return: */
/* SD_SUCCESS (0) if successful */
/* error code otherwise */
/************************************************************************/
ST_RET cosp_enc_fn_dn (ACSE_CONN *con, char **spdu_ptr, ST_UINT *spdu_len,
ST_UCHAR spdu_type)
{
ST_UINT envelope_len;
ST_UINT udata_len;
ST_UCHAR *enc_buf;
ST_UINT enc_len;
ST_UINT idx;
/*------------------------------------------------------------*/
/* make sure data len is OK (User Data mandatory) */
/*------------------------------------------------------------*/
udata_len = con->ppdu_len;
envelope_len = cosp_envelope_len (con, 0, spdu_type);
if (udata_len == 0 || udata_len > COSP_MAX_UDATA)
{
COSP_LOG_ERR2 ("COSP-ERROR: Encoding FN/DN: Invalid User Data length=%u (0<length<=%u).",
udata_len, COSP_MAX_UDATA);
return (COSP_ERR_INV_UDATA_LEN);
}
/* set the pointer to beginning of encoding in the buffer (global buf)*/
enc_buf = con->ppdu_ptr - envelope_len;
if (enc_buf < cosp_buf)
{
COSP_LOG_ERR0 ("COSP-ERROR: Encoding FN/DN: Invalid pointer to Global Encoding Buffer.");
return (COSP_ERR_INV_POINTER);
}
idx = 0;
/*------------------------------------------*/
/* Encode FN or DN code and total SPDU len */
/*------------------------------------------*/
/* SPDU length to encode does not include 1 byte for FN or DN code */
/* and 1 or 3 bytes for total len */
if (envelope_len-2 + udata_len <= 254)
enc_len = envelope_len-2 + udata_len; /* len enc on 1 byte */
else
enc_len = envelope_len-4 + udata_len; /* len enc on 3 bytes */
enc_buf [idx++] = spdu_type;
idx += cosp_enc_len ((ST_UINT16) enc_len, &enc_buf [idx]);
/*--------------------------------------------------------------------*/
/* encode User Data (length only), SS-user Data should be already in */
/* the enc_buf (in proper position). */
/*--------------------------------------------------------------------*/
enc_buf [idx++] = 193; /* PI code */
idx += cosp_enc_len ((ST_UINT16) udata_len, &enc_buf [idx]);
/*-----------------------------------------------*/
/* set values to be returned to calling function */
/*-----------------------------------------------*/
*spdu_len = envelope_len + udata_len;
*spdu_ptr = (char *) enc_buf;
return (SD_SUCCESS);
}
/************************************************************************/
/* cosp_enc_u_ab */
/*----------------------------------------------------------------------*/
/* Function to encode a SS-user generated ABORT SPDU */
/* This function assumed that there is enough place in the enc_buf for */
/* the AB SPDU encoding. The function cosp_envelope_len can be used */
/* to compute exact envelope encoding length. */
/* Note that this function assumes that the SS-user data (ARP /ATU PPDU)*/
/* has been already copied into the enc_buf in proper position. */
/* */
/* Parameters: */
/* ACSE_CON *con Connection info parameters */
/* char **spdu_ptr Pointer where to return pointer to SPDU */
/* ST_UINT *spdu_len Pointer where to return the SPDU len */
/* */
/* Return: */
/* SD_SUCCESS (0) if successful */
/* error code otherwise */
/************************************************************************/
ST_RET cosp_enc_u_ab (ACSE_CONN *con, char **spdu_ptr, ST_UINT *spdu_len)
{
ST_UINT envelope_len;
ST_UINT udata_len;
ST_UCHAR *enc_buf;
ST_UINT enc_len;
ST_UINT idx;
/*------------------------------------------------------------*/
/* make sure data len is OK (depending on the reason the User */
/* Data or the Reflect Parameter presence is mandatory) */
/*------------------------------------------------------------*/
udata_len = con->ppdu_len;
envelope_len = cosp_envelope_len (con, 0, COSP_SI_ABORT);
//envelope_len = cosp_envelope_len (con, 0, COSP_SI_AB_ACCEPT); //renxiaobao2022 mod
if (udata_len == 0 || udata_len > COSP_MAX_UDATA)
{
COSP_LOG_ERR2 ("COSP-ERROR: Encoding U-AB: Invalid User Data length=%u (0<length<=%u).",
udata_len, COSP_MAX_UDATA);
return (COSP_ERR_INV_UDATA_LEN);
}
/* set the pointer to beginning of encoding in the buffer (global buf)*/
enc_buf = con->ppdu_ptr - envelope_len;
if (enc_buf < cosp_buf)
{
COSP_LOG_ERR0 ("COSP-ERROR: Encoding U-AB: Invalid pointer to Global Encoding Buffer.");
return (COSP_ERR_INV_POINTER);
}
idx = 0;
/*------------------------------------*/
/* Encode AB code and total SPDU len */
/*------------------------------------*/
/* SPDU length to encode does not include 1 byte for AB code and */
/* 1 or 3 bytes for total len */
if (envelope_len-2 + udata_len <= 254)
enc_len = envelope_len-2 + udata_len; /* len enc on 1 byte */
else
enc_len = envelope_len-4 + udata_len; /* len enc on 3 bytes */
enc_buf [idx++] = COSP_SI_ABORT;
//enc_buf [idx++] = COSP_SI_AB_ACCEPT;; //renxiaobao2022 mod
idx += cosp_enc_len ((ST_UINT16) enc_len, &enc_buf [idx]);
/*----------------------------------------------------*/
/* Encode Transport Disonnect PI (release TP conn) */
/*----------------------------------------------------*/
enc_buf [idx++] = 17; /* PI code */
enc_buf [idx++] = 1; /* PI len */
enc_buf [idx++] = COSP_TCONN_RELEASE | COSP_AB_REASON_USER_ABORT;
/*--------------------------------------------------------------------*/
/* encode User Data (length only), SS-user Data should be already */
/* in the enc_buf (in proper position). */
/*--------------------------------------------------------------------*/
if (udata_len > 0)
{
/* encode User Data */
enc_buf [idx++] = 193; /* PGI code */
idx += cosp_enc_len ((ST_UINT16) udata_len, &enc_buf [idx]);
/* udata should be already in enc_buf */
}
/*-----------------------------------------------*/
/* set values to be returned to calling function */
/*-----------------------------------------------*/
*spdu_len = envelope_len + udata_len;
*spdu_ptr = (char *) enc_buf;
return (SD_SUCCESS);
}
/************************************************************************/
/* cosp_enc_p_ab */
/*----------------------------------------------------------------------*/
/* Function to encode a SS-provider generated ABORT SPDU */
/* This function assumed that there is enough place in the enc_buf for */
/* the AB SPDU encoding (COSP_P_AB_LEN bytes). */
/* */
/* Parameters: */
/* char *spdu_ptr Pointer to encode buffer for SPDU */
/* ST_INT err_code This value will be passed for AB reason */
/* */
/* Return: */
/* SD_SUCCESS (0) if successful */
/* error code otherwise */
/************************************************************************/
ST_RET cosp_enc_p_ab (char *spdu_ptr, ST_INT err_code)
{
/*------------------------------------*/
/* Encode AB code and total SPDU len */
/*------------------------------------*/
spdu_ptr [0] = COSP_SI_ABORT;
spdu_ptr [1] = 3 + 4;
/*----------------------------------------------------*/
/* Encode Transport Disonnect PI (release TP conn) */
/*----------------------------------------------------*/
spdu_ptr [2] = 17; /* PI code */
spdu_ptr [3] = 1; /* PI len */
spdu_ptr [4] = COSP_TCONN_RELEASE | COSP_AB_REASON_PROT_ERROR;
/* encode the Reflect Parameter PI */
spdu_ptr [5] = 49; /* PI code */
spdu_ptr [6] = (ST_UCHAR) 2; /* PI len (0-9) */
spdu_ptr [7] = (ST_UCHAR) ((err_code >> 8) & 0x00FF);
spdu_ptr [8] = (ST_UCHAR) (err_code & 0x00FF);
/* !!! if number of encoded bytes changes make sure that the define */
/* !!! COSP_P_AB_SPDU_LEN is changed accordingly. */
return (SD_SUCCESS);
}
/************************************************************************/
/* cosp_enc_dt */
/*----------------------------------------------------------------------*/
/* Function to encode a DATA SPDU */
/* This function assumed that there is enough place in the enc_buf for */
/* the GIVE-TOKEN ans DT SPDU encoding. */
/* The function cosp_envelope_len can be used to compute exact envelope */
/* encoding length. */
/* Note that this function assumes that the SS-user data have been */
/* already copied into the enc_buf in proper position. */
/* */
/* Parameters: */
/* ACSE_CON *con Connection info parameters */
/* char **spdu_ptr Pointer where to return pointer to SPDU */
/* ST_UINT *spdu_len Pointer where to return the SPDU len */
/* */
/* Return: */
/* SD_SUCCESS (0) if successful */
/* error code otherwise */
/************************************************************************/
ST_RET cosp_enc_dt (ACSE_CONN *con, char **spdu_ptr, ST_UINT *spdu_len)
{
ST_UINT envelope_len;
ST_UINT udata_len;
ST_UCHAR *enc_buf;
ST_UINT idx;
/*------------------------------------------------------------*/
/* make sure data len is OK */
/*------------------------------------------------------------*/
udata_len = con->ppdu_len;
envelope_len = cosp_envelope_len (con, 0, COSP_SI_DATA);
if (udata_len == 0)
{
COSP_LOG_ERR2 ("COSP-ERROR: Encoding DT: Invalid User Data length=%u (0<length<=%u).",
udata_len, COSP_MAX_UDATA);
return (COSP_ERR_INV_UDATA_LEN);
}
/* set the pointer to beginning of encoding in the buffer (global buf)*/
enc_buf = con->ppdu_ptr - envelope_len;
if (enc_buf < cosp_buf)
{
COSP_LOG_ERR0 ("COSP-ERROR: Encoding DT: Invalid pointer to Global Encoding Buffer.");
return (COSP_ERR_INV_POINTER);
}
idx = 0;
/*--------------------------------------------*/
/* Encode GIVE-TOKEN code and params len LI=0 */
/*--------------------------------------------*/
enc_buf [idx++] = COSP_SI_GIVE_TOKEN;
enc_buf [idx++] = 0; /* no parameters present LI=0 */
/*------------------------------------*/
/* Encode DT code and params len LI=0 */
/*------------------------------------*/
enc_buf [idx++] = COSP_SI_DATA;
enc_buf [idx++] = 0; /* no parameters present LI=0 */
/* udata should be already in enc_buf */
/*-----------------------------------------------*/
/* set values to be returned to calling function */
/*-----------------------------------------------*/
*spdu_len = envelope_len + udata_len;
*spdu_ptr = (char *) enc_buf;
return (SD_SUCCESS);
}
/************************************************************************/
/* cosp_enc_len */
/*----------------------------------------------------------------------*/
/* Function to encode a parameter's len. If len<=254 then 1 byte */
/* will be used to encode the length. If len>254 then 3 bytes will */
/* be used to encode the length. */
/* */
/* Parameters: */
/* ST_UINT16 len Parameter's length to encode */
/* ST_UCHAR *buf Pointer where to encode the len */
/* */
/* Return: */
/* ST_UINT Number of bytes used in encoding of len */
/************************************************************************/
static ST_UINT cosp_enc_len (ST_UINT16 len, ST_UCHAR *buf)
{
ST_UINT bytes;
if (len <= 254)
{
buf [0] = (ST_UCHAR) len;
bytes = 1;
}
else
{
buf [0] = (ST_UCHAR) 0xFF; /* indicates len>254 */
buf [1] = (ST_UCHAR)((len >> 8) & 0x00FF); /* high order byte */
buf [2] = (ST_UCHAR) (len & 0x00FF); /* low order byte */
bytes = 3;
}
return (bytes);
}

2043
mmslib/ositcps/cospmain.c Normal file

File diff suppressed because it is too large Load Diff

1271
mmslib/ositcps/lean_cfg.c Normal file

File diff suppressed because it is too large Load Diff

163
mmslib/ositcps/lean_var.c Normal file
View File

@@ -0,0 +1,163 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 2005 - 2008 All Rights Reserved */
/* */
/* MODULE NAME : lean_var.c */
/* PRODUCT(S) : Lean-T Stack */
/* */
/* MODULE DESCRIPTION : */
/* Global variables used by the stack components are placed here, */
/* so that when they are referenced, the linker is NOT forced */
/* to pull in a lot of code. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* None */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 08/24/07 EJV 08 Ported for SNAP-Lite. */
/* 02/11/08 EJV 07 Turned ON the COPP_LOG_ERR and COSP_LOG_ERR. */
/* 10/04/07 MDE 06 Tweaked LOGCFG_VALUE_GROUP/LOGCFGX_VALUE_MAP */
/* 12/13/06 JRB 05 hPktSock moved here (avail on any system). */
/* 08/18/06 JRB 04 Init *_debug_sel with appropriate *_ERR. */
/* 05/24/05 EJV 03 Moved xxxLogMaskMapCtrl from logcfgx.c */
/* 02/01/05 JRB 02 Remove DEBUG_SISCO around *_debug_sel so old */
/* apps link without problems. */
/* 01/24/05 JRB 01 Created. */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#include "acse2usr.h" /* for ACSE_LOG_xxx */
#include "acse2log.h"
#include "tp4_log.h"
#if defined(MMS_LITE)
#include "clnp_log.h"
#endif
/************************************************************************/
/* Global Variables for ACSE, COPP, COSP layer logging. */
/************************************************************************/
ST_UINT acse_debug_sel = (ACSE_LOG_ERR | COPP_LOG_ERR | COSP_LOG_ERR);
#if defined(DEBUG_SISCO)
SD_CONST ST_CHAR *SD_CONST _acse_err_logstr = "ACSE_LOG_ERR";
SD_CONST ST_CHAR *SD_CONST _acse_enc_logstr = "ACSE_LOG_ENC";
SD_CONST ST_CHAR *SD_CONST _acse_dec_logstr = "ACSE_LOG_DEC";
SD_CONST ST_CHAR *SD_CONST _acse_dib_logstr = "ACSE_LOG_DIB";
SD_CONST ST_CHAR *SD_CONST _copp_err_logstr = "COPP_LOG_ERR";
SD_CONST ST_CHAR *SD_CONST _copp_dec_logstr = "COPP_LOG_DEC";
SD_CONST ST_CHAR *SD_CONST _copp_dec_hex_logstr = "COPP_LOG_DEC_HEX";
SD_CONST ST_CHAR *SD_CONST _copp_enc_logstr = "COPP_LOG_ENC";
SD_CONST ST_CHAR *SD_CONST _copp_enc_hex_logstr = "COPP_LOG_ENC_HEX";
SD_CONST ST_CHAR *SD_CONST _cosp_err_logstr = "COSP_LOG_ERR";
SD_CONST ST_CHAR *SD_CONST _cosp_dec_logstr = "COSP_LOG_DEC";
SD_CONST ST_CHAR *SD_CONST _cosp_dec_hex_logstr = "COSP_LOG_DEC_HEX";
SD_CONST ST_CHAR *SD_CONST _cosp_enc_logstr = "COSP_LOG_ENC";
SD_CONST ST_CHAR *SD_CONST _cosp_enc_hex_logstr = "COSP_LOG_ENC_HEX";
LOGCFGX_VALUE_MAP acseLogMaskMaps[] =
{
{"ACSE_LOG_ERR", ACSE_LOG_ERR, &acse_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "AcseError"},
{"ACSE_LOG_ENC", ACSE_LOG_ENC, &acse_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "AcseEncode"},
{"ACSE_LOG_DEC", ACSE_LOG_DEC, &acse_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "AcseDecode"},
{"ACSE_LOG_DIB", ACSE_LOG_DIB, &acse_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "DIB"},
{"COPP_LOG_ERR", COPP_LOG_ERR, &acse_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "CoppError"},
{"COPP_LOG_DEC", COPP_LOG_DEC, &acse_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "CoppDecode"},
{"COPP_LOG_DEC_HEX",COPP_LOG_DEC_HEX, &acse_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "CoppDecodeHex"},
{"COPP_LOG_ENC", COPP_LOG_ENC, &acse_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "CoppEncode"},
{"COPP_LOG_ENC_HEX",COPP_LOG_ENC_HEX, &acse_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "CoppEncodeHex"},
{"COSP_LOG_ERR", COSP_LOG_ERR, &acse_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "CoppError"},
{"COSP_LOG_DEC", COSP_LOG_DEC, &acse_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "CoppDecode"},
{"COSP_LOG_DEC_HEX",COSP_LOG_DEC_HEX, &acse_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "CoppDecodeHex"},
{"COSP_LOG_ENC", COSP_LOG_ENC, &acse_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "CoppEncode"},
{"COSP_LOG_ENC_HEX",COSP_LOG_ENC_HEX, &acse_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "CoppEncodeHex"}
};
LOGCFG_VALUE_GROUP acseLogMaskMapCtrl =
{
{NULL,NULL},
"AcseLogMasks", /* Parent Tag */
sizeof(acseLogMaskMaps)/sizeof(LOGCFGX_VALUE_MAP),
acseLogMaskMaps
};
#endif /* DEBUG_SISCO */
/************************************************************************/
/* Global Variables for TP4 layer logging. */
/************************************************************************/
ST_UINT tp4_debug_sel = TP4_LOG_ERR;
#if defined(DEBUG_SISCO)
SD_CONST ST_CHAR *SD_CONST _tp4_err_logstr = "TP4_LOG_ERR";
SD_CONST ST_CHAR *SD_CONST _tp4_flowup_logstr = "TP4_LOG_FLOWUP";
SD_CONST ST_CHAR *SD_CONST _tp4_flowdown_logstr = "TP4_LOG_FLOWDOWN";
LOGCFGX_VALUE_MAP tp4LogMaskMaps[] =
{
{"TP4_LOG_ERR", TP4_LOG_ERR, &tp4_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "Tp4Error"},
{"TP4_LOG_FLOWUP", TP4_LOG_FLOWUP, &tp4_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "Tp4FlowUp"},
{"TP4_LOG_FLOWDOWN", TP4_LOG_FLOWDOWN, &tp4_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "Tp4FlowDown"},
/* for TP0 use different names in xml file */
{"TP_LOG_ERR", TP4_LOG_ERR, &tp4_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "TpError"},
{"TP_LOG_FLOWUP", TP4_LOG_FLOWUP, &tp4_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "TpFlowUp"},
{"TP_LOG_FLOWDOWN", TP4_LOG_FLOWDOWN, &tp4_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "TpFlowDown"}
};
LOGCFG_VALUE_GROUP tp4LogMaskMapCtrl =
{
{NULL,NULL},
"TransportLogMasks", /* Parent Tag */
sizeof(tp4LogMaskMaps)/sizeof(LOGCFGX_VALUE_MAP),
tp4LogMaskMaps
};
#endif /* DEBUG_SISCO */
#if defined(MMS_LITE)
/************************************************************************/
/* Global Variables for CLNP layer logging. */
/************************************************************************/
ST_UINT clnp_debug_sel = CLNP_LOG_ERR;
#if defined(DEBUG_SISCO)
SD_CONST ST_CHAR *SD_CONST _clnp_err_logstr = "CLNP_LOG_ERR";
SD_CONST ST_CHAR *SD_CONST _clnp_nerr_logstr = "CLNP_LOG_NERR";
SD_CONST ST_CHAR *SD_CONST _clnp_req_logstr = "CLNP_LOG_REQ";
SD_CONST ST_CHAR *SD_CONST _clnp_ind_logstr = "CLNP_LOG_IND";
SD_CONST ST_CHAR *SD_CONST _clnp_enc_dec_logstr = "CLNP_LOG_ENC_DEC";
SD_CONST ST_CHAR *SD_CONST _clnp_llc_enc_dec_logstr = "CLNP_LOG_LLC_ENC_DEC";
SD_CONST ST_CHAR *SD_CONST _clsns_req_logstr = "CLSNS_LOG_REQ";
SD_CONST ST_CHAR *SD_CONST _clsns_ind_logstr = "CLSNS_LOG_IND";
LOGCFGX_VALUE_MAP clnpLogMaskMaps[] =
{
{"CLNP_LOG_ERR", CLNP_LOG_ERR, &clnp_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "Error"},
{"CLNP_LOG_NERR", CLNP_LOG_NERR, &clnp_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "Notice"},
{"CLNP_LOG_REQ", CLNP_LOG_REQ, &clnp_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "ClnpRequest"},
{"CLNP_LOG_IND", CLNP_LOG_IND, &clnp_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "ClnpIndication"},
{"CLNP_LOG_ENC_DEC", CLNP_LOG_ENC_DEC, &clnp_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "EncodeDecode"},
{"CLNP_LOG_LLC_ENC_DEC", CLNP_LOG_LLC_ENC_DEC, &clnp_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "EncodeDecode"},
{"CLSNS_LOG_REQ", CLSNS_LOG_REQ, &clnp_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "ClnsRequest"},
{"CLSNS_LOG_IND", CLSNS_LOG_IND, &clnp_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "ClnsIndication"}
};
LOGCFG_VALUE_GROUP clnpLogMaskMapCtrl =
{
{NULL,NULL},
"ClnpLogMasks", /* Parent Tag */
sizeof(clnpLogMaskMaps)/sizeof(LOGCFGX_VALUE_MAP),
clnpLogMaskMaps
};
#endif /* DEBUG_SISCO */
/************************************************************************/
/* hPktSock is used in LINUX subnetwork code (see clnp_linux.c) and it */
/* may be used on new systems. */
/************************************************************************/
int hPktSock = -1; /* Packet Socket handle: initialized to invalid value*/
#endif /* defined(MMS_LITE) */

1822
mmslib/ositcps/osicfgx.c Normal file

File diff suppressed because it is too large Load Diff

181
mmslib/ositcps/tp0_dec.c Normal file
View File

@@ -0,0 +1,181 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1997 All Rights Reserved */
/* */
/* MODULE NAME : tp0_dec.c */
/* PRODUCT(S) : Lean-T Stack */
/* */
/* MODULE DESCRIPTION : */
/* TP0 decode functions. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* np_data_ind () */
/* np_disconnect_ind () */
/* np_connect_cnf_pos () */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 10/22/08 JRB 06 TPDU must be at least 2 bytes to decode. */
/* Chg tp_decode_er to really decode ER TPDU. */
/* 04/07/03 JRB 05 Add SPDU_RX_NO_PREALLOCATE option. */
/* 04/13/00 JRB 04 Lint cleanup. */
/* 08/13/98 JRB 03 Lint cleanup. */
/* 09/25/97 JRB 02 Don't generate exception for invalid state. */
/* 08/01/97 JRB 01 Created (compatible with MMS-EASE 7.0). */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#include "mem_chk.h"
#include "tp4api.h" /* User definitions for tp4 */
#include "tp4.h" /* Internal definitions for tp4 */
#include "tp4_encd.h"
#include "tp4_log.h"
#ifdef DEBUG_SISCO
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
#endif
/************************************************************************/
/* np_data_ind */
/* This "np_data_ind" funct is similar to "tp_decode_nsdu" used for TP4.*/
/* It calls one function to decode the PDU, then another function to */
/* process it. The "decode" functions are shared with TP4. */
/************************************************************************/
ST_VOID np_data_ind (SOCK_INFO *sock_info, ST_UCHAR *pdu_ptr, ST_UINT16 pdu_len)
{
ST_UCHAR type;
ST_UINT16 len; /* len of processed TPDU by a dec func */
TPDU_CX tpdu_cx_rx; /* tpdu_cr_rx or tpdu_cc_rx */
TPDU_DR tpdu_dr_rx;
TPDU_DT tpdu_dt_rx;
TPDU_ER tpdu_er_rx;
/* TP0 TPDU starts after TPKT hdr (RFC1006_HEAD_LEN bytes). */
/* TPDU must be at least 2 bytes (len and TPDU code) to safely decode.*/
if (pdu_len < RFC1006_HEAD_LEN + 2)
{
TP_LOG_ERR0 ("TP0 TPDU too short to decode. Ignored.");
return;
}
/* Strip off TPKT header. */
pdu_len -= RFC1006_HEAD_LEN;
pdu_ptr += RFC1006_HEAD_LEN;
/* get the TPDU type (from the second octet, bits 4-7) */
type = pdu_ptr [1] & TP_PDU_MASK_CDT;
/* Based on type of TPDU (CR, CC, DT, etc.) call appropriate decode */
/* subfunction. */
switch (type)
{
case TP_PDU_TYPE_CR:
case TP_PDU_TYPE_CC:
if ((len = tp_decode_cx (&tpdu_cx_rx, pdu_ptr, pdu_len, type,
TP_PDU_MAX_SIZE_65531)) != 0) /* Default TPDU size=65531*/
{
tpdu_cx_rx.sock_info = sock_info;
tp_log_tsdu ((ST_VOID *) &tpdu_cx_rx, type, TP_IND);
/* This is the only step different in processing CR or CC. */
if (type == TP_PDU_TYPE_CR)
tp0_process_cr (&tpdu_cx_rx);
else
tp0_process_cc (&tpdu_cx_rx);
}
break;
case TP_PDU_TYPE_DR:
if ((len = tp_decode_dr (&tpdu_dr_rx, pdu_ptr, pdu_len)) != 0)
{
tpdu_dr_rx.sock_info = sock_info;
tp_log_tsdu ((ST_VOID *) &tpdu_dr_rx, TP_PDU_TYPE_DR, TP_IND);
tp0_process_dr (&tpdu_dr_rx);
}
break;
case TP_PDU_TYPE_DT:
if ((len = tp0_decode_dt (&tpdu_dt_rx, pdu_ptr, pdu_len)) != 0)
{
tpdu_dt_rx.sock_info = sock_info;
tp_log_tsdu ((ST_VOID *) &tpdu_dt_rx, TP_PDU_TYPE_DT, TP_IND);
tp0_process_dt (&tpdu_dt_rx);
}
break;
case TP_PDU_TYPE_ER:
/* NOTE: the last arg indicates this is Transport Class 0. */
if ((len = tp_decode_er (&tpdu_er_rx, pdu_ptr, pdu_len, 0)) > 0)
{
/* decode succeeded but we ignore ER TPDU. Log so user knows.*/
TP_LOG_ERR0 ("DEBUG: processing of TPDU-ER.ind not implemented yet.");
}
break;
case TP_PDU_TYPE_ED: /* we do not support expedited data */
case TP_PDU_TYPE_EA:
TP_LOG_ERR0 ("TP-ERROR: decode ED or EA TPDU failed (not supported)");
break; /* Do nothing */
default: /* type unknown, we should exit decoding */
TP_LOG_ERR1 ("TP-ERROR: decode TPDU failed (invalid type 0x%2.2X)",
(unsigned) type);
break;
} /* end "switch" */
}
/************************************************************************/
/* np_disconnect_ind */
/************************************************************************/
ST_VOID np_disconnect_ind (SOCK_INFO *sock_info)
{
TP0_CONN *tp_conn;
ST_INT reason; /* Transport Disconnect reason */
if (sock_info->user_conn_id == INVALID_CONN_ID)
return; /* Transport doesn't know about connection yet. IGNORE. */
tp_conn = (TP0_CONN *) sock_info->user_conn_id;
switch (tp_conn->state)
{
case TP_STATE_WFNC:
case TP_STATE_WFCC:
case TP_STATE_OPEN:
case TP_STATE_WFTRESP:
reason = 0; /* Normal disconnection */
/* NOTE: To save memory, user data is never passed up to user. */
tp4_disconnect_ind (tp_conn->user_conn_id, reason,
0, NULL); /* No user data passed up. */
tp_conn->state = TP_STATE_CLOSED;
#if defined(SPDU_RX_NO_PREALLOCATE)
M_FREE (MSMEM_STARTUP, tp_conn->spdu_rx.spdu_ptr);
#endif
break;
default:
TP_LOG_ERR1 ("TP-ERROR: invalid state (%d) for N-DISCONNECT.ind. Ignored.",
tp_conn->state);
break;
}
}
/************************************************************************/
/* np_connect_cnf_pos */
/************************************************************************/
ST_VOID np_connect_cnf_pos (SOCK_INFO *sock_info, ST_LONG user_conn_id)
{
TP0_CONN *tp_conn = (TP0_CONN *) user_conn_id;
/* Save sock_info ptr in tp_conn. */
tp_conn->sock_info = sock_info;
/* CRITICAL: Save sock_info in tp_conn->tpdu_cx before calling tp0_send_cr*/
tp_conn->tpdu_cx.sock_info = tp_conn->sock_info;
/* Send T-CONNECT.req */
tp0_send_cr (&tp_conn->tpdu_cx);
tp_conn->state = TP_STATE_WFCC;
}

1937
mmslib/ositcps/tp0_socks.c Normal file

File diff suppressed because it is too large Load Diff

210
mmslib/ositcps/tp0calld.c Normal file
View File

@@ -0,0 +1,210 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1997 - 2005 All Rights Reserved */
/* */
/* MODULE NAME : tp0calld.c */
/* PRODUCT(S) : Lean-T Stack */
/* */
/* MODULE DESCRIPTION : */
/* TP0 functions for handling of "Called" side of connections. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* tp0_accept () */
/* tp0_process_cr () */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 07/30/08 JRB 08 Use DR reason codes valid for TP0. */
/* 03/29/05 EJV 07 Added MMSEASE_MOSI support. */
/* 06/20/02 JRB 06 Chg addr args to tp4_connect_ind. */
/* 05/09/01 JRB 05 On T-CONNECT.ind, save TSAPs in TP0_CONN. */
/* 04/25/00 JRB 04 Lint cleanup. */
/* 06/08/99 JRB 03 Chg to support 1024 connections. */
/* 08/13/98 JRB 02 Lint cleanup. */
/* 08/01/97 JRB 01 Created (compatible with MMS-EASE 7.0). */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#include "mem_chk.h"
#include "tp4api.h" /* User definitions for tp4 */
#include "tp4.h" /* Internal definitions for tp4 */
#include "tp4_encd.h" /* Encode/decode defs for tp4 */
#include "tp4_log.h"
#ifdef DEBUG_SISCO
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
#endif
/*======================================================================*/
/*======================================================================*/
/* FUNCTIONS BELOW CALLED BY USER TO ENCODE AND SEND TPDUs. */
/*======================================================================*/
/*======================================================================*/
/************************************************************************/
/* tp0_accept */
/* This function is called by the user to accept a connect request from */
/* a remote node */
/************************************************************************/
ST_RET tp0_accept (ST_LONG tp0_conn_id, ST_LONG user_conn_id,
ST_INT conndata_len,
char *conndata)
{
TP0_CONN *tp_conn;
if ((ST_ULONG) (tp0_conn_id-MIN_TP0_CONN_ID) >= tp0_cfg.max_num_conns)
return (TP4E_BADCONN);
tp_conn = &tp0_conn_arr [tp0_conn_id-MIN_TP0_CONN_ID];
if (tp_conn->state != TP_STATE_WFTRESP)
return (TP4E_BADCONN);
tp_conn->user_conn_id = user_conn_id; /* Save User's ID */
/* Save User Data in tp_conn for retransmission. */
/* DEBUG: Can we blow this off to save space? */
tp_conn->tpdu_cx.udata_len = min ((ST_UINT16) conndata_len, TP_MAX_CONN_UDATA);
memcpy (tp_conn->tpdu_cx.udata_buf, conndata, tp_conn->tpdu_cx.udata_len);
tp_conn->state = TP_STATE_OPEN;
tp0_send_cc (&tp_conn->tpdu_cx);
return (SD_SUCCESS);
}
/*======================================================================*/
/*======================================================================*/
/* FUNCTIONS BELOW CALLED BY TP0 TO PROCESS TPDUs RECEIVED */
/* (TPDUs ALREADY DECODED BY TP0). */
/*======================================================================*/
/*======================================================================*/
/************************************************************************/
/* tp0_process_cr */
/* Process a CR (Connection Request) TPDU. */
/************************************************************************/
ST_VOID tp0_process_cr (TPDU_CX *tpdu_cr_rx)
{
ST_UINT16 conn_id; /* index into "tp0_conn_arr" array (Unsigned so */
/* no sign-extension on compare to tp0_cfg.max_num_conns).*/
TP0_CONN *tp_conn; /* ptr to struct in "tp0_conn_arr" array. */
TPDU_DR tpdu_dr;
ST_LONG tp0_user_bind_id;
/* Fill in TPDU_DR struct in case DR needs to be sent. */
/* Do not fill in "reason" yet. */
tpdu_dr.loc_ref = 0; /* src-ref = 0 (always) */
tpdu_dr.rem_ref = tpdu_cr_rx->rem_ref;
tpdu_dr.sock_info = tpdu_cr_rx->sock_info;
/* Check if Local TSAP is correct. */
#if defined(MMSEASE_MOSI)
if (tp0_check_tsel (tpdu_cr_rx->loc_tsap, &tp0_user_bind_id) != SD_SUCCESS)
#else
tp0_user_bind_id = only_tp0_user_bind_id;
if (memcmp (tpdu_cr_rx->loc_tsap, only_tp0_loc_tsap, only_tp0_loc_tsap[0]+1))
#endif
{
TP_LOG_ERR0 ("TP-ERROR: received CR with invalid TSAP. Sending DR.");
TP_LOGH_ERR (tpdu_cr_rx->loc_tsap[0], &tpdu_cr_rx->loc_tsap[1]);
tpdu_dr.reason = TP_DR_ADDR_UNKNOWN;
tp0_send_dr (&tpdu_dr);
return;
}
/* Check for Transport Class 0. Don't allow any other. */
if (tpdu_cr_rx->preferred_class != 0)
{
TP_LOG_ERR1 ("TP-ERROR: received CR with invalid class %d. Sending DR.",
tpdu_cr_rx->preferred_class);
/* NOTE: this DR "reason" is not legal for Class 0, but caller */
/* proposed different class, so they should recognize this reason. */
tpdu_dr.reason = TP_DR_CLASS_UNSUPPORTED; /* illegal for TP0 but OK here*/
tp0_send_dr (&tpdu_dr);
return;
}
/* Local Ref must equal 0. If not, it is protocol error. */
if (tpdu_cr_rx->loc_ref != 0)
{
TP_LOG_ERR0 ("TP-ERROR: received CR with invalid reference. Sending DR.");
tpdu_dr.reason = TP_DR_NO_REASON;
tp0_send_dr (&tpdu_dr);
return;
}
/* Look for a position in "tp0_conn_arr" where state = TP_STATE_CLOSED */
tp_conn = &tp0_conn_arr [0];
for (conn_id = 0; conn_id < tp0_cfg.max_num_conns; conn_id++, tp_conn++)
{
if (tp_conn->state == TP_STATE_CLOSED)
{
tp0_conn_clean (tp_conn); /* Good time to clean up conn struct. */
inc_loc_ref_offset (tp_conn->loc_ref_offset);
/* Save sock_info in "tp_conn". */
tp_conn->sock_info = tpdu_cr_rx->sock_info;
/* Save tp_conn (as user_conn_id) in "sock_info". */
tp_conn->sock_info->user_conn_id = (ST_LONG) tp_conn;
/* Copy the CR info to the tp_conn struct and modify it for the CC.*/
/* Most parameters we send back exactly as received (all except */
/* max_tpdu_len, loc_ref, cdt, udata_buf/len). */
/* NOTE: udata_buf/len not changed until tp0_accept. */
memcpy (&tp_conn->tpdu_cx, tpdu_cr_rx, sizeof (TPDU_CX));
tp_conn->tpdu_cx.max_tpdu_len_enc = min (tp0_cfg.max_tpdu_len_enc,
tpdu_cr_rx->max_tpdu_len_enc);
/* Save negotiated TPDU len in tp_conn. */
switch (tp_conn->tpdu_cx.max_tpdu_len_enc)
{ /* code for PDU size */
case TP_PDU_MAX_SIZE_128 : tp_conn->max_tpdu_len = 128; break;
case TP_PDU_MAX_SIZE_256 : tp_conn->max_tpdu_len = 256; break;
case TP_PDU_MAX_SIZE_512 : tp_conn->max_tpdu_len = 512; break;
case TP_PDU_MAX_SIZE_1024 : tp_conn->max_tpdu_len = 1024; break;
case TP_PDU_MAX_SIZE_2048 : tp_conn->max_tpdu_len = 2048; break;
case TP_PDU_MAX_SIZE_4096 : tp_conn->max_tpdu_len = 4096; break;
case TP_PDU_MAX_SIZE_8192 : tp_conn->max_tpdu_len = 8192; break;
case TP_PDU_MAX_SIZE_65531: tp_conn->max_tpdu_len = 65531; break;
default:
TP_LOG_ERR0 ("TP-ERROR: received CR with illegal TPDU size. Sending DR.");
tpdu_dr.reason = TP_DR_NO_REASON;
tp0_send_dr (&tpdu_dr);
return;
} /* end "switch" */
tp_conn->tpdu_cx.loc_ref = calc_loc_ref (conn_id, tp_conn->loc_ref_offset);
tp_conn->tpdu_cx.cdt = 0; /* CDT always 0 for Class 0 */
/* Set "tp_conn" parameters for new connection. */
tp_conn->rem_ref = tpdu_cr_rx->rem_ref; /* need for sending AKs */
tp_conn->state = TP_STATE_WFTRESP;
/* Save TSAPs in TP0_CONN struct. */
memcpy (tp_conn->loc_tsap, tpdu_cr_rx->loc_tsap, tpdu_cr_rx->loc_tsap[0]+1);
memcpy (tp_conn->rem_tsap, tpdu_cr_rx->rem_tsap, tpdu_cr_rx->rem_tsap[0]+1);
tp4_connect_ind (tp0_user_bind_id, conn_id+MIN_TP0_CONN_ID,
tpdu_cr_rx->loc_tsap,
tpdu_cr_rx->rem_tsap,
NULL, /* NSAP: not used */
tp_conn->sock_info->ip_addr,
(ST_INT) tpdu_cr_rx->udata_len,
tpdu_cr_rx->udata_buf);
break; /* BREAK OUT OF LOOP. Only want 1 connection!!! */
}
} /* end "for" loop */
if (conn_id >= tp0_cfg.max_num_conns)
{ /* Did not find an available conn_id. */
TP_LOG_ERR0 ("TP-ERROR: not enough resources for received CR. Sending DR.");
tpdu_dr.reason = TP_DR_CONGESTION_AT_TSAP; /* legal for TP0 */
tp0_send_dr (&tpdu_dr);
return;
}
return;
}

243
mmslib/ositcps/tp0callg.c Normal file
View File

@@ -0,0 +1,243 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1997-2005 All Rights Reserved */
/* */
/* MODULE NAME : tp0callg.c */
/* PRODUCT(S) : Lean-T Stack */
/* */
/* MODULE DESCRIPTION : */
/* TP0 functions for handling of "Calling" side of connections. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* tp0_connect */
/* tp0_process_cc */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 11/12/08 MDE 15 Added tpdu_cc->sock_info->user_conn_id check */
/* 07/30/08 JRB 14 Use DR reason codes valid for TP0. */
/* 05/06/05 EJV 13 Added port param to np_connect_req call. */
/* 03/29/05 EJV 12 Added MMSEASE_MOSI support. */
/* 09/17/04 JRB 11 Chg tp0_connect to return connection ID. */
/* 02/02/04 JRB 10 tp0_connect: fix tp_type, bind_id checks. */
/* 07/30/03 EJV 09 Added encrypt_ctrl to tp0_connect. */
/* 04/07/03 JRB 08 Add SPDU_RX_NO_PREALLOCATE option. */
/* 06/20/02 JRB 07 Pass ip addr as ulong to np_connect_req. */
/* 06/08/99 JRB 06 Chg to support 1024 connections. */
/* 08/13/98 JRB 05 Lint cleanup. */
/* 06/17/98 JRB 04 Increment loc_ref_offset before encoding CR */
/* to avoid sending duplicate CR. */
/* 12/04/97 JRB 03 Don't chk TSAPs on CC (may not be sent). */
/* 09/25/97 JRB 02 Don't generate exception for invalid state. */
/* 08/01/97 JRB 01 Created (compatible with MMS-EASE 7.0). */
/************************************************************************/
static char *thisFileName = __FILE__; /* For TP4_EXCEPT and slog macros*/
#include "glbtypes.h"
#include "sysincs.h"
#include "mem_chk.h"
#include "tp4api.h" /* User definitions for tp4 */
#include "tp4.h" /* Internal definitions for tp4 */
#include "tp4_encd.h" /* Encode/decode defs for tp4 */
#include "tp4_log.h"
/************************************************************************/
/* tp0_connect */
/* This function is called by the user to initiate a connect request to */
/* a remote node */
/* RETURNS: connection ID if successful, (-1) on error */
/* CRITICAL: connection ID = (conn_id+MIN_TP0_CONN_ID). Remember that */
/* this is hoe we distinguish between TP0 and TP4 connections. */
/************************************************************************/
ST_LONG tp0_connect (ST_LONG tp0_bind_id, ST_LONG user_conn_id,
TP4_ADDR *rem_tp4_addr,
ST_INT conndata_len,
char *conndata,
S_SEC_ENCRYPT_CTRL *encrypt_ctrl)
{
ST_UINT16 conn_id; /* index into "tp0_conn_arr" array. */
TP0_CONN *tp_conn;
TPDU_CX *tpdu_cr;
ST_UCHAR *tp0_loc_tsap;
if (rem_tp4_addr->tp_type == TP_TYPE_TCP)
{
#if defined(MMSEASE_MOSI)
if (tp0_check_bind_id (tp0_bind_id, &tp0_loc_tsap) != SD_SUCCESS)
#else
tp0_loc_tsap = only_tp0_loc_tsap;
if (tp0_bind_id != only_tp0_bind_id)
#endif
{
TP_LOG_ERR1 ("tp0_connect: bind id %ld invalid. TCP must be enabled in config.", tp0_bind_id);
return (-1);
}
}
else /* Transport type not TP0, this is error. */
{
TP_LOG_ERR0 ("tp0_connect: invalid transport type");
return (-1);
}
if (rem_tp4_addr->tp4_sel_len > MAX_TSEL_LEN)
{
TP4_EXCEPT (); /* If this happens, user code is invalid. */
return (-1);
}
/* Look for available connection. */
tp_conn = &tp0_conn_arr [0];
for (conn_id = 0; conn_id < tp0_cfg.max_num_conns; conn_id++, tp_conn++)
{
if (tp_conn->state == TP_STATE_CLOSED)
break; /* Found one!! "tp_conn" points to it now. */
} /* end "for" */
if (conn_id >= tp0_cfg.max_num_conns)
{ /* Didn't find one!! */
TP_LOG_ERR0 ("TP-ERROR: tp0_connect: all connections in use");
return (-1);
}
/* "tp_conn" now points to a connection in TP_STATE_CLOSED state. */
tp0_conn_clean (tp_conn); /* Good time to clean up conn struct. */
/* Increment "loc_ref_offset" to avoid duplicate CR. */
inc_loc_ref_offset (tp_conn->loc_ref_offset);
/* Set "tpdu_cr" pointing to "tp_conn->tpdu_cx" and fill in. */
/* Info stored in "tp_conn" in case retransmissions needed. */
tpdu_cr = &tp_conn->tpdu_cx;
memcpy (tpdu_cr->loc_tsap, tp0_loc_tsap, tp0_loc_tsap [0]+1);
tpdu_cr->rem_tsap [0] = (ST_UCHAR) rem_tp4_addr->tp4_sel_len;
memcpy (&tpdu_cr->rem_tsap [1], rem_tp4_addr->tp4_sel, rem_tp4_addr->tp4_sel_len);
tpdu_cr->loc_ref = calc_loc_ref (conn_id, tp_conn->loc_ref_offset);
tpdu_cr->rem_ref = 0;
tpdu_cr->max_tpdu_len_enc = tp0_cfg.max_tpdu_len_enc;
tpdu_cr->preferred_class = 0;
tpdu_cr->cdt = 0;
tpdu_cr->udata_len = min ((ST_UINT16) conndata_len, TP_MAX_CONN_UDATA);
memcpy (tpdu_cr->udata_buf, conndata, tpdu_cr->udata_len);
/* Set state before calling np_connect_req (may complete immediately).*/
tp_conn->user_conn_id = user_conn_id; /* Save User's ID for confirm. */
tp_conn->state = TP_STATE_WFNC;
if ((tp_conn->sock_info = np_connect_req ((ST_LONG) tp_conn, rem_tp4_addr->netAddr.ip,
rem_tp4_addr->port, encrypt_ctrl)) == NULL)
{
tp_conn->state = TP_STATE_CLOSED; /* CRITICAL: so tp_conn can be reused.*/
#if defined(SPDU_RX_NO_PREALLOCATE)
M_FREE (MSMEM_STARTUP, tp_conn->spdu_rx.spdu_ptr);
#endif
return (-1); /* Network connect failed immediately. */
}
/* CRITICAL: For TP0, connection ID = (conn_id+MIN_TP0_CONN_ID). */
return (conn_id+MIN_TP0_CONN_ID);
}
/************************************************************************/
/* tp0_process_cc */
/************************************************************************/
ST_VOID tp0_process_cc (TPDU_CX *tpdu_cc)
{
ST_ULONG conn_id; /* index into "tp0_conn_arr" array (Unsigned so */
/* no sign-extension on compare to tp0_cfg.max_num_conns).*/
TP0_CONN *tp_conn; /* ptr to struct in "tp0_conn_arr" array. */
TPDU_DR tpdu_dr;
ST_INT unacceptable_cc = SD_FALSE;
ST_INT reason;
/* Fill in TPDU_DR struct in case DR needs to be sent. */
/* Do not fill in "reason" yet. */
tpdu_dr.loc_ref = tpdu_cc->loc_ref;
tpdu_dr.rem_ref = tpdu_cc->rem_ref;
tpdu_dr.sock_info = tpdu_cc->sock_info;
/* Check connection ID. */
if (tpdu_cc->sock_info->user_conn_id == INVALID_CONN_ID)
{
/* Invalid ID means CR has not been sent, so this CC is unexpected. */
/* CC most likely received from "abnormal" application. */
TP_LOG_ERR0 ("TP-ERROR: tp0_process_cc: Invalid tp_conn");
/* May be intentional attack, so disconnect immediately. */
np_disconnect_req (tpdu_cc->sock_info);
return;
}
/* Find the correct "tp_conn". It should have been saved in sock_info.*/
tp_conn = (TP0_CONN *) tpdu_cc->sock_info->user_conn_id;
conn_id = tp_conn - tp0_conn_arr; /* conn_id = index into array */
switch (tp_conn->state)
{
case TP_STATE_CLOSED:
tpdu_dr.reason = TP_DR_NO_SESSION; /* We're not trying to connect*/
tp0_send_dr (&tpdu_dr);
break;
case TP_STATE_WFCC:
/* Check for Transport Class 0. Don't allow any other. */
if (tpdu_cc->preferred_class != 0)
{
unacceptable_cc = SD_TRUE;
}
/* Save negotiated TPDU len in tp_conn->max_tpdu_len. */
switch (tpdu_cc->max_tpdu_len_enc)
{
case TP_PDU_MAX_SIZE_128 : tp_conn->max_tpdu_len = 128; break;
case TP_PDU_MAX_SIZE_256 : tp_conn->max_tpdu_len = 256; break;
case TP_PDU_MAX_SIZE_512 : tp_conn->max_tpdu_len = 512; break;
case TP_PDU_MAX_SIZE_1024 : tp_conn->max_tpdu_len = 1024; break;
case TP_PDU_MAX_SIZE_2048 : tp_conn->max_tpdu_len = 2048; break;
case TP_PDU_MAX_SIZE_4096 : tp_conn->max_tpdu_len = 4096; break;
case TP_PDU_MAX_SIZE_8192 : tp_conn->max_tpdu_len = 8192; break;
case TP_PDU_MAX_SIZE_65531: tp_conn->max_tpdu_len = 65531; break;
/* Default to ILLEGAL value (i.e. 0) */
default: tp_conn->max_tpdu_len = 0; break;
} /* end "switch" */
/* If max_tpdu_len ILLEGAL or ">" proposed, this is protocol error.*/
if (tp_conn->max_tpdu_len == 0 || /* ILLEGAL */
tp_conn->max_tpdu_len > tp0_cfg.max_tpdu_len) /* ">" proposed */
{
tpdu_dr.reason = TP_DR_NO_REASON;
unacceptable_cc = SD_TRUE;
}
if (unacceptable_cc)
{ /* UN-ACCEPTABLE CLASS 0 CC TPDU. */
reason = 0xff; /* Local user error */
tp4_disconnect_ind (tp_conn->user_conn_id, reason,
0, NULL); /* No user data passed up. */
np_disconnect_req (tp_conn->sock_info);
tp_conn->state = TP_STATE_CLOSED;
#if defined(SPDU_RX_NO_PREALLOCATE)
M_FREE (MSMEM_STARTUP, tp_conn->spdu_rx.spdu_ptr);
#endif
}
else
{ /* ACCEPTABLE CLASS 0 CC TPDU. */
/* Save "rem_ref" in "tp_conn". */
tp_conn->rem_ref = tpdu_cc->rem_ref;
/* CRITICAL: set state before tp4_connect_cnf because may */
/* send first Transport data from within tp4_connect_cnf. */
tp_conn->state = TP_STATE_OPEN;
tp4_connect_cnf (tp_conn->user_conn_id, conn_id+MIN_TP0_CONN_ID,
(ST_UINT) tpdu_cc->udata_len, tpdu_cc->udata_buf);
tp_conn->state = TP_STATE_OPEN;
}
break;
default:
TP_LOG_ERR1 ("TP-ERROR: invalid state (%d) for received CC. Ignored.",
tp_conn->state);
break;
} /* end "switch" */
return;
}

1173
mmslib/ositcps/tp0main.c Normal file

File diff suppressed because it is too large Load Diff

539
mmslib/ositcps/tp4_enc.c Normal file
View File

@@ -0,0 +1,539 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1996, All Rights Reserved. */
/* */
/* PROPRIETARY AND CONFIDENTIAL */
/* */
/* MODULE NAME : tp4_enc.c */
/* PRODUCT(S) : Lean-T Stack */
/* */
/* MODULE DESCRIPTION : */
/* This module implements the encoding of the TPDUs. */
/* */
/* For information see the: */
/* ISO 8073 "Information processing systems - Open Systems */
/* Interconnections - Connection oriented transport protocol */
/* specification. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* tp_encode_cx */
/* tp_encode_dr */
/* tp_encode_dc */
/* tp_encode_dt */
/* tp0_encode_dt */
/* tp_encode_ak */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 08/13/98 JRB 04 Fix indenting. */
/* 08/26/97 JRB 03 RFC1006 changes: */
/* - add TP0 encode */
/* - tp_encode_cx: if TPDU size = 65531, don't */
/* encode it. Peer should default to 65531. */
/* - Use TP_PDU_TYPE_* everywhere. */
/* 05/27/97 JRB 7.00 MMSEASE 7.0 release. */
/* 10/04/96 JRB 02 Use max_tpdu_len_enc (binary encoded value). */
/* 06/20/96 EJV 01 Created */
/************************************************************************/
static char *thisFileName = __FILE__; /* For TP4_EXCEPT and slog macros*/
#include "glbtypes.h"
#include "sysincs.h"
#include "checksum.h"
#include "tp4api.h" /* User definitions for tp4 */
#include "tp4.h"
#include "tp4_encd.h"
#include "tp4_log.h"
/* local functions prototypes */
static ST_VOID tp_enc_par_checksum (ST_UCHAR *buf, ST_UINT16 buf_len, ST_UINT16 par_pos);
/************************************************************************/
/* tp_encode_cx */
/*----------------------------------------------------------------------*/
/* This function is used to encode a CR or CC TPDU. */
/* */
/* Parameters: */
/* ST_UCHAR *enc_buf Pointer where to encode the CX TPDU */
/* TPDU_CX *tpdu_cx Pointer to info struct for CX TPDU */
/* ST_UCHAR pdu_type TP_PDU_TYPE_CR or TP_PDU_TYPE_CC */
/* */
/* Return: */
/* ST_UINT16 The actual length of encoded TPDU */
/************************************************************************/
ST_UINT16 tp_encode_cx (ST_UCHAR *enc_buf, TPDU_CX *tpdu_cx, ST_UCHAR pdu_type)
{
ST_UINT16 enc_len; /* The actual length of encoded TPDU */
TP_FHDR_CX *pdu;
TP_PAR *param; /* generic struct for a parameter */
ST_UINT16 idx; /* points to current offset into enc_buf*/
enc_len = 0;
/*------------------------------------*/
/* encode TPDU header, fixed part */
/*------------------------------------*/
pdu = (TP_FHDR_CX *) enc_buf;
/* compute actual header length (do not count the hdr_len byte) */
if (tpdu_cx->preferred_class == 0)
pdu->hdr_len =
(ST_UCHAR) (TP_FHDR_CX_LEN - sizeof(pdu->hdr_len)+ /* fixed part of header */
TP_PAR_FIX_LEN + tpdu_cx->loc_tsap [0] + /* local TSAP parameter */
TP_PAR_FIX_LEN + tpdu_cx->rem_tsap [0]); /* remote TSAP parameter*/
else
pdu->hdr_len =
(ST_UCHAR) (TP_FHDR_CX_LEN - sizeof(pdu->hdr_len)+ /* fixed part of header */
TP_PAR_FIX_LEN + tpdu_cx->loc_tsap [0] + /* local TSAP parameter */
TP_PAR_FIX_LEN + tpdu_cx->rem_tsap [0] + /* remote TSAP parameter*/
TP_PAR_LEN_VERSION + /* TP version parameter */
TP_PAR_LEN_ADD_OPTIONS + /* additional opt param */
TP_PAR_LEN_CHECKSUM); /* checksum parameter */
/* NOTE: if TPDU size gets encoded hdr_len must be increased. */
/* set TPDU type */
if (pdu_type == TP_PDU_TYPE_CR || pdu_type == TP_PDU_TYPE_CC)
pdu->type_cdt = pdu_type;
else
{
TP_LOG_ERR1 ("TP-ERROR: Encode CR or CC failed (invalid pdu_type %u passed to func)",
pdu_type);
TP4_EXCEPT ();
return (enc_len); /* valid types are CR and CC */
}
/* set CDT, if specified CDT is greater then max default to max */
if (tpdu_cx->cdt <= TP_MAX_CDT)
pdu->type_cdt |= tpdu_cx->cdt;
else
pdu->type_cdt |= TP_MAX_CDT;
/* copy to dest ref remote connection reference */
if (pdu_type == TP_PDU_TYPE_CR)
pdu->dest_ref [0] = pdu->dest_ref [1] = 0; /* always 0 */
else
memcpy (pdu->dest_ref, (ST_UCHAR *) &tpdu_cx->rem_ref, sizeof (pdu->dest_ref));
/* copy to src ref local connection reference */
memcpy (pdu->src_ref, (ST_UCHAR *) &tpdu_cx->loc_ref, sizeof (pdu->src_ref));
if (tpdu_cx->preferred_class == 4)
pdu->class_opt = TP_CLASS_4_NORMAL; /* set the TP class */
else if (tpdu_cx->preferred_class == 0)
pdu->class_opt = TP_CLASS_0; /* set the TP class */
else
{
/* only class 4 (normal format) implemented */
TP_LOG_ERR1 ("TP-ERROR: Encode CR or CC failed (not implemented class %u)",
tpdu_cx->preferred_class);
TP4_EXCEPT ();
return (enc_len);
}
idx = TP_FHDR_CX_LEN;
/*------------------------------------*/
/* encode calling TSAP parameter */
/*------------------------------------*/
param = (TP_PAR *) &enc_buf [idx];
param->code = TP_PAR_CODE_TSAP_CALLING; /* parameter code */
if (pdu_type == TP_PDU_TYPE_CR)
{
/* Copy len and local TSAP to enc_buf */
memcpy (&param->len, tpdu_cx->loc_tsap, 1 + tpdu_cx->loc_tsap [0]);
idx += (ST_UINT16) (TP_PAR_FIX_LEN + tpdu_cx->loc_tsap [0]);
}
else
{
/* for CC copy len and remote TSAP to enc_buf */
memcpy (&param->len, tpdu_cx->rem_tsap, 1 + tpdu_cx->rem_tsap [0]);
idx += (ST_UINT16) (TP_PAR_FIX_LEN + tpdu_cx->rem_tsap [0]);
}
/*------------------------------------*/
/* encode called TSAP parameter */
/*------------------------------------*/
param = (TP_PAR *) &enc_buf [idx];
param->code = TP_PAR_CODE_TSAP_CALLED; /* parameter code */
if (pdu_type == TP_PDU_TYPE_CR)
{
/* Copy len and remote TSAP to enc_buf */
memcpy (&param->len, tpdu_cx->rem_tsap, 1 + tpdu_cx->rem_tsap [0]);
idx += (ST_UINT16) (TP_PAR_FIX_LEN + tpdu_cx->rem_tsap [0]);
}
else
{
/* for CC copy len and local TSAP to enc_buf */
memcpy (&param->len, tpdu_cx->loc_tsap, 1 + tpdu_cx->loc_tsap [0]);
idx += (ST_UINT16) (TP_PAR_FIX_LEN + tpdu_cx->loc_tsap [0]);
}
/*------------------------------------*/
/* encode TPDU size parameter */
/*------------------------------------*/
/* Can't encode 65531. If not encoded, other side defaults to 65531. */
if (tpdu_cx->max_tpdu_len_enc != TP_PDU_MAX_SIZE_65531)
{
pdu->hdr_len += TP_PAR_LEN_TPDU_SIZE; /* Adjust "hdr_len" */
param = (TP_PAR *) &enc_buf [idx];
param->code = TP_PAR_CODE_TPDU_SIZE; /* parameter code */
param->len = 1; /* parameter len */
if (tpdu_cx->max_tpdu_len_enc < TP_PDU_MAX_SIZE_128 ||
tpdu_cx->max_tpdu_len_enc > TP_PDU_MAX_SIZE_8192)
{
TP_LOG_ERR1 ("TP-ERROR: Encode CR or CC failed (invalid TPDU size %u)",
tpdu_cx->max_tpdu_len_enc);
TP4_EXCEPT ();
return (enc_len);
}
else
param->value[0] = tpdu_cx->max_tpdu_len_enc;
idx += TP_PAR_LEN_TPDU_SIZE;
}
/*------------------------------------*/
/* encode TP version */
/*------------------------------------*/
if (tpdu_cx->preferred_class != 0)
{
param = (TP_PAR *) &enc_buf [idx];
param->code = TP_PAR_CODE_VERSION; /* parameter code */
param->len = 1; /* parameter len */
param->value [0] = TP_VERSION; /* version number */
idx += TP_PAR_LEN_VERSION;
}
/*------------------------------------*/
/* encode TP additional options */
/*------------------------------------*/
if (tpdu_cx->preferred_class != 0)
{
param = (TP_PAR *) &enc_buf [idx];
param->code = TP_PAR_CODE_ADD_OPTIONS;/* parameter code */
param->len = 1; /* parameter len */
param->value [0] = TP_OPT_CHECKSUM_USE | TP_OPT_EXPEDITED_NON_USE;
/* this param is 0 for our selected options */
idx += TP_PAR_LEN_ADD_OPTIONS;
/* next param is checksum */
}
/*-----------------------------------------------------*/
/* copy the user data (if any) after the last parameter*/
/* (in our case the last param will be checksum param) */
/*-----------------------------------------------------*/
enc_len = (ST_UINT16) (pdu->hdr_len+1); /* set the TPDU size and add to it */
/* user data len (if any); add 1 for the*/
/* len byte we didn't counted in hdr_len*/
if (tpdu_cx->udata_len > 0)
{
if (tpdu_cx->preferred_class == 4) /* leave room for checksum */
memcpy (&enc_buf [idx + TP_PAR_LEN_CHECKSUM], tpdu_cx->udata_buf, tpdu_cx->udata_len);
else
memcpy (&enc_buf [idx], tpdu_cx->udata_buf, tpdu_cx->udata_len);
enc_len += tpdu_cx->udata_len;
}
/*------------------------------------*/
/* encode the checksum parameter */
/*------------------------------------*/
if (tpdu_cx->preferred_class == 4)
{
tp_enc_par_checksum (enc_buf, enc_len, idx);
}
return (enc_len);
}
/************************************************************************/
/* tp_encode_dr */
/*----------------------------------------------------------------------*/
/* This function is used to encode a DR TPDU. */
/* */
/* Parameters: */
/* ST_UCHAR *enc_buf Pointer where to encode the DR TPDU */
/* TPDU_DR *tpdu_dr Pointer to info struct for DR TPDU */
/* */
/* Return: */
/* ST_UINT16 The actual length of encoded TPDU */
/************************************************************************/
ST_UINT16 tp_encode_dr (ST_UCHAR *enc_buf, TPDU_DR *tpdu_dr)
{
ST_UINT16 enc_len; /* The actual length of encoded TPDU */
TP_FHDR_DR *pdu;
enc_len = TP_MAX_LEN_DR;
/*------------------------------------*/
/* encode the TPDU header, fixed part */
/*------------------------------------*/
pdu = (TP_FHDR_DR *) enc_buf;
pdu->hdr_len = TP_MAX_LEN_DR - sizeof (pdu->hdr_len);
/* header length */
/* don't count the hdr_len byte */
pdu->type = TP_PDU_TYPE_DR; /* TPDU type */
memcpy (pdu->dest_ref, (ST_UCHAR *) &tpdu_dr->rem_ref, sizeof (pdu->dest_ref));
/* Remote connection reference */
memcpy (pdu->src_ref, (ST_UCHAR *) &tpdu_dr->loc_ref, sizeof (pdu->src_ref));
/* Local connection reference */
pdu->reason = tpdu_dr->reason; /* reason for DR */
/*------------------------------------*/
/* encode the checksum parameter */
/*------------------------------------*/
tp_enc_par_checksum (enc_buf, /* buf on which checksum is computed */
enc_len, /* len of buffer (length of TPDU) */
TP_FHDR_DR_LEN); /* position of checksum param in enc_buf*/
return (enc_len);
}
/************************************************************************/
/* tp_encode_dc */
/*----------------------------------------------------------------------*/
/* This function is used to encode a DC TPDU. */
/* */
/* Parameters: */
/* ST_UCHAR *enc_buf Pointer where to encode the DC TPDU */
/* TPDU_DR *tpdu_dc Pointer to info struct for DC TPDU */
/* */
/* Return: */
/* ST_UINT16 The actual length of encoded TPDU */
/************************************************************************/
ST_UINT16 tp_encode_dc (ST_UCHAR *enc_buf, TPDU_DC *tpdu_dc)
{
ST_UINT16 enc_len; /* The actual length of encoded TPDU */
TP_FHDR_DC *pdu;
enc_len = TP_MAX_LEN_DC;
/*------------------------------------*/
/* encode the TPDU header, fixed part */
/*------------------------------------*/
pdu = (TP_FHDR_DC *) enc_buf;
pdu->hdr_len = TP_MAX_LEN_DC - sizeof (pdu->hdr_len);
/* header length */
/* don't count the hdr_len byte */
pdu->type = TP_PDU_TYPE_DC; /* TPDU type */
memcpy (pdu->dest_ref, (ST_UCHAR *) &tpdu_dc->rem_ref, sizeof (pdu->dest_ref));
/* Remote connection reference */
memcpy (pdu->src_ref, (ST_UCHAR *) &tpdu_dc->loc_ref, sizeof (pdu->src_ref));
/* Local connection reference */
/*------------------------------------*/
/* encode the checksum parameter */
/*------------------------------------*/
tp_enc_par_checksum (enc_buf, /* buf on which checksum is computed */
enc_len, /* len of buffer (length of TPDU) */
TP_FHDR_DC_LEN); /* position of checksum param in enc_buf*/
return (enc_len);
}
/************************************************************************/
/* tp_encode_dt */
/*----------------------------------------------------------------------*/
/* This function is used to encode a DT TPDU. */
/* */
/* Parameters: */
/* ST_UCHAR *enc_buf Pointer to buffer where the TPDU should */
/* be encoded. */
/* TPDU_DT *tpdu_dt Pointer data info structure */
/* */
/* Return: */
/* ST_UINT16 The actual length of encoded TPDU */
/************************************************************************/
ST_UINT16 tp_encode_dt (ST_UCHAR *enc_buf, TPDU_DT *tpdu_dt)
{
ST_UINT16 enc_len; /* The actual length of encoded TPDU */
TP_FHDR_DT *pdu;
enc_len = (ST_UINT16) (TP_HEAD_LEN_DT + tpdu_dt->udata_len);
/*------------------------------------*/
/* encode the TPDU header, fixed part */
/*------------------------------------*/
pdu = (TP_FHDR_DT *) enc_buf;
pdu->hdr_len = TP_HEAD_LEN_DT - sizeof (pdu->hdr_len);
/* header length */
/* don't count the hdr_len byte */
pdu->type = TP_PDU_TYPE_DT; /* TPDU type */
memcpy (pdu->dest_ref, (ST_UCHAR *) &tpdu_dt->dst_ref, sizeof (pdu->dest_ref));
/* Remote connection reference */
/* set sequence number (make sure that bit 8 is not set) */
pdu->eot_sn = (ST_UCHAR) (tpdu_dt->sn & TP_PDU_MASK_EOF);
if (tpdu_dt->eot)
pdu->eot_sn |= TP_PDU_EOF; /* set EOT flag */
/*------------------------------------*/
/* copy the udata to enc_buf */
/*------------------------------------*/
memcpy (&enc_buf [TP_HEAD_LEN_DT], tpdu_dt->udata_ptr, tpdu_dt->udata_len);
/*------------------------------------*/
/* encode the checksum parameter */
/*------------------------------------*/
tp_enc_par_checksum (enc_buf, /* buf on which checksum is computed */
enc_len, /* len of buffer (length of TPDU) */
TP_FHDR_DT_LEN); /* position of checksum param in enc_buf*/
return (enc_len);
}
/************************************************************************/
/* tp0_encode_dt */
/* This function is used to encode a Class 0 DT TPDU. */
/* Same as tp_encode_dt except dest_ref and Checksum NOT encoded. */
/************************************************************************/
ST_UINT16 tp0_encode_dt (ST_UCHAR *enc_buf, TPDU_DT *tpdu_dt)
{
ST_UINT16 enc_len; /* The actual length of encoded TPDU */
TP0_FHDR_DT *tp0_fhdr_dt;
enc_len = (ST_UINT16) (TP0_HEAD_LEN_DT + tpdu_dt->udata_len);
/*------------------------------------*/
/* encode the TPDU header, fixed part */
/*------------------------------------*/
tp0_fhdr_dt = (TP0_FHDR_DT *) enc_buf;
tp0_fhdr_dt->hdr_len = TP0_HEAD_LEN_DT - 1; /* header length */
/* don't count the hdr_len byte */
tp0_fhdr_dt->type = TP_PDU_TYPE_DT; /* TPDU type */
/* set sequence number (make sure that bit 8 is not set) */
tp0_fhdr_dt->eot_sn = (ST_UCHAR) 0; /* sequence number always 0 */
if (tpdu_dt->eot)
tp0_fhdr_dt->eot_sn |= TP_PDU_EOF; /* set EOT flag */
/*------------------------------------*/
/* copy the udata to enc_buf */
/*------------------------------------*/
memcpy (&enc_buf [TP0_HEAD_LEN_DT], tpdu_dt->udata_ptr, tpdu_dt->udata_len);
return (enc_len);
}
/************************************************************************/
/* tp_encode_ak */
/*----------------------------------------------------------------------*/
/* This function is used to encode an AK TPDU. */
/* */
/* Parameters: */
/* ST_UCHAR *enc_buf Pointer to buffer where the TPDU should */
/* be encoded. */
/* TPDU_AK *tpdu_ak Pointer to AK info struct */
/* */
/* Return: */
/* ST_UINT16 The actual length of encoded TPDU */
/************************************************************************/
ST_UINT16 tp_encode_ak (ST_UCHAR *enc_buf, TPDU_AK *tpdu_ak)
{
ST_UINT16 enc_len; /* The actual length of encoded TPDU */
TP_FHDR_AK *pdu;
enc_len = TP_MAX_LEN_AK;
/*------------------------------------*/
/* encode the TPDU header, fixed part */
/*------------------------------------*/
pdu = (TP_FHDR_AK *) enc_buf;
pdu->hdr_len = TP_MAX_LEN_AK - sizeof (pdu->hdr_len);
/* header length */
/* don't count the hdr_len byte */
pdu->type_cdt = TP_PDU_TYPE_AK; /* TPDU type */
/* encode the CDT (from cfg struct) */
if (tpdu_ak->cdt <= TP_MAX_CDT)
pdu->type_cdt |= tpdu_ak->cdt;
else
pdu->type_cdt |= TP_MAX_CDT;
memcpy (pdu->dest_ref, (ST_UCHAR *) &tpdu_ak->dst_ref, sizeof (pdu->dest_ref));
/* Remote connection reference */
pdu->sn = tpdu_ak->sn; /* set next expected seq number */
/*------------------------------------*/
/* encode the checksum parameter */
/*------------------------------------*/
tp_enc_par_checksum (enc_buf, /* buf on which checksum is computed */
enc_len, /* len of buffer (length of TPDU) */
TP_FHDR_AK_LEN); /* position of checksum param in enc_buf*/
return (enc_len);
}
/*======================================================================*/
/* LOCAL FUNCTIONS for ENCODING */
/*======================================================================*/
/************************************************************************/
/* tp_enc_par_checksum */
/*----------------------------------------------------------------------*/
/* This function is used to encode the checksum parameter in TPDU. */
/* */
/* Parameters: */
/* ST_UCHAR *buf Ptr to encoding buffer on which checksum*/
/* will be computed. */
/* ST_UINT16 buf_len Length of the buffer (TPDU). */
/* ST_UINT16 par_pos Position of checksum parameter in buf. */
/* */
/* Return: */
/* ST_VOID none */
/************************************************************************/
static ST_VOID tp_enc_par_checksum (ST_UCHAR *buf, ST_UINT16 buf_len, ST_UINT16 par_pos)
{
TP_PAR *param;
param = (TP_PAR *) &buf [par_pos];
param->code = TP_PAR_CODE_CHECKSUM; /* parameter code */
param->len = 2; /* Parameter length */
/* compute the checksum of the entire TPDU, the position of the */
/* checksum first byte in the buf is computed as the difference */
/* between pointers */
checksum_insert (buf, buf_len, (ST_UINT16) (param->value - buf));
}

100
mmslib/ositcps/tp4port.c Normal file
View File

@@ -0,0 +1,100 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1996-2003 All Rights Reserved */
/* */
/* MODULE NAME : tp4port.c */
/* PRODUCT(S) : Lean-T Stack */
/* */
/* MODULE DESCRIPTION : */
/* Functions for porting to new operating systems. */
/* The purpose of these functions is to cause "tp4_timer_tick" */
/* to be called on 1 second intervals. These functions are */
/* appropriate for MS-DOS or any other single tasking OS. */
/* They may be replaced by any Operating System appropriate code */
/* which causes the same result. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* tp4_init_timer () */
/* tp4_check_timer () */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 12/19/03 JRB 04 Use sGetMsTime instead of "time" function to */
/* avoid problems when system time changed. */
/* 09/11/00 JRB 03 Make sure tp4_check_timer called at least */
/* once a second. If NOT, write msg to log. */
/* 08/13/98 JRB 02 Lint cleanup. */
/* 05/27/97 JRB 7.00 MMSEASE 7.0 release. */
/* 07/17/96 JRB 01 Created */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#include "tp4api.h" /* User definitions for tp4 */
#include "tp4_log.h"
#ifdef DEBUG_SISCO
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
#endif
static ST_DOUBLE oldtime; /* milliseconds */
static ST_DOUBLE newtime; /* milliseconds */
/************************************************************************/
/* tp4_init_timer */
/************************************************************************/
ST_VOID tp4_init_timer (ST_VOID)
{
oldtime = sGetMsTime ();
}
/************************************************************************/
/* tp4_check_timer */
/************************************************************************/
ST_VOID tp4_check_timer (ST_VOID)
{
#ifdef DEBUG_SISCO
static ST_BOOLEAN time_problem; /* Timing problem detected. */
#endif
newtime = sGetMsTime ();
#ifdef DEBUG_SISCO /* Don't check for problem if can't log it. */
/* Check time since last call. */
/* This function should be called at least every second, so time diff */
/* should be < 1000 ms. If difference is > 3000 ms, service loop may */
/* be too slow. */
/* //renxiaobao ͨѶ<CDA8><D1B6>ʱ
//if (newtime - oldtime > 3000.0)
*/ if (newtime - oldtime > 10000.0)
{
TP_LOG_ERR1 ("WARNING: stack not serviced for %.3f seconds.", (newtime-oldtime)/1000.0);
if (!time_problem)
{
/* Log this message only the first time it happens. */
TP_LOGC_ERR0 ("MAY CAUSE UNEXPECTED TIMEOUTS, DISCONNECTS, ABORTS.");
time_problem = SD_TRUE;
}
}
#endif
/* Increment "oldtime" by 1000 ms increments as much as possible */
/* without exceeding "newtime". */
/* Call "tp4_timer_tick" once for each increment. */
/*renxiaobao ͨѶ<CDA8><D1B6>ʱ*/
while (oldtime + 5000.0 < newtime)
{
tp4_timer_tick (); /* Call function to process timer tick. */
oldtime += 5000.0;
}
/* //while (oldtime + 1000.0 < newtime)
//{
// tp4_timer_tick (); Call function to process timer tick.
// oldtime += 1000.0;
//}
*/
}

1053
mmslib/ositcps/tpx_dec.c Normal file

File diff suppressed because it is too large Load Diff