📄 test.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include "commsdms.h"
#include "swi.h"
/*=================== INI file variables ==================
In order to convert string to value,
all numeric INI variables must be long */
char HostName[INI_LEN];
char SWIPort[INI_LEN]; /* SWI service name */
char OfficeFileName[INI_LEN];
char NECG30UserName[INI_LEN];
long TimeOut; /* Time out */
long LOG;
long TIDLen;
long NECG30AutoConnTime;
struct SwitchStru *Switch;
struct SwitchStru *Sw; // Current switch pointer
struct ExkStru *Exk;
int SwitchNum, SwPtr;
int ExkNum, ExkPtr;
char WarnHost[64]; // Warnning center client host name
char SndBuff[512];
char RcvBuff[MAX_TCP_STREAM_BUFFER+256];
char LogBuff[MAX_TCP_STREAM_BUFFER+256];
time_t systime;
int QUIT = 0;
void main(void)
{
char Copywrite[]="SWI v1.0, Switch interface of Subscriber's Data Management System, Copywrite by Jason Chen, 1997.11";
int i;
char TcpNodeName[24], tmp[128];
/* 1. Initialize */
signal(SIGHUP, SIG_IGN);
signal(SIGQUIT, Quit);
signal(SIGPIPE, SIG_IGN);
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
ReadINIFile();
ReadExkFile();
SetupTcp();
time(&systime); /* use for timer() */
while (!QUIT) {
timer();
/* Read tcp packet */
if (SelectTcpStream(RcvBuff, TcpNodeName) == 1) {
if (strlen(TcpNodeName) > 8) { /* >2 is request source */
sprintf(LogBuff, "Rcv : %s\n", RcvBuff);
LogInfo(LogBuff);
AcceptRequestPacket(TcpNodeName);
}
else {
sscanf(TcpNodeName, "%d", &SwPtr);
if (Switch[SwPtr].Busy == 1) {
strcat(Switch[SwPtr].RcvBuff, RcvBuff);
Switch[SwPtr].Step[Switch[SwPtr].SP] ++;
Switch[SwPtr].timer = 0;
}
}
}
/* Switch */
/* step = SwitchType * 1000,000 + FunctionCode * 1000 */
for (SwPtr=0; SwPtr<SwitchNum; SwPtr++) {
Sw = Switch + SwPtr;
// NECG30 Auto connect
// if NECG30AutoConnTime == 0 then disable auto connect
if (Sw->Busy == 0 && Sw->SwitchType == NECG30) {
if (NECG30AutoConnTime != 0 && Sw->timer > NECG30AutoConnTime) {
Sw->SP = 0;
Go(3000000);
Sw->Busy = 1;
break;
}
}
switch (Sw->Step[Sw->SP]) {
/* ======== NEC New Line ======== */
case 2001000:
GoSub(2000000);
break;
case 2001001:
GetPara(Sw->Para, "LL=", tmp, 30);
sprintf(SndBuff, "SOD:NEW,N=%s,EL=%s,LC=101010,", Sw->Tel, tmp);
if (Sw->NewSrv[TOLL_CALL] == '1')
strcat(SndBuff, "RC=003;");
else
strcat(SndBuff, "RC=002;");
Send2Switch();
strcpy(Sw->RcvBuff, "");
Go(2001002);
break;
default:
Sw->ReturnCode = 9999;
//strcpy(Sw->Para, "");
// Log Step value
sprintf(Sw->Para, "Step=%d", Sw->Step[Sw->SP]);
Go(100);
break;
}
}
}
ClearCAPI();
}
/*======================================================================
Function: ReadINIFile
Note : Get INI variables from file
Para : None
Return : None
======================================================================*/
void ReadINIFile(void)
{
char *ININame[] = { /* INI name table */
"HOSTNAME",
"SWIPORT",
"OFFICEFILENAME",
"TIMEOUT",
"LOG",
"TIDLEN",
"NECG30USERNAME",
"NECG30AUTOCONNTIME",
NULL
};
char *INIAddr[] = {
HostName,
SWIPort,
OfficeFileName,
(char*)(&TimeOut),
(char*)(&LOG),
(char*)(&TIDLen),
NECG30UserName,
(char*)(&NECG30AutoConnTime),
(char*)NULL
};
char buff[512], *p;
char *EqualPos, *value;
FILE *fp;
int i;
bzero(HostName, INI_LEN);
bzero(SWIPort, INI_LEN);
bzero(OfficeFileName, INI_LEN);
TimeOut = 90; /* Switch timeout = 3 minutes */
LOG = 0;
TIDLen = 14;
strcpy(NECG30UserName, "swsh");
NECG30AutoConnTime = 1200; /* 15 mins */
if ((fp=fopen(INIFileName,"r"))==NULL) {
printf("Error: Can not open INI file: %s\n", INIFileName);
printf("Program terminated.\n");
exit(0);
}
while (!feof(fp)) { /* Scan INI file */
fscanf(fp, "%s", buff);
if ( (p=strchr(buff,';')) != NULL) *p=0; /* Remove char after ';' */
if ( (p=strchr(buff,' ')) != NULL) *p=0; /* Remove char after ' ' */
if (buff[0]=='[' || buff[0]==0) continue;
EqualPos = strchr(buff, '=');
if (EqualPos == NULL) continue; /* if no '=', skip this line */
*EqualPos = 0; /* Split buff into 2 parts */
for (i=0; ININame[i]!=NULL; i++) /* Scan varibles table */
if (strcmp(ININame[i], strupr(buff)) == 0) {
value = EqualPos + 1;
if (*value>='0' && *value<='9' || *value=='-')
*((long*)INIAddr[i]) = atol(value);
else
strcpy(INIAddr[i], value);
}
}
fclose(fp);
}
/*==============================================================
Function: ReadExkFile
Note : Read Exk code file which generated by DataBase center
Para : None
Return : None
==============================================================*/
void ReadExkFile(void)
{
FILE *fp;
char buf[1024], s1[80], s2[80], s3[80], s4[80], s5[80], s6[80];
#define MAX_SWITCH_NUM 60
char OfficeName[MAX_SWITCH_NUM][20];
struct {
char SwitchStr[16];
int SwitchType;
} SwitchTypeMap[SWITCH_TYPE_NUM] = {
{"E10B", E10B},
{"NEC", NEC},
{"NECBF62", NECBF62},
{"NECG30", NECG30},
{"CC08", CC08},
{"F150V8", F150V8},
{"F150V8V5", F150V8V5},
{"F150V9", F150V9},
{"F150V9V5", F150V9V5},
{"S1240E", S1240E},
{"S1240J", S1240J},
{"5ESS", _5ESS},
{"5ESSV5", _5ESSV5},
{"EWSD", EWSD}
};
int TotalLine, line, i, InsPos;
if ((fp=fopen(OfficeFileName,"r"))==NULL) {
printf("Can not open office code file : %s\n", OfficeFileName);
printf("Program terminate.\n");
exit(1);
}
// 1. Count line & switch num, alloc memory for Switch, Evt & Exk
TotalLine = 0;
SwitchNum = 0;
bzero(OfficeName, MAX_SWITCH_NUM * 20);
while (1) {
bzero(buf, 128);
fgets(buf, 120, fp);
TotalLine ++;
if (feof(fp)) break;
if (buf[0] == '#') continue; // Skip remark line
for (i=0; i<strlen(buf); i++)
if (buf[i]==';') buf[i]=' ';
strcpy(s1, ""); strcpy(s2, ""); strcpy(s3, "");
strcpy(s4, ""); strcpy(s5, ""); strcpy(s6, "");
sscanf(buf, "%s%s%s%s%s%s", s1, s2, s3, s4, s5, s6);
if (strlen(s6)==0) continue; /* Skip invalid line */
for (i=0; i<SwitchNum; i++)
if (strcmp(OfficeName[i], s2) == 0) break;
if (i == SwitchNum) { // New switch
strcpy(OfficeName[i], s2);
SwitchNum ++;
}
}
Switch = (struct SwitchStru *)calloc(SwitchNum, sizeof(struct SwitchStru));
Exk = (struct ExkStru *)calloc(TotalLine, sizeof(struct ExkStru));
if (Switch == NULL || Exk == NULL) {
printf("Not enough memory for Switch, Evt & Exk !\n");
printf("Program terminate.\n");
fclose(fp);
exit(1);
}
bzero(Switch, SwitchNum * sizeof(struct SwitchStru));
bzero(Exk, TotalLine * sizeof(struct ExkStru));
// 2. Read office file
rewind(fp);
/* File office.ini format:
670;长江1;133.228.47.120;2004;PASS;F150V9
*/
SwitchNum = 0;
ExkPtr = 0;
for (line=0; line<TotalLine; line++) {
bzero(buf, 128);
fgets(buf, 120, fp);
if (buf[0] == '#') continue; // Skip remark line
for (i=0;i<strlen(buf);i++)
if (buf[i]==';') buf[i]=' ';
strcpy(s1, ""); strcpy(s2, ""); strcpy(s3, "");
strcpy(s4, ""); strcpy(s5, ""); strcpy(s6, "");
sscanf(buf, "%s%s%s%s%s%s", s1, s2, s3, s4, s5, s6);
if (strlen(s6)==0) continue; /* Skip invalid line */
// Seek the same office name
for (InsPos=0; InsPos<SwitchNum; InsPos++)
if (strcmp(Switch[InsPos].Office, s2) == 0) break;
if (InsPos == SwitchNum) { // New switch
// update switch array
strcpy(Switch[InsPos].Office, s2);
strcpy(Switch[InsPos].Addr, s3);
strcpy(Switch[InsPos].Port, s4);
strcpy(Switch[InsPos].Password, s5);
// convert switch type
Switch[InsPos].SwitchType = 0;
for (i=0;i<SWITCH_TYPE_NUM;i++)
if (strcmp(SwitchTypeMap[i].SwitchStr, s6)==0) {
Switch[InsPos].SwitchType = SwitchTypeMap[i].SwitchType;
strcpy(Switch[InsPos].SwitchTypeStr, SwitchTypeMap[i].SwitchStr);
break;
}
// error switch type, exit
if (Switch[InsPos].SwitchType == 0) {
printf("Error switch type in file: %s , line %d\n", OfficeFileName, line+1);
printf("Program terminate.\n");
fclose(fp);
exit(1);
}
SwitchNum ++;
}
strcpy(Switch[InsPos].Exk[Switch[InsPos].ExkPtr], s1);
Switch[InsPos].ExkPtr ++;
// update Exk array
strcpy(Exk[ExkPtr].Exk, s1);
strcpy(Exk[ExkPtr].Office, s2);
strcpy(Exk[ExkPtr].SwitchTypeStr, s6);
Exk[ExkPtr].SwPtr = Switch + InsPos;
ExkPtr ++;
}
fclose(fp);
ExkNum = ExkPtr;
// 3. Log switch code
strcpy(LogBuff, "\n\n====== Switch ======\n");
LogInfo(LogBuff);
for (i=0;i<SwitchNum;i++) {
Sw = Switch + i;
strcpy(buf, "");
for (Sw->ExkPtr=0; strlen(Sw->Exk[Sw->ExkPtr]) > 0; Sw->ExkPtr++) {
strcat(buf, Sw->Exk[Sw->ExkPtr]);
strcat(buf, " ");
}
sprintf(LogBuff, "Node= %s,%s, Exk= %s\n", Sw->Addr, Sw->Port, buf);
LogInfo(LogBuff);
}
strcpy(LogBuff, "\n\n");
LogInfo(LogBuff);
}
/*==============================================================
Function: SetupTCP
Note : 1. Create tcp client node connect to switch
node name ex: "1", "2", "3", ...
2. Create SLTS tcp server node
Para : None
Return : None
==============================================================*/
void SetupTcp(void)
{
InitCAPI(LogErr, ErrLogFileName, 0);
/* 1. SWI server node */
/*if (CreateTcpStream(TCP_SERVER, "SWI", HostName, SWIPort, "\x02", "\x03", NULL) == -1) {
printf("Can not create tcp server node: SWI.\n");
printf("Program terminate.\n");
exit(0);
}
*/
/* 2. Create tcp client node connect to switch
node name use: "1", "2", "3", ... */
for (SwPtr=0;SwPtr<SwitchNum;SwPtr++) {
Sw = Switch + SwPtr;
sprintf(Sw->TcpNodeName, "%d", SwPtr);
if (CreateTcpStream(TCP_CLIENT, Sw->TcpNodeName, Sw->Addr, Sw->Port, "", "", NULL) == -1) {
sprintf(LogBuff, "Can not create tcp node connect to %s: %s,%s\n",
Sw->Office, Sw->Addr, Sw->Port);
LogErr(LogBuff);
}
Sw->DisconnectTimes = 0;
if (CAPINodeStatus(Sw->TcpNodeName) == TCP_CONNECTED)
Sw->Connect = 1;
else
Sw->Connect = 0;
if (Sw->SwitchType == _5ESS || Sw->SwitchType == NECG30)
Sw->Connect = 0;
LogWarn();
if (Sw->SwitchType == _5ESS) {
Go(9000000);
Sw->Busy = 1;
}
else {
if (Sw->SwitchType == NECG30) {
Go(3000000);
Sw->Busy = 1;
}
else
Sw->Busy = 0;
}
}
//3. clear warnning host name
strcpy(WarnHost, "");
}
/*==========================================================
Function: AcceptRequestPacket
Note :
Para : char *ReqSrc
Return :
==========================================================*/
void AcceptRequestPacket(char *ReqSrc)
{
char TID[64], Tel[TEL_LEN+1], NewTel[TEL_LEN+1];
int Func, ReturnCode;
char tmp[80], *p, *Para;
struct SwitchStru *NewSw; /* for 移机 */
int TotalEvt; /* for Spy */
/* Packet format :
1234567 001 0123456789 (end)
*/
/* 1. Packet error */
if (strlen(RcvBuff) < TIDLen + FUNC_CODE_LEN + TEL_LEN + 3) {
sprintf(LogBuff, "Rcv a error packet from %s : %s", ReqSrc, RcvBuff);
LogErr(LogBuff);
return;
}
/* 2. Read Para */
p = RcvBuff;
strncpy(TID, p, TIDLen);
TID[TIDLen] = '\0';
p += TIDLen + 1;
strncpy(tmp, p, FUNC_CODE_LEN);
tmp[FUNC_CODE_LEN] = '\0';
sscanf(tmp, "%d", &Func);
p += FUNC_CODE_LEN + 1;
strncpy(tmp, p, TEL_LEN);
tmp[TEL_LEN] = '\0';
sscanf(tmp, "%s", Tel);
p += TEL_LEN + 1;
Para = p;
/* 3. Error function code */
if (Func == 0) {
ReturnCode = 1;
ReturnResult(ReqSrc, TID, ReturnCode, "");
return;
}
/* 4. Spy */
if (Func == 999) {
for (TotalEvt=0,SwPtr=0; SwPtr<SwitchNum; SwPtr++)
if (Switch[SwPtr].Busy == 1) TotalEvt ++;
sprintf(Para, "Total event(s): %d", TotalEvt);
ReturnCode = 0;
ReturnResult(ReqSrc, TID, ReturnCode, Para);
return;
}
/* Warnning */
if (Func == 700) {
strcpy(WarnHost, ReqSrc); // save warnning host name
for (SwPtr=0;SwPtr<SwitchNum;SwPtr++) {
Sw = Switch + SwPtr;
Send2Warn();
}
}
/* 5. Seek switch */
if (Func >=1 && Func <= 100) {
for (ExkPtr=0; ExkPtr<ExkNum; ExkPtr++)
if (strncmp(Tel, Exk[ExkPtr].Exk, strlen(Exk[ExkPtr].Exk)) == 0) {
Sw = Exk[ExkPtr].SwPtr;
if (Sw->Busy == 1) {
if (Sw->Step[Sw->SP] >= 3000000 && Sw->Step[Sw->SP] < 3000020 ||
Sw->Step[Sw->SP] >= 9000000 && Sw->Step[Sw->SP] < 9000010)
ReturnCode = 4; // NECG30 or 5ESS login
else
ReturnCode = 5; // Switch busy
ReturnResult(ReqSrc, TID, ReturnCode, "");
return;
}
/*
if (CAPINodeStatus(Sw->TcpNodeName) != TCP_CONNECTED) {
ReturnCode = 4;
ReturnResult(ReqSrc, TID, ReturnCode, "");
return;
}
*/
strcpy(Sw->ReqSrc, ReqSrc);
strcpy(Sw->TID, TID);
strcpy(Sw->Tel, Tel);
strcpy(Sw->Para, Para);
GetPara(Para, "NEWSRV=", Sw->NewSrv, MAX_NEWSRV_LEN);
strcat(Sw->NewSrv, "-"); // Temp for Incoming Call Display
Sw->Func = Func;
if (Sw->SwitchType != NECG30 && Func == 6)
Sw->Func = 5;
Sw->Busy = 1;
Sw->SP = 0;
Sw->Step[0] = Sw->SwitchType * 1000000 + Sw->Func * 1000;
// V5
if (strstr(Exk[ExkPtr].SwitchTypeStr, "V5"))
Sw->V5 = 1;
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -