Browse Source

organizações de código

master
Rodgger 2 years ago
parent
commit
001a221ae9
  1. 1
      .gitignore
  2. 16
      Makefile
  3. 0
      obj/method_obj/delete-me
  4. 393
      src/asterisk.c
  5. 58
      src/asterisk.h
  6. 57
      src/client.c
  7. 3
      src/client_simplesip.h
  8. 145
      src/communication.c
  9. 18
      src/crypt.c
  10. 72
      src/info_client.c
  11. 25
      src/log.c
  12. 112
      src/login.c
  13. 40
      src/method_api/agent.c
  14. 10
      src/method_api/agent.h
  15. 272
      src/method_api/call.c
  16. 12
      src/method_api/call.h
  17. 39
      src/method_api/campaign.c
  18. 10
      src/method_api/capaign.h
  19. 35
      src/method_api/method.h

1
.gitignore vendored

@ -1,5 +1,6 @@
obj/*o
obj/method_obj/*o
client
client_static

16
Makefile

@ -2,9 +2,11 @@
CC=gcc
DIR_OBJ=obj/
DIR_OBJ_METHOD=$(DIR_OBJ)method_obj/
DIR_SRC=src/
DIR_SRC_METHOD=$(DIR_SRC)method_api/
CFLAGS = -g -W -Wall -I$(DIR_SRC) $(CFLAGS_OPT)
CFLAGS = -g -W -Wall -I$(DIR_SRC) -I$(DIR_SRC_METHOD) $(CFLAGS_OPT)
LIBS= -ldl -lpthread -lm
@ -18,6 +20,10 @@ obj/info_client.o \
obj/communication.o \
obj/globals.o \
obj/log.o \
obj/login.o \
obj/method_obj/call.o \
obj/method_obj/agent.o \
obj/method_obj/campaign.o \
/opt/libevent/lib/lib_s_ip_event.a \
/opt/openssl/lib64/lib_s_ip_ssl.a \
/opt/openssl/lib64/lib_s_ip_crypto.a
@ -58,6 +64,14 @@ else
$(CC) -c -o $@ $< -DCLIENT_DEBUG $(CFLAGS)
endif
$(DIR_OBJ_METHOD)%.o: $(DIR_SRC_METHOD)%.c
ifeq ( $(DEBUG), )
$(CC) -c -o $@ $< $(CFLAGS)
else
$(info compilar com debug)
$(CC) -c -o $@ $< -DCLIENT_DEBUG $(CFLAGS)
endif
.PHONE: clean
clean:
@rm -f client

0
obj/method_obj/delete-me

393
src/asterisk.c

@ -2,6 +2,8 @@
const char *_session = NULL;
/* retornará o erro genérico do comandos */
int id_error_generic(request_api *api){
@ -27,8 +29,14 @@ int id_error_generic(request_api *api){
}
/* essa estrutura será inseridas o comando e seus domínios */
struct s_idrequest request_validated [] = {
/* grupos de chamada */
{ "Originate", METHOD_CALL },
{ "schedule", METHOD_CALL },
@ -45,6 +53,11 @@ struct s_idrequest request_validated [] = {
{0}
};
/* obter informações do /var/www/html/include/bd
* nesse arquivo será obtido informações de login para AMI */
int get_access(struct s_asterisk *asterisk){
@ -157,6 +170,10 @@ int get_access(struct s_asterisk *asterisk){
}
/* identifica o comando da request */
int identify_request(const char *request){
int i = 0;
@ -176,6 +193,11 @@ int identify_request(const char *request){
return -1;
}
/* libera ponteiro request_api -> informações do comando */
int request_free(request_api *api ){
@ -192,105 +214,9 @@ int request_free(request_api *api ){
}
/* usado para o method_call
* Isso indica que esse request deve ser uma ligação */
int method_call(json_t *json_from_api, const char *request/*, struct s_client *client*/){
request_api *api_call = calloc(1, sizeof(request_api));
if(!api_call){
const char *session = json_string_value( json_object_get(json_from_api, KEY_SESSION));
response_command_error(session, "", CALL_FAIL, FAIL_ALLOC);
return -1; /* falta espaço no cliente retorna para o servidor */
}
memset(&api_call->call, 0, sizeof(struct s_protocol_call));
new_strcpy(&api_call->call.request, request);
api_call->call.id_request = METHOD_CALL;
/* obtém session do json e copia para api_call.call */
const char *session = json_string_value( json_object_get( json_from_api, KEY_SESSION ) );
if(!session){
response_command_error(NULL, "", CALL_FAIL, JSON_KEY_SESSION);
request_free(api_call);
return -1;
}
new_strcpy(&api_call->call.session, session);
_session = session;
/* obtém document do json e copia para api_call.call */
const char *document = json_string_value(json_object_get(json_from_api, KEY_DOCUMENT));
if(!document){
response_command_error(session, "", CALL_FAIL, JSON_KEY_DOCUMENT);
request_free(api_call);
return -1;
}
new_strcpy(&api_call->call.document, document);
/* obtém branch do json e copia para api_call.call - branch o chamador(originador) */
const char *branch = json_string_value(json_object_get(json_from_api, KEY_BRANCH));
if(!branch){
response_command_error(session, "", CALL_FAIL, JSON_KEY_BRANCH);
request_free(api_call);
return -1;
}
new_strcpy(&api_call->call.branch, branch);
/* obtém session do json e copia para api_call.call number - chamado(receber a chamada do branch) */
const char *number = json_string_value(json_object_get(json_from_api, KEY_NUMBER));
if(!number){
request_error(api_call, CALL_FAIL, JSON_KEY_NUMBER);
request_free(api_call);
return -1;
}
new_strcpy(&api_call->call.number, number);
pthread_t pthread;
int ret = pthread_create(&pthread, NULL, to_asterisk, (void*)api_call); /* cria uma thread */
if(0 != ret){
request_error(api_call, CALL_FAIL, PTHREAD_FAIL);/*fazer return rede erro do thread*/
request_free(api_call);
return -1;
}
return 0;
}
int method_campaign(json_t *json_from_api, const char *request ){
request_api api_campaign;
memset(&api_campaign.campaign, 0, sizeof(struct s_protocol_campaign));
new_strcpy(&api_campaign.campaign.request, request);
api_campaign.campaign.id_request = METHOD_CAMPAIGN;
const char *document = json_string_value(json_object_get(json_from_api, KEY_DOCUMENT));
if(!document)
goto fail;
new_strcpy(&api_campaign.campaign.document, document);
const char *session = json_string_value(json_object_get(json_from_api, KEY_SESSION));
if(!session)
goto fail;
new_strcpy(&api_campaign.campaign.session, session);
const char *campaignid = json_string_value(json_object_get(json_from_api, KEY_NUMBER));
if(!campaignid)
goto fail;
new_strcpy(&api_campaign.campaign.campaignid, campaignid);
printf("%d\n", api_campaign.campaign.id_request);
printf("%s\n", api_campaign.campaign.document);
printf("%s\n", api_campaign.campaign.session);
return 0;
fail:
free(api_campaign.campaign.request);
free(api_campaign.campaign.session);
return -1;
}
int get_info_ami(struct s_asterisk *asterisk){
@ -405,54 +331,12 @@ int get_info_ami(struct s_asterisk *asterisk){
}
int method_agent(json_t *json_from_api, const char *request ){
request_api api_agent;
memset(&api_agent.agent, 0, sizeof(struct s_protocol_agent));
new_strcpy(&api_agent.agent.request, request);
api_agent.agent.id_request = METHOD_AGENT;
const char *document = json_string_value(json_object_get(json_from_api, KEY_DOCUMENT));
if(!document)
goto fail;
new_strcpy(&api_agent.agent.document, document);
const char *session = json_string_value(json_object_get(json_from_api, KEY_SESSION));
if(!session)
goto fail;
new_strcpy(&api_agent.agent.session, session);
const char *operatorid = json_string_value(json_object_get(json_from_api, KEY_OPERATORID));
if(!operatorid)
goto fail;
new_strcpy(&api_agent.agent.operatorid, operatorid);
printf("%d\n", api_agent.agent.id_request);
printf("%s\n", api_agent.agent.document);
printf("%s\n", api_agent.agent.session);
printf("%s\n", api_agent.agent.operatorid);
return 0;
fail:
free(api_agent.agent.request);
free(api_agent.agent.session);
return -1;
}
const char *json_session_get(json_t *root){
return json_string_value( json_object_get(root, KEY_SESSION));
}
/* Recebe a json do servidor e identifica seu domínio
* METHOD_CALL
* METHOD_AGENT
* METHOD_CAMPAIGN */
int parse_from_api(json_t *json_from_api, struct s_client *client){
/* Recebe a json do servidor e identifica seu domínio */
int method_from_api(json_t *json_from_api, struct s_client *client){
client->last_command = time(NULL);
const char *session = NULL; // é usado obter erro se ocasionar erro nesta função
@ -490,6 +374,12 @@ int parse_from_api(json_t *json_from_api, struct s_client *client){
return -1;
}
/* socket para ami do asterisk */
void create_socket_ami(struct s_asterisk *asterisk){
@ -503,6 +393,11 @@ void create_socket_ami(struct s_asterisk *asterisk){
fcntl(asterisk->sock_net, F_SETFL, O_NONBLOCK); /* socket não block */
}
/* função padrão para enviar para o asterisk, isto é, ami do asterisk */
int send_asterisk(struct s_asterisk *asterisk, char *str){
@ -526,6 +421,12 @@ int send_asterisk(struct s_asterisk *asterisk, char *str){
return 0;
}
/* Fazer login no AMI */
int send_credentials(struct s_asterisk *asterisk){
@ -541,6 +442,12 @@ int send_credentials(struct s_asterisk *asterisk){
return 0;
}
/* O mesmo que strstr, porém escolhe quantos caracteres serão testados */
char *strnstr(const char *s, const char *find, size_t slen){
char c, sc;
@ -562,6 +469,12 @@ char *strnstr(const char *s, const char *find, size_t slen){
}
/* Espera a resposta da autenticação
* Espera por 10 segundos a resposta
* Se cair a conexão no login também retornará false */
@ -615,6 +528,12 @@ int wait_response_login(struct s_asterisk *asterisk){
}
}
/* limpar buffer antes de começar o comando */
void clean_buffer_network(struct s_asterisk *asterisk){
@ -626,15 +545,19 @@ void clean_buffer_network(struct s_asterisk *asterisk){
if(pfd[0].revents & POLLIN) {
/* limpa o buffer */
recv(asterisk->sock_net, asterisk->buffer_from_asterisk, SIZE_buffer_AMI - 1, MSG_DONTWAIT);
memset(&asterisk->buffer_from_asterisk, 0, SIZE_buffer_AMI);
memset( &asterisk->buffer_from_asterisk, 0, SIZE_buffer_AMI );
}
}
int verify_reponse_event(struct s_asterisk *asterisk/*, struct s_response_ami *ami_call*/, int *result){
int verify_reponse_event(struct s_asterisk *asterisk/*, struct s_response_ami *ami_call*/, int *result){
char name_event[26] = "Event: OriginateResponse";
char *point = NULL;
char *p = asterisk->buffer_from_asterisk;
@ -674,6 +597,12 @@ int verify_reponse_event(struct s_asterisk *asterisk/*, struct s_response_ami *a
}
int verify_reponse_action(struct s_asterisk *asterisk, int *result){
char init_response[60] = "Response: Success\r\nActionID: ";
@ -702,6 +631,12 @@ int verify_reponse_action(struct s_asterisk *asterisk, int *result){
}
int verify_reponse_ring(struct s_asterisk *asterisk){
char name_event[26] = "Event: DialBegin";
@ -760,6 +695,11 @@ int verify_reponse_ring(struct s_asterisk *asterisk){
}
int verify_reponse_answered(struct s_asterisk *asterisk, int *result){
char name_event[26] = "Event: DialEnd";
@ -850,6 +790,11 @@ int verify_reponse_answered(struct s_asterisk *asterisk, int *result){
int verify_reponse_hangup(struct s_asterisk *asterisk, int *result){
char name_event[26] = "Event: Hangup";
@ -918,147 +863,8 @@ int verify_reponse_hangup(struct s_asterisk *asterisk, int *result){
int monitor_call(struct s_asterisk *asterisk){
struct s_response_ami ami_call;
ami_call.action = 0;
ami_call.response_action = 0;
ami_call.event = 0;
ami_call.ring = 0;
ami_call.answered = 0;
ami_call.hangup = 0;
int result_response = 0;
while(1){
struct pollfd pfd[1];
pfd[0].fd = asterisk->sock_net;
pfd[0].events = POLLIN;
if(poll(pfd, 1, 30) == -1){ /* erro no pool, caso erro retorna fail na ligação */
request_error(asterisk->request, CALL_FAIL, POLL_FAIL);
return -1;
}
if(pfd[0].revents & POLLHUP) {
request_error(asterisk->request, CALL_FAIL, CONNECTION_CLOSE);/* connection down */
return -1;
}
else if(pfd[0].revents & POLLIN) {
/* buffer */
int bytes;
bytes = recv(asterisk->sock_net, asterisk->buffer_from_asterisk, SIZE_buffer_AMI - 1, MSG_DONTWAIT);
asterisk->buffer_from_asterisk[bytes] = '\0';
/* identifica apenas se AMI recebeu e conseguiu manipular,
* apenas se a action foi recebida e está formatada corretamente*/
if(ami_call.response_action == 0 &&
verify_reponse_action(asterisk, &result_response) == 1){
ami_call.response_action = 1;
request_ok(asterisk->request, CALL_OK, ACTION_OK);
}
else if(result_response == -1){
request_error(asterisk->request, CALL_FAIL, ACTION_ERROR); /* action return error */
return -1;
}
/* verifica o evento resposta Originate */
result_response = 0;
if(ami_call.response_action == 1 &&
verify_reponse_event(asterisk, &result_response) == 1){
ami_call.event = 1;
request_ok(asterisk->request, CALL_OK, ACTION_EVENT_OK);
}
else if(result_response == -1){
request_error(asterisk->request, CALL_FAIL, ACTION_EVENT_FAIL); /* fail */
return -1;
}
/* Verifica se está tocando, apenas depois que o primeiro (remetente) atende.
* Isto é, toque do canal */
result_response = 0;
if(ami_call.response_action == 1 &&
ami_call.ring == 0 &&
ami_call.event == 1 &&
verify_reponse_ring(asterisk) == 1){
request_ok(asterisk->request, CALL_RING, CALL_RING);
ami_call.ring = 1;
}
/* Apenas verifica se o destinatário atendeu */
result_response = 0;
if(ami_call.response_action == 1 &&
ami_call.answered == 0 &&
verify_reponse_answered(asterisk, &result_response) == 1){
ami_call.answered = 1;
request_ok(asterisk->request, CALL_ANSWERED, CALL_ANSWERED); /* atendida */
}
else if(result_response == -1){
fflush(stdout);
request_error(asterisk->request, CALL_UNANSWERED, CALL_UNANSWERED); /* não atendida */
return -1;
}
/* termina a chamada. Aqui também retornará o erro ou a causa do hangup */
result_response = 0;
if(ami_call.response_action == 1 &&
ami_call.event == 1 &&
ami_call.hangup == 0 &&
verify_reponse_hangup(asterisk, &result_response) == 1){
switch(result_response){
case 20:
request_error(asterisk->request, CALL_NOT_REGISTER, CALL_NOT_REGISTER); /* ramal não registrado */
break;
case 21:
request_error(asterisk->request, CALL_REJECT, CALL_REJECT); /* chamada rejeitada */
break;
case 17:
/* O se tocar, então o ramal naõ está ocupado, logo se sair ele rejeitou */
if(ami_call.ring == 1)
request_error(asterisk->request, CALL_REJECT, CALL_REJECT); /* chamada rejeitada, isto é, recebeu sinal, mas chegou a tocar*/
else
request_error(asterisk->request, CALL_BUSY, CALL_BUSY); /* ocupado */
break;
case 19:
request_error(asterisk->request, CALL_UNANSWERED, CALL_UNANSWERED); /* não respondida */
break;
case 16:
if(ami_call.answered == 0){
request_error(asterisk->request, CALL_HANGUP_RING, CALL_HANGUP_RING);/* O remetende desligou no toque */
return -1;
}
request_ok(asterisk->request, HANGUP_SUCCESS, SIGNAL_COMMAND_END);/* Foi desligada normalmente */
return 1;
break;
default:
if(ami_call.answered == 1)
request_error(asterisk->request, CALL_FAIL_CURRENT, CALL_FAIL_CURRENT); /* Algum erro enquanto a chamada estava em curso */
else
request_error(asterisk->request, CALL_FAIL, CALL_FAIL); /* algum erro antes do destinatário atender */
break;
}
return -1;
}
} else {
usleep(10000);
continue;
}
}
return 0;
}
int insert_command_api(struct s_asterisk *asterisk){
@ -1129,6 +935,10 @@ OtherChannelId: %s\r\n\r\n", asterisk->actionid, /* ActionID */
}
int ami(struct s_asterisk *asterisk){
if(send_credentials(asterisk) == -1){
@ -1171,8 +981,12 @@ int to_ami(struct s_asterisk *asterisk){
return 0;
}
/* Essa função será iniciado pela thread
* */
/* Essa função será iniciado pela thread */
void *to_asterisk(void *arg){
struct s_asterisk asterisk;
asterisk.request = (request_api *) arg;
@ -1200,6 +1014,12 @@ fail:
return NULL;
}
int request_ok(request_api *api, int code, int code_extra){
if(!api){
reponse_server_ok(NULL, code, code_extra);
@ -1222,6 +1042,13 @@ int request_ok(request_api *api, int code, int code_extra){
return 0;
}
int request_error(request_api *api, int code, int code_extra){
if(!api){

58
src/asterisk.h

@ -1,63 +1,13 @@
#ifndef ASTERISK_H
#define ASTERISK_H 1
#include <method.h>
/*
o máximo que poderá receber do socket | recv read
*/
#define SIZE_buffer_AMI 30000
struct s_protocol_campaign {
int id_request;
char *request;
char *document;
char *session;
char *campaignid;
};
struct s_protocol_agent {
int id_request;
char *request;
char *document;
char *session;
char *operatorid;
};
struct s_protocol_call {
int id_request;
char *request;
char *document;
char *session;
char *branch;
char *number;
};
typedef union {
int id_request;
struct s_protocol_campaign campaign;
struct s_protocol_agent agent;
struct s_protocol_call call;
} request_api;
/* Tipos de comando que irá aceitar nesta versão*/
enum {
METHOD_CALL,
METHOD_AGENT,
METHOD_CAMPAIGN
};
struct s_idrequest {
char *request;
int id;
};
extern struct s_idrequest request_validated [];
#define SIZE_buffer_AMI 3000
/* credenciais para logar no AMI */
struct s_credentials {
@ -97,8 +47,8 @@ int method_call(json_t *json_from_api, const char *request/*, struct s_client *c
int method_campaign(json_t *json_from_api, const char *request );
int get_info_ami(struct s_asterisk *asterisk);
int method_agent(json_t *json_from_api, const char *request );
const char *json_session_get(json_t *root);
void create_socket_ami(struct s_asterisk *asterisk);
int method_from_api(json_t *json_from_api, struct s_client *client);
int send_asterisk(struct s_asterisk *asterisk, char *str);
int send_credentials(struct s_asterisk *asterisk);
char *strnstr(const char *s, const char *find, size_t slen);

57
src/client.c

@ -1,5 +1,7 @@
#include <client_simplesip.h>
/* Essa função recebe dados da rede
* Essa é a primeira função que nós temos acesso aos dados
*/
@ -72,7 +74,7 @@ void ssl_read(struct bufferevent * bev, void * arg) {
continue;
}
parse_from_api(json_from_api, client); /* os comandos da api serão manipulados */
method_from_api(json_from_api, client); /* os comandos da api serão manipulados */
json_decref (json_from_api);
free(json_single);
}
@ -81,6 +83,46 @@ void ssl_read(struct bufferevent * bev, void * arg) {
}
/* recebe a json do servidor e retorna com algumas outras informações
* dentro da json */
int server_latency(json_t *json_message, struct s_client *client){
json_t *time_connected = NULL;
json_t *last_command = NULL;
char *str_net = NULL;
time_connected = json_integer(client->time_connected);// acrescenta tempo conectado
last_command = json_integer(client->last_command);// tempo do últimop comando recebido pelo cliente
json_t *json_array = json_object_get(json_message, "NET");
//acrescenta no array
if(json_array_append(json_array, time_connected) == -1)
return -1;
//acrescenta no array
if(json_array_append(json_array, last_command) == -1)
return -1;
str_net = json_dumps(json_message, 0);
send_server(client->bev, str_net);
free(str_net);
json_decref(time_connected);
json_decref(last_command);
return 1;
}
/* Manipula os sinais dos fd
* Isso vai reconhecer quando a conexão for fechada */
void ssl_descriptor(struct bufferevent *bev, short error, void *param){
@ -176,6 +218,10 @@ void ssl_descriptor(struct bufferevent *bev, short error, void *param){
}
/* essa funções é o padrão enviar dados ao servidor
* sempre será chamada para enviar */
int send_server(struct bufferevent *bev, const char *str){
@ -208,6 +254,11 @@ int send_server(struct bufferevent *bev, const char *str){
return 0;
}
/* conecta ao servidor */
int connect_server(struct s_client *client){
@ -276,6 +327,10 @@ int connect_server(struct s_client *client){
}
int main(){
struct s_client *client;

3
src/client_simplesip.h

@ -149,7 +149,7 @@ int Base64Encode(const unsigned char* buffer, size_t length, char** b64text) ;
size_t calcDecodeLength(const char* b64input) ;
int Base64Decode(char* b64message, unsigned char** buffer, size_t* length) ;
void *update_network(void *c);
int parse_from_api(json_t *message_server, struct s_client *client);
int method_from_api(json_t *message_server, struct s_client *client);
int get_cnpj(struct s_client *client);
char *strnstr(const char *s, const char *find, size_t slen);
double calculate_percent_cpu(struct s_stat_cpu *icpu);
@ -184,3 +184,4 @@ void send_log(int id, char *str, ...);
#define PATH_LOG "/var/log/client_simplesip/"
#endif

145
src/communication.c

@ -1,38 +1,5 @@
#include <client_simplesip.h>
/* recebe a json do servidor e retorna com algumas outras informações
* dentro da json */
int server_latency(json_t *json_message, struct s_client *client){
json_t *time_connected = NULL;
json_t *last_command = NULL;
char *str_net = NULL;
time_connected = json_integer(client->time_connected);// acrescenta tempo conectado
last_command = json_integer(client->last_command);// tempo do últimop comando recebido pelo cliente
json_t *json_array = json_object_get(json_message, "NET");
//acrescenta no array
if(json_array_append(json_array, time_connected) == -1)
return -1;
//acrescenta no array
if(json_array_append(json_array, last_command) == -1)
return -1;
str_net = json_dumps(json_message, 0);
send_server(client->bev, str_net);
free(str_net);
json_decref(time_connected);
json_decref(last_command);
return 1;
}
char *str_code(int code, char *str){
@ -196,6 +163,9 @@ char *str_code(int code, char *str){
}
int response_command_error(const char *session, char *user, int code, int error_extra){
char message[128];
@ -225,6 +195,9 @@ int response_command_error(const char *session, char *user, int code, int error_
}
int reponse_server_ok(char *session, int code, int code_extra){
char message[128];
@ -246,43 +219,8 @@ int reponse_server_ok(char *session, int code, int code_extra){
/* mensagem para login, autenticar o usuário
* [ CNPJ, "CNPJ + salt"] = esse salt é conhecido pelo servidor */
json_t *build_message_login(struct s_client *client) {
char *base64 = NULL;
/* mixer */
char simples_ok[20];
simples_ok[0] = '_';
simples_ok[1] = 'O';
simples_ok[2] = 'K';
simples_ok[3] = '_';//¨¨|
simples_ok[4] = 'S';// |
simples_ok[5] = 'I';// |
simples_ok[6] = 'M';// |
simples_ok[7] = 'P';// |
simples_ok[8] = 'L';// |
simples_ok[9] = 'E';// |
simples_ok[10] = 'S';// |
simples_ok[11] = '_';// |
simples_ok[12] = 'O';// |
simples_ok[13] = 'K';// |
simples_ok[14] = '_';// |
simples_ok[15] = '\0';//_|
/* cria a hash com cnpj e o salt */
unsigned char tohash[SHA512_DIGEST_LENGTH + LEN_CNPJ + 1];
sprintf((char *)tohash, "%s%s", client->cnpj, (simples_ok + 3)); /* cnpj e salt */
create_hash_base64(tohash, &base64);
memset(simples_ok, 1, 10);
/* cria o json em para login */
json_t *first_message = json_pack("[ s s ]", client->cnpj, base64);
free(base64);
return first_message;
}
char *login_response_json(char *response){
@ -307,6 +245,7 @@ char *login_response_json(char *response){
/* copia str, mas antes alloca memória para receber */
int new_strcpy(char **dest, const char *src){
@ -328,72 +267,9 @@ int new_strcpy(char **dest, const char *src){
}
/* verifica a resposta do servidor
* Login foi aceito, agora verifica o o salt do servidor */
int verify_login(struct s_client *client, char *response_server){
unsigned char str_login[30]; /* salt sha512 */
str_login[0] = 'L';
str_login[1] = 'O';
str_login[2] = 'G';
str_login[3] = 'I';
str_login[4] = 'N';
str_login[5] = '_';
str_login[6] = 'O';
str_login[7] = 'K';
str_login[8] = '_';
str_login[9] = 'C';
str_login[10] = 'L';
str_login[11] = 'I';
str_login[12] = 'E';
str_login[13] = 'n';
str_login[14] = 'T';
str_login[15] = '_';
str_login[16] = 'S';
str_login[17] = 'I';
str_login[18] = 'M';
str_login[19] = 'P';
str_login[20] = 'L';
str_login[21] = 'E';
str_login[22] = 'S';
str_login[23] = 'I';
str_login[24] = 'P';
str_login[25] = '\0';
str_login[4] = 'N'; /* mixer */
str_login[13] = 'N';/* mixer correct N*/
str_login[17] = 'I';/* mixer */
str_login[11] = 'I';/* mixer */
char *str_base64 = NULL;
create_hash_base64(str_login, &str_base64); /* cria shash512 e codifica em base64 */
if(!str_base64) /* erro receber hash512 codificado base64 */
goto fail;
json_t *json_reponse_login = json_loads(response_server, 0 , NULL); /* carrega json */
if(!json_reponse_login){ /* não é um json */
goto fail;
}
/* varifica se a hash512 criada no servidor é a mesma que o cliente criou */
if(strcmp( json_string_value(json_array_get(json_reponse_login, 0)), str_base64) != 0 ){
goto fail;
printf("LOGIN FAIL\n");
return -1;
}
/* cliente autenticado e poderá seguir normalmente */
client->login = 1;
free(str_base64);
printf("LOGIN OK\n");
return 1;
fail:
free(str_base64);
return -1;
}
/* obter o json no array */
@ -439,6 +315,9 @@ int get_json_array(char* message, char **json, int id ){
}
/* verificar a quantidade de json no texto */
int json_amount(char *message){

18
src/crypt.c

@ -10,6 +10,7 @@ int Base64Encode(const unsigned char* buffer, size_t length, char** b64text); //
size_t calcDecodeLength(const char* b64input); //Calculates the length of a decoded string
int Base64Decode(char* b64message, unsigned char** buffer, size_t* length); //Decodes a base64 encoded string
/* inicializa as bibliotecas openssl */
void Init_crypt(struct s_client *client){
SSL_library_init();
@ -40,6 +41,10 @@ void Init_crypt(struct s_client *client){
}
/* obtém os certificados do servidor */
int ShowCerts(SSL * ssl){
X509 *cert;
@ -73,6 +78,9 @@ int ShowCerts(SSL * ssl){
}
/* Essa função cria uma hash baseado no texto tohash
* depois retorna da função codificada em base64 */
int create_hash_base64(unsigned char *tohash, char **base64){
@ -87,6 +95,9 @@ int create_hash_base64(unsigned char *tohash, char **base64){
}
/* cofifica a menssagem em base64 retorna sempre sucesso
* b64text -> ponteiro que será colocada a codificações
* precisa do free */
@ -112,6 +123,10 @@ int Base64Encode(const unsigned char* buffer, size_t length, char** b64text) { /
return (0); //success
}
size_t calcDecodeLength(const char* b64input) { //Calculates the length of a decoded string
size_t len = strlen(b64input),
padding = 0;
@ -125,6 +140,9 @@ size_t calcDecodeLength(const char* b64input) { //Calculates the length of a dec
}
/* decodifica a menssagem em base 64 */
int Base64Decode(char* b64message, unsigned char** buffer, size_t* length) { //Decodes a base64 encoded string
BIO *bio, *b64;

72
src/info_client.c

@ -1,5 +1,7 @@
#include <client_simplesip.h>
/* construir json sobre rede */
json_t *build_json_net(struct s_client *client){
/* inormação de redes */
@ -12,9 +14,13 @@ json_t *build_json_net(struct s_client *client){
client->time_connected,
client->last_command);
return json_net;
return json_net;
}
/* construir json sobre o software */
json_t *build_json_app(struct s_client *client){
/* informações para aplicação para o servidor */
@ -24,6 +30,10 @@ json_t *build_json_app(struct s_client *client){
return json_app;
}
/* json dos dados uname */
json_t *build_json_uname(struct s_client *client){
/* informação do host */
@ -68,6 +78,10 @@ fail:
return NULL;
}
/* json sobre disk */
json_t *build_json_disk(){
/* ["total", "use", "free", "porcent_use"] */
@ -183,6 +197,11 @@ int get_next_cpustat(uint64_t out[10], struct stat_parser *p, int fd){
return (p->pos == 10);
}
float get_usage_percent(struct cpu_usage *stat){
uint64_t idle, sum;
int i;
@ -202,11 +221,21 @@ float get_usage_percent(struct cpu_usage *stat){
return usage;
}
int proc_stat_loop(int fd){
// you may need to reopen the file in old kernel ((tempo passado)
return (lseek(fd, 0, SEEK_SET) != -1);
}
struct s_stat_cpu *get_info_cpu(){
struct cpu_usage *usage;
@ -263,6 +292,11 @@ struct s_stat_cpu *get_info_cpu(){
return icpu;
}
/* tempo do computador ligado */
int time_statup(){
int fd;
@ -280,6 +314,10 @@ int time_statup(){
}
/* carrega os dados do cpu load
* Isso é para saber tráfego entre os processos */
int load_cpu(float *load){
@ -312,6 +350,11 @@ int load_cpu(float *load){
return 1;
}
/* json da cpu */
json_t *build_json_cpu(){
/*
@ -420,6 +463,10 @@ json_t *build_json_cpu(){
}
struct s_meminfo {
int memtotal;
int memfree;
@ -428,6 +475,10 @@ struct s_meminfo {
int slab;
};
/* obter da linha o valor númerico
* /proc/meminfo */
int get_number_meminfo(char **str){
@ -446,6 +497,10 @@ int get_number_meminfo(char **str){
return atoi(number);
}
/* carregar os dados sobre memória */
int get_meminfo(struct s_meminfo *meminfo){
@ -512,6 +567,11 @@ fail:
return -1;
}
/* json memória */
json_t *build_json_memory(){
@ -531,6 +591,11 @@ json_t *build_json_memory(){
return json_memory;
}
/* construir json e enviar ao cliente */
void *update_network(void *c){
@ -602,6 +667,11 @@ void *update_network(void *c){
}
/* obtem cnpj do cliente */
int get_cnpj(struct s_client *client){

25
src/log.c

@ -30,6 +30,11 @@ char *file_log(char *full_path, int flag){
return full_path;
}
/* Cria o pre log, isto é, a informação de data e o tipo */
int pre_str_log(char *pre, int flag){
@ -49,6 +54,11 @@ int pre_str_log(char *pre, int flag){
return 0;
}
/* consegue privilégios para usar o pasta log */
int get_privileges(){
@ -59,6 +69,11 @@ int get_privileges(){
return 0;
}
/* retira o privilégio para o programa continuar rodando usu[ario comum */
int drop_privileges(){
@ -71,6 +86,11 @@ int drop_privileges(){
return 0;
}
/* Enviar para o arquivo debug */
void send_debug(char *str, ...){
@ -107,6 +127,11 @@ void send_debug(char *str, ...){
}
/* enviar para o arquivo log */
void send_log(int id, char *str, ...){

112
src/login.c

@ -0,0 +1,112 @@
#include <client_simplesip.h>
/* mensagem para login, autenticar o usuário
* [ CNPJ, "CNPJ + salt"] = esse salt é conhecido pelo servidor */
json_t *build_message_login(struct s_client *client) {
char *base64 = NULL;
/* mixer */
char simples_ok[20];
simples_ok[0] = '_';
simples_ok[1] = 'O';
simples_ok[2] = 'K';
simples_ok[3] = '_';//¨¨¨|
simples_ok[4] = 'S';// |
simples_ok[5] = 'I';// |
simples_ok[6] = 'M';// |
simples_ok[7] = 'P';// |
simples_ok[8] = 'L';// |
simples_ok[9] = 'E';// |
simples_ok[10] = 'S';// |
simples_ok[11] = '_';// |
simples_ok[12] = 'O';// |
simples_ok[13] = 'K';// |
simples_ok[14] = '_';// |
simples_ok[15] = '\0';//_|
/* cria a hash com cnpj e o salt */
unsigned char tohash[SHA512_DIGEST_LENGTH + LEN_CNPJ + 1];
sprintf((char *)tohash, "%s%s", client->cnpj, (simples_ok + 3)); /* cnpj e salt */
create_hash_base64(tohash, &base64);
memset(simples_ok, 1, 10);
/* cria o json em para login */
json_t *first_message = json_pack("[ s s ]", client->cnpj, base64);
free(base64);
return first_message;
}
/* verifica a resposta do servidor
* Login foi aceito, agora verifica o o salt do servidor */
int verify_login(struct s_client *client, char *response_server){
unsigned char str_login[30]; /* salt sha512 */
str_login[0] = 'L';
str_login[1] = 'O';
str_login[2] = 'G';
str_login[3] = 'I';
str_login[4] = 'N';
str_login[5] = '_';
str_login[6] = 'O';
str_login[7] = 'K';
str_login[8] = '_';
str_login[9] = 'C';
str_login[10] = 'L';
str_login[11] = 'I';
str_login[12] = 'E';
str_login[13] = 'n';
str_login[14] = 'T';
str_login[15] = '_';
str_login[16] = 'S';
str_login[17] = 'I';
str_login[18] = 'M';
str_login[19] = 'P';
str_login[20] = 'L';
str_login[21] = 'E';
str_login[22] = 'S';
str_login[23] = 'I';
str_login[24] = 'P';
str_login[25] = '\0';
str_login[4] = 'N'; /* mixer */
str_login[13] = 'N';/* mixer correct N*/
str_login[17] = 'I';/* mixer */
str_login[11] = 'I';/* mixer */
char *str_base64 = NULL;
create_hash_base64(str_login, &str_base64); /* cria shash512 e codifica em base64 */
if(!str_base64) /* erro receber hash512 codificado base64 */
goto fail;
json_t *json_reponse_login = json_loads(response_server, 0 , NULL); /* carrega json */
if(!json_reponse_login){ /* não é um json */
goto fail;
}
/* varifica se a hash512 criada no servidor é a mesma que o cliente criou */
if(strcmp( json_string_value(json_array_get(json_reponse_login, 0)), str_base64) != 0 ){
goto fail;
printf("LOGIN FAIL\n");
return -1;
}
/* cliente autenticado e poderá seguir normalmente */
client->login = 1;
free(str_base64);
printf("LOGIN OK\n");
return 1;
fail:
free(str_base64);
return -1;
}

40
src/method_api/agent.c

@ -0,0 +1,40 @@
#include <client_simplesip.h>
int method_agent(json_t *json_from_api, const char *request ){
request_api api_agent;
memset(&api_agent.agent, 0, sizeof(struct s_protocol_agent));
new_strcpy(&api_agent.agent.request, request);
api_agent.agent.id_request = METHOD_AGENT;
const char *document = json_string_value(json_object_get(json_from_api, KEY_DOCUMENT));
if(!document)
goto fail;
new_strcpy(&api_agent.agent.document, document);
const char *session = json_string_value(json_object_get(json_from_api, KEY_SESSION));
if(!session)
goto fail;
new_strcpy(&api_agent.agent.session, session);
const char *operatorid = json_string_value(json_object_get(json_from_api, KEY_OPERATORID));
if(!operatorid)
goto fail;
new_strcpy(&api_agent.agent.operatorid, operatorid);
printf("%d\n", api_agent.agent.id_request);
printf("%s\n", api_agent.agent.document);
printf("%s\n", api_agent.agent.session);
printf("%s\n", api_agent.agent.operatorid);
return 0;
fail:
free(api_agent.agent.request);
free(api_agent.agent.session);
return -1;
}

10
src/method_api/agent.h

@ -0,0 +1,10 @@
struct s_protocol_agent {
int id_request;
char *request;
char *document;
char *session;
char *operatorid;
};

272
src/method_api/call.c

@ -0,0 +1,272 @@
#include <client_simplesip.h>
static int json_session_get(request_api *api_call, json_t *json_from_api){
const char *session = json_string_value( json_object_get( json_from_api, KEY_SESSION ) );
if(!session){
response_command_error(NULL, "", CALL_FAIL, JSON_KEY_SESSION);
request_free(api_call);
return -1;
}
new_strcpy(&api_call->call.session, session);
return 0;
}
static int json_document_get(request_api *api_call, json_t *json_from_api){
/* obtém document do json e copia para api_call.call */
const char *document = json_string_value(json_object_get(json_from_api, KEY_DOCUMENT));
if(!document){
response_command_error(api_call->call.session, "", CALL_FAIL, JSON_KEY_DOCUMENT);
request_free(api_call);
return -1;
}
new_strcpy(&api_call->call.document, document);
return 0;
}
static int json_branch_get(request_api *api_call, json_t *json_from_api){
const char *branch = json_string_value(json_object_get(json_from_api, KEY_BRANCH));
if(!branch){
response_command_error(api_call->call.session, "", CALL_FAIL, JSON_KEY_BRANCH);
request_free(api_call);
return -1;
}
new_strcpy(&api_call->call.branch, branch);
return 0;
}
static int json_number_get(request_api *api_call, json_t *json_from_api){
/* obtém session do json e copia para api_call.call number - chamado(receber a chamada do branch) */
const char *number = json_string_value(json_object_get(json_from_api, KEY_NUMBER));
if(!number){
request_error(api_call, CALL_FAIL, JSON_KEY_NUMBER);
request_free(api_call);
return -1;
}
new_strcpy(&api_call->call.number, number);
return 0;
}
/* usado para o method_call
* Isso indica que esse request deve ser uma ligação */
int method_call(json_t *json_from_api, const char *request/*, struct s_client *client*/){
request_api *api_call = calloc(1, sizeof(request_api));
if(!api_call){
const char *session = json_string_value( json_object_get(json_from_api, KEY_SESSION));
response_command_error(session, "", CALL_FAIL, FAIL_ALLOC);/* erro calloc falta espaço */
return -1; /* falta espaço no cliente retorna para o servidor */
}
memset(&api_call->call, 0, sizeof(struct s_protocol_call));
new_strcpy(&api_call->call.request, request);
api_call->call.id_request = METHOD_CALL;
/* obtém session do json e copia para api_call.call */
if(json_session_get(api_call, json_from_api) == -1)
return -1;
/* obtém document do json e copia para api_call.call */
if( json_document_get(api_call, json_from_api) == -1)
return -1;
/* obtém branch do json e copia para api_call.call - branch o chamador(originador) */
if( json_branch_get(api_call, json_from_api) == -1)
return -1;
/* obtém session do json e copia para api_call.call number - chamado(receber a chamada do branch) */
if( json_number_get(api_call, json_from_api) == -1)
return -1;
pthread_t pthread;
int ret = pthread_create(&pthread, NULL, to_asterisk, (void*)api_call); /* cria uma thread */
if(0 != ret){
request_error(api_call, CALL_FAIL, PTHREAD_FAIL);/*fazer return rede erro do thread*/
request_free(api_call);
return -1;
}
return 0;
}
int monitor_call(struct s_asterisk *asterisk){
struct s_response_ami ami_call;
ami_call.action = 0;
ami_call.response_action = 0;
ami_call.event = 0;
ami_call.ring = 0;
ami_call.answered = 0;
ami_call.hangup = 0;
int result_response = 0;
while(1){
struct pollfd pfd[1];
pfd[0].fd = asterisk->sock_net;
pfd[0].events = POLLIN;
if(poll(pfd, 1, 30) == -1){ /* erro no pool, caso erro retorna fail na ligação */
request_error(asterisk->request, CALL_FAIL, POLL_FAIL);
return -1;
}
if(pfd[0].revents & POLLHUP) {
request_error(asterisk->request, CALL_FAIL, CONNECTION_CLOSE);/* connection down */
return -1;
}
else if(pfd[0].revents & POLLIN) {
/* buffer */
int bytes;
bytes = recv(asterisk->sock_net, asterisk->buffer_from_asterisk, SIZE_buffer_AMI - 1, MSG_DONTWAIT);
asterisk->buffer_from_asterisk[bytes] = '\0';
/* identifica apenas se AMI recebeu e conseguiu manipular,
* apenas se a action foi recebida e está formatada corretamente*/
if(ami_call.response_action == 0 &&
verify_reponse_action(asterisk, &result_response) == 1){
ami_call.response_action = 1;
request_ok(asterisk->request, CALL_OK, ACTION_OK);
}
else if(result_response == -1){
request_error(asterisk->request, CALL_FAIL, ACTION_ERROR); /* action return error */
return -1;
}
/* verifica o evento resposta Originate */
result_response = 0;
if(ami_call.response_action == 1 &&
verify_reponse_event(asterisk, &result_response) == 1){
ami_call.event = 1;
request_ok(asterisk->request, CALL_OK, ACTION_EVENT_OK);
}
else if(result_response == -1){
request_error(asterisk->request, CALL_FAIL, ACTION_EVENT_FAIL); /* fail */
return -1;
}
/* Verifica se está tocando, apenas depois que o primeiro (remetente) atende.
* Isto é, toque do canal */
result_response = 0;
if(ami_call.response_action == 1 &&
ami_call.ring == 0 &&
ami_call.event == 1 &&
verify_reponse_ring(asterisk) == 1){
request_ok(asterisk->request, CALL_RING, CALL_RING);
ami_call.ring = 1;
}
/* Apenas verifica se o destinatário atendeu */
result_response = 0;
if(ami_call.response_action == 1 &&
ami_call.answered == 0 &&
verify_reponse_answered(asterisk, &result_response) == 1){
ami_call.answered = 1;
request_ok(asterisk->request, CALL_ANSWERED, CALL_ANSWERED); /* atendida */
}
else if(result_response == -1){
fflush(stdout);
request_error(asterisk->request, CALL_UNANSWERED, CALL_UNANSWERED); /* não atendida */
return -1;
}
/* termina a chamada. Aqui também retornará o erro ou a causa do hangup */
result_response = 0;
if(ami_call.response_action == 1 &&
ami_call.event == 1 &&
ami_call.hangup == 0 &&
verify_reponse_hangup(asterisk, &result_response) == 1){
switch(result_response){
case 20:
request_error(asterisk->request, CALL_NOT_REGISTER, CALL_NOT_REGISTER); /* ramal não registrado */
break;
case 21:
request_error(asterisk->request, CALL_REJECT, CALL_REJECT); /* chamada rejeitada */
break;
case 17:
/* O se tocar, então o ramal naõ está ocupado, logo se sair ele rejeitou */
if(ami_call.ring == 1)
request_error(asterisk->request, CALL_REJECT, CALL_REJECT); /* chamada rejeitada, isto é, recebeu sinal, mas chegou a tocar*/
else
request_error(asterisk->request, CALL_BUSY, CALL_BUSY); /* ocupado */
break;
case 19:
request_error(asterisk->request, CALL_UNANSWERED, CALL_UNANSWERED); /* não respondida */
break;
case 16:
if(ami_call.answered == 0){
request_error(asterisk->request, CALL_HANGUP_RING, CALL_HANGUP_RING);/* O remetende desligou no toque */
return -1;
}
request_ok(asterisk->request, HANGUP_SUCCESS, SIGNAL_COMMAND_END);/* Foi desligada normalmente */
return 1;
break;
default:
if(ami_call.answered == 1)
request_error(asterisk->request, CALL_FAIL_CURRENT, CALL_FAIL_CURRENT); /* Algum erro enquanto a chamada estava em curso */
else
request_error(asterisk->request, CALL_FAIL, CALL_FAIL); /* algum erro antes do destinatário atender */
break;
}
return -1;
}
} else {
usleep(10000);
continue;
}
}
return 0;
}

12
src/method_api/call.h

@ -0,0 +1,12 @@
struct s_protocol_call {
int id_request;
char *request;
char *document;
char *session;
char *branch;
char *number;
};

39
src/method_api/campaign.c

@ -0,0 +1,39 @@
#include <client_simplesip.h>
int method_campaign(json_t *json_from_api, const char *request ){
request_api api_campaign;
memset(&api_campaign.campaign, 0, sizeof(struct s_protocol_campaign));
new_strcpy(&api_campaign.campaign.request, request);
api_campaign.campaign.id_request = METHOD_CAMPAIGN;
const char *document = json_string_value(json_object_get(json_from_api, KEY_DOCUMENT));
if(!document)
goto fail;
new_strcpy(&api_campaign.campaign.document, document);
const char *session = json_string_value(json_object_get(json_from_api, KEY_SESSION));
if(!session)
goto fail;
new_strcpy(&api_campaign.campaign.session, session);
const char *campaignid = json_string_value(json_object_get(json_from_api, KEY_NUMBER));
if(!campaignid)
goto fail;
new_strcpy(&api_campaign.campaign.campaignid, campaignid);
printf("%d\n", api_campaign.campaign.id_request);
printf("%s\n", api_campaign.campaign.document);
printf("%s\n", api_campaign.campaign.session);
return 0;
fail:
free(api_campaign.campaign.request);
free(api_campaign.campaign.session);
return -1;
}

10
src/method_api/capaign.h

@ -0,0 +1,10 @@
struct s_protocol_campaign {
int id_request;
char *request;
char *document;
char *session;
char *campaignid;
};

35
src/method_api/method.h

@ -0,0 +1,35 @@
#ifndef METHOD
#define METHOD 1
#include <client_simplesip.h>
#include "call.h"
#include "capaign.h"
#include "agent.h"
typedef union {
int id_request;
struct s_protocol_campaign campaign;
struct s_protocol_agent agent;
struct s_protocol_call call;
} request_api;
/* Tipos de comando que irá aceitar nesta versão*/
enum {
METHOD_CALL,
METHOD_AGENT,
METHOD_CAMPAIGN
};
struct s_idrequest {
char *request;
int id;
};
extern struct s_idrequest request_validated [];
#endif
Loading…
Cancel
Save