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