View Comments
Há algum tempo atrás, desenvolvi em C++ um tarifador simples para PABX com saída serial. Com ele, você loga em um banco mysql todas as ligações que sua central faz e recebe. Espero que gostem. Só por curiosidade ele ta rodando até hoje se problemas lá :).
tarifador-v2.cpp
/* Author: Wagner Sartori Junior <wsartori@uol.com.br> Revision: $Id: tarifador-v2.cpp,v 2.0 2004/11/04 17:38:51 greg Exp greg $ GPL License Compatible */ #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <ctype.h> #include <string> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <syslog.h> #include <getopt.h> #include <termios.h> #include <mysql++/mysql++.h> using namespace std; char __revision__[] = "$Id: tarifador.cpp,v 2.0 2004/11/04 17:38:51 greg Exp greg $"; /* Override with -f option */ #define DEFAULT_CONFIG_FILE "/etc/tarifador.conf" /* Modify with -v/-q options */ static int VERBOSE = 0; /* Default */ #define VERSAO "2.0" #define _POSIX_SOURCE 1 #define FALSE 0 #define TRUE 1 volatile int STOP=FALSE; static char * USAGE = "usage: tarifador [options]\n" "\n" "options:\n" " -h, --help this help screen\n" " -d, --daemon detach and run as a daemon process\n" " -v increase verbosity by 1\n" " -q, --quiet run with no output\n" " -fFILE, --file=FILE read config from FILE\n" " (default: " DEFAULT_CONFIG_FILE ")\n" "\n" "-d implies -q; non-zero verbosity disables -d\n"; /* DataBase Variables */ char *dbserver; char *database; char *username; char *password; /* Serial Variables */ char *device; char *baudrate; static char * munge_line (char * line) { char * c; c = line+strlen(line)-1; if (*c == '\n') *c = (char) 0; c = strchr(line, '#'); if (c != NULL) *c = (char) 0; else c = line + strlen(line); c--; while (c > line && isspace(*c)) { *c = (char) 0; c--; } c++; if (c == line) return NULL; else return line; } static void read_config(char * filename) { char buf[1024]; FILE * file; char * param; char * resul; int i; int linenum; file = fopen(filename, "r"); if (!file) { fprintf(stderr, USAGE); if (VERBOSE > 0) { printf("Erro abrindo arquivo de configura��o %s\n", filename); exit(1); } } linenum = 0; while (!feof(file)) { char * line; if (!fgets(buf, 1024, file)) { break; } linenum++; line = munge_line(buf); if (line == NULL) continue; if (VERBOSE > 1) { printf("valid configfile line(%d): %s\n", linenum, line); } param = strtok(line, "="); resul = strtok(NULL, "="); if (strcmp(param, "dbserver") == 0) { dbserver = (char *)malloc(sizeof(char *) * (strlen(resul) + 1)); strcpy(dbserver, resul); } else if (strcmp(param, "database") == 0) { database = (char *)malloc(sizeof(char *) * (strlen(resul) + 1)); strcpy(database, resul); } else if (strcmp(param, "username") == 0) { username = (char *)malloc(sizeof(char *) * (strlen(resul) + 1)); strcpy(username, resul); } else if (strcmp(param, "password") == 0) { password = (char *)malloc(sizeof(char *) * (strlen(resul) + 1)); strcpy(password, resul); } else if (strcmp(param, "device") == 0) { device = (char *)malloc(sizeof(char *) * (strlen(resul) + 1)); strcpy(device, resul); } else if (strcmp(param, "baudrate") == 0) { baudrate = (char *)malloc(sizeof(char *) * (strlen(resul) + 1)); strcpy(baudrate, resul); } } fclose(file); } static void daemonize (void) { pid_t pid; pid = fork(); if (pid) { printf("parent process exiting\n"); exit(0); } else { printf("child process detaching\n"); setsid(); chdir("/"); close(0); open("/dev/null", O_RDONLY); close(1); open("/dev/null", O_WRONLY); close(2); open("/dev/null", O_WRONLY); } } MYSQL *pConnection; int main (int argc, char *argv[]) { int fd,c, res; struct termios oldtio,newtio; char buf[255]; string Query; string linha; int daemon = 0; char * config_file = DEFAULT_CONFIG_FILE; char * optstring = "dvqhf:"; struct option longopts[] = { { "daemon", no_argument, NULL, 'd' }, { "quiet", no_argument, NULL, 'q' }, { "help", no_argument, NULL, 'h' }, { "file", required_argument, NULL, 'f' }, { NULL, 0, NULL, 0 } }; int opt; int longindex = 0; opt = getopt_long(argc, argv, optstring, longopts, &longindex); while (opt != -1) { if (opt == 'd') { daemon = 1; VERBOSE = 0; } else if (opt == 'v') { VERBOSE++; daemon = 0; } else if (opt == 'q') { VERBOSE = 0; } else if (opt == 'f') { config_file = strdup(optarg); } else if (opt == 'h' || opt == '?') { fprintf(stderr, USAGE); exit(1); } opt = getopt_long(argc, argv, optstring, longopts, &longindex); } read_config(config_file); if (VERBOSE > 0) { printf("Var: device=%s\n", device); printf("Var: baudrate=%s\n", baudrate); printf("Var: dbserver=%s\n", dbserver); printf("Var: dbserver=%s\n", database); printf("Var: dbserver=%s\n", username); printf("Var: dbserver=%s\n", password); } fd = open(device, O_RDONLY | O_NOCTTY ); if (fd < 0) { printf("Erro na abertura do device (%s)\n", device); exit(1); } tcgetattr(fd,&oldtio); bzero(&newtio, sizeof(newtio)); if (strcmp(baudrate, "2400") == 0) { newtio.c_cflag = B2400 | CRTSCTS | CS8 | CLOCAL | CREAD; } else if (strcmp(baudrate, "4800") == 0) { newtio.c_cflag = B4800 | CRTSCTS | CS8 | CLOCAL | CREAD; } else if (strcmp(baudrate, "4800") == 0) { newtio.c_cflag = B4800 | CRTSCTS | CS8 | CLOCAL | CREAD; } else if (strcmp(baudrate, "9600") == 0) { newtio.c_cflag = B9600 | CRTSCTS | CS8 | CLOCAL | CREAD; } else if (strcmp(baudrate, "19200") == 0) { newtio.c_cflag = B19200 | CRTSCTS | CS8 | CLOCAL | CREAD; } else if (strcmp(baudrate, "38400") == 0) { newtio.c_cflag = B38400 | CRTSCTS | CS8 | CLOCAL | CREAD; } else { printf("Baudrate (%s) not supported.", baudrate); exit(1); } newtio.c_iflag = IGNPAR | ICRNL; newtio.c_oflag = 0; newtio.c_lflag = ICANON; tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); if (daemon) { daemonize(); syslog(LOG_NOTICE, "Daemon started"); } while (STOP==FALSE) { res = read(fd,buf,255); buf[res]=0; if (res > 30) { linha.empty(); Query.empty(); linha = buf; if (VERBOSE > 0) { cout<<"Linha:"<<linha<<endl; cout<<"Data:"<<linha.substr(0,8)<<endl; cout<<"Hora:"<<linha.substr(8,8)<<endl; cout<<"Linha:"<<linha.substr(17,1)<<endl; cout<<"Ramal:"<<linha.substr(21,2)<<endl; cout<<"Duracao:"<<linha.substr(28,8)<<endl; cout<<"Destino:"<<linha.substr(36,32)<<endl; cout<<"Tipo:"<<linha.substr(68,1)<<endl; cout<<"================================================"<<endl; } if (linha.substr(68,1) == "2") { pConnection = mysql_init(NULL); if(!pConnection) { if (daemon) syslog(LOG_ERR, "mysql_init error"); printf("mysql_init error\n"); exit(1); } if(mysql_real_connect(pConnection, dbserver, username, password, database,0,NULL,0) == NULL) { if (daemon) syslog(LOG_ERR, "mysql pConnection error"); printf("mysql pConnection error\n"); exit(1); } Query = "INSERT INTO pabx_ligacoes (lin_id, ram_ramal, lig_data, lig_duracao, lig_destino) VALUES ('" + linha.substr(17,1) + "', '" + linha.substr(21,2) + "', '20" + linha.substr(6,2) + "-" + linha.substr(3,2) + "-" + linha.substr(0,2) + " " + linha.substr(8,8) + "', '" + linha.substr(28,8) + "', '" + linha.substr(36,32) + "');"; if(mysql_query(pConnection,Query.c_str()) != 0) { if (daemon) syslog(LOG_ERR, "Query (%s) error\n", Query.c_str()); printf("Query (%s) error\n", Query.c_str()); exit(1); } mysql_close(pConnection); } } if (buf[0]=='z') STOP=TRUE; } tcsetattr(fd,TCSANOW,&oldtio); return 0; }
tarifador.conf
# Configuracoes do Tarifador # device = device serial para leitura das tarifas # dbserver = hostname/ip do servidor de banco de dados # database = nome do banco de dados # username = nome do usuario para acesso ao banco de dados # password = senha de acesso ao banco de dados device=/dev/ttyS0 baudrate=2400 dbserver=server01 database=dbname username=dbuser password=dbpass sql=INSERT INTO pabx_ligacoes (lin_id, ram_ramal, lig_data, lig_duracao, lig_destino) VALUES (?, ?, ?, ?, ?);
tarifador.sql
-- -- Estrutura da tabela `pabx_ligacoes` -- CREATE TABLE `pabx_ligacoes` ( `lig_id` int(11) NOT NULL auto_increment, `lin_id` int(11) NOT NULL default '0', `ram_ramal` int(2) NOT NULL default '0', `lig_data` datetime NOT NULL default '0000-00-00 00:00:00', `lig_duracao` time NOT NULL default '00:00:00', `lig_destino` varchar(32) NOT NULL default '', PRIMARY KEY (`lig_id`), KEY `lin_id` (`lin_id`), KEY `ram_ramal` (`ram_ramal`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Tabela de Ligacoes Telefonicas' AUTO_INCREMENT=0; -- -------------------------------------------------------- -- -- Estrutura da tabela `pabx_linhas` -- CREATE TABLE `pabx_linhas` ( `lin_id` int(11) NOT NULL auto_increment, `lin_linha` int(8) NOT NULL default '0', `lin_celular` int(11) NOT NULL default '0', PRIMARY KEY (`lin_id`), UNIQUE KEY `lin_linha` (`lin_linha`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Tabela de Linhas Telefonicas' AUTO_INCREMENT=0 ; -- -------------------------------------------------------- -- -- Estrutura da tabela `pabx_ramais` -- CREATE TABLE `pabx_ramais` ( `ram_ramal` int(2) NOT NULL default '0', `fun_id` int(11) default NULL, PRIMARY KEY (`ram_ramal`), KEY `fun_id` (`fun_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='Tabela de Ramais Telefonicos'; -- -- Constraints for table `pabx_ligacoes` -- --ALTER TABLE `pabx_ligacoes` -- ADD CONSTRAINT `pabx_ligacoes_ibfk_1` FOREIGN KEY (`lin_id`) REFERENCES `pabx_linhas` (`lin_id`), -- ADD CONSTRAINT `pabx_ligacoes_ibfk_2` FOREIGN KEY (`ram_ramal`) REFERENCES `pabx_ramais` (`ram_ramal`); -- -- Constraints for table `pabx_ramais` -- --ALTER TABLE `pabx_ramais` -- ADD CONSTRAINT `pabx_ramais_ibfk_1` FOREIGN KEY (`fun_id`) REFERENCES `funcionarios` (`fun_id`);