📄 ivr_frame.c
字号:
#include <stdio.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <signal.h>#include "bktcp.h"#include "ivr_rtime.h"char TxnCode[5];fldDef *fldReq=NULL; /* 请求域定义 */fldDef *fldRsp=NULL; /* 响应域定义 */int fldReqNum=0; /* 请求域个数 */int fldRspNum=0; /* 响应域个数 */int fldRealNum=0; /* 实际响应域个数 */ /* 读取功能配置文件加载到内存 */int IvrinitTxnCfg(char *fname){ FILE *fp=NULL; int i=0; fp = fopen(fname, "r"); if(fp == NULL) { errlog("打开功能配置文件[%s]错误!\n", fname); return -1; } while(fgets(CfgBuf[i], IVR_MAXCOL, fp)!=NULL) { if(CfgBuf[i][0] == '#' || strlen(CfgBuf[i]) == 0) continue; i++; if(i > IVR_MAXLINE) { /* 交易配置数达到系统最大限制 */ errlog("交易配置数达到系统最大限制[%d] 交易配置数[%d]\n",IVR_MAXLINE, i); break; } } fclose(fp); return 0;}/* 通过域号取域名 */int IvrgetNameByNo(char *ibuf, int fNo, char *fName){ char *s=ibuf; char *d=NULL; int i=0, len=0; while(*s) { d=strchr(s, SPLIT); if(d==NULL) { errlog("getNoByName error fno=[%d] fname[%s]\n", fNo, fName); return -1; } if( i==fNo ) { if((d-s) >IVR_MAXLEN) { memcpy(fName, s, IVR_MAXLEN); len = IVR_MAXLEN; } else { memcpy(fName, s, d-s); len = d-s; } break; } i++; s=d+1; } return len;}/* 通过域名取域号 */int IvrgetNoByName(char *ibuf, char *fName, int *fNo){ char *s=ibuf; char *d=NULL; int i=0; while(*s) { d=strchr(s, SPLIT); if(d==NULL) { errlog("IvrgetNoByName error fno=[%d] fname[%s]\n", fNo, fName); return -1; } i++; if( strncmp(fName, s, d-s ) == 0) { *fNo = i; break; } s=d+1; } return 0;}/* 获得报文配置域数 */int IvrGetFldNum(char *ibuf){ char *s=NULL; int i=0; s = ibuf; while(*s){ if( *s == SPLIT) i++; s++; } return i;}/* 定义交易结构 */ /* 函数功能:获得请求包格式*/int IvrgetReqPackForm(){ int i=0, ret; char txncode[6]; for(i=0; i<IVR_MAXLINE; i++) { memset(txncode, 0x00, sizeof(txncode)); if(strlen(CfgBuf[i]) == 0) { errlog("没有找到合适的交易配置 交易码[%s]\n", TxnCode); return -1; } ret = IvrgetNameByNo(CfgBuf[i], 0, txncode); if(ret < 0) return -1; if(strncmp(txncode, TxnCode, 4) == 0&&txncode[4]=='R') return i; } if( i == IVR_MAXLINE ) { errlog("没有找到合适的交易配置 交易码[%s]\n", TxnCode); return -1; } return -1;}/* 获得响应包格式 */int IvrgetRspPackForm(){ int i=0, ret; char txncode[6]; for(i=0; i<IVR_MAXLINE; i++) { memset(txncode, 0x00, sizeof(txncode)); if(strlen(CfgBuf[i]) == 0) { errlog("%s %d 没有找到合适的响应交易配置 交易码[%s]\n", __FILE__, __LINE__,TxnCode); return -1; } ret = IvrgetNameByNo(CfgBuf[i], 0, txncode); if(ret <0) return -1; if(strncmp(txncode, TxnCode, 4) == 0 && txncode[4] == 'S') return i; } if( i == IVR_MAXLINE ) { errlog("没有找到合适的交易配置 交易码[%s]\n", TxnCode); return -1; } return -1;}/* 名字值对应关系 */int IvrUnpackFldDef(char *rbuf, char *formBuf){ int i = 0, ret; char fval[IVR_MAXLEN]; char fnam[IVR_MAXLEN]; fldReqNum = IvrGetFldNum(formBuf); if(fldReqNum <0) { errlog("IvrGetFldNum error %s %d", __FILE__, __LINE__); return -1; } fldReq = (fldDef*)malloc(sizeof(fldDef)*fldReqNum); if(fldReq == NULL) { errlog("malloc fldReq error[%s]\n", strerror(errno)); return -1; } for(i=0; i<fldReqNum; i++) { /* 获得请求报文数据值 */ memset(fval, 0x00, sizeof(fval)); ret = IvrgetNameByNo(rbuf, i, fval); if( ret<0 ){ errlog("IvrgetNameByNo error %s %d", __FILE__, __LINE__); return -1; } fldReq[i].fldVal = (char *)malloc(sizeof(char)*(ret+1)); if(fldReq[i].fldVal == NULL) { errlog("malloc fldReq.fldVal error[%s]\n", strerror(errno)); return -1; } memset(fldReq[i].fldVal, 0x00, (ret+1)); memcpy(fldReq[i].fldVal, fval, ret); fldReq[i].len = ret; memset(fnam, 0x00, sizeof(fnam)); ret = IvrgetNameByNo(formBuf, i, fnam); if( ret<0 ){ errlog("IvrgetNameByNo error %s %d", __FILE__, __LINE__); return -1; } fldReq[i].fldName = (char *)malloc(sizeof(char)*(ret+1)); if(fldReq[i].fldName == NULL) { errlog("malloc fldReq.fldName error[%s]\n", strerror(errno)); return -1; } memset(fldReq[i].fldName, 0x00, (ret+1)); memcpy(fldReq[i].fldName, fnam, ret); } ret = IvrMallocRsp(); if( ret ) {/* IvrPutData("ERRMSG", "响应报文未找到交易配置");*/ errlog("IvrMallocRsp error %s %d", __FILE__, __LINE__); return -1; } return 0;}/* 分配名字值对应关系 */int IvrMallocRsp(){ int i=0; i = IvrgetRspPackForm(); if( i<0 ) return -1; fldRspNum = IvrGetFldNum(CfgBuf[i]); if(fldRspNum <0) return -1; return 0;}/* 按长度根据名字获得值 */char *IvrGetData_0(char *name, char *val, int len){ int i=0; for(i=0; i<fldReqNum; i++) { if(strcmp(fldReq[i].fldName, name) == 0) { if(len <= 0) memcpy(val, fldReq[i].fldVal, fldReq[i].len); else memcpy(val, fldReq[i].fldVal, len); return val; } } strcpy(val, ""); return val;}/* 不按长度根据名字获得值 */char *IvrGetData(char *name, char *val){ return(IvrGetData_0(name, val, 0));}/* 增加链表数据项 */int IvrAddQueue(fldDef *fldp){ fldDef *fldt; fldt = fldRsp; while(fldt->next!=NULL){ fldt=fldt->next; } fldt->next=fldp; return 0;}/* 向名字中付值按长度 */int IvrPutData_0(char *name, char *val, int len){ int nlen=0; fldDef *fldp=NULL; /* 响应域定义 */ fldp = (fldDef *)malloc(sizeof(fldDef)); if(fldp == NULL) { errlog("malloc fldp error[%d]\n", errno); return -1; } fldp->next=NULL; if(IvrFindRepByName(fldRsp, name, val, len)==1) return 0; nlen = strlen(name)+1; fldp->fldName = (char *)malloc(sizeof(char)*nlen); memset(fldp->fldName, 0x00, nlen); if(fldp->fldName == NULL) { errlog("malloc fldp.fldName error:[%s]\n", strerror(errno)); return -1; } strncpy(fldp->fldName, name, nlen-1); if(len == 0) len = strlen(val); fldp->fldVal = (char *)malloc(sizeof(char)*(len+1)); if(fldp->fldVal == NULL) { errlog("malloc fldp.fldVal error:[%s]\n", strerror(errno)); return -1; } memset(fldp->fldVal, 0x00, len+1); memcpy(fldp->fldVal, val, len); fldp->len = len; if(fldRealNum == 0) fldRsp=fldp; else IvrAddQueue(fldp); fldRealNum ++; return 0;}int IvrPutData(char *name, char *val){ return(IvrPutData_0(name, val, 0));}/* 根据名字查找值 */int IvrFindValByName(fldDef *flddef, char *name, char *val){ fldDef *fldf=NULL; fldf = flddef; while(fldf!=NULL) { if(strcmp(fldf->fldName, name) == 0) { memcpy(val, fldf->fldVal, fldf->len); return fldf->len; } fldf=fldf->next; } if(fldf==NULL){ strcpy(val, ""); } return 0;}/* 查找替换值 * 返回1-找到 返回0未找到*/int IvrFindRepByName(fldDef *flddef, char *name, char *val, int len){ int i=0; fldDef *fldf=NULL; fldf = flddef; if(fldf == NULL) return -1; do { if(strcmp(fldf->fldName, name) == 0) { memset(fldf->fldVal, 0x00, fldf->len); if(len == 0) len = strlen(val); memcpy(fldf->fldVal, val, len); fldf->len = len; return 1; } fldf = fldf->next; } while(fldf!=NULL); if(fldf==NULL){ return 0; } return 0;}/* 响应报文解析, 返回包长 */int IvrPackRspProc(char *sbuf, char *formBuf){ int i=0, ret; int buflen=0; char fName[IVR_MAXLEN]; char fVal[IVR_MAXLEN]; fldRspNum = IvrGetFldNum(formBuf); if(fldRspNum <0) return -1; memset(fName, 0x00, sizeof(fName)); sprintf(fName, "%sS",TxnCode); IvrPutData_0(fName, TxnCode,5); for(i=0; i<fldRspNum; i++) { memset(fName, 0x00, sizeof(fName)); ret = IvrgetNameByNo(formBuf, i, fName); if(ret <0) return -1; ret = IvrFindValByName(fldRsp, fName, fVal); if(ret <0) return -1; if(i == 0) { fVal[4]=0; ret = 4; } if(ret > 0) { memcpy(sbuf+buflen, fVal, ret); buflen+=ret; } sbuf[buflen]=SPLIT; buflen++; } return buflen;}/* 解请求报文 */int IvrUnpackReqProc(char *rbuf){ int i =0; memcpy(TxnCode, rbuf, 4); /* 获得请求报文格式 */ i = IvrgetReqPackForm(); if(i<0) { return -1; } i=IvrUnpackFldDef(rbuf, CfgBuf[i]); if(i<0) { errlog("IvrUnpackFldDef error\n"); return -1; } return 0; }/* 解响应报文 */int IvrPackRspFuc(char *sbuf){ int i =0, len=0; /* 获得请求报文格式 */ i = IvrgetRspPackForm(); if(i<0) return -1; len=IvrPackRspProc(sbuf, CfgBuf[i]); if(i<0) return -1; return len; }int IvrFreeMem(){ int i=0; fldDef *fldf=NULL; for(i=0; i<fldReqNum; i++) { if(fldReq[i].fldName != NULL) { free(fldReq[i].fldName); fldReq[i].fldName = NULL; } if(fldReq[i].fldVal != NULL) { free(fldReq[i].fldVal); fldReq[i].fldVal = NULL; } } if(fldReq != NULL) { free(fldReq); fldReq=NULL; } while(fldRsp!=NULL) { if(fldRsp->fldName != NULL) { free(fldRsp->fldName); fldRsp->fldName = NULL; } if(fldRsp->fldVal != NULL) { free(fldRsp->fldVal); fldRsp->fldVal = NULL; } fldf = fldRsp; fldRsp = fldRsp->next; free(fldf); fldf=NULL; } return 0;}/* 屏蔽相关信号 */int IvrSignalProc(){ int i=0; int sig[]={SIGCHLD,SIGHUP}; int signum=sizeof(sig)/sizeof(sig[0]); struct sigaction new_action; new_action.sa_handler = SIG_IGN; sigemptyset(&(new_action.sa_mask)); new_action.sa_flags=0; for(i=0; i<signum; i++) { if(sigaction(sig[i], &new_action,NULL)==-1) { errlog("sigactions is error[%s]\n", strerror(errno)); return -1; } } return 0; }/* 成为精灵进程 */void IvrDeamon(){ if(IvrSignalProc()) return; pid_t pid; pid = fork(); if(pid >0) exit(0); if(pid <0 ) { printf("create child process failure\n"); }}/* 交易处理主控 */void ProcessCtl(int acctfd){ char recvBuf[IVR_MAXLEN]; char sndBuf[IVR_MAXLEN]; ssize_t rcvlen; int ret, len; /* 接收数据 */ memset(recvBuf, 0x00, sizeof(recvBuf)); rcvlen = BkReadFromSocket(acctfd, (char *)recvBuf, IVR_MAXLEN, IVR_TIMEOUT); if(rcvlen <0) { errlog("BkReadFromSocket error ret[%d]\n", rcvlen); return; } /* 记录上送报文 */ memcpy(TxnCode, recvBuf, 4); /* 响应报文初始话 */ memset(sndBuf, 0x00, sizeof(sndBuf)); writeBinLog("bin.log", recvBuf, rcvlen, "请求交易:"); /* 上送报文解包处理 */ ret = IvrUnpackReqProc(recvBuf); if(ret <0){ errlog("IvrUnpackReqProc error ret[%d]\n", ret); sprintf(sndBuf, "%s|%s|", TxnCode, "解请求报文错误!"); len = strlen(sndBuf); goto loop; } /* 交易处理 */ ret = IvrfuncProcess(); if(ret <0) { errlog("IvrfuncProcess error ret[%d]\n", ret); } /* 响应处理 */ len = IvrPackRspFuc(sndBuf); if(len <0) { errlog("IvrPackRspFuc error ret[%d]\n", ret); sprintf(sndBuf, "%s|%s|", TxnCode, "打响应包错误!"); } /* 释放动态内存 */ loop: writeBinLog("bin.log", sndBuf, len, "响应交易:"); ret = BkWriteToSocket(acctfd, sndBuf, len, IVR_TIMEOUT); if(ret <0) { errlog("IvrfuncProcess error ret[%d]\n", ret); } memTrace("mem.trc"); IvrFreeMem(); memTrace("mem.trc"); close(acctfd);}main(int argc, char **argv) { int sockfd=0; int acctfd=0; char ipaddr[16]; pid_t pid=0; int ret=0, len=0; char fname[81]; /* 配置文件名 */ sprintf(fname, "%s/etc/%s", getenv("HOME"), "ivrSock.etc"); ret=IvrinitTxnCfg(fname); if(ret!=0) exit(-1); /* 用法:ivrrtime port */ if(argc < 2) { printf("usage:ivr_rtime portname\n"); exit(-1); } /* 产生精灵进程,脱离终端控制 */ IvrDeamon(); sockfd = BkCreateServerSocket((char *)NULL, argv[1], 64); if(sockfd <=0) { printf("启动ivrtime 失败!errmsg=[%d]\n", sockfd); exit (-1); } printf("成功启动服务 %s %s...!\n", argv[0], argv[1]); memset(ipaddr, 0x00, sizeof(ipaddr)); while( 1 ) { acctfd = BkAcceptConnection(sockfd, ipaddr, 0); if(acctfd <0) continue; pid = fork(); if(pid > 0){ close(acctfd); } else if(pid >0){ errlog("create child pid is error\n"); exit(-1); } else if(pid == 0){ /* 交易处理控制 */ close(sockfd); ProcessCtl(acctfd); exit(0); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -