Files
svc.ems/plat/aif/src/aifg.c
2024-09-27 15:39:34 +08:00

266 lines
7.1 KiB
C

/********************************************************************
Copyright ?2007 LGC Wireless, Inc. All rights reserved
File Name: aifg_if.c
Description: Interface of AIFG
Version: v9.0.0
Author: Roy Jiang
Create Date: 2007-3-12
History:
2007-3-6 v9.0.1 Create
*********************************************************************/
#include "./include/aifg_var_ext.h"
#include "../../public/src/include/license_id.h"
/*
Name: aifg_bind
Purpose: Request to create a SAP in AIFG module.
Input: aifg_sap_type type: type of upper layer entity
int (*callback)(): pointer to call back function
Output: SAP id
*/
int aifg_bind(aifg_sap_type type, int (*callback)(aifg_indication, aifg_msg_pre_decoded *))
{
//checking parameters
assert(type == AIFG_SAP_MSC || type == AIFG_SAP_BSC);
assert(callback != NULL);
assert(sap[type].enable == 0);
if (wxc2_get_license(LIC_AIF) != 1)
return -1;
sap[type].enable = 1;
sap[type].callback_func = callback;
return (int)type;
}
/*
Name: aifg_modify
Purpose: Request to modify the SAP parameter in AIFG module.
Input: aifg_sap_type type: type of upper layer entity
aifg_callback_func *callback: new callback functions, null if no need to modify
Output: None
*/
void aifg_modify(int sapid, int (*callback)(aifg_indication, aifg_msg_pre_decoded*))
{
//checking parameters
assert(sapid == AIFG_SAP_MSC || sapid == AIFG_SAP_BSC);
assert(sap[sapid].enable == 1);
sap[sapid].enable = 1;
if(callback != NULL)
sap[sapid].callback_func = callback;
return;
}
/*
Name: aifg_set_running_mode
Purpose: Set the running mode of AIFG module.
Input: enum aifg_run_mode mode: running mode, 0 - single, 1 - dual
int alter_ip:IP address of the alternative server, hex format
Output: None
*/
void aifg_set_running_mode(aifg_run_mode mode)
{
assert(mode == AIFG_RUN_MODE_SINGLE || mode == AIFG_RUN_MODE_DUAL);
dual_server.mode = mode;
return;
}
/*
Name: aifg_createCircuitGroup
Purpose: Request to create a circuit group in AIFG module.
Input: int sapid: SAP ID of upper layer entity
int dpc: DPC of the circuit group.
aifg_ni ni: NI of the circuit group.
Output: Circuit Group ID - Upper layer entity should record this ID and pass it to AIFG module
whenever it request to send a message through this circuit group
AIFG_ERR_NO_RESOURCE: Create failed
*/
int aifg_createCircuitGroup(int sapid, int dpc, aifg_ni ni, int tgid)
{
int i;
assert(sapid == AIFG_SAP_MSC || sapid == AIFG_SAP_BSC);
assert(ni >= 0 && ni <= 3);
assert(dpc >= 0);
if (sap[sapid].enable == 0)
goto ERR_PROC;
//check if there is a existing CG with the same dpc and ni
for(i=0; i < AIFG_MAX_CG; i++){
if(cg[i].enable == 1 && cg[i].dpc == dpc && cg[i].ni == ni)
return i;
}
//create a new circuit group
i = 0;
while(cg[i].enable == 1)
i++;
if(i >= AIFG_MAX_CG){
aifg_event = AIFG_ERR_OUT_OF_RESOURCE;
goto ERR_PROC;
}
cg[i].enable = 1;
cg[i].dpc = dpc;
cg[i].ni = ni;
cg[i].sapid = sapid;
cg[i].tgid = tgid;
return i;
ERR_PROC:
return -1;
}
/*
Name: aifg_delCircuitGroup
Purpose: Request to delete a circuit group in AIFG module.
Input: int sapid: SAP ID of upper layer entity
int cgid: Circuit Group ID
Output: None
*/
void aifg_delCircuitGroup(int sapid, int cgid)
{
assert(sapid == AIFG_SAP_MSC || sapid == AIFG_SAP_BSC);
assert(cgid >= 0 && cgid < AIFG_MAX_CG);
cg[cgid].enable = 0;
cg[cgid].dpc = 0;
cg[cgid].ni = 0;
cg[cgid].sapid = 0;
cg[cgid].tgid = 0;
return;
}
/*
Name: aifg_modCircuitGroup
Purpose: Request to modify the parameter of a circuit group in AIFG module.
Input: int sapid: SAP ID of upper layer entity
int cgid: Circuit Group ID
int dpc: new DPC of the circuit group, -1 if no need to change.
enum aifg_ni: new NI of the circuit group, -1 if no need to change.
Output: Circuit Group ID - Upper layer entity should record this ID and pass it to AIFG module
whenever it request to send a message through this circuit group
*/
int aifg_modCircuitGroup(int sapid, int cgid, int dpc, int ni)
{
assert(sapid == AIFG_SAP_MSC || sapid == AIFG_SAP_BSC);
assert(cg[cgid].sapid == sapid);
assert(ni >= 0 && ni <= 3);
assert(dpc >= 0);
assert(cgid >= 0 && cgid < AIFG_MAX_CG);
cg[cgid].enable = 1;
cg[cgid].dpc = dpc;
cg[cgid].ni = ni;
return cgid;
}
/*
Name: aifg_send
Purpose: Request to send a message through A-interface.
Input: int sapid: SAP ID of upper layer entity.
int cgid: Circuit Group ID
int u_port: process port of upper layer entity
aifg_msg *msg: content of assign request message
Output: 0 - succeed
-1 - failed, no free port available
-2 - failed, circuit group not ready
*/
int aifg_send(int sapid, int cgid, int u_port, aifg_msg_t *msg)
{
int protocol;
assert(sapid == AIFG_SAP_MSC || sapid == AIFG_SAP_BSC);
assert(cgid >= 0 && cgid < AIFG_MAX_CG);
assert(msg != NULL);
if (sap[sapid].enable == 0){
aifg_event = AIFG_ERR_SAP_NOT_CREATED;
goto ERR_PROC;
}
//check message protocol and pd
msg->app_port = u_port;
if(msg->id <= AIFG_MSG_ID_RP_SMMA){
if(msg->id <= AIFG_MSG_ID_MM_INFO)
msg->pd = AIFG_PD_DTAP_MM;
else if(msg->id <= AIFG_MSG_ID_FACILITY)
msg->pd = AIFG_PD_DTAP_CC;
else if(msg->id <= AIFG_MSG_ID_RELEASE_CMP_SS)
msg->pd = AIFG_PD_DTAP_SS;
else if(msg->id <= AIFG_MSG_ID_RP_SMMA)
msg->pd = AIFG_PD_DTAP_SMS;
else
assert(0);
protocol = AIFG_MSG_DTAP;
}
else{
if(msg->id <= AIFG_MSG_ID_HO_CAN_RESP)
msg->pd = AIFG_PD_BSSMAP_GLOBAL;
else if(msg->id <= AIFG_MSG_ID_LSA_INFO)
msg->pd = AIFG_PD_BSSMAP_DEDICATED;
else
assert(0);
protocol = AIFG_MSG_BSSMAP;
}
if(msg->aif_port == -1 || msg->pd == AIFG_PD_BSSMAP_GLOBAL){
if(msg->pd != AIFG_PD_BSSMAP_GLOBAL || msg->id == AIFG_MSG_ID_PAGING){
if((msg->aif_port = aifg_port_assign(sapid, cgid, -1)) < 0){
aifg_event = AIFG_ERR_ASSIGN_PORT_FAIL;
goto ERR_PROC;
}
aifg_pcb[msg->aif_port].upper_port = u_port;
aifg_pcb[msg->aif_port].trace_flag = msg->trace_flag;
}
else{
msg->aif_port = -1; //no port need
aifg_send_udt(cgid, msg, NULL); //global BSSMAP message needs no aifg port, except paging
}
}
else if (aifg_pcb[msg->aif_port].stat == AIFG_PORT_TRANSACTION && aifg_pcb[msg->aif_port].ti_type != AIFG_TRANS_UNKNOW){
if((msg->id == AIFG_MSG_ID_SETUP
&& (aifg_pcb[msg->aif_port].ti_stat > 0 || aifg_pcb[msg->aif_port].ti_type != AIFG_TRANS_CC))
|| (msg->id == AIFG_MSG_ID_RP_DATA
&& aifg_pcb[msg->aif_port].ti_type != AIFG_TRANS_SMS))
{
//new transaction
int new_port = aifg_port_assign(sapid, cgid, -1);
if (new_port < 0){
aifg_event = AIFG_ERR_ASSIGN_PORT_FAIL;
goto ERR_PROC;
}
aifg_pcb[new_port].upper_port = u_port;
aifg_pcb[new_port].link_id = aifg_pcb[msg->aif_port].link_id;
aifg_pcb[new_port].trace_flag = msg->trace_flag;
msg->aif_port = new_port;
}
}
if(msg->aif_port != -1){
if (aifg_pcb[msg->aif_port].stat == AIFG_PORT_IDLE){
aifg_event = AIFG_ERR_MSG_SD_TO_IDLE_PORT;
goto ERR_PROC;
}
aifg_pcb[msg->aif_port].cgid = cgid;
aifg_port_proc(&aifg_pcb[msg->aif_port], msg, NULL);
}
aifg_debug_print(msg->aif_port, AIFG_EVENT_RV_REQ, msg, 0);
return AIFG_SUCCEED;
ERR_PROC:
aifg_debug_print(msg->aif_port, aifg_event, msg, u_port);
return AIFG_ERROR;
}