Browse Source

Documentação das funções relacionadas a "agent" e renomear estrutura s_list_agents para s_list_agent

pull/23/head
Diego Nakaniwa 3 months ago
parent
commit
af9d6c9816
  1. 4
      info/camada permanência
  2. 2
      info/camada_de_persistencia.svg
  3. 361
      src/agent/agent.c
  4. 68
      src/agent/agent.h
  5. 63
      src/agent/agent_db.c
  6. 12
      src/database/database.c
  7. 12
      src/database/database.h
  8. 49
      src/frame/agent_frame.c
  9. 31
      src/frame/agent_frame.h
  10. 6
      src/frame/frame_asterisk.h
  11. 2
      src/frame/frame_globals.h
  12. 1
      src/methods_actions.c

4
info/camada permanência

@ -29,7 +29,7 @@ struct s_peer ( s_list_peer )
│ ├── char *paused_reason;
│ ├── int ringin_use;
│ ├── unsigned int action_update:1;
│ ├── strut s_list_agents; (não free)
│ ├── strut s_list_agent; (não free)
│ ├── struct s_peer *node_up;
│ └── struct s_queue_member *next;
├── struct s_channel *channel;
@ -104,7 +104,7 @@ struct s_list_queue
└── struct s_list_queue *next;
struct s_list_agents
struct s_list_agent
├── unsigned long long int id;
├── char *name;
├── char *matricula;

2
info/camada_de_persistencia.svg

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

361
src/agent/agent.c

