/* acsapinitiat.c - ACPM: initiator */
static char *rcsid
= "$Header: /f/osi/acsap/RCS/acsapinitiat.c,v 7.4 91/02/22 09:14:09 mrose Interim $";
* $Header: /f/osi/acsap/RCS/acsapinitiat.c,v 7.4 91/02/22 09:14:09 mrose Interim $
* $Log: acsapinitiat.c,v $
* Revision 7.4 91/02/22 09:14:09 mrose
* Revision 7.3 90/08/18 00:48:49 mrose
* Revision 7.2 90/07/09 14:30:32 mrose
* Revision 7.1 90/07/01 21:01:55 mrose
* Revision 7.0 89/11/23 21:21:50 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 A-(ASYN-)ASSOCIATE.REQUEST */
int AcAsynAssocRequest (context
, callingtitle
, calledtitle
, callingaddr
,
calledaddr
, ctxlist
, defctxname
, prequirements
, srequirements
, isn
,
settings
, ref
, data
, ndata
, qos
, acc
, aci
, async
)
struct PSAPaddr
*callingaddr
,
struct PSAPctxlist
*ctxlist
;
struct AcSAPconnect
*acc
;
struct AcSAPindication
*aci
;
/* let presentation provider catch errors in presentation parameters */
toomuchP (data
, ndata
, NACDATA
, "initial");
if (data
) { /* XXX: probably should have a more intensive check... */
for (pep
= data
, i
= ndata
; i
> 0; pep
++, i
--)
if ((*pep
) -> pe_context
== PE_DFLT_CTX
)
return acsaplose (aci
, ACS_PARAMETER
, NULLCP
,
"default context not allowed for user-data at slot %d",
result
= AcAssocRequestAux (context
, callingtitle
, calledtitle
,
callingaddr
, calledaddr
, ctxlist
, defctxname
, prequirements
,
srequirements
, isn
, settings
, ref
, data
, ndata
, qos
, acc
, aci
,
(void) sigiomask (smask
);
static int AcAssocRequestAux (context
, callingtitle
, calledtitle
, callingaddr
,
calledaddr
, ctxlist
, defctxname
, prequirements
, srequirements
, isn
,
settings
, ref
, data
, ndata
, qos
, acc
, aci
, async
)
struct PSAPaddr
*callingaddr
,
struct PSAPctxlist
*ctxlist
;
struct AcSAPconnect
*acc
;
struct AcSAPindication
*aci
;
register struct assocblk
*acb
;
register struct PSAPcontext
*pp
;
register struct PSAPconnect
*pc
= &acc
-> acc_connect
;
struct PSAPindication pis
;
register struct PSAPindication
*pi
= &pis
;
register struct PSAPabort
*pa
= &pi
-> pi_abort
;
register struct type_ACS_AARQ__apdu
*pdu
;
if ((acb
= newacblk ()) == NULL
)
return acsaplose (aci
, ACS_CONGEST
, NULLCP
, "out of memory");
if ((pdu
= (struct type_ACS_AARQ__apdu
*) calloc (1, sizeof *pdu
))
result
= acsaplose (aci
, ACS_CONGEST
, NULLCP
, "out of memory");
pdu
-> application__context__name
= context
;
pdu
-> called__AP__title
= calledtitle
-> aei_ap_title
;
pdu
-> called__AE__qualifier
= calledtitle
-> aei_ae_qualifier
;
if (calledtitle
-> aei_flags
& AEI_AP_ID
)
pdu
-> called__AP__invocation__id
=
(struct type_ACS_AP__invocation__id
*)
&calledtitle
-> aei_ap_id
;
if (calledtitle
-> aei_flags
& AEI_AE_ID
)
pdu
-> called__AE__invocation__id
=
(struct type_ACS_AE__invocation__id
*)
&calledtitle
-> aei_ae_id
;
pdu
-> calling__AP__title
= callingtitle
-> aei_ap_title
;
pdu
-> calling__AE__qualifier
= callingtitle
-> aei_ae_qualifier
;
if (callingtitle
-> aei_flags
& AEI_AP_ID
)
pdu
-> calling__AP__invocation__id
=
(struct type_ACS_AP__invocation__id
*)
&callingtitle
-> aei_ap_id
;
if (callingtitle
-> aei_flags
& AEI_AE_ID
)
pdu
-> calling__AE__invocation__id
=
(struct type_ACS_AE__invocation__id
*)
&callingtitle
-> aei_ae_id
;
&& (pdu
-> user__information
= info2apdu (acb
, aci
, data
, ndata
))
result
= encode_ACS_AARQ__apdu (&pe
, 1, 0, NULLCP
, pdu
);
if (pdu
-> user__information
)
free_ACS_Association__information (pdu
-> user__information
);
(void) acsaplose (aci
, ACS_CONGEST
, NULLCP
, "error encoding PDU: %s",
if (ctxlist
-> pc_nctx
>= NPCTX
) {
result
= acsaplose (aci
, ACS_PARAMETER
, NULLCP
,
if ((oid
= ode2oid (AC_ASN
)) == NULLOID
) {
result
= acsaplose (aci
, ACS_PARAMETER
, NULLCP
,
for (pp
= ctxlist
-> pc_ctx
, i
= ctxlist
-> pc_nctx
- 1;
if (oid_cmp (pp
-> pc_asn
, oid
)) {
if (acb
-> acb_rosid
== PE_DFLT_CTX
)
acb
-> acb_rosid
= pp
-> pc_id
;
for (pp
= ctxlist
-> pc_ctx
, i
= ctxlist
-> pc_nctx
- 1;
if (oid_cmp (pp
-> pc_asn
, oid
) == 0) {
acb
-> acb_id
= pp
-> pc_id
;
acb
-> acb_offset
= pp
- ctxlist
-> pc_ctx
;
if ((pp
-> pc_asn
= oid_cpy (oid
)) == NULLOID
)
if (pp
-> pc_atn
= ode2oid (BER
))
pp
-> pc_atn
= oid_cpy (pp
-> pc_atn
);
acb
-> acb_id
= pp
-> pc_id
;
pe
-> pe_context
= acb
-> acb_id
;
PLOGP (acsap_log
,ACS_ACSE__apdu
, pe
, "AARQ-apdu", 0);
bzero ((char *) acc
, sizeof *acc
);
result
= PAsynConnRequest (callingaddr
, calledaddr
,
ctxlist
, defctxname
, prequirements
, srequirements
, isn
,
settings
, ref
, &pe
, 1, qos
, pc
, pi
, async
);
pp
-> pc_asn
= pp
-> pc_atn
= NULLOID
;
(void) ps2acslose (NULLACB
, aci
, "PAsynConnRequest", pa
);
acb
-> acb_fd
= pc
-> pc_sd
;
acb
-> acb_flags
|= ACB_ACS
;
acb
-> acb_uabort
= PUAbortRequest
;
acc
-> acc_sd
= acb
-> acb_fd
;
if ((result
= AcAsynRetryAux (acb
, pc
, pi
, acc
, aci
)) == DONE
&& !async
)
if (pdu
-> user__information
)
free_ACS_Association__information (pdu
-> user__information
);
/* \f A-ASYN-RETRY.REQUEST (pseudo) */
int AcAsynRetryRequest (sd
, acc
, aci
)
struct AcSAPconnect
*acc
;
struct AcSAPindication
*aci
;
register struct assocblk
*acb
;
register struct PSAPconnect
*pc
;
struct PSAPindication pis
;
register struct PSAPindication
*pi
= &pis
;
register struct PSAPabort
*pa
= &pi
-> pi_abort
;
if ((acb
= findacblk (sd
)) == NULL
) {
(void) sigiomask (smask
);
return acsaplose (aci
, ACS_PARAMETER
, NULLCP
,
"invalid association descriptor");
if (acb
-> acb_flags
& ACB_CONN
) {
(void) sigiomask (smask
);
return acsaplose (aci
, ACS_OPERATION
, NULLCP
,
"association descriptor connected");
pc
= &acc
-> acc_connect
;
bzero ((char *) acc
, sizeof *acc
);
switch (result
= PAsynRetryRequest (acb
-> acb_fd
, pc
, pi
)) {
(void) ps2acslose (acb
, aci
, "PAsynRetryRequest", pa
);
result
= AcAsynRetryAux (acb
, pc
, pi
, acc
, aci
);
(void) sigiomask (smask
);
static int AcAsynRetryAux (acb
, pc
, pi
, acc
, aci
)
register struct assocblk
*acb
;
struct PSAPindication
*pi
;
struct AcSAPconnect
*acc
;
struct AcSAPindication
*aci
;
register struct PSAPcontext
*pp
;
register struct PSAPabort
*pa
= &pi
-> pi_abort
;
struct type_ACS_ACSE__apdu
*pdu
;
register struct type_ACS_AARE__apdu
*aare
;
if (pc
-> pc_result
== PC_ABORTED
) {
(void) ps2acsabort (acb
, pa
, aci
);
acc
-> acc_result
= ACS_ABORTED
;
if (pc
-> pc_ninfo
< 1) {
if (pc
-> pc_result
!= PC_ACCEPT
) {
bzero ((char *) pa
, sizeof *pa
);
pa
-> pa_reason
= pc
-> pc_result
;
(void) ps2acslose (acb
, aci
, "PAsynConnRequest(pseudo)", pa
);
acc
-> acc_result
= aci
-> aci_abort
.aca_reason
;
result
= acpktlose (acb
, aci
, ACS_PROTOCOL
, NULLCP
, NULLCP
);
acb
-> acb_fd
= pc
-> pc_sd
;
acb
-> acb_sversion
= pc
-> pc_qos
.qos_sversion
;
result
= decode_ACS_ACSE__apdu (pe
= pc
-> pc_info
[0], 1, NULLIP
, NULLVP
,
if (result
== OK
&& (acsap_log
-> ll_events
& LLOG_PDUS
))
pvpdu (acsap_log
, print_ACS_ACSE__apdu_P
, pe
, "ACSE-apdu", 1);
pe
= pc
-> pc_info
[0] = NULLPE
;
(void) acpktlose (acb
, aci
, ACS_PROTOCOL
, NULLCP
, "%s", PY_pepy
);
if (pdu
-> offset
!= type_ACS_ACSE__apdu_aare
) {
result
= acpktlose (acb
, aci
, ACS_PROTOCOL
, NULLCP
,
"unexpected PDU %d on P-CONNECT", pdu
-> offset
);
switch (aare
-> result
) {
case int_ACS_result_accepted
:
if (pc
-> pc_result
!= PC_ACCEPT
) {
result
= acpktlose (acb
, aci
, ACS_PROTOCOL
, NULLCP
,
PErrString (pc
-> pc_result
));
acb
-> acb_flags
|= ACB_CONN
;
acc
-> acc_sd
= acb
-> acb_fd
;
acc
-> acc_result
= ACS_ACCEPT
;
if ((i
= acb
-> acb_offset
) < 0)
i
= pc
-> pc_ctxlist
.pc_nctx
- 1;
pp
= pc
-> pc_ctxlist
.pc_ctx
+ i
;
if (pp
-> pc_id
!= acb
-> acb_id
) {
result
= acpktlose (acb
, aci
, ACS_PROTOCOL
, NULLCP
,
if (pp
-> pc_result
!= PC_ACCEPT
) {
result
= acpktlose (acb
, aci
, ACS_PROTOCOL
, NULLCP
,
if (acb
-> acb_offset
< 0)
pc
-> pc_ctxlist
.pc_nctx
--;
for (pp
= pc
-> pc_ctxlist
.pc_ctx
; i
>= 0; i
--, pp
++)
if (pp
-> pc_id
!= acb
-> acb_id
&& pp
-> pc_result
== PC_ACCEPT
) {
acb
-> acb_rosid
= pp
-> pc_id
;
case int_ACS_result_rejected__permanent
:
acc
-> acc_result
= ACS_PERMANENT
;
case int_ACS_result_rejected__transient
:
acc
-> acc_result
= ACS_TRANSIENT
;
if (pc
-> pc_result
!= PC_ACCEPT
)
if (acb
-> acb_offset
< 0
&& (i
= pc
-> pc_ctxlist
.pc_nctx
- 1) >= 0)
pc
-> pc_ctxlist
.pc_nctx
= i
;
switch (aare
-> result__source__diagnostic
-> offset
) {
case type_ACS_Associate__source__diagnostic_acse__service__user
:
aare
-> result__source__diagnostic
-> un
.acse__service__user
case type_ACS_Associate__source__diagnostic_acse__service__provider
:
aare
-> result__source__diagnostic
-> un
.acse__service__provider
if ((result
= apdu2info (acb
, aci
, aare
-> user__information
,
acc
-> acc_info
, &acc
-> acc_ninfo
)) == NOTOK
)
acc
-> acc_context
= aare
-> application__context__name
;
aare
-> application__context__name
= NULLOID
;
acc
-> acc_respondtitle
.aei_ap_title
= aare
-> responding__AP__title
;
aare
-> responding__AP__title
= NULLPE
;
acc
-> acc_respondtitle
.aei_ae_qualifier
=
aare
-> responding__AE__qualifier
;
aare
-> responding__AE__qualifier
= NULLPE
;
if (aare
-> responding__AP__invocation__id
) {
acc
-> acc_respondtitle
.aei_ap_id
=
aare
-> responding__AP__invocation__id
-> parm
;
acc
-> acc_respondtitle
.aei_flags
|= AEI_AP_ID
;
if (aare
-> responding__AE__invocation__id
) {
acc
-> acc_respondtitle
.aei_ae_id
=
aare
-> responding__AE__invocation__id
-> parm
;
acc
-> acc_respondtitle
.aei_flags
|= AEI_AE_ID
;
for (i
= pc
-> pc_ninfo
- 1; i
>= 0; i
--)
pe_free (pc
-> pc_info
[i
]);
free_ACS_ACSE__apdu (pdu
);
if (pc
-> pc_result
!= PC_ACCEPT
)
if (pc
-> pc_ninfo
> 0 && pe
== pc
-> pc_info
[0])
free_ACS_ACSE__apdu (pdu
);
/* \f A-ASYN-NEXT.REQUEST (pseudo) */
int AcAsynNextRequest (sd
, acc
, aci
)
struct AcSAPconnect
*acc
;
struct AcSAPindication
*aci
;
register struct assocblk
*acb
;
register struct PSAPconnect
*pc
;
struct PSAPindication pis
;
register struct PSAPindication
*pi
= &pis
;
register struct PSAPabort
*pa
= &pi
-> pi_abort
;
if ((acb
= findacblk (sd
)) == NULL
) {
(void) sigiomask (smask
);
return acsaplose (aci
, ACS_PARAMETER
, NULLCP
,
"invalid association descriptor");
if (acb
-> acb_flags
& ACB_CONN
) {
(void) sigiomask (smask
);
return acsaplose (aci
, ACS_OPERATION
, NULLCP
,
"association descriptor connected");
pc
= &acc
-> acc_connect
;
bzero ((char *) acc
, sizeof *acc
);
switch (result
= PAsynNextRequest (acb
-> acb_fd
, pc
, pi
)) {
(void) ps2acslose (acb
, aci
, "PAsynRetryRequest", pa
);
result
= AcAsynRetryAux (acb
, pc
, pi
, acc
, aci
);
(void) sigiomask (smask
);