This appendix contains programming code fragments for the following connection-related tasks:
Making a call
Adding more parties to a point-to-multipoint connection
Processing an incoming call
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 IEs */ 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 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; }
For point-to-multipoint connections, use the
ATM_CT_PTM
argument in place of the
ATM_CT_PTP
argument.
[Return to example]
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 IEs */ 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 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; atm_uni_call_ie_p nblli; /* Verify IEs to make sure they are valid for our service */ if(addr != NULL && (iep = addr->setup)) { for(;; iep++) { switch(iep->ie_type) { /* Things we do not want to see */ case ATM_IET_AAL1: case ATM_IET_AAL2: case ATM_IET_AAL3: case ATM_IET_AALU: return ATM_CAUSE_APNS; /* Do not 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 MTUs 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); nblli = iep+1; bcopy(rblli,nblli,sizeof(atm_uni_call_ie_t)); nblli->last = 1; *reply = iep; /* Now take care of the services stuff */ if ( (avail) && (*avail) ) { (*avail)->fmtu = (*avail)->bmtu = 1500; } } vc->conv_pp1 = vc->conv_pp2 = /* If there is no signalling protocol, then this is a PVC */ if(vc->ppa->sig != NULL) { addr->conv_p1 = addr->conv_p2 = } return ATM_CAUSE_GOOD; }