@ -24,161 +24,136 @@
#include <string_functions.h>
#include <stdlib.h>
#include <parse_actions.h>
#include <parse_events.h>
int parse_event_agents( EVENT *event, s_manager *smanager ){
/*!
* Receberá o evento agents
* \param event estrutura do evento agents
* \param principal estrutura
* \return 1 em caso de sucesso e -1 em caso de falha
*/
int parse_event_agents( PARAM_EVENT_SMANAGER ){
/*
* Agent - Agent ID of the agent.
* Name - User friendly name of the agent.
* Status - Current status of the agent.
* The valid values are:
* AGENT_LOGGEDOFF - desconectado
* AGENT_IDLE - disponível
* AGENT_ONCALL - em chamada
*
* TalkingToChan - BRIDGEPEER value on agent channel.
* Present if Status value is AGENT_ONCALL.
* CallStarted - Epoche time when the agent started talking with the caller.
* Present if Status value is AGENT_ONCALL.
* LoggedInTime - Epoche time when the agent logged in.
* Present if Status value is AGENT_IDLE or AGENT_ONCALL.
* Channel
* ChannelState - A numeric code for the channel's current state, related to ChannelStateDesc
* ChannelStateDesc
* Down
* Rsrvd
* OffHook
* Dialing
* Ring
* Ringing
* Up
* Busy
* Dialing Offhook
* Pre-ring
* Unknown
* CallerIDNum
* CallerIDName
* ConnectedLineNum
* ConnectedLineName
* Language
* AccountCode
* Context
* Exten
* Priority
* Uniqueid
* Linkedid - Uniqueid of the oldest channel associated with this channel.
* ActionID - ActionID for this transaction. Will be returned.
*
*/
/*
* Atendimento automático aparecerá logado, porém outros aparecerá logoff
*/
// Caso o agente esteja desconectado ou em modo manual.
// Event: Agents
// Agent: 1000
// Name: admin
// Status: AGENT_LOGGEDOFF
// Caso o agente esteja em modo automatico e em espera.
// Event: Agents
// Agent: 1000
// Name: admin
// Status: AGENT_IDLE
// LoggedInTime: 1719496232
// Channel: SIP/1001-000000c3
// ChannelState: 6
// ChannelStateDesc: Up
// CallerIDNum: 1001
// CallerIDName: <unknown>
// ConnectedLineNum: 1000
// ConnectedLineName: Aguardando
// Language: en
// AccountCode:
// Context: app-login
// Exten: **62
// Priority: 8
// Uniqueid: 1719496230.541
// Linkedid: 1719496230.541
// Caso o agente esteja em modo automatico e em ligação.
// Event: Agents
// Agent: 1000
// Name: admin
// Status: AGENT_ONCALL
// TalkingToChan: Local/1001@app-callcenter-0000003a;2
// CallStarted: 1719496294
// LoggedInTime: 1719496232
// Channel: SIP/1001-000000c3
// ChannelState: 6
// ChannelStateDesc: Up
// CallerIDNum: 1001
// CallerIDName: <unknown>
// ConnectedLineNum: 1002
// ConnectedLineName: 1002
// Language: en
// AccountCode:
// Context: app-login
// Exten: **62
// Priority: 8
// Uniqueid: 1719496230.541
// Linkedid: 1719496230.541
const char *matricula, *name, *status;
unsigned int is_login_auto = 0, is_login_manual = 0;
RESPONSE_MARIADB *rmdb = NULL, *rmdb_update = NULL, *rmdb_insert = NULL;
matricula = ami_get_value( smanager->ami, event->args, "Agent" );
if( !matricula ) { goto fail; }
name = ami_get_value( smanager->ami, event->args, "Name" );
if( !name ){ goto fail; }
status = ami_get_value( smanager->ami, event->args, "Status" );
if( !status ) { goto fail; }
/* 3 valores
* AGENT_LOGGEDOFF - login manual ou desconectado
* AGENT_IDLE - login automático
* AGENT_ONCALL - login automático
*/
// Obtem os valores do evento.
GET_EVENT_ARGUMENT_VALUE("Agent", matricula);
GET_EVENT_ARGUMENT_VALUE("Name", name);
GET_EVENT_ARGUMENT_VALUE("Status", status);
// Verifica se é agente automatico ou manual/desconectado.
is_login_auto = strcmp_n( "AGENT_LOGGEDOFF", status ) ? TRUE : FALSE ;
is_login_manual = exists_agent_in_queue( matricula ) == 1 ? ( is_login_auto == 0 ? TRUE : FALSE ) : FALSE ;
// Se não for agente automatico, verifica se o agente está em alguma fila. Se estiver, é agente manual.
is_login_manual = is_agent_in_any_queue( matricula ) == 1 ? ( is_login_auto == 0 ? TRUE : FALSE ) : FALSE ;
{ //banco de dados
rmdb = get_agents_db( Select_agents, matricula );
if( !GET_SUCCESS_MARIADB( rmdb ) ){ /* falha de buscar dados do banco de dados */
FAIL( "FAIL get_agents_db - function %s", __func__ );
}
TABLE_TYPE_AGENT *table_agent = (struct s_table_agent *)GET_DATA_MARIADB(rmdb);
if (table_agent) {
/* dados na tabela agente */
int same_name = (strcmp_n( table_agent->name, name ) == 0
? TRUE
: FALSE
);
int same_login_auto = (is_login_auto == table_agent->login_auto
? TRUE
: FALSE
);
int same_login_manual = (is_login_manual == table_agent->login_manual
? TRUE
: FALSE
);
if( !same_name || !same_login_auto || !same_login_manual ){
/* atualizar linha de dados da tabela agent */
rmdb_update = update_agents_db( Update_agents, name, is_login_auto, is_login_manual, NULL, matricula );
if( !GET_SUCCESS_MARIADB( rmdb_update ) ){ /* falha de update dados do banco de dados */
FAIL( "FAIL update_agents_db - function %s", __func__ );
}
// Procura o agente no banco de dados.
rmdb = get_agent_db( Select_agent, matricula );
if( !GET_SUCCESS_MARIADB( rmdb ) ){ // Falha na busca no banco de dados.
FAIL( "FAIL get_agent_db - function %s", __func__ );
}
TABLE_TYPE_AGENT *table_agent = (struct s_table_agent *)GET_DATA_MARIADB(rmdb);
// Se o agente ja existe no banco de dados, verifica se há diferenças entre as informações do evento e as do banco de dados.
if (table_agent) {
int same_name = (strcmp_n( table_agent->name, name ) == 0 ? TRUE : FALSE );
int same_login_auto = (is_login_auto == table_agent->login_auto ? TRUE : FALSE );
int same_login_manual = (is_login_manual == table_agent->login_manual ? TRUE : FALSE );
// Em caso de diferença, atualiza o banco de dados com as informações do evento.
if( !same_name || !same_login_auto || !same_login_manual ){
rmdb_update = update_agent_db( Update_agent, name, is_login_auto, is_login_manual, NULL, matricula );
if( !GET_SUCCESS_MARIADB( rmdb_update ) ){ // Falha no update do banco de dados.
FAIL( "FAIL update_agent_db - function %s", __func__ );
}
}
else {
// inseri uma linha na tabela
rmdb_insert = insert_agents_db( Insert_agents, name, matricula, is_login_auto, is_login_manual );
if( !GET_SUCCESS_MARIADB( rmdb_insert ) ){ /* falha de buscar dados do banco de dados */
FAIL( "FAIL insert_agents_db - function %s", __func__ );
}
}
else { // Se o agente não existe no banco de dados, insere o agente .
rmdb_insert = insert_agent_db( Insert_agent, name, matricula, is_login_auto, is_login_manual );
if( !GET_SUCCESS_MARIADB( rmdb_insert ) ){ // Falha na inserção do agente no banco de dados.
FAIL( "FAIL insert_agent_db - function %s", __func__ );
}
}
{ // camada de persistência (CP)
struct s_list_agents *agent = get_agents(matricula);
// Procura o agente na frame.
struct s_list_agent *agent = get_agent(matricula);
if(agent){
if( strcasecmp_n( agent->name, name ) ){
free( agent->name );
newstrncpy( &agent->name, name );
}
if( strcasecmp_n( agent->status, status ) ){
free( agent->status );
newstrncpy( &agent->status, status );
}
agent->login_manual = is_login_manual;
agent->login_auto = is_login_auto;
agent->action_update = TRUE; // esse agente existe no asterisk
}
else{ // criar um novo agente na persistência que existe no asteriks
agent = create_agents();
newstrncpy( &agent->matricula, matricula );
// Se o agente ja existe na frame, atualiza se houver diferença.
if(agent){
if( strcasecmp_n( agent->name, name ) ){
free( agent->name );
newstrncpy( &agent->name, name );
}
if( strcasecmp_n( agent->status, status ) ){
free( agent->status );
newstrncpy( &agent->status, status );
agent->login_manual = is_login_manual;
agent->login_auto = is_login_auto;
agent->action_update = TRUE;
insert_agents( agent );
}
agent->login_manual = is_login_manual;
agent->login_auto = is_login_auto;
agent->action_update = 1; // Marca o agente como existente no asterisk.
}
else{ // Se o agente não existe na frame, insere um novo agente na frame.
agent = create_agent();
newstrncpy( &agent->matricula, matricula );
newstrncpy( &agent->name, name );
newstrncpy( &agent->status, status );
agent->login_manual = is_login_manual;
agent->login_auto = is_login_auto;
agent->action_update = 1; // Marca o agente como existente no asterisk.
insert_agent( agent );
}
// Libera a memoria das respostas das queries feitas ao banco de dados.
FREE_RESPONSE_MARIADB_AGENT( rmdb );
FREE_RESPONSE_MARIADB_AGENT( rmdb_insert );
FREE_RESPONSE_MARIADB_AGENT( rmdb_update );
@ -194,80 +169,58 @@ fail:
return -1;
}
/*
* lida com o eventos agentscomplete.
* esse evento é recebido quando terminou a lista de eventos dos agentes, por isso o nome
* Esse evento é usado para sincronizar agentes com o asterisk
*/
int parse_event_agentscomplete(EVENT *event, s_manager *smanager){
/* agent->action_update = 0 - agente não está definido asterisk *
* agent->action_update = 1 - agente está definido no asterisk */
/* Informar que o comando foi terminado */
action_complete(AGENTS_OK, smanager);
// Event: AgentsComplete
// EventList: Complete
// ListItems: 5
// Não deve acontecer, mas se a eventlist não for "Complete", cria um registro no log.
if( strcasecmp_n( ami_get_value(smanager->ami, event->args, "Eventlist"), "Complete" ) ) {
return -1;
FAIL ("Evento 'AgentsComplete' não veio com 'EventList: Complete'");
}
// Excluí agentes na camada de persistência que não estão no asterisk
// Remove da frame agentes marcados para exclusão (action_update == 0).
agent_update();
// Excluí agentes no banco de dados que não estão na camada de persistência
/* { */
RESPONSE_MARIADB *rmdb = get_agents_all_db(Select_agents_update);
if( !GET_SUCCESS_MARIADB( rmdb ) ){ /* falha de buscar dados do banco de dados */
FAIL( "FAIL get_agents_all_db - function %s", __func__ );
}
struct s_table_agent *table_agent = GET_DATA_MARIADB(rmdb);
while(table_agent){
struct s_list_agents *agent = get_agents(table_agent->matricula);
if(!agent){
delete_agents_db(Delete_agents, table_agent->matricula);
} else {
// Remove do banco de dados agentes não encontrados na frame.
RESPONSE_MARIADB *rmdb_get_all_agents = get_all_agents_db(Select_agent_update);
if( !GET_SUCCESS_MARIADB( rmdb_get_all_agents ) ){ // Falha na busca no banco de dados.
FAIL( "FAIL get_all_agents_db - function %s", __func__ );
}
struct s_table_agent *table_agent = GET_DATA_MARIADB(rmdb_get_all_agents);
if(!agent->action_update){
delete_agents_db(Delete_agents, table_agent->matricula);
}
while(table_agent){
struct s_list_agent *agent = get_agent(table_agent->matricula);
/* Na próxima atualização verificará se ainda
* está no asterisk. Se estiver, o resultado
* da action irá definir 1 */
agent->action_update = 0;
if(!agent){
delete_agent_db(Delete_agent, table_agent->matricula);
}
}
table_agent = table_agent->next;
}
table_agent = table_agent->next;
}
/* } */
// Libera a memoria das respostas das queries feitas ao banco de dados.
FREE_RESPONSE_MARIADB_AGENT( rmdb_get_all_agents );
FREE_RESPONSE_MARIADB_AGENT( rmdb );
// Fim da action "Agents" e inicio da proxima action da sequencia
action_complete(AGENTS_OK, smanager);
return 1;
fail:
FREE_RESPONSE_MARIADB_AGENT( rmdb );
// Libera a memoria das respostas das queries feitas ao banco de dados.
FREE_RESPONSE_MARIADB_AGENT( rmdb_get_all_agents );
return -1;
}
/*
* Verificar se essa matricula está conectada em alguma fila
* Não diz qual é a fila, apenas se esse agent está conectado
*/
int exists_agent_in_queue( const char *matricula ){
int is_agent_in_any_queue( const char *matricula ){
int exist = 0;
RESPONSE_MARIADB *rmdb = NULL;
rmdb = exist_agents_queue_db( Exist_agents_queue, matricula );
rmdb = is_agent_in_any_queue_db( Exist_agent_in_any_queue, matricula );
if( !GET_SUCCESS_MARIADB( rmdb ) ){ /* falha de buscar dados do banco de dados */
FAIL( "FAIL get_agents_db - function %s", __func__ );
FAIL( "FAIL get_agent_db - function %s", __func__ );
}
TABLE_TYPE_AGENT *table_agent = (struct s_table_agent *)GET_DATA_MARIADB(rmdb);
@ -281,16 +234,14 @@ fail:
return -1; // erro consulta sql
}
// atualiza o login do agent e o peer number
int update_agent_login_and_peer_number( const char *matricula, const char *peer_number, unsigned int log_auto, unsigned int log_manual){
RESPONSE_MARIADB *rmdb = NULL, *rmdb_update = NULL;
RESPONSE_MARIADB *rmdb_get_agent = NULL, *rmdb_update_agent = NULL;
/* camada de persistência */
struct s_list_agents *agent = get_agents( matricula );
// Procura o agent na frame e atualiza o peer_number e o status de login.
struct s_list_agent *agent = get_agent( matricula );
if( !agent ){
goto fail;
FAIL("Erro na função %s, agente com matricula %s e numero peer %s não encontrado na frame!", __func__, matricula, peer_number);
}
if (!agent->peer_number) {
newstrncpy(&agent->peer_number, peer_number);
@ -298,12 +249,12 @@ int update_agent_login_and_peer_number( const char *matricula, const char *peer_
agent->login_auto = log_auto;
agent->login_manual = log_manual;
/* banco de dados */
rmdb = get_agents_db( Select_agents, matricula );
if( !GET_SUCCESS_MARIADB( rmdb ) ){ /* falha de buscar dados do banco de dados */
FAIL( "FAIL get_agents_db - function %s", __func__ );
// Procura o agent no banco de dados
rmdb_get_agent = get_agent_db( Select_agent, matricula );
if( !GET_SUCCESS_MARIADB( rmdb_get_agent ) ){ // Falha na busca no banco de dados.
FAIL( "FAIL get_agent_db - function %s", __func__ );
}
TABLE_TYPE_AGENT *table_agent = (struct s_table_agent *)GET_DATA_MARIADB(rmdb);
TABLE_TYPE_AGENT *table_agent = (struct s_table_agent *)GET_DATA_MARIADB(rmdb_get_agent);
if (!table_agent) {
goto fail;
}
@ -315,22 +266,18 @@ int update_agent_login_and_peer_number( const char *matricula, const char *peer_
if( !same_login_auto || !same_login_manual || !same_peer_number){
/* atualizar linha de dados da tabela agent */
rmdb_update = update_agents_db( Update_agents, table_agent->name, agent->login_auto, agent->login_manual, peer_number, matricula );
if( !GET_SUCCESS_MARIADB( rmdb_update ) ){ /* falha de buscar dados do banco de dados */
FAIL( "FAIL update_agents_db - function %s", __func__ );
rmdb_update_agent = update_agent_db( Update_agent, table_agent->name, agent->login_auto, agent->login_manual, peer_number, matricula );
if( !GET_SUCCESS_MARIADB( rmdb_update_agent ) ){ /* falha de buscar dados do banco de dados */
FAIL( "FAIL update_agent_db - function %s", __func__ );
}
}
FREE_RESPONSE_MARIADB_AGENT( rmdb_update );
FREE_RESPONSE_MARIADB_AGENT( rmdb );
FREE_RESPONSE_MARIADB_AGENT( rmdb_update_agent );
FREE_RESPONSE_MARIADB_AGENT( rmdb_get_agent );
return 1;
fail:
FREE_RESPONSE_MARIADB_AGENT( rmdb_update );
FREE_RESPONSE_MARIADB_AGENT( rmdb );
FREE_RESPONSE_MARIADB_AGENT( rmdb_update_agent );
FREE_RESPONSE_MARIADB_AGENT( rmdb_get_agent );
return -1;
}

68
src/agent/agent.h

@ -69,40 +69,70 @@ add_table_agent( PARAM_ADD_ROW_AGENT );
FREE_RESPONSE_MARIADB( rmdb, free_table_agent, TABLE_TYPE_AGENT );
/* Event https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+ManagerEvent_Agents */
/// \brief - Processa os eventos "Agents", gerado ao iniciar o amid e nas actions periodicas.
/// \brief - As informações do evento são usadas para adicionar/atualizar agentes no banco de dados e frame.
/// \param event Estrutura do evento.
/// \param smanager Estrutura principal do AMID.
/// \return - `1` Sucesso no processamento do evento.
/// \return - `-1` Falha no processamento do evento.
int parse_event_agents( EVENT *event, s_manager *smanager );
/* Event https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+ManagerEvent_AgentComplete */
// Processa o evento "AgentsComplete", gerado ao fim da lista de eventos "Agents".
// Esse evento é usado para periodicamente verificar se os agents do banco de dados e frame estão no asterisk.
/// \param event Estrutura do evento.
/// \param smanager Estrutura principal do AMID.
/// \return - `1` Sucesso no processamento do evento.
/// \return - `-1` Falha no processamento do evento.
int parse_event_agentscomplete(EVENT *event, s_manager *smanager);
int exists_agent_in_queue( const char *matricula );
/// \brief - Verifica na frame se o agent está em alguma queue.
/// \param matricula Numero da matricula do agent a ser verificado.
/// \return - `1` Agent está em alguma queue.
/// \return - `0` Agent está em nenhuma queue.
/// \return - `-1` Falha na busca no banco de dados.
int is_agent_in_any_queue( const char *matricula );
/// \brief - Atualiza o login e peer number de um agent.
/// \param matricula Numero da matricula do agent a ser atualizado.
/// \param peer_number Numero peer a registrar para o agent.
/// \param log_auto 1 se agent login automatico, 0 se não.
/// \param log_manual 1 se agent login manual, 0 se nao.
/// \return - `1` Sucesso na atualização.
/// \return - `-1` Falha na atualização.
int update_agent_login_and_peer_number( const char *matricula, const char *peer_number, unsigned int log_auto, unsigned int log_manual);
/* adcionar a próxima linha do resultado sql */
/// \brief - Adiciona a próxima linha do resultado da query à estrutura table_agent.
/// @return - `0` - Ao finalizar a função
int add_table_agent(struct s_table_agent **A, struct s_table_agent *next);
/* liberar ponteiro do resultado */
/// \brief - Libera o ponteiro/memória do resultado da query.
/// @return - `0` - Ao finalizar a função
int free_table_agent(struct s_table_agent **A);
/* atualizar campo login do agent */
int update_agent_login_and_peer_number( const char *matricula, const char *peer_number, unsigned int log_auto, unsigned int log_manual);
/// \brief - Obtem todos os agentes no banco de dados.
/// \return - Ponteiro para a estrutura `RESPONSE_MARIADB` com a resposta do banco de dados.
RESPONSE_MARIADB *get_all_agents_db(stmt_t Select_agent_update);
/* Recebe todas as agentes */
RESPONSE_MARIADB *get_agents_all_db(stmt_t Select_agents_update);
/// \brief - Busca um agente a partir de sua matrícula no banco de dados.
/// \return - Ponteiro para a estrutura `RESPONSE_MARIADB` com a resposta do banco de dados.
RESPONSE_MARIADB *get_agent_db( stmt_t Select_agent, const char *matricula );
/* buscar um agente de acordo com a matrícula */
RESPONSE_MARIADB *get_agents_db( stmt_t Select_agents, const char *matricula );
/// \brief - Atualiza dados do agent no banco de dados.
/// \return - Ponteiro para a estrutura `RESPONSE_MARIADB` com a resposta do banco de dados.
RESPONSE_MARIADB *update_agent_db( stmt_t Update_agent, const char *name, unsigned int login_auto, unsigned int login_manual, const char *peer_number, const char *matricula );
/* atualizar um linha da tabela */
RESPONSE_MARIADB *update_agents_db( stmt_t Update_agents, const char *name, unsigned int login_auto, unsigned int login_manual, const char *peer_number, const char *matricula );
/// \brief - Insere um novo agente no banco de dados.
/// \return - Ponteiro para a estrutura `RESPONSE_MARIADB` com a resposta do banco de dados.
RESPONSE_MARIADB *insert_agent_db( stmt_t insert_agent_db, const char *name, const char *matricula, unsigned int login_auto, unsigned int login_manual );
/* inserir uma linha da tabela */
RESPONSE_MARIADB *insert_agents_db( stmt_t insert_agents_db, const char *name, const char *matricula, unsigned int login_auto, unsigned int login_manual );
/// \brief - Deleta um agente do banco de dados a partir de sua matrícula.
/// \return - Ponteiro para a estrutura `RESPONSE_MARIADB` com a resposta do banco de dados.
RESPONSE_MARIADB *delete_agent_db(stmt_t Delete_agent, char *matricula);
/* deletar uma linha databela agents */
RESPONSE_MARIADB *delete_agents_db(stmt_t Delete_agents, char *matricula);
/// \brief - Procura no banco de dados se o agente está em alguma queue (fila), a partir de sua matrícula.
/// \return - Ponteiro para a estrutura `RESPONSE_MARIADB` com a resposta do banco de dados.
RESPONSE_MARIADB *is_agent_in_any_queue_db( stmt_t Exist_agent_in_any_queue, const char *matricula );
RESPONSE_MARIADB *exist_agents_queue_db( stmt_t Exist_agents_queue, const char *matricula );
#endif

63
src/agent/agent_db.c

@ -21,8 +21,6 @@
#include <string_functions.h>
#include <agent/agent.h>
/* Adcionar nova linha no resultado da query */
int add_table_agent(struct s_table_agent **A, struct s_table_agent *next){
while(*A){
@ -34,9 +32,6 @@ int add_table_agent(struct s_table_agent **A, struct s_table_agent *next){
return 0;
}
/* Liberar os resultados da query */
int free_table_agent(struct s_table_agent **A){
if(*A == NULL)
@ -51,12 +46,9 @@ int free_table_agent(struct s_table_agent **A){
return 0;
}
RESPONSE_MARIADB *get_all_agents_db(stmt_t Select_agent_update){
/* obter todos os agentes no banco de dados */
RESPONSE_MARIADB *get_agents_all_db(stmt_t Select_agents_update){
DB_FUNCTION_INIT( Select_agents_update, 0 );
DB_FUNCTION_INIT( Select_agent_update, 0 );
DB_FUNCTION_EXECUTE_AND_RESPONSE
@ -66,10 +58,10 @@ RESPONSE_MARIADB *get_agents_all_db(stmt_t Select_agents_update){
ALLOC_TABLE_AGENT;
RESET_DBINDEX;
/* column id */
// coluna id
GET_DB_INTEGER( ROW_NEXT_AGENT->id, *(unsigned long long *) );
/* column matricula */
// coluna matricula
GET_DB_CHAR( ROW_NEXT_AGENT->matricula );
ADD_ROW_AGENT;
@ -81,12 +73,9 @@ fail:
DB_FUNCTION_EXIT_FAIL;
}
RESPONSE_MARIADB *get_agent_db( stmt_t Select_agent, const char *matricula ){
/* Buscar agente de um matrícula no banco de dados */
RESPONSE_MARIADB *get_agents_db( stmt_t Select_agents, const char *matricula ){
DB_FUNCTION_INIT( Select_agents, 1 );
DB_FUNCTION_INIT( Select_agent, 1 );
DB_PARAM_TYPE_BLOB(matricula);
DB_FUNCTION_EXECUTE_AND_RESPONSE;
@ -97,18 +86,18 @@ RESPONSE_MARIADB *get_agents_db( stmt_t Select_agents, const char *matricula ){
ALLOC_TABLE_AGENT;
RESET_DBINDEX;
/* column id */
// coluna id
GET_DB_INTEGER( ROW_NEXT_AGENT->id, *(unsigned long long *) );
/* columns name */
// coluna name
GET_DB_CHAR( ROW_NEXT_AGENT->name );
++DBINDEX; /* pula coluna matricula */
++DBINDEX; // pula coluna matricula
/* columns status */
// coluna login_auto
GET_DB_INTEGER( ROW_NEXT_AGENT->login_auto, *(unsigned int *) );
/* columns status */
// coluna login_manual
GET_DB_INTEGER( ROW_NEXT_AGENT->login_manual, *(unsigned int *) );
ADD_ROW_AGENT;
@ -119,13 +108,9 @@ fail:
DB_FUNCTION_EXIT_FAIL;
}
RESPONSE_MARIADB *update_agent_db( stmt_t Update_agent, const char *name, unsigned int login_auto, unsigned int login_manual, const char *peer_number, const char *matricula ){
/* Atualizar dados do agent no banco de dados */
RESPONSE_MARIADB *update_agents_db( stmt_t Update_agents, const char *name, unsigned int login_auto, unsigned int login_manual, const char *peer_number, const char *matricula ){
DB_FUNCTION_INIT( Update_agents, 5 );
DB_FUNCTION_INIT( Update_agent, 5 );
DB_PARAM_TYPE_BLOB( name );
DB_PARAM_TYPE_TINY( login_auto );
DB_PARAM_TYPE_TINY( login_manual );
@ -139,12 +124,9 @@ fail:
DB_FUNCTION_EXIT_FAIL;
}
RESPONSE_MARIADB *insert_agent_db( stmt_t insert_agent_db, const char *name, const char *matricula, unsigned int login_auto, unsigned int login_manual ){
/* Inseri um novo agente */
RESPONSE_MARIADB *insert_agents_db( stmt_t insert_agents_db, const char *name, const char *matricula, unsigned int login_auto, unsigned int login_manual ){
DB_FUNCTION_INIT( insert_agents_db, 4 );
DB_FUNCTION_INIT( insert_agent_db, 4 );
DB_PARAM_TYPE_BLOB( name );
DB_PARAM_TYPE_BLOB( matricula );
DB_PARAM_TYPE_TINY( login_auto );
@ -157,13 +139,9 @@ fail:
DB_FUNCTION_EXIT_FAIL;
}
RESPONSE_MARIADB *delete_agent_db(stmt_t Delete_agent, char *matricula){
/* Deletar agente na tabela agent */
RESPONSE_MARIADB *delete_agents_db(stmt_t Delete_agents, char *matricula){
DB_FUNCTION_INIT( Delete_agents, 1 );
DB_FUNCTION_INIT( Delete_agent, 1 );
DB_PARAM_TYPE_BLOB( matricula );
DB_FUNCTION_EXECUTE;
@ -173,10 +151,9 @@ fail:
DB_FUNCTION_EXIT_FAIL;
}
RESPONSE_MARIADB *is_agent_in_any_queue_db( stmt_t Exist_agent_in_any_queue, const char *matricula ){
RESPONSE_MARIADB *exist_agents_queue_db( stmt_t Exist_agents_queue, const char *matricula ){
DB_FUNCTION_INIT( Exist_agents_queue, 1 );
DB_FUNCTION_INIT( Exist_agent_in_any_queue, 1 );
DB_PARAM_TYPE_BLOB( matricula );
DB_FUNCTION_EXECUTE_AND_RESPONSE;
@ -187,7 +164,7 @@ RESPONSE_MARIADB *exist_agents_queue_db( stmt_t Exist_agents_queue, const char *
ALLOC_TABLE_AGENT;
RESET_DBINDEX;
/* column id */
// coluna id
GET_DB_INTEGER( ROW_NEXT_AGENT->id, *(unsigned long long *) );
ADD_ROW_AGENT;

12
src/database/database.c

@ -82,12 +82,12 @@ static s_table_query _query_prepare[] =
"SELECT queue.queue_id, queue.queue_name FROM queue;", NULL },
/* Evento agents */
{ Select_agents, "SELECT id, name, matricula, login_auto, login_manual FROM agent WHERE matricula=?;", NULL },
{ Update_agents, "UPDATE agent SET name=?, login_auto=?, login_manual=?, peer_number=(COALESCE(peer_number, ?)) WHERE matricula=?;", NULL },
{ Insert_agents, "INSERT INTO agent (name, matricula, login_auto, login_manual ) VALUES (?, ?, ?, ?);", NULL },
{ Delete_agents, "DELETE FROM agent WHERE matricula=?", NULL},
{ Select_agents_update, "SELECT id, matricula FROM agent;", NULL },
{ Exist_agents_queue, "SELECT EXISTS(SELECT 1 FROM queue_member WHERE agt_id = (SELECT id FROM agent WHERE matricula = ?));", NULL },
{ Select_agent, "SELECT id, name, matricula, login_auto, login_manual FROM agent WHERE matricula=?;", NULL },
{ Update_agent, "UPDATE agent SET name=?, login_auto=?, login_manual=?, peer_number=(COALESCE(peer_number, ?)) WHERE matricula=?;", NULL },
{ Insert_agent, "INSERT INTO agent (name, matricula, login_auto, login_manual ) VALUES (?, ?, ?, ?);", NULL },
{ Delete_agent, "DELETE FROM agent WHERE matricula=?", NULL},
{ Select_agent_update, "SELECT id, matricula FROM agent;", NULL },
{ Exist_agent_in_any_queue, "SELECT EXISTS(SELECT 1 FROM queue_member WHERE agt_id = (SELECT id FROM agent WHERE matricula = ?));", NULL },
/* tabela queue_member */
{ Insert_queuemember,

12
src/database/database.h

@ -78,12 +78,12 @@ enum {
Select_queueparams_update,
/* Agents */
Select_agents,
Update_agents,
Insert_agents,
Delete_agents,
Select_agents_update,
Exist_agents_queue,
Select_agent,
Update_agent,
Insert_agent,
Delete_agent,
Select_agent_update,
Exist_agent_in_any_queue,
/* tabela queue_member */
Insert_queuemember,

49
src/frame/agent_frame.c

@ -39,54 +39,41 @@
#include <frame/frame_asterisk.h>
#include <frame/frame_globals.h>
struct s_list_agents *_agents = NULL;
// Inicializa o ponteiro global da lista de agents para ser utilizado nas funções do frame.
struct s_list_agent *_agents = NULL;
struct s_list_agents *create_agents(){
struct s_list_agents *agent;
CREATE_NODE( agent, struct s_list_agents );
struct s_list_agent *create_agent(){
struct s_list_agent *agent;
CREATE_NODE( agent, struct s_list_agent );
return agent;
}
struct s_list_agent *get_agent( const char *matricula ){
struct s_list_agents *get_agents( const char *matricula ){
struct s_list_agents **A = &_agents;
struct s_list_agent **A = &_agents;
SEARCH_NODE( A, matricula, matricula );
return NULL;
}
int insert_agent(struct s_list_agent *agent){
struct s_list_agents *get_agents_name( const char *name ){
struct s_list_agents **A = &_agents;
SEARCH_NODE( A, name, name );
return NULL;
}
int insert_agents(struct s_list_agents *agent){
struct s_list_agents **A = &_agents;
struct s_list_agent **A = &_agents;
LAST_NODE( A, agent );
return 0;
}
int remove_agent( const char *matricula ){
int remove_agents( const char *matricula ){
struct s_list_agent **agents = &_agents;
REMOVE_NODE( agents, matricula, matricula, struct s_list_agent, free_agent );
struct s_list_agents **agents = &_agents;
REMOVE_NODE( agents, matricula, matricula, struct s_list_agents, free_agents );
return 0;
return -1;
}
void free_agents(struct s_list_agents **agent){
void free_agent(struct s_list_agent **agent){
if(! (*agent)){
return;
@ -111,7 +98,7 @@ void free_agents(struct s_list_agents **agent){
void set_agent_update(){
struct s_list_agents *agent = _agents;
struct s_list_agent *agent = _agents;
while( agent ){
agent->action_update = 0;
agent = agent->next;
@ -120,12 +107,12 @@ void set_agent_update(){
void agent_update(){
struct s_list_agents **agent = &_agents;
struct s_list_agent **agent = &_agents;
while( *agent ){
if((*agent)->action_update == 0){
struct s_list_agents *agent_remove = *agent;
struct s_list_agent *agent_remove = *agent;
*agent = agent_remove->next;
free_agents(&agent_remove);
free_agent(&agent_remove);
continue;
}

31
src/frame/agent_frame.h

@ -38,19 +38,34 @@
/// @brief - Cria um nó da estrutura `s_list_agent`, que deve ser preenchida antes de ser inserida na lista global de agent.
/// @return - Ponteiro para a `s_list_agent` vazia.
struct s_list_agent *create_agent();
struct s_list_agents *create_agents();
/// @brief - Procura na lista global de agents um nó `s_list_agent` que contenha o numero de matricula.
/// @param Matricula Matricula utilizada na busca do agent.
/// @return - Ponteiro para o nó `s_list_agent` que contem a matricula.
/// @return - `NULL` se não encontrou.
struct s_list_agent *get_agent( const char *matricula );
/// @brief - Insere na lista global de agents um nó `s_list_agent`.
/// @param agent Nó `s_list_agent` a ser inserido.
/// @return - `0` - Ao finalizar a função
int insert_agent(struct s_list_agent *agent);
struct s_list_agents *get_agents( const char *matricula );
/// @brief - Remove da lista global de agents um nó `s_list_agent`.
/// @param matricula Matricula do agent a ser removido.
/// @return - `0` - Remoção bem sucedida.
/// @return - `-1` - Matricula não encontrada.
int remove_agent( const char *matricula );
int insert_agents(struct s_list_agents *agent);
int remove_agents( const char *matricula );
void free_agents(struct s_list_agents **agent);
/// @brief - Chamada pela função `remove_agent` para liberar a memória do nó `s_list_agent` a ser removido.
/// @param agent `s_list_agent` nó cuja memoria será liberada.
void free_agent(struct s_list_agent **agent);
/// @brief - Marca todos os agents da lista global de agents para remoção.
/// @brief - Obs: Estes agents serão 'desmarcados' caso sejam encontrados na frame pela action `agents` periodica.
void set_agent_update();
/// @brief - Remove da lista global de agents, os agents marcados para remoção.
void agent_update();

6
src/frame/frame_asterisk.h

@ -71,7 +71,7 @@ struct s_route {
/* list agents
*/
struct s_list_agents {
struct s_list_agent {
unsigned long long id;
char *name;
char *matricula;
@ -81,7 +81,7 @@ struct s_list_agents {
unsigned int login_auto:1;
unsigned int action_update:1;
struct s_list_agents *next;
struct s_list_agent *next;
};
@ -92,7 +92,7 @@ struct s_list_agents {
struct s_queue_member {
unsigned long long id;
struct s_list_agents *agent;
struct s_list_agent *agent;
char *queue_name;
char *membername;
int _static;

2
src/frame/frame_globals.h

@ -25,7 +25,7 @@
extern struct s_list_peer *_peer;
extern struct s_list_queue *_queue;
extern struct s_list_bridge *_bridge;
extern struct s_list_agents *_agents;
extern struct s_list_agent *_agents;
extern struct s_list_call *_call;
extern struct s_transfer *_transfers;

1
src/methods_actions.c

@ -161,6 +161,7 @@ int create_Agents( s_manager *smanager, void *args ){
}
set_agent_update();
set_value_actionid( action_id, "Agents", Agents->args[0].value, NULL, 1 );
strcpy( Agents->name_action, "Agents" );

Loading…
Cancel
Save