266 lines
7.1 KiB
C
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;
|
|
}
|