This appendix contains programming code fragments for the following connection-related tasks:
Example B-1 shows one way to make a call for point-to-point connections and to make the first call for a point-to-multipoint connection.
make_call(unsigned char *called_party)
{
register atm_uni_call_ie_p iep, ie;
register union atm_cmi_addr ra;
register atm_vc_services_p vcs;
atm_error_t retval;
int rv = ESUCCESS;
extern atm_cvg_handle_t my_handle;
extern atm_bind_handle_t my_bind;
/* Get memory for setup IE's */
iep = ie = atm_cmm_alloc_ie(3);
if(ie == NULL)
{
rv = ENOMEM;
goto bad;
}
/* Get memory for services structure */
vcs = atm_cmm_alloc_services();
if(vcs == NULL)
{
atm_cmm_free_ie(iep);
rv = ENOMEM;
goto bad;
}
/* get the storage for the endpoint address */
ra.addr = atm_cmm_alloc_addr();
if(ra.addr == NULL)
{
atm_cmm_free_ie(iep);
atm_cmm_free_services(vcs);
rv = ENOMEM;
goto bad;
}
/* Set cell rate information for ABR traffic.
* Cell rates - cells/sec. 1 cell = 53 bytes .
*/
vcs->fpeakcr[ATM_CLP_1] = 0x800;
vcs->bpeakcr[ATM_CLP_1] = 0x800;
vcs->valid_rates = ATM_VCRV_FPEAK1 |
ATM_VCRV_BPEAK1;
/* Best effort service class and enable tagging */
vcs->flags = ATM_SERVICES_BEI;
/* Set the Qos */
vcs->fqos = ATM_QOS_CLASSA;
vcs->bqos = ATM_QOS_CLASSA;
/* Set the MTU in the services structure */
vcs->fmtu = 1500;
vcs->bmtu = 1500;
/* Set the BB bearer class in the services structure */
vcs->bearer_class = ATM_BBEARER_BCOB_X;
/* Fill out the AAL 5 IE */
ie->ie_type = ATM_IET_AAL5;
ATM_IE_SETVAL(ie->ie.aal_params.aal5.fsdu,1500);
ATM_IE_SETVAL(ie->ie.aal_params.aal5.bsdu,1500);
ATM_IE_SETVAL(ie->ie.aal_params.aal5.mode,
ATM_AAL_MESG_MODE);
ATM_IE_SETVAL(ie->ie.aal_params.aal5.sscs,
ATM_AAL_SSCS_NULL);
/* Fill out the BB bearer Capability IE */
ie++;
ie->ie_type = ATM_IET_BBBC;
ATM_IE_SETVAL(ie->ie.bbbc.type,0);
ATM_IE_SETVAL(ie->ie.bbbc.timing,0);
ATM_IE_SETVAL(ie->ie.bbbc.clipping,0);
ATM_IE_SETVAL(ie->ie.bbbc.upcc,0);
/* Fill out the BLLI IE */
ie++;
ie->last = 1;
ie->ie_type = ATM_IET_BBLOW;
ATM_IE_SETVAL(ie->ie.bb_low_layer.layer2proto,
ATM_BLLI_UIL2_LAN_LLC_8022);
bcopy(called_party,ra.addr->address,ATMADDR_LEN);
ra.addr->ton = 0;
ra.addr->anpi = 2;
if((retval = atm_cmm_connect(my_handle,ATM_CT_PTP, [1]
my_bind,ra,iep,ATM_AGE_FOREVER,vcs)) !=
ATM_CAUSE_GOOD)
{
atm_cmm_free_ie(iep);
atm_cmm_free_services(vcs);
atm_cmm_free_addr(ra.addr);
ATM_FREE(ivc);
rv = EIO;
goto bad;
}
/* The VC is valid if the call is proceeding! */
ra.addr->vc->conv_pp1 =
ra.addr->conv_p1 =
ra.addr->conv_p2 =
return rv;
}
Example B-2 shows one way to add more parties to the VC associated with the first call in a point-to-multipoint connection.
add_leaf(atm_vc_p vc, unsigned char *new_leaf)
{
register atm_uni_call_ie_p iep, ie;
register struct atm_addr_p leaf;
atm_error_t retval;
int rv = ESUCCESS;
extern atm_cvg_handle_t my_handle;
extern atm_bind_handle_t my_bind;
/* Get memory for setup IE's */
iep = ie = atm_cmm_alloc_ie(3);
if(ie == NULL)
{
rv = ENOMEM;
goto bad;
}
/* get the storage for the endpoint address */
leaf = atm_cmm_alloc_addr();
if(leaf == NULL)
{
atm_cmm_free_ie(iep);
atm_cmm_free_services(vcs);
rv = ENOMEM;
goto bad;
}
/* Fill out the AAL 5 IE */
ie->ie_type = ATM_IET_AAL5;
ATM_IE_SETVAL(ie->ie.aal_params.aal5.fsdu,1500);
ATM_IE_SETVAL(ie->ie.aal_params.aal5.bsdu,1500);
ATM_IE_SETVAL(ie->ie.aal_params.aal5.mode,
ATM_AAL_MESG_MODE);
ATM_IE_SETVAL(ie->ie.aal_params.aal5.sscs,
ATM_AAL_SSCS_NULL);
/* Fill out the BB bearer Capability IE */
ie++;
ie->ie_type = ATM_IET_BBBC;
ATM_IE_SETVAL(ie->ie.bbbc.class,
ATM_BBEARER_BCOB_X);
ATM_IE_SETVAL(ie->ie.bbbc.type,0);
ATM_IE_SETVAL(ie->ie.bbbc.timing,0);
ATM_IE_SETVAL(ie->ie.bbbc.clipping,0);
ATM_IE_SETVAL(ie->ie.bbbc.upcc,0);
/* Fill out the BLLI IE */
ie++;
ie->last = 1;
ie->ie_type = ATM_IET_BBLOW;
ATM_IE_SETVAL(ie->ie.bb_low_layer.layer2proto,
ATM_BLLI_UIL2_LAN_LLC_8022);
bcopy(new_leaf,leaf->address,ATMADDR_LEN);
leaf->ton = 0;
leaf->anpi = 2;
if((retval = atm_cmm_add(my_handle,leaf,ie,vc)) !=
ATM_CAUSE_GOOD)
{
atm_cmm_free_ie(iep);
atm_cmm_free_addr(leaf);
ATM_FREE(ivc);
rv = EIO;
goto bad;
}
/* The VC is valid if the call is proceeding! */
ra.addr->conv_p1 =
ra.addr->conv_p2 =
return rv;
}
Example B-3 shows how a convergence module processes an incoming call.
atm_error_t
new_connect(void *bind_handle,
atm_addr_p addr,
atm_bind_handle_t bind,
atm_vc_p vc,
atm_uni_call_ie_p *reply,
atm_vc_services_p requested,
atm_vc_services_p *avail)
{
register atm_uni_call_ie_p iep = NULL;
atm_uni_call_ie_p rblli = NULL, raal = NULL;
/* verify IE's to make sure they're valid for our service */
if(addr != NULL && (iep = addr->setup))
{
for(;; iep++)
{
switch(iep->ie_type)
{
/* things we don't want to see */
case ATM_IET_AAL1:
case ATM_IET_AAL2:
case ATM_IET_AAL3:
case ATM_IET_AALU:
return ATM_CAUSE_APNS;
/* don't need to look at these */
case ATM_IET_BBBC:
case ATM_IET_BBHI:
break;
case ATM_IET_REPEAT:
break;
case ATM_IET_AAL5:
/* Make sure the MTU is supported. Accept
* an MTU greater than 1500 and then
* negotiate it down until larger MTU's are
* supported.
*/
if(ATM_IE_ISVALID(iep->ie.aal_params.aal5.fsdu))
{
if(ATM_IE_GETVAL(iep->ie.aal_params.aal5.fsdu)
< 1500)
return ATM_CAUSE_APNS;
}
if(ATM_IE_ISVALID(iep->ie.aal_params.aal5.bsdu))
{
if(ATM_IE_GETVAL(iep->ie.aal_params.aal5.bsdu)
< 1500)
return ATM_CAUSE_APNS;
}
raal = iep;
break;
case ATM_IET_BBLOW:
/* Check for LLC encapsulation */
if(ATM_IE_ISVALID(iep->ie.bb_low_layer.layer2proto))
{
if(ATM_IE_GETVAL(iep->ie.bb_low_layer.layer2proto)
!= 0x0C)
return ATM_CAUSE_BCNI;
rblli = iep;
break;
}
break;
}
if(iep->last)
break;
}
/* Make sure the required info is present */
if(rblli == NULL) /* No required BLLI */
{
addr->diag_length = 2;
addr->diagnostic[0] = 0x5;
addr->diagnostic[1] = 0x5e;
return ATM_CAUSE_CR;
}
if(raal == NULL) /* no required AAL parameters */
{
addr->diag_length = 2;
addr->diagnostic[0] = 0x5;
addr->diagnostic[1] = 0x58;
return ATM_CAUSE_CR;
}
/* set up reply values */
iep = atm_cmm_alloc_ie(2);
if(!iep)
return ATM_CAUSE_RUU;
bcopy(raal,iep,sizeof(atm_uni_call_ie_t));
ATM_IE_SETVAL(iep->ie.aal_params.aal5.fsdu,1500);
ATM_IE_SETVAL(iep->ie.aal_params.aal5.bsdu,1500);
raal = iep+1;
bcopy(rblli,raal,sizeof(atm_uni_call_ie_t));
raal->last = 1;
*reply = iep;
/* now take case of the services stuff */
if ( (avail) && (*avail) ) {
(*avail)->fmtu = (*avail)->bmtu = 1500;
}
}
vc->conv_pp1 =
vc->conv_pp2 =
/* If there's no signalling protocol then this is a PVC */
if(vc->ppa->sig != NULL)
{
addr->conv_p1 =
addr->conv_p2 =
}
return ATM_CAUSE_GOOD;
}