341 lines
7.4 KiB
C
341 lines
7.4 KiB
C
#include "./include/radius_pub.h"
|
|
|
|
#define test_nowsms_enable 0
|
|
#define test_css_enable 0
|
|
|
|
#define radius_set_pid_state(val) do { \
|
|
pid_ptr->state = val; \
|
|
radius_log_event("[%05d] \33[32m%s\33[0m transfer to state \33[36m%s\33[0m\r\n", pid, __FUNCTION__, #val); \
|
|
} while(0)
|
|
|
|
#define radius_set_pid_timer(val) do { \
|
|
pid_ptr->timer = val; \
|
|
} while(0)
|
|
|
|
#if(test_nowsms_enable)
|
|
static void radius_test(int pid, BYTE sap_index, WORD *usr_pid, RADIUS_MSG *ptr_radius)
|
|
{
|
|
RADIUS_MSG pdu;
|
|
|
|
if(usr_pid == NULL || ptr_radius == NULL)
|
|
return;
|
|
memset(&pdu, 0, sizeof(RADIUS_MSG));
|
|
pdu.msg_type = RADIUS_MSG_TYPE_ACCESS_ACCEPT;
|
|
pdu.msg.access_accept.message_authenticator.flag = 1;
|
|
radius_send_access_accept(sap_index, pid, *usr_pid, &pdu);
|
|
return;
|
|
}
|
|
#elif(test_css_enable)
|
|
static void radius_test(int pid, BYTE sap_index, WORD *usr_pid, RADIUS_MSG *ptr_radius)
|
|
{
|
|
static BYTE user_id = 0;
|
|
BYTE count = 0;
|
|
int num, i;
|
|
RADIUS_MSG pdu;
|
|
RADIUS_ACCESS_ACCEPT *access_accept;
|
|
RADIUS_VENDOR_SPECIFIC *vendor_specific;
|
|
RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAC *ppac;
|
|
RADIUS_VENDOR_ATTRIBUTE_3GPP2_PPAQ *ppaq;
|
|
|
|
if(usr_pid == NULL || ptr_radius == NULL)
|
|
return;
|
|
if(ptr_radius->msg.access_request.user_password.flag == 1)
|
|
{
|
|
count = 1;
|
|
*usr_pid = user_id;
|
|
user_id++;
|
|
}
|
|
else if((num = ptr_radius->msg.access_request.vendor_specific.num) > 0)
|
|
{
|
|
for(i = 0; i < num; i++)
|
|
{
|
|
vendor_specific = &ptr_radius->msg.access_request.vendor_specific;
|
|
ppaq = &vendor_specific->vendor_specific[i].attribute_3gpp2.ppaq;
|
|
if((vendor_specific->vendor_specific[i].vendor_type == RADIUS_VENDOR_TYPE_3GPP2_PPAQ) && (ppaq->qid.flag == 1))
|
|
{
|
|
*usr_pid = (ppaq->qid.qid.value >> 16) & 0xFF;
|
|
count = (ppaq->qid.qid.value & 0xFF) + 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
memset(&pdu, 0, sizeof(RADIUS_MSG));
|
|
pdu.msg_type = RADIUS_MSG_TYPE_ACCESS_ACCEPT;
|
|
access_accept = &pdu.msg.access_accept;
|
|
vendor_specific = &access_accept->vendor_specific;
|
|
num = vendor_specific->num;
|
|
vendor_specific->vendor_specific[num].flag = 1;
|
|
vendor_specific->vendor_specific[num].vendor_type = RADIUS_VENDOR_TYPE_3GPP2_PPAC;
|
|
ppac = &vendor_specific->vendor_specific[num].attribute_3gpp2.ppac;
|
|
ppac->sfs.flag = 1;
|
|
//ppac->sfs.sfs = 2; //dt && dq
|
|
ppac->sfs.sfs = 1; //vt && vq
|
|
vendor_specific->num++;
|
|
num = vendor_specific->num;
|
|
vendor_specific->vendor_specific[num].vendor_type = RADIUS_VENDOR_TYPE_3GPP2_PPAQ;
|
|
ppaq = &vendor_specific->vendor_specific[num].attribute_3gpp2.ppaq;
|
|
ppaq->qid.flag = 1;
|
|
ppaq->qid.qid.value = ((*usr_pid) << 16) | (count * 1);
|
|
|
|
if(ppac->sfs.sfs == 1)
|
|
{
|
|
ppaq->vq.flag = 1;
|
|
ppaq->vq.vq.integer = (count + 1) * 1024 * 20;
|
|
ppaq->vq.vq.exponent = 1;
|
|
ppaq->vt.flag = 1;
|
|
ppaq->vt.vt.integer = (count + 1) * 1024 * 20 - 1024 * 2;
|
|
ppaq->vt.vt.exponent = 1;
|
|
}
|
|
else if(ppac->sfs.sfs == 2)
|
|
{
|
|
ppaq->dq.flag = 1;
|
|
ppaq->dq.dq.value = count * 20;
|
|
ppaq->dt.flag = 1;
|
|
ppaq->dt.dt.value = count * 20 - 2;
|
|
}
|
|
|
|
vendor_specific->num++;
|
|
access_accept->message_authenticator.flag = 1;
|
|
radius_send_access_accept(sap_index, pid, *usr_pid, &pdu);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
int radius_pid_indication_process(int pid)
|
|
{
|
|
BYTE sap_index;
|
|
RADIUS_PID *pid_ptr;
|
|
|
|
pid_ptr = radius_get_pid_ptr(pid);
|
|
|
|
sap_index = pid_ptr->sap_index;
|
|
|
|
switch (pid_ptr->state)
|
|
{
|
|
case RADIUS_PID_IND_STATE_IDLE:
|
|
if (pid_ptr->rv_msg_flag != 0)
|
|
{
|
|
pid_ptr->rv_msg_flag = 0;
|
|
|
|
if (radius_sap[sap_index].radius_ind == NULL)
|
|
return 1;
|
|
#if(test_nowsms_enable || test_css_enable)
|
|
{
|
|
radius_test(pid, sap_index, &pid_ptr->usr_pid, &radius_msg_pdu);
|
|
}
|
|
#else
|
|
if (radius_sap[sap_index].radius_ind(&pid_ptr->usr_pid, pid, &radius_msg_pdu) < 0)
|
|
{
|
|
radius_log_err("[%04d] %s: radius_ind error! usr_pid=%d\r\n", pid, __FUNCTION__, pid_ptr->usr_pid);
|
|
return 1;
|
|
}
|
|
#endif
|
|
radius_log_event("[%04d] %s: recv indication and send it to up layer\r\n", pid, __FUNCTION__);
|
|
|
|
radius_set_pid_state(RADIUS_PID_IND_STATE_WAIT_FOR_USER_RESP);
|
|
radius_set_pid_timer(RADIUS_TIMER_16S);
|
|
}
|
|
else
|
|
{
|
|
return 1;
|
|
}
|
|
break;
|
|
case RADIUS_PID_IND_STATE_WAIT_FOR_USER_RESP:
|
|
if (pid_ptr->sd_msg_flag == 1)
|
|
{
|
|
pid_ptr->sd_msg_flag = 0;
|
|
|
|
radius_send_msg(pid);
|
|
|
|
radius_set_pid_timer(RADIUS_TIMER_16S);
|
|
|
|
radius_set_pid_state(RADIUS_PID_IND_STATE_WAIT_FOR_TERMINATE);
|
|
|
|
break;
|
|
}
|
|
|
|
if (pid_ptr->timer > 0)
|
|
{
|
|
if (--pid_ptr->timer == 0)
|
|
{
|
|
radius_log_warn("[%04d] %s: wait user response time out\r\n", pid, __FUNCTION__);
|
|
radius_set_pid_state(RADIUS_PID_IND_STATE_TERMINATE);
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
case RADIUS_PID_IND_STATE_WAIT_FOR_TERMINATE:
|
|
if (pid_ptr->rv_msg_flag != 0)
|
|
{
|
|
radius_send_msg(pid);
|
|
|
|
pid_ptr->rv_msg_flag = 0;
|
|
}
|
|
|
|
if (pid_ptr->timer > 0)
|
|
{
|
|
if (--pid_ptr->timer == 0)
|
|
{
|
|
radius_set_pid_state(RADIUS_PID_IND_STATE_TERMINATE);
|
|
return 1;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int radius_pid_indication_fsm(int pid)
|
|
{
|
|
switch (radius_pid_indication_process(pid))
|
|
{
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
radius_init_pid(pid);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int radius_pid_request_process(int pid)
|
|
{
|
|
BYTE sap_index;
|
|
RADIUS_PID *pid_ptr;
|
|
|
|
pid_ptr = radius_get_pid_ptr(pid);
|
|
sap_index = pid_ptr->sap_index;
|
|
|
|
switch (pid_ptr->state)
|
|
{
|
|
case RADIUS_PID_REQ_STATE_IDLE:
|
|
if (pid_ptr->sd_msg_flag == 1)
|
|
{
|
|
pid_ptr->sd_msg_flag = 0;
|
|
|
|
radius_send_msg(pid);
|
|
|
|
radius_set_pid_state(RADIUS_PID_REQ_STATE_WAIT_FOR_PEER_RESP);
|
|
|
|
radius_set_pid_timer(RADIUS_TIMER_16S);
|
|
|
|
break;
|
|
}
|
|
|
|
if (pid_ptr->timer > 0)
|
|
{
|
|
if (--pid_ptr->timer == 0)
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
break;
|
|
case RADIUS_PID_REQ_STATE_WAIT_FOR_PEER_RESP:
|
|
if (pid_ptr->rv_msg_flag != 0)
|
|
{
|
|
radius_log_event("[%04d]%s: recv peer response and send it to up layer\r\n", pid, __FUNCTION__);
|
|
|
|
radius_set_pid_state(RADIUS_PID_REQ_STATE_TERMINATE);
|
|
|
|
if (radius_sap[sap_index].radius_cnf == NULL)
|
|
{
|
|
radius_log_err("[%04d] %s: radius_cnf error! usr_pid=%d\r\n", pid, __FUNCTION__, pid_ptr->usr_pid);
|
|
return 1;
|
|
}
|
|
|
|
radius_sap[sap_index].radius_cnf(pid_ptr->usr_pid, pid, &radius_msg_pdu);
|
|
|
|
return 1;
|
|
}
|
|
|
|
if (pid_ptr->timer > 0)
|
|
{
|
|
if (--pid_ptr->timer == 0)
|
|
{
|
|
radius_log_warn("[%04d] %s: wait peer response time out\r\n", pid, __FUNCTION__);
|
|
radius_set_pid_state(RADIUS_PID_REQ_STATE_TERMINATE);
|
|
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
if ((pid_ptr->timer % RADIUS_RETRANS_TIMER) == 0)
|
|
{
|
|
radius_send_msg(pid);
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
default:
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int radius_pid_request_fsm(int pid)
|
|
{
|
|
switch (radius_pid_request_process(pid))
|
|
{
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
radius_init_pid(pid);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int radius_p_fsm(int pid)
|
|
{
|
|
RADIUS_PID *pid_ptr;
|
|
|
|
if ((pid_ptr = radius_get_pid_ptr(pid)) == NULL)
|
|
return -1;
|
|
|
|
switch (pid_ptr->type)
|
|
{
|
|
case RADIUS_PID_TYPE_IND:
|
|
radius_pid_indication_fsm(pid);
|
|
break;
|
|
case RADIUS_PID_TYPE_REQ:
|
|
radius_pid_request_fsm(pid);
|
|
break;
|
|
default:
|
|
radius_init_pid(pid);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int radius_fsm(void)
|
|
{
|
|
int i;
|
|
RADIUS_PID *pid_ptr;
|
|
|
|
for (i = 0; i < RADIUS_MAX_NUM_OF_PID; i++)
|
|
{
|
|
pid_ptr = radius_get_pid_ptr(i);
|
|
|
|
if (pid_ptr->flag != 1)
|
|
continue;
|
|
|
|
radius_p_fsm(i);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|