340 lines
7.0 KiB
C
340 lines
7.0 KiB
C
/*
|
|
* pal/rm.c
|
|
*
|
|
* Copyright (C) 2008 ACRD
|
|
* Written by: Xinyu Yan <xinyu.yan@adc.com>
|
|
*
|
|
* Description: Protocol Abstraction Layer - resource management part
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#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;
|
|
}
|
|
|