Files
microser/mmslib/ositcps/tp0calld.c
2026-06-15 15:48:16 +08:00

211 lines
8.7 KiB
C

/************************************************************************/
/* 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;
}