/* * pal/rm.c * * Copyright (C) 2008 ACRD * Written by: Xinyu Yan * * Description: Protocol Abstraction Layer - resource management part */ #include #include #include "pal.h" struct resource_mgmt { pal_sap_struct sap[PAL_MAX_SAP]; pal_cg_struct cg[PAL_MAX_CG]; pal_circuit_struct circuit[PAL_MAX_CIRCUIT]; }; #define ERROR_STRING_LEN 256 static u8 version[4] = {9, 0, 0, 1}; static struct resource_mgmt pal_resource; static char error_string[ERROR_STRING_LEN+1]; u8 *pal_version(void) { return version; } char *pal_error(void) { return error_string; } /****************************************************/ /*************** PAL upper layer interface ***************/ /****************************************************/ int pal_bind_sap(sap_attrib_struct *attrib) { int i; pal_sap_struct *sap; for(i = 0; i < PAL_MAX_SAP; i++) { sap = &pal_resource.sap[i]; if(sap->enable == 0) { sap->id = i; sap->enable = 1; memcpy(&sap->attrib, attrib, sizeof(sap_attrib_struct)); return i; } } sprintf(error_string, "%s: no free sap\r\n", __FUNCTION__); return -1; } int pal_unbind_sap(u8 sap_id) { //need not support// return -1; } int pal_create_cg(u8 sap_id, cg_attrib_struct *attrib) { int i; pal_cg_struct *cg; if(sap_id >= PAL_MAX_SAP) { sprintf(error_string, "%s: sap id(%d) out of range\r\n", __FUNCTION__, sap_id); return -1; } if(pal_resource.sap[sap_id].enable == 0) { sprintf(error_string, "%s: sap (%d) is not created\r\n", __FUNCTION__, sap_id); return -1; } for(i = 0; i < PAL_MAX_CG; i++) { cg = &pal_resource.cg[i]; if(cg->enable == 0) { cg->id = i; cg->enable = 1; cg->sap_id = sap_id; cg->circuit_num = 0; memcpy(&cg->attrib, attrib, sizeof(cg_attrib_struct)); return i; } } sprintf(error_string, "%s: no free cg\r\n", __FUNCTION__); return -1; } int pal_delete_cg(int cg_id) { pal_cg_struct *cg; if(cg_id >= PAL_MAX_CG) { sprintf(error_string, "%s: cg id(%d) out of range\r\n", __FUNCTION__, cg_id); return -1; } cg = &pal_resource.cg[cg_id]; if(cg->circuit_num > 0) { sprintf(error_string, "%s: %d circuit in used\r\n", __FUNCTION__, cg->circuit_num); return -1; } cg->enable = 0; return 0; } int pal_modify_cg(int cg_id, cg_attrib_struct *attrib) { pal_cg_struct *cg; if(cg_id >= PAL_MAX_CG) { sprintf(error_string, "%s: cg id(%d) out of range\r\n", __FUNCTION__, cg_id); return -1; } cg = &pal_resource.cg[cg_id]; memcpy(&cg->attrib, attrib, sizeof(cg_attrib_struct)); return 0; } int pal_create_circuit(int cg_id, circuit_attrib_struct *attrib) { int i; pal_cg_struct *cg; pal_circuit_struct *circuit; if(cg_id >= PAL_MAX_CG) { sprintf(error_string, "%s: cg id(%d) out of range\r\n", __FUNCTION__, cg_id); return -1; } cg = &pal_resource.cg[cg_id]; if(cg->enable == 0) { sprintf(error_string, "%s: cg(%d) is not created\r\n", __FUNCTION__, cg_id); return -1; } for(i = 0; i < PAL_MAX_CIRCUIT; i++) { circuit = &pal_resource.circuit[i]; if(circuit->enable == 0) { circuit->id = i; circuit->enable = 1; circuit->cg_id = cg_id; memcpy(&circuit->attrib, attrib, sizeof(circuit_attrib_struct)); cg->circuit_num++; return i; } } sprintf(error_string, "%s: no free circuit\r\n", __FUNCTION__); return -1; } int pal_delete_circuit(int circuit_id) { pal_cg_struct *cg; pal_circuit_struct *circuit; if(circuit_id >= PAL_MAX_CIRCUIT) { sprintf(error_string, "%s: circuit id(%d) out of range\r\n", __FUNCTION__, circuit_id); return -1; } circuit = &pal_resource.circuit[circuit_id]; cg = &pal_resource.cg[circuit->cg_id]; circuit->enable = 0; cg->circuit_num--; return 0; } /****************************************************/ /*************** PAL lower layer interface ***************/ /****************************************************/ static int protocol_is_ss7(u8 proto) { if((proto == PROTO_AIF) || (proto == PROTO_ISUP) || (proto == PROTO_BICC)) return 1; else return 0; } void *pal_get_handler(u32 cg_id) { u32 sap_id; sap_id = pal_resource.cg[cg_id].sap_id; return pal_resource.sap[sap_id].attrib.event_handle; } const pal_sap_struct *pal_sap_ptr(u8 sap_id) { if(sap_id < PAL_MAX_SAP) return &pal_resource.sap[sap_id]; else return NULL; } const pal_cg_struct *pal_cg_ptr(u32 cg_id) { if(cg_id < PAL_MAX_CG) return &pal_resource.cg[cg_id]; else return NULL; } const pal_circuit_struct *pal_circuit_ptr(u32 circuit_id) { if(circuit_id < PAL_MAX_CIRCUIT) return &pal_resource.circuit[circuit_id]; else return NULL; } const pal_cg_struct *pal_ss7_find_cg(u8 ni, u32 dpc, u32 opc) { int i; pal_cg_struct *cg; for(i = 0; i < PAL_MAX_CG; i++) { cg = &pal_resource.cg[i]; if(cg->enable == 0) continue; if(protocol_is_ss7(cg->attrib.protocol) == 0) continue; if((cg->attrib.network_id == ni) && (cg->attrib.opc == opc) && (cg->attrib.dpc == dpc)) return cg; } return NULL; } const pal_cg_struct *pal_isdn_find_cg(u32 link_id) { int i; pal_circuit_struct *circuit; for(i = 0; i < PAL_MAX_CIRCUIT; i++) { circuit = &pal_resource.circuit[i]; if(circuit->enable == 0) continue; if(pal_resource.cg[circuit->cg_id].attrib.protocol != PROTO_ISDN) continue; if(circuit->attrib.link_id == link_id) return &pal_resource.cg[circuit->cg_id]; } return NULL; } const pal_cg_struct *pal_sip_find_cg(char *domain, char *their_domain) { int i; pal_cg_struct *cg; for(i = 0; i < PAL_MAX_CG; i++) { cg = &pal_resource.cg[i]; if(cg->enable == 0) continue; if(cg->attrib.protocol != PROTO_SIP) continue; if((strcmp(cg->attrib.local_domain, domain) == 0) && \ (strcmp(cg->attrib.dest_domain, their_domain) == 0)) return cg; } return NULL; } /* * Use "locate" when received primitive from upper layer * Use "find" when received message from network */ const pal_circuit_struct *pal_locate_circuit(u32 cg_id, u32 cic) { int i; pal_circuit_struct *circuit; circuit_attrib_struct *attrib; for(i = 0; i < PAL_MAX_CIRCUIT; i++) { circuit = &pal_resource.circuit[i]; if(circuit->cg_id != cg_id) continue; attrib = &circuit->attrib; if((cic >= attrib->head_cic) && (cic < attrib->head_cic+attrib->cic_range)) return circuit; } return NULL; } const pal_circuit_struct *pal_ss7_find_circuit(u8 ni, u32 dpc, u32 opc, u32 cic) { const pal_cg_struct *cg; if((cg = pal_ss7_find_cg(ni, dpc, opc)) == NULL) return NULL; return pal_locate_circuit(cg->id, cic); } const pal_circuit_struct *pal_isdn_find_circuit(u32 link_id, u32 cic) { const pal_cg_struct *cg; if((cg = pal_isdn_find_cg(link_id)) == NULL) return NULL; return pal_locate_circuit(cg->id, cic); } const pal_circuit_struct *pal_isdn_find_circuit_of_link(u32 link_id) { int i; pal_circuit_struct *circuit; for(i = 0; i < PAL_MAX_CIRCUIT; i++) { circuit = &pal_resource.circuit[i]; if(circuit->enable == 0) continue; if(pal_resource.cg[circuit->cg_id].attrib.protocol != PROTO_ISDN) continue; if(circuit->attrib.link_id == link_id) return circuit; } return NULL; }