Tarifador em C++


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`);

If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.

Comments

Cara bacana, soh que o link ta quebrado, voce pode me enviar por email?

Alterei o post em vez do link com os códigos na página. Qualquer coisa, estamos aí.

Cara muito obrigado, vou testa lo amanha e te retorno, muito obrigado novamente

Deixe um comentário

(obrigatório)

(obrigatório)


Get Adobe Flash playerPlugin by wpburn.com wordpress themes
multifarious