449 lines
10 KiB
C
449 lines
10 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <dirent.h>
|
|
#include <sys/shm.h>
|
|
#include <sys/ipc.h>
|
|
#include <sys/sem.h>
|
|
#include <sys/ioctl.h>
|
|
#include <errno.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include "./include/cdr.h"
|
|
|
|
static _cdr_vm_struct *cdr_vm_ptr;
|
|
static int cdr_sem_id;
|
|
static _cdr_param cdr_param;
|
|
static char cdr_time[8];
|
|
static int cdr_counter0=0,cdr_counter1=0;
|
|
static int ssn_counter[256];
|
|
|
|
int cdr_init(char plane_id, char type_flag) /* type=0/1: slave(MSS), master */
|
|
{
|
|
int cdr_shm_id;
|
|
|
|
GetCurrentTime(cdr_time);
|
|
|
|
cdr_vm_ptr = (_cdr_vm_struct *)shm_init(cdr_shm_id,
|
|
"cdr_init",
|
|
CDR_SHM_KEY,
|
|
sizeof(_cdr_vm_struct),
|
|
CDR_SHM_PERM|IPC_CREAT);
|
|
cdr_sem_id = sem_init("cdr_init", CDR_SEM_KEY, 1, CDR_SEM_PERM|IPC_CREAT );
|
|
|
|
if(type_flag == 0)
|
|
{
|
|
memset(cdr_vm_ptr, 0x00, sizeof(_cdr_vm_struct));
|
|
cdr_vm_ptr->plane_id = plane_id;
|
|
}
|
|
else
|
|
{
|
|
cdr_config();
|
|
cdr_vm_ptr->plane_id = cdr_param.system_id;
|
|
}
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
int cdr_timer()
|
|
{
|
|
static int cdr_timer_counter = 0;
|
|
|
|
if(cdr_timer_counter++%200 == 0) /*every 2 seconds */
|
|
{
|
|
GetCurrentTime(cdr_time);
|
|
if(cdr_time[4] == 0 && cdr_time[5]>0 && cdr_time[5] <= 2)
|
|
{
|
|
cdr_open_all_new_fd();
|
|
}
|
|
if(cdr_time[3] == 0 && cdr_time[4] ==0 && cdr_time[5] <= 2)
|
|
{
|
|
clean_expired_backup_file();
|
|
}
|
|
}
|
|
|
|
cdr_backup();
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* -------- initialisation functions *---------- */
|
|
|
|
_cdr_param default_param=
|
|
{
|
|
0,
|
|
"/usr/local/backup/cdr",
|
|
".csv",
|
|
0,
|
|
7,
|
|
};
|
|
|
|
int cdr_open_ssn_file(int index)
|
|
{
|
|
char *file_name, file_name0[128],file_name_new[128];
|
|
|
|
if(!cdr_param.ssn_param[index].ssn)
|
|
return 0;
|
|
file_name = &file_name0[0];
|
|
|
|
if(cdr_param.max_records_per_file == 0)
|
|
{
|
|
sprintf(file_name,"%s/cdrFrom%s%d_%d_%02d_%02d_%02d%s",
|
|
cdr_param.base_dir,
|
|
cdr_param.ssn_param[index].name,
|
|
cdr_vm_ptr->plane_id,
|
|
cdr_time[0]+2000,
|
|
cdr_time[1],
|
|
cdr_time[2],
|
|
cdr_time[3],
|
|
cdr_param.file_suffix);
|
|
}
|
|
else
|
|
{
|
|
if(cdr_param.init_flag == 0)
|
|
{
|
|
DIR *dp;
|
|
struct dirent *dirp;
|
|
int no=0,n;
|
|
|
|
if((dp=opendir(cdr_param.base_dir))==NULL)
|
|
printf("can't open %s",cdr_param.base_dir);
|
|
|
|
while (((dirp=readdir(dp))!=NULL) && (n<=50))
|
|
{
|
|
sprintf(file_name_new,"cdrFrom%s%d_%d_%02d_%02d_%02d",
|
|
cdr_param.ssn_param[index].name,
|
|
cdr_vm_ptr->plane_id,
|
|
cdr_time[0]+2000,
|
|
cdr_time[1],
|
|
cdr_time[2],
|
|
cdr_time[3]);
|
|
no = 0;
|
|
if(!strncasecmp(dirp->d_name,file_name_new,strlen((char *)file_name_new)))
|
|
{
|
|
while(1)
|
|
{
|
|
sprintf(file_name,"%s_%d%s",
|
|
file_name_new,
|
|
no,
|
|
cdr_param.file_suffix);
|
|
if(strncasecmp(dirp->d_name,file_name,strlen((char *)file_name)<0))
|
|
break;
|
|
else if(!strncasecmp(dirp->d_name,file_name,strlen((char *)file_name)))
|
|
{
|
|
if((no+1)>cdr_param.ssn_param[index].file_sn) /* a new file */
|
|
cdr_param.ssn_param[index].file_sn = no+1;
|
|
break;
|
|
}
|
|
no++;
|
|
} //while
|
|
} //if
|
|
}//while
|
|
|
|
closedir(dp);
|
|
|
|
sprintf(file_name,"%s/cdrFrom%s%d_%d_%02d_%02d_%02d_%d%s",
|
|
cdr_param.base_dir,
|
|
cdr_param.ssn_param[index].name,
|
|
cdr_vm_ptr->plane_id,
|
|
cdr_time[0]+2000,
|
|
cdr_time[1],
|
|
cdr_time[2],
|
|
cdr_time[3],
|
|
cdr_param.ssn_param[index].file_sn++,
|
|
cdr_param.file_suffix);
|
|
|
|
}
|
|
else
|
|
{
|
|
sprintf(file_name,"%s/cdrFrom%s%d_%d_%02d_%02d_%02d_%d%s",
|
|
cdr_param.base_dir,
|
|
cdr_param.ssn_param[index].name,
|
|
cdr_vm_ptr->plane_id,
|
|
cdr_time[0]+2000,
|
|
cdr_time[1],
|
|
cdr_time[2],
|
|
cdr_time[3],
|
|
cdr_param.ssn_param[index].file_sn++,
|
|
cdr_param.file_suffix);
|
|
}
|
|
}
|
|
|
|
strcpy(cdr_param.ssn_param[index].file_name,file_name);
|
|
|
|
if(cdr_param.ssn_param[index].fd != NULL)
|
|
fclose(cdr_param.ssn_param[index].fd);
|
|
|
|
cdr_param.ssn_param[index].fd = fopen(file_name,"a+b");
|
|
cdr_param.ssn_param[index].total_records = 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
int cdr_open_all_new_fd()
|
|
{
|
|
int index;
|
|
|
|
for(index=0;index<MAX_CDR_APP_NUM;index++)
|
|
{
|
|
cdr_open_ssn_file(index);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int cdr_config()
|
|
{
|
|
char file_name[128]="./conf/cdr.conf";
|
|
FILE *fp=NULL;
|
|
char s[80],len=0;
|
|
char index=-1;
|
|
|
|
memcpy(&cdr_param, &default_param, sizeof(_cdr_param));
|
|
|
|
fp = fopen(file_name, "r");
|
|
if(fp == NULL)
|
|
return 0;
|
|
|
|
strcpy(s,"");
|
|
|
|
while(fgets(s,80,fp) !=(char *)0)
|
|
{
|
|
if( (int *)strchr(s,'#') !=NULL) continue;
|
|
if( (len= strlen(s))==0 ) continue;
|
|
s[len-2] = 0;
|
|
|
|
if(!strncasecmp(s,"[global]"))
|
|
continue;
|
|
if(!strncasecmp(s,"system id=",10))
|
|
{
|
|
cdr_param.system_id = atoi(&s[10]);
|
|
continue;
|
|
}
|
|
if(!strncasecmp(s,"base dir=",9))
|
|
{
|
|
strcpy(cdr_param.base_dir, &s[9]);
|
|
continue;
|
|
}
|
|
if(!strncasecmp(s,"file suffix=",12))
|
|
{
|
|
strcpy(cdr_param.file_suffix,&s[12]);
|
|
continue;
|
|
}
|
|
if(!strncasecmp(s,"max records=",12))
|
|
{
|
|
cdr_param.max_records_per_file = atoi(&s[12]);
|
|
continue;
|
|
}
|
|
if(!strncasecmp(s,"max days=",9))
|
|
{
|
|
cdr_param.max_days = atoi(&s[9]);
|
|
continue;
|
|
}
|
|
if(!strncasecmp(s,"[ system",8))
|
|
{
|
|
index++;
|
|
continue;
|
|
}
|
|
if(index<0 || index>=MAX_CDR_APP_NUM) continue;
|
|
|
|
if(!strncasecmp(s,"ssn=",4))
|
|
{
|
|
cdr_param.ssn_param[index].ssn = atoi(&s[4]);
|
|
continue;
|
|
}
|
|
if(!strncasecmp(s,"name=",5))
|
|
{
|
|
strcpy(cdr_param.ssn_param[index].name,&s[5]);
|
|
}
|
|
}
|
|
fclose(fp);
|
|
|
|
for(index=0;index<MAX_CDR_APP_NUM;index++)
|
|
{
|
|
cdr_param.ssn_param[index].file_sn = 0;
|
|
cdr_param.ssn_param[index].fd = NULL;
|
|
}
|
|
|
|
cdr_param.init_flag = 0;
|
|
cdr_open_all_new_fd();
|
|
cdr_param.init_flag = 1;
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
int clean_expired_backup_file()
|
|
{
|
|
DIR *dp;
|
|
struct dirent *dirp;
|
|
struct stat fileinfo;
|
|
char name[128];
|
|
|
|
if(cdr_param.max_days == 0)
|
|
return 1;
|
|
|
|
if((dp=opendir(cdr_param.base_dir))==NULL)
|
|
{
|
|
printf("can't open %s",cdr_param.base_dir);
|
|
return 0;
|
|
}
|
|
while ((dirp=readdir(dp))!=NULL)
|
|
{
|
|
sprintf(name,"%s//%s",cdr_param.base_dir, dirp->d_name);
|
|
stat(name,&fileinfo);
|
|
|
|
if(time(NULL)>=(fileinfo.st_mtime+cdr_param.max_days*3600*24) )
|
|
{
|
|
remove(name);
|
|
}
|
|
}
|
|
closedir(dp);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* -------- END of initialisation functions *----*/
|
|
|
|
/* ------- CDR submit & write file--------------*/
|
|
|
|
int cdr_submit1(char ssn, unsigned short length, char *data)
|
|
{
|
|
int head, tail;
|
|
_cdr_record *ptr=NULL;
|
|
|
|
head = cdr_vm_ptr->head_ptr;
|
|
tail = cdr_vm_ptr->tail_ptr;
|
|
|
|
ptr = &cdr_vm_ptr->cdr_data[head];
|
|
ptr->ssn = ssn;
|
|
ptr->length = length%CDR_RECORD_SIZE;
|
|
memcpy(ptr->data, data , ptr->length);
|
|
|
|
// sem_lock(cdr_sem_id, 1, 1, IPC_NOWAIT);
|
|
cdr_vm_ptr->head_ptr ++;
|
|
if(cdr_vm_ptr->head_ptr>=MAX_CDR_RECORDS)
|
|
cdr_vm_ptr->head_ptr = 0;
|
|
/*
|
|
if(cdr_vm_ptr->head_ptr == tail)
|
|
{
|
|
cdr_vm_ptr->tail_ptr ++;
|
|
if(cdr_vm_ptr->tail_ptr>=MAX_CDR_RECORDS)
|
|
cdr_vm_ptr->tail_ptr = 0;
|
|
}
|
|
*/
|
|
// sem_unlock(cdr_sem_id, 1, 1, IPC_NOWAIT);
|
|
|
|
cdr_counter0++;
|
|
ssn_counter[ssn]++;
|
|
return 1;
|
|
}
|
|
|
|
int cdr_submit(char ssn, unsigned short length, char *data)
|
|
{
|
|
int head, tail;
|
|
_cdr_record *ptr=NULL;
|
|
|
|
head = cdr_vm_ptr->head_ptr;
|
|
tail = cdr_vm_ptr->tail_ptr;
|
|
|
|
ptr = &cdr_vm_ptr->cdr_data[head];
|
|
ptr->ssn = ssn;
|
|
ptr->length = length%CDR_RECORD_SIZE;
|
|
memcpy(ptr->data, data , ptr->length);
|
|
|
|
// sem_lock(cdr_sem_id, 1, 1, IPC_NOWAIT);
|
|
cdr_vm_ptr->head_ptr ++;
|
|
if(cdr_vm_ptr->head_ptr>=MAX_CDR_RECORDS)
|
|
cdr_vm_ptr->head_ptr = 0;
|
|
/*
|
|
if(cdr_vm_ptr->head_ptr == tail)
|
|
{
|
|
cdr_vm_ptr->tail_ptr ++;
|
|
if(cdr_vm_ptr->tail_ptr>=MAX_CDR_RECORDS)
|
|
cdr_vm_ptr->tail_ptr = 0;
|
|
}
|
|
*/
|
|
// sem_unlock(cdr_sem_id, 1, 1, IPC_NOWAIT);
|
|
|
|
cdr_counter1++;
|
|
ssn_counter[ssn]++;
|
|
return 1;
|
|
}
|
|
|
|
int cdr_get_ssn_index(int ssn)
|
|
{
|
|
int i;
|
|
|
|
for(i=0;i<MAX_CDR_APP_NUM;i++)
|
|
{
|
|
if(cdr_param.ssn_param[i].ssn == ssn)
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
int cdr_back_record(_cdr_record *ptr)
|
|
{
|
|
int index;
|
|
char data[1024];
|
|
|
|
if(ptr == NULL)
|
|
return 0;
|
|
|
|
if((index = cdr_get_ssn_index(ptr->ssn))<0)
|
|
return 0;
|
|
|
|
if(cdr_param.ssn_param[index].fd == NULL)
|
|
return 0;
|
|
|
|
BcdToAscii(data,ptr->data,(ptr->length%CDR_RECORD_SIZE)*2);
|
|
|
|
fprintf(cdr_param.ssn_param[index].fd,"%s\n",data);
|
|
cdr_param.ssn_param[index].total_records++;
|
|
|
|
if(cdr_param.max_records_per_file>0)
|
|
{
|
|
if(cdr_param.ssn_param[index].total_records>=cdr_param.max_records_per_file)
|
|
cdr_open_ssn_file(index);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int cdr_backup()
|
|
{
|
|
int head, tail;
|
|
_cdr_record *ptr=NULL;
|
|
register int loop;
|
|
|
|
head = cdr_vm_ptr->head_ptr;
|
|
|
|
for(loop=0;loop<MAX_CDR_PER_CYCLE;loop++)
|
|
{
|
|
|
|
tail = cdr_vm_ptr->tail_ptr;
|
|
if(head == tail)
|
|
break;
|
|
|
|
ptr = &cdr_vm_ptr->cdr_data[tail];
|
|
//memcpy(ptr, &cdr_vm_ptr->cdr_data, sizeof(_cdr_record));
|
|
|
|
cdr_back_record(ptr);
|
|
|
|
// sem_lock(cdr_sem_id, 1, 1, IPC_NOWAIT);
|
|
cdr_vm_ptr->tail_ptr ++;
|
|
if(cdr_vm_ptr->tail_ptr>=MAX_CDR_RECORDS)
|
|
cdr_vm_ptr->tail_ptr = 0;
|
|
// sem_unlock(cdr_sem_id, 1, 1, IPC_NOWAIT);
|
|
|
|
// if(cdr_vm_ptr->tail_ptr == head)
|
|
// {
|
|
// break;
|
|
// }
|
|
}
|
|
return 1;
|
|
}
|