/* psapinitiate.c - PPM: initiator */
static char *rcsid
= "$Header: /f/osi/psap2/RCS/psapinitiate.c,v 7.4 91/02/22 09:37:31 mrose Interim $";
* $Header: /f/osi/psap2/RCS/psapinitiate.c,v 7.4 91/02/22 09:37:31 mrose Interim $
* $Log: psapinitiate.c,v $
* Revision 7.4 91/02/22 09:37:31 mrose
* Revision 7.3 90/07/01 21:05:00 mrose
* Revision 7.2 90/01/27 10:26:29 mrose
* Revision 7.1 89/11/24 16:22:14 mrose
* Revision 7.0 89/11/23 22:14:20 mrose
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
/* \f P-(ASYN-)CONNECT.REQUEST */
int PAsynConnRequest (calling
, called
, ctxlist
, defctxname
, prequirements
,
srequirements
, isn
, settings
, ref
, data
, ndata
, qos
, pc
, pi
, async
)
struct PSAPaddr
*calling
,
struct PSAPctxlist
*ctxlist
;
struct PSAPindication
*pi
;
if (ctxlist
&& ctxlist
-> pc_nctx
> NPCTX
)
return psaplose (pi
, PC_PARAMETER
, NULLCP
,
"only %d proposed presentation contexts supported", NPCTX
);
if (prequirements
& ~PR_MYREQUIRE
)
return psaplose (pi
, PC_PARAMETER
, NULLCP
,
"presentation requirements settings not supported");
if ((prequirements
& PR_RESTORATION
)
&& !(prequirements
& PR_MANAGEMENT
))
return psaplose (pi
, PC_PARAMETER
, NULLCP
,
"context restoration service requires context management service");
/* let session provider catch errors in session parameters */
toomuchP (data
, ndata
, NPDATA
, "initial");
result
= PConnRequestAux (calling
, called
, ctxlist
, defctxname
,
prequirements
, srequirements
, isn
, settings
, ref
, data
, ndata
,
(void) sigiomask (smask
);
static int PConnRequestAux (calling
, called
, ctxlist
, defctxname
,
prequirements
, srequirements
, isn
, settings
, ref
, data
, ndata
, qos
,
struct PSAPaddr
*calling
,
struct PSAPctxlist
*ctxlist
;
struct PSAPindication
*pi
;
register struct psapblk
*pb
;
register struct SSAPconnect
*sc
= &scs
;
struct SSAPindication sis
;
register struct SSAPindication
*si
= &sis
;
register struct SSAPabort
*sa
= &si
-> si_abort
;
register struct type_PS_CP__type
*pdu
;
register struct element_PS_0
*normal
;
if ((pb
= newpblk ()) == NULL
)
return psaplose (pi
, PC_CONGEST
, NULLCP
, "out of memory");
pb
-> pb_srequirements
= pb
-> pb_urequirements
= srequirements
;
if (called
-> pa_selectlen
> 0) {
static struct PSAPaddr pas
;
bzero ((char *) calling
, sizeof *calling
);
if (calling
-> pa_selectlen
== 0) {
htons ((u_short
) (0x8000 | (getpid () & 0x7fff)));
calling
-> pa_selectlen
= sizeof calling
-> pa_port
;
if ((pdu
= (struct type_PS_CP__type
*) calloc (1, sizeof *pdu
)) == NULL
) {
(void) psaplose (pi
, PC_CONGEST
, NULLCP
, "out of memory");
if ((pdu
-> mode
= (struct type_PS_Mode__selector
*)
malloc (sizeof *pdu
-> mode
)) == NULL
)
pdu
-> mode
-> parm
= int_PS_Mode__selector_normal__mode
;
if ((pdu
-> normal__mode
= (struct element_PS_0
*)
calloc (1, sizeof *pdu
-> normal__mode
))
normal
= pdu
-> normal__mode
;
&& calling
-> pa_selectlen
> 0
&& (normal
-> calling
= str2qb (calling
-> pa_selector
,
calling
-> pa_selectlen
, 1))
if (called
-> pa_selectlen
> 0
&& (normal
-> called
= str2qb (called
-> pa_selector
,
called
-> pa_selectlen
, 1))
if ((pb
-> pb_asn
= ode2oid (DFLT_ASN
)) == NULLOID
) {
(void) psaplose (pi
, PC_ABSTRACT
, NULLCP
, "%s: unknown", DFLT_ASN
);
if ((pb
-> pb_asn
= oid_cpy (pb
-> pb_asn
)) == NULLOID
)
if ((pb
-> pb_atn
= ode2oid (DFLT_ATN
)) == NULLOID
) {
(void) psaplose (pi
, PC_TRANSFER
, NULLCP
, "%s: unknown", DFLT_ATN
);
if ((pb
-> pb_atn
= oid_cpy (pb
-> pb_atn
)) == NULLOID
)
if ((pb
-> pb_ber
= oid_cpy (pb
-> pb_atn
)) == NULLOID
)
if (ctxlist
&& ctxlist
-> pc_nctx
> 0) {
register struct type_PS_Definition__list
*cd
,
register struct PSAPcontext
*pp
,
cp
= &normal
-> context__list
;
i
= ctxlist
-> pc_nctx
- 1;
for (pp
= ctxlist
-> pc_ctx
, qp
= pb
-> pb_contexts
;
if (!((qp
-> pc_id
= pp
-> pc_id
) & 01)) {
(void) psaplose (pi
, PC_PARAMETER
, NULLCP
,
"only odd values allowed for context identifiers");
if (pp
-> pc_asn
== NULLOID
) {
(void) psaplose (pi
, PC_PARAMETER
, NULLCP
,
"no abstract syntax name given for context %d",
if ((qp
-> pc_asn
= oid_cpy (pp
-> pc_asn
)) == NULLOID
)
if (pp
-> pc_atn
&& !atn_is_ok (pb
, pp
-> pc_atn
)) {
(void) psaplose (pi
, PC_TRANSFER
, NULLCP
,
"unknown transfer syntax name given for context %d",
if ((qp
-> pc_atn
= oid_cpy (pp
-> pc_atn
? pp
-> pc_atn
: pb
-> pb_atn
)) == NULLOID
)
if ((cd
=(struct type_PS_Definition__list
*)
calloc (1, sizeof *cd
)) == NULL
)
if ((cd
-> element_PS_5
= (struct element_PS_6
*)
calloc (1, sizeof *cd
-> element_PS_5
)) == NULL
)
cd
-> element_PS_5
-> identifier
= qp
-> pc_id
;
if ((cd
-> element_PS_5
-> abstract__syntax
=
oid_cpy (qp
-> pc_asn
)) == NULLOID
|| (cd
-> element_PS_5
-> transfer__syntax__list
=
calloc (1, sizeof (struct element_PS_7
)))
|| (cd
-> element_PS_5
-> transfer__syntax__list
->
qp
-> pc_result
= PC_ACCEPT
;
if ((pb
-> pb_asn
= oid_cpy (defctxname
)) == NULLOID
|| (normal
-> default__context
=
(struct type_PS_Context__name
*)
calloc (1, sizeof *normal
-> default__context
))
|| (normal
-> default__context
-> abstract__syntax
=
oid_cpy (pb
-> pb_asn
)) == NULLOID
/* perhaps should be user-definable */
|| (normal
-> default__context
-> transfer__syntax
=
oid_cpy (pb
-> pb_atn
)) == NULLOID
)
pb
-> pb_result
= PC_ACCEPT
;
if ((pb
-> pb_prequirements
= prequirements
) != PR_MYREQUIRE
) {
register struct pair
*pp
;
if ((normal
-> presentation__fu
= prim2bit (pe_alloc (PE_CLASS_UNIV
,
for (pp
= preq_pairs
; pp
-> p_mask
; pp
++)
if ((pb
-> pb_prequirements
& pp
-> p_mask
)
&& bit_on (normal
-> presentation__fu
, pp
-> p_bitno
)
if (bit2prim (normal
-> presentation__fu
) == NULLPE
)
if (pb
-> pb_prequirements
& PR_MANAGEMENT
)
pb
-> pb_srequirements
|= SR_TYPEDATA
;
if (pb
-> pb_urequirements
!= pb
-> pb_srequirements
) {
register struct pair
*pp
;
if ((normal
-> session__fu
= prim2bit (pe_alloc (PE_CLASS_UNIV
,
for (pp
= sreq_pairs
; pp
-> p_mask
; pp
++)
if ((pb
-> pb_urequirements
& pp
-> p_mask
)
&& bit_on (normal
-> session__fu
, pp
-> p_bitno
) == NOTOK
)
if (bit2prim (normal
-> session__fu
) == NULLPE
)
&& (normal
-> user__data
= info2ppdu (pb
, pi
, data
, ndata
,
if (encode_PS_CP__type (&pe
, 1, 0, NULLCP
, pdu
) == NOTOK
) {
(void) psaplose (pi
, PC_CONGEST
, NULLCP
, "error encoding PDU: %s",
PLOGP (psap2_log
,PS_CP__type
, pe
, "CP-type", 0);
if (pe2ssdu (pe
, &pb
-> pb_retry
, &len
) == NOTOK
)
if ((result
= SAsynConnRequest (ref
, calling
? &calling
-> pa_addr
: NULLSA
, &called
-> pa_addr
, pb
-> pb_srequirements
, settings
,
isn
, pb
-> pb_retry
, len
, qos
, sc
, si
, async
)) == NOTOK
) {
(void) ss2pslose (NULLPB
, pi
, "SAsynConnRequest", sa
);
pb
-> pb_fd
= sc
-> sc_sd
;
pc
-> pc_sd
= pb
-> pb_fd
;
if ((result
= PAsynRetryAux (pb
, sc
, si
, pc
, pi
)) == DONE
&& !async
)
/* \f P-ASYN-RETRY.REQUEST (pseudo) */
int PAsynRetryRequest (sd
, pc
, pi
)
struct PSAPindication
*pi
;
register struct psapblk
*pb
;
register struct SSAPconnect
*sc
= &scs
;
struct SSAPindication sis
;
register struct SSAPindication
*si
= &sis
;
register struct SSAPabort
*sa
= &si
-> si_abort
;
if ((pb
= findpblk (sd
)) == NULL
) {
(void) sigiomask (smask
);
return psaplose (pi
, PC_PARAMETER
, NULLCP
,
"invalid presentation descriptor");
if (pb
-> pb_flags
& PB_CONN
) {
(void) sigiomask (smask
);
return psaplose (pi
, PC_OPERATION
, NULLCP
,
"presentation descriptor connected");
switch (result
= SAsynRetryRequest (pb
-> pb_fd
, sc
, si
)) {
(void) ss2pslose (pb
, pi
, "SAsynRetryRequest", sa
);
result
= PAsynRetryAux (pb
, sc
, si
, pc
, pi
);
(void) sigiomask (smask
);
static int PAsynRetryAux (pb
, sc
, si
, pc
, pi
)
register struct psapblk
*pb
;
struct SSAPindication
*si
;
struct PSAPindication
*pi
;
register struct SSAPabort
*sa
= &si
-> si_abort
;
struct type_PS_CPA__type
*cpa
;
register struct element_PS_1
*cpa_normal
;
struct type_PS_CPR__type
*cpr
;
register struct element_PS_2
*cpr_normal
;
struct type_PS_ARP__PPDU
*arp
;
bzero ((char *) pc
, sizeof *pc
);
if (sc
-> sc_result
== SC_ABORT
) {
(void) ss2psabort (pb
, sa
, pi
);
pc
-> pc_result
= PC_ABORTED
;
cpa
= NULL
, cpr
= NULL
, arp
= NULL
;
if ((pe
= ssdu2pe (sc
-> sc_data
, sc
-> sc_cc
, NULLCP
, &result
))
if (sc
-> sc_result
!= SC_ACCEPT
) {
bzero ((char *) sa
, sizeof *sa
);
sa
-> sa_reason
= sc
-> sc_result
;
(void) ss2pslose (pb
, pi
, "SAsynConnRequest(pseudo)", sa
);
pc
-> pc_result
= pi
-> pi_abort
.pa_reason
;
(void) ppktlose (pb
, pi
, result
!= PS_ERR_NMEM
? PC_UNRECOGNIZED
: PC_NOTSPECIFIED
, sc
-> sc_result
== SC_ACCEPT
? PPDU_CPA
: PPDU_CPR
, NULLCP
, "%s", ps_error (result
));
if (sc
-> sc_result
== SC_ACCEPT
) {
pb
-> pb_flags
|= PB_CONN
;
pb
-> pb_srequirements
= sc
-> sc_requirements
;
pb
-> pb_urequirements
&= pb
-> pb_srequirements
;
#define dotoken(requires,shift,bit,type) \
if (pb -> pb_srequirements & requires) \
switch (sc -> sc_settings & (ST_MASK << shift)) { \
case ST_INIT_VALUE << shift: \
case ST_RESP_VALUE << shift: \
pb
-> pb_ssdusize
= sc
-> sc_ssdusize
;
if (decode_PS_CPA__type (pe
, 1, NULLIP
, NULLVP
, &cpa
) == NOTOK
) {
(void) ppktlose (pb
, pi
, PC_UNRECOGNIZED
, PPDU_CPA
, NULLCP
, "%s",
PLOGP (psap2_log
,PS_CPA__type
, pe
, "CPA-type", 1);
if (cpa
-> mode
-> parm
!= int_PS_Mode__selector_normal__mode
) {
(void) ppktlose (pb
, pi
, PC_INVALID
, PPDU_CPA
, NULLCP
,
cpa_normal
= cpa
-> normal__mode
;
pc
-> pc_sd
= pb
-> pb_fd
;
if (sc
-> sc_result
== SC_NOTSPECIFIED
) {
if (decode_PS_ARP__PPDU (pe
, 1, NULLIP
, NULLVP
, &arp
) == NOTOK
) {
(void) ppktlose (pb
, pi
, PC_UNRECOGNIZED
, PPDU_ARP
, NULLCP
,
PLOGP (psap2_log
,PS_ARP__PPDU
, pe
, "ARP-PPDU", 1);
if (arp
-> provider__reason
) {
if ((result
= arp
-> provider__reason
-> parm
) == 0)
result
= PC_NOTSPECIFIED
;
result
= PC_NOTSPECIFIED
;
(void) psaplose (pi
, result
, NULLCP
, NULLCP
);
if (decode_PS_CPR__type (pe
, 1, NULLIP
, NULLVP
, &cpr
) == NOTOK
) {
(void) ppktlose (pb
, pi
, PC_UNRECOGNIZED
, PPDU_CPR
, NULLCP
, "%s",
PLOGP (psap2_log
,PS_CPR__type
, pe
, "CPR-type", 1);
if (cpr
-> offset
!= type_PS_CPR__type_normal__mode
) {
(void) ppktlose (pb
, pi
, PC_INVALID
, PPDU_CPR
, NULLCP
,
cpr_normal
= cpr
-> un
.normal__mode
;
pb
-> pb_responding
.pa_addr
= sc
-> sc_responding
; /* struct copy */
if (qb
= cpa
? cpa_normal
-> responding
: cpr_normal
-> responding
) {
if ((base
= qb2str (qb
)) == NULLCP
&& sc
-> sc_result
== SC_ACCEPT
) {
(void) ppktlose (pb
, pi
, PC_INVALID
, PPDU_CPA
, NULLCP
,
"malformed PSAP selector");
if (qb
-> qb_len
> sizeof pc
-> pc_responding
.pa_selector
)
qb
-> qb_len
= sizeof pc
-> pc_responding
.pa_selector
;
bcopy (base
, pb
-> pb_responding
.pa_selector
,
pb
-> pb_responding
.pa_selectlen
= qb
-> qb_len
);
pc
-> pc_responding
= pb
-> pb_responding
; /* struct copy */
register struct PSAPcontext
*pp
,
register struct type_PS_Definition__result__list
*lp
,
lp
= cpa
? cpa_normal
-> context__list
: cpr_normal
-> context__list
;
for (mp
= lp
; mp
; mp
= mp
-> next
)
if (i
!= pb
-> pb_ncontext
&& i
!= 0) {
if (sc
-> sc_result
!= SC_ACCEPT
) {
pc
-> pc_ctxlist
.pc_nctx
= 0;
(void) ppktlose (pb
, pi
, PC_INVALID
, PPDU_CPA
, NULLCP
,
"proposed/resulting presentation contexts mismatch");
i
= (pc
-> pc_ctxlist
.pc_nctx
= pb
-> pb_ncontext
) - 1;
for (pp
= pc
-> pc_ctxlist
.pc_ctx
, qp
= pb
-> pb_contexts
, mp
= lp
;
pp
-> pc_id
= qp
-> pc_id
;
pp
-> pc_asn
= pp
-> pc_atn
= NULLOID
;
pp
-> pc_result
= PC_ACCEPT
;
switch (mp
-> element_PS_12
-> result
) {
case int_PS_result_acceptance
:
/* assume they gave back ASN.1 */
pp
-> pc_result
= qp
-> pc_result
= PC_ACCEPT
;
case int_PS_result_user__rejection
:
pp
-> pc_result
= qp
-> pc_result
= PC_REJECTED
;
case int_PS_result_provider__rejection
:
mp
-> element_PS_12
-> provider__reason
) == 0)
pp
-> pc_result
= PC_NOTSPECIFIED
;
pp
-> pc_result
+= PC_REASON_BASE
;
qp
-> pc_result
= pp
-> pc_result
;
i
= pb
-> pb_ncontext
- 1;
for (qp
= pb
-> pb_contexts
+ i
; i
>= 0; i
--, qp
--)
if (qp
-> pc_result
!= PC_ACCEPT
) {
register struct PSAPcontext
*qqp
;
qqp
= pb
-> pb_contexts
+ --pb
-> pb_ncontext
;
*qp
= *qqp
; /* struct copy */
if (cpr
== NULL
|| cpr_normal
-> default__context
== NULL
)
pc
-> pc_defctxresult
= PC_ACCEPT
;
switch (cpr_normal
-> default__context
-> parm
) {
case int_PS_Result_acceptance
:
pc
-> pc_defctxresult
= PC_ACCEPT
;
case int_PS_Result_user__rejection
:
pc
-> pc_defctxresult
= PC_REJECTED
;
case int_PS_Result_provider__rejection
:
pc
-> pc_defctxresult
= PC_NOTSPECIFIED
;
if (ppdu2info (pb
, pi
, cpa
? cpa_normal
-> user__data
: cpr_normal
-> user__data
, pc
-> pc_info
,
&pc
-> pc_ninfo
, cpa
? PPDU_CPA
: PPDU_CPR
) == NOTOK
)
if (sc
-> sc_result
== SC_ACCEPT
) {
if (cpa_normal
-> presentation__fu
) {
register struct pair
*pp
;
if (!(pb
-> pb_srequirements
& SR_TYPEDATA
)) {
(void) bit_off (cpa_normal
-> presentation__fu
,
bit_PS_Presentation__requirements_context__management
);
(void) bit_off (cpa_normal
-> presentation__fu
,
bit_PS_Presentation__requirements_restoration
);
for (pp
= preq_pairs
; pp
-> p_mask
; pp
++)
if (!(pb
-> pb_prequirements
& pp
-> p_mask
)) {
if (bit_test (cpa_normal
-> presentation__fu
,
(void) ppktlose (pb
, pi
, PC_INVALID
, PPDU_CPA
, NULLCP
,
"presentation-requirements negotiation botched");
if (bit_test (cpa_normal
-> presentation__fu
,
pb
-> pb_prequirements
&= ~pp
-> p_mask
;
pc
-> pc_prequirements
= pb
-> pb_prequirements
;
if (cpa_normal
-> session__fu
) {
register struct pair
*pp
;
for (pp
= preq_pairs
; pp
-> p_mask
; pp
++)
if (bit_test (cpa_normal
-> session__fu
, pp
-> p_bitno
) < 1)
pb
-> pb_urequirements
&= ~pp
-> p_mask
;
pc
-> pc_srequirements
= pb
-> pb_urequirements
;
pc
-> pc_settings
= sc
-> sc_settings
;
pc
-> pc_please
= sc
-> sc_please
;
pc
-> pc_isn
= sc
-> sc_isn
;
pc
-> pc_connect
= sc
-> sc_connect
; /* struct copy */
pc
-> pc_ssdusize
= sc
-> sc_ssdusize
;
pc
-> pc_qos
= sc
-> sc_qos
; /* struct copy */
pc
-> pc_result
= PC_ACCEPT
;
if (cpr_normal
-> optionals
& opt_PS_element_PS_2_reason
)
pc
-> pc_result
= cpr_normal
-> reason
+ PC_PROV_BASE
;
pc
-> pc_result
= PC_NOTSPECIFIED
;
/* \f P-ASYN-NEXT.REQUEST (pseudo) */
int PAsynNextRequest (sd
, pc
, pi
)
struct PSAPindication
*pi
;
register struct psapblk
*pb
;
register struct SSAPconnect
*sc
= &scs
;
struct SSAPindication sis
;
register struct SSAPindication
*si
= &sis
;
register struct SSAPabort
*sa
= &si
-> si_abort
;
if ((pb
= findpblk (sd
)) == NULL
) {
(void) sigiomask (smask
);
return psaplose (pi
, PC_PARAMETER
, NULLCP
,
"invalid presentation descriptor");
if (pb
-> pb_flags
& PB_CONN
) {
(void) sigiomask (smask
);
return psaplose (pi
, PC_OPERATION
, NULLCP
,
"presentation descriptor connected");
switch (result
= SAsynNextRequest (pb
-> pb_fd
, sc
, si
)) {
(void) ss2pslose (pb
, pi
, "SAsynRetryRequest", sa
);
result
= PAsynRetryAux (pb
, sc
, si
, pc
, pi
);
(void) sigiomask (smask
);