1996-02-14 01:07:57 +03:00
|
|
|
/* $NetBSD: tp_param.h,v 1.9 1996/02/13 22:11:32 christos Exp $ */
|
1994-06-29 10:39:25 +04:00
|
|
|
|
1993-04-09 16:00:07 +04:00
|
|
|
/*-
|
1994-05-13 10:08:03 +04:00
|
|
|
* Copyright (c) 1991, 1993
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
1993-04-09 16:00:07 +04:00
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed by the University of
|
|
|
|
* California, Berkeley and its contributors.
|
|
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
1994-06-29 10:39:25 +04:00
|
|
|
* @(#)tp_param.h 8.1 (Berkeley) 6/10/93
|
1993-04-09 16:00:07 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
/***********************************************************
|
|
|
|
Copyright IBM Corporation 1987
|
|
|
|
|
|
|
|
All Rights Reserved
|
|
|
|
|
1996-02-14 01:07:57 +03:00
|
|
|
Permission to use, copy, modify, and distribute this software and its
|
|
|
|
documentation for any purpose and without fee is hereby granted,
|
1993-04-09 16:00:07 +04:00
|
|
|
provided that the above copyright notice appear in all copies and that
|
1996-02-14 01:07:57 +03:00
|
|
|
both that copyright notice and this permission notice appear in
|
1993-04-09 16:00:07 +04:00
|
|
|
supporting documentation, and that the name of IBM not be
|
|
|
|
used in advertising or publicity pertaining to distribution of the
|
1996-02-14 01:07:57 +03:00
|
|
|
software without specific, written prior permission.
|
1993-04-09 16:00:07 +04:00
|
|
|
|
|
|
|
IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
|
|
|
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
|
|
|
IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
|
|
|
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
|
|
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
|
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
|
|
SOFTWARE.
|
|
|
|
|
|
|
|
******************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
|
|
|
|
*/
|
|
|
|
|
1994-05-13 10:08:03 +04:00
|
|
|
#ifndef _NETISO_TP_PARAM_H_
|
|
|
|
#define _NETISO_TP_PARAM_H_
|
|
|
|
|
1993-04-09 16:00:07 +04:00
|
|
|
/******************************************************
|
|
|
|
* compile time parameters that can be changed
|
|
|
|
*****************************************************/
|
|
|
|
|
1996-02-14 01:07:57 +03:00
|
|
|
#define TP_CLASSES_IMPLEMENTED 0x11 /* zero and 4 */
|
1993-04-09 16:00:07 +04:00
|
|
|
|
|
|
|
#define TP_DECBIT_CLEAR_COUNT 3
|
|
|
|
|
1996-02-14 01:07:57 +03:00
|
|
|
/* #define N_TPREF 100 */
|
1995-03-27 00:35:13 +04:00
|
|
|
#ifdef _KERNEL
|
1996-02-14 01:07:57 +03:00
|
|
|
extern int N_TPREF;
|
1993-04-09 16:00:07 +04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#define TP_SOCKBUFSIZE ((u_long)4096)
|
|
|
|
#define TP0_SOCKBUFSIZE ((u_long)512)
|
|
|
|
#define MAX_TSAP_SEL_LEN 64
|
|
|
|
|
|
|
|
/* maximum tpdu size we'll accept: */
|
1996-02-14 01:07:57 +03:00
|
|
|
#define TP_TPDUSIZE 0xc /* 4096 octets for
|
|
|
|
* classes 1-4 */
|
|
|
|
#define TP0_TPDUSIZE 0xb /* 2048 octets for class 0 */
|
|
|
|
#define TP_DFL_TPDUSIZE 0x7 /* 128 octets default */
|
|
|
|
/*
|
|
|
|
* NOTE: don't ever negotiate 8192 because could get wraparound in
|
|
|
|
* checksumming (No mtu is likely to be larger than 4K anyway...)
|
|
|
|
*/
|
|
|
|
#define TP_NRETRANS 12 /* TCP_MAXRXTSHIFT + 1 */
|
|
|
|
#define TP_MAXRXTSHIFT 6 /* factor of 64 */
|
1993-04-09 16:00:07 +04:00
|
|
|
#define TP_MAXPORT 0xefff
|
|
|
|
|
1996-02-14 01:07:57 +03:00
|
|
|
/*
|
|
|
|
* ALPHA: to be used in the context: gain= 1/(2**alpha), or put another way,
|
|
|
|
* gaintimes(x) (x)>>alpha (forgetting the case alpha==0)
|
1993-04-09 16:00:07 +04:00
|
|
|
*/
|
1996-02-14 01:07:57 +03:00
|
|
|
#define TP_RTT_ALPHA 3
|
1993-04-09 16:00:07 +04:00
|
|
|
#define TP_RTV_ALPHA 2
|
1994-05-13 10:08:03 +04:00
|
|
|
#define TP_REXMTVAL(tpcb)\
|
1996-02-14 01:07:57 +03:00
|
|
|
(((tp_rttadd + (tpcb)->tp_rtt + ((tpcb)->tp_rtv)) << 2) / tp_rttdiv)
|
1994-05-13 10:08:03 +04:00
|
|
|
#define TP_RANGESET(tv, value, min, max) \
|
|
|
|
((tv = value) > (max) ? (tv = max) : (tv < min ? tv = min : tv))
|
1993-04-09 16:00:07 +04:00
|
|
|
|
|
|
|
/*
|
1996-02-14 01:07:57 +03:00
|
|
|
* not sure how to treat data on disconnect
|
1993-04-09 16:00:07 +04:00
|
|
|
*/
|
|
|
|
#define T_CONN_DATA 0x1
|
|
|
|
#define T_DISCONNECT 0x2
|
|
|
|
#define T_DISC_DATA 0x4
|
|
|
|
#define T_XDATA 0x8
|
|
|
|
|
|
|
|
#define ISO_CLNS 0
|
|
|
|
#define IN_CLNS 1
|
|
|
|
#define ISO_CONS 2
|
|
|
|
#define ISO_COSNS 3
|
|
|
|
#define TP_MAX_NETSERVICES 3
|
|
|
|
|
|
|
|
/* Indices into tp stats ackreason[i] */
|
|
|
|
#define _ACK_DONT_ 0
|
|
|
|
#define _ACK_STRAT_EACH_ 0x1
|
|
|
|
#define _ACK_STRAT_FULLWIN_ 0x2
|
|
|
|
#define _ACK_DUP_ 0x3
|
|
|
|
#define _ACK_EOT_ 0x4
|
|
|
|
#define _ACK_REORDER_ 0x5
|
|
|
|
#define _ACK_USRRCV_ 0x6
|
|
|
|
#define _ACK_FCC_ 0x7
|
|
|
|
#define _ACK_NUM_REASONS_ 0x8
|
|
|
|
|
|
|
|
/* masks for use in tp_stash() */
|
|
|
|
#define ACK_DONT 0
|
|
|
|
#define ACK_STRAT_EACH (1<< _ACK_STRAT_EACH_)
|
|
|
|
#define ACK_STRAT_FULLWIN (1<< _ACK_STRAT_FULLWIN_)
|
|
|
|
#define ACK_DUP (1<< _ACK_DUP_)
|
|
|
|
#define ACK_EOT (1<< _ACK_EOT_)
|
|
|
|
#define ACK_REORDER (1<< _ACK_REORDER_)
|
|
|
|
|
|
|
|
/******************************************************
|
1996-02-14 01:07:57 +03:00
|
|
|
* constants used in the protocol
|
1993-04-09 16:00:07 +04:00
|
|
|
*****************************************************/
|
|
|
|
|
|
|
|
#define TP_VERSION 0x1
|
|
|
|
|
|
|
|
#define TP_MAX_HEADER_LEN 256
|
|
|
|
|
1996-02-14 01:07:57 +03:00
|
|
|
#define TP_MIN_TPDUSIZE 0x7 /* 128 octets */
|
|
|
|
#define TP_MAX_TPDUSIZE 0xd /* 8192 octets */
|
1993-04-09 16:00:07 +04:00
|
|
|
|
|
|
|
#define TP_MAX_XPD_DATA 0x10 /* 16 octets */
|
|
|
|
#define TP_MAX_CC_DATA 0x20 /* 32 octets */
|
|
|
|
#define TP_MAX_CR_DATA TP_MAX_CC_DATA
|
|
|
|
#define TP_MAX_DR_DATA 0x40 /* 64 octets */
|
|
|
|
|
|
|
|
#define TP_XTD_FMT_BIT 0x80000000
|
|
|
|
#define TP_XTD_FMT_MASK 0x7fffffff
|
|
|
|
#define TP_NML_FMT_BIT 0x80
|
|
|
|
#define TP_NML_FMT_MASK 0x7f
|
|
|
|
|
1996-02-14 01:07:57 +03:00
|
|
|
/*
|
|
|
|
* values for the tpdu_type field, 2nd byte in a tpdu
|
1993-04-09 16:00:07 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#define TP_MIN_TPDUTYPE 0x1
|
|
|
|
|
|
|
|
#define XPD_TPDU_type 0x1
|
|
|
|
#define XAK_TPDU_type 0x2
|
1996-02-14 01:07:57 +03:00
|
|
|
#define GR_TPDU_type 0x3
|
1993-04-09 16:00:07 +04:00
|
|
|
#define AK_TPDU_type 0x6
|
|
|
|
#define ER_TPDU_type 0x7
|
|
|
|
#define DR_TPDU_type 0x8
|
|
|
|
#define DC_TPDU_type 0xc
|
|
|
|
#define CC_TPDU_type 0xd
|
|
|
|
#define CR_TPDU_type 0xe
|
|
|
|
#define DT_TPDU_type 0xf
|
|
|
|
|
|
|
|
#define TP_MAX_TPDUTYPE 0xf
|
|
|
|
|
|
|
|
/*
|
1996-02-14 01:07:57 +03:00
|
|
|
* identifiers for the variable-length options in tpdus
|
1993-04-09 16:00:07 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#define TPP_acktime 0x85
|
|
|
|
#define TPP_residER 0x86
|
|
|
|
#define TPP_priority 0x87
|
|
|
|
#define TPP_transdelay 0x88
|
|
|
|
#define TPP_throughput 0x89
|
|
|
|
#define TPP_subseq 0x8a
|
|
|
|
#define TPP_flow_cntl_conf 0x8c /* not implemented */
|
|
|
|
#define TPP_addl_info 0xe0
|
|
|
|
#define TPP_tpdu_size 0xc0
|
|
|
|
#define TPP_calling_sufx 0xc1
|
1996-02-14 01:07:57 +03:00
|
|
|
#define TPP_invalid_tpdu 0xc1 /* the bozos used a value
|
|
|
|
* twice */
|
1993-04-09 16:00:07 +04:00
|
|
|
#define TPP_called_sufx 0xc2
|
|
|
|
#define TPP_checksum 0xc3
|
|
|
|
#define TPP_vers 0xc4
|
|
|
|
#define TPP_security 0xc5
|
|
|
|
#define TPP_addl_opt 0xc6
|
|
|
|
#define TPP_alt_class 0xc7
|
1996-02-14 01:07:57 +03:00
|
|
|
#define TPP_perf_meas 0xc8 /* local item : perf meas on,
|
|
|
|
* svp */
|
1994-05-13 10:08:03 +04:00
|
|
|
#define TPP_ptpdu_size 0xf0 /* preferred TPDU size */
|
|
|
|
#define TPP_inact_time 0xf2 /* inactivity time exchanged */
|
|
|
|
|
1993-04-09 16:00:07 +04:00
|
|
|
|
|
|
|
/******************************************************
|
|
|
|
* Some fundamental data types
|
|
|
|
*****************************************************/
|
|
|
|
#ifndef TRUE
|
|
|
|
#define TRUE 1
|
1996-02-14 01:07:57 +03:00
|
|
|
#endif /* TRUE */
|
1993-04-09 16:00:07 +04:00
|
|
|
|
|
|
|
#ifndef FALSE
|
|
|
|
#define FALSE 0
|
1996-02-14 01:07:57 +03:00
|
|
|
#endif /* FALSE */
|
1993-04-09 16:00:07 +04:00
|
|
|
|
|
|
|
#define TP_LOCAL 22
|
|
|
|
#define TP_FOREIGN 33
|
|
|
|
|
|
|
|
#ifndef EOK
|
|
|
|
#define EOK 0
|
1996-02-14 01:07:57 +03:00
|
|
|
#endif /* EOK */
|
1993-04-09 16:00:07 +04:00
|
|
|
|
|
|
|
#define TP_CLASS_0 (1<<0)
|
|
|
|
#define TP_CLASS_1 (1<<1)
|
|
|
|
#define TP_CLASS_2 (1<<2)
|
|
|
|
#define TP_CLASS_3 (1<<3)
|
|
|
|
#define TP_CLASS_4 (1<<4)
|
|
|
|
|
|
|
|
#define TP_FORCE 0x1
|
|
|
|
#define TP_STRICT 0x2
|
|
|
|
|
|
|
|
#ifndef MNULL
|
|
|
|
#define MNULL (struct mbuf *)0
|
1996-02-14 01:07:57 +03:00
|
|
|
#endif /* MNULL */
|
|
|
|
/*
|
|
|
|
* if ../sys/mbuf.h gets MT_types up to 0x40, these will have to be changed:
|
|
|
|
*/
|
|
|
|
#define MT_XPD 0x44
|
1993-04-09 16:00:07 +04:00
|
|
|
#define MT_EOT 0x40
|
|
|
|
|
|
|
|
#define TP_ENOREF 0x80000000
|
|
|
|
|
1996-02-14 01:07:57 +03:00
|
|
|
typedef unsigned int SeqNum;
|
|
|
|
typedef unsigned short RefNum;
|
1993-04-09 16:00:07 +04:00
|
|
|
|
|
|
|
/******************************************************
|
|
|
|
* Macro used all over, for driver
|
|
|
|
*****************************************************/
|
|
|
|
|
|
|
|
#define DoEvent(x) \
|
|
|
|
((E.ev_number=(x)),(tp_driver(tpcb,&E)))
|
|
|
|
|
|
|
|
/******************************************************
|
|
|
|
* Some macros used all over, for timestamping
|
|
|
|
*****************************************************/
|
|
|
|
|
|
|
|
#define GET_CUR_TIME(tvalp) ((*tvalp) = time)
|
|
|
|
|
|
|
|
#define GET_TIME_SINCE(oldtvalp, diffp) {\
|
|
|
|
(diffp)->tv_sec = time.tv_sec - (oldtvalp)->tv_sec;\
|
|
|
|
(diffp)->tv_usec = time.tv_usec - (oldtvalp)->tv_usec;\
|
|
|
|
if( (diffp)->tv_usec <0 ) {\
|
|
|
|
(diffp)->tv_sec --;\
|
|
|
|
(diffp)->tv_usec = 1000000 - (diffp)->tv_usec;\
|
|
|
|
}\
|
|
|
|
}
|
1996-02-14 01:07:57 +03:00
|
|
|
|
1993-04-09 16:00:07 +04:00
|
|
|
/******************************************************
|
|
|
|
* Macro used for changing types of mbufs
|
|
|
|
*****************************************************/
|
|
|
|
|
|
|
|
#define CHANGE_MTYPE(m, TYPE)\
|
|
|
|
if((m)->m_type != TYPE) { \
|
|
|
|
mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[TYPE]++; \
|
|
|
|
(m)->m_type = TYPE; \
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************
|
|
|
|
* Macros used for adding options to a tpdu header and for
|
|
|
|
* parsing the headers.
|
|
|
|
* Options are variable-length and must be bcopy-d because on the
|
|
|
|
* RT your assignments must be N-word aligned for objects of length
|
|
|
|
* N. Such a drag.
|
|
|
|
*****************************************************/
|
|
|
|
|
|
|
|
struct tp_vbp {
|
1996-02-14 01:07:57 +03:00
|
|
|
u_char tpv_code;
|
|
|
|
char tpv_len;
|
|
|
|
char tpv_val;
|
1993-04-09 16:00:07 +04:00
|
|
|
};
|
|
|
|
#define vbptr(x) ((struct tp_vbp *)(x))
|
|
|
|
#define vbval(x,type) (*((type *)&(((struct tp_vbp *)(x))->tpv_val)))
|
|
|
|
#define vbcode(x) (vbptr(x)->tpv_code)
|
|
|
|
#define vblen(x) (vbptr(x)->tpv_len)
|
|
|
|
|
|
|
|
#define vb_putval(dst,type,src)\
|
|
|
|
bcopy((caddr_t)&(src),(caddr_t)&(((struct tp_vbp *)(dst))->tpv_val),\
|
|
|
|
sizeof(type))
|
|
|
|
|
|
|
|
#define vb_getval(src,type,dst)\
|
|
|
|
bcopy((caddr_t)&(((struct tp_vbp *)(src))->tpv_val),(caddr_t)&(dst),sizeof(type))
|
|
|
|
|
|
|
|
#define ADDOPTION(type, DU, len, src)\
|
|
|
|
{ register caddr_t P;\
|
|
|
|
P = (caddr_t)(DU) + (int)((DU)->tpdu_li);\
|
|
|
|
vbptr(P)->tpv_code = type;\
|
|
|
|
vbptr(P)->tpv_len = len;\
|
|
|
|
bcopy((caddr_t)&src, (caddr_t)&(vbptr(P)->tpv_val), (unsigned)len);\
|
|
|
|
DU->tpdu_li += len+2;/* 1 for code, 1 for length */\
|
|
|
|
}
|
|
|
|
/******************************************************
|
|
|
|
* Macro for the local credit:
|
|
|
|
* uses max transmission unit for the ll
|
1996-02-14 01:07:57 +03:00
|
|
|
* (as modified by the max TPDU size negotiated)
|
1993-04-09 16:00:07 +04:00
|
|
|
*****************************************************/
|
|
|
|
|
|
|
|
#if defined(ARGO_DEBUG)&&!defined(LOCAL_CREDIT_EXPAND)
|
|
|
|
#define LOCAL_CREDIT(tpcb) tp_local_credit(tpcb)
|
|
|
|
#else
|
1994-05-13 10:08:03 +04:00
|
|
|
#define LOCAL_CREDIT(tpcb) { if (tpcb->tp_rsycnt == 0) {\
|
1993-04-09 16:00:07 +04:00
|
|
|
register struct sockbuf *xxsb = &((tpcb)->tp_sock->so_rcv);\
|
1994-05-13 10:08:03 +04:00
|
|
|
register int xxi = sbspace(xxsb);\
|
|
|
|
xxi = (xxi<0) ? 0 : ((xxi) / (tpcb)->tp_l_tpdusize);\
|
|
|
|
xxi = min(xxi, (tpcb)->tp_maxlcredit); \
|
1993-04-09 16:00:07 +04:00
|
|
|
if (!(tpcb->tp_cebit_off)) { \
|
|
|
|
(tpcb)->tp_lcredit = ROUND((tpcb)->tp_win_recv); \
|
|
|
|
if (xxi < (tpcb)->tp_lcredit) { \
|
|
|
|
(tpcb)->tp_lcredit = xxi; \
|
|
|
|
} \
|
1994-05-13 10:08:03 +04:00
|
|
|
} else \
|
1993-04-09 16:00:07 +04:00
|
|
|
(tpcb)->tp_lcredit = xxi; \
|
1994-05-13 10:08:03 +04:00
|
|
|
} }
|
1996-02-14 01:07:57 +03:00
|
|
|
#endif /* ARGO_DEBUG */
|
1993-04-09 16:00:07 +04:00
|
|
|
|
1995-03-27 00:35:13 +04:00
|
|
|
#ifdef _KERNEL
|
1996-02-14 01:07:57 +03:00
|
|
|
extern int tp_rttadd, tp_rttdiv;
|
1994-05-13 10:08:03 +04:00
|
|
|
#include <sys/syslog.h>
|
|
|
|
#define printf logpri(LOG_DEBUG),addlog
|
1993-04-09 16:00:07 +04:00
|
|
|
|
1996-02-14 01:07:57 +03:00
|
|
|
#ifndef tp_NSTATES
|
1993-04-09 16:00:07 +04:00
|
|
|
|
1994-05-13 10:08:03 +04:00
|
|
|
#include <netiso/tp_states.h>
|
|
|
|
#include <netiso/tp_events.h>
|
1993-04-09 16:00:07 +04:00
|
|
|
|
1996-02-14 01:07:57 +03:00
|
|
|
#ifndef __CONCAT3
|
|
|
|
# if __STDC__
|
|
|
|
# define __CONCAT3(a,b,c) a ## b ## c
|
|
|
|
# else
|
|
|
|
# define __CONCAT3(a,b,c) a/**/b/**/c
|
|
|
|
# endif /* __STDC__ */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define TPDU_ATTR(X) __CONCAT3(ev_union.EV_,X,_TPDU)
|
|
|
|
|
|
|
|
#endif /* tp_NSTATES */
|
1995-03-27 00:35:13 +04:00
|
|
|
#endif /* _KERNEL */
|
1993-04-09 16:00:07 +04:00
|
|
|
|
1994-05-13 10:08:03 +04:00
|
|
|
#endif /* _NETISO_TP_PARAM_H_ */
|