static int w_agent_login(struct sip_msg *req, char *agent_v, char *state_v) { struct cc_agent *agent, *prev_agent; str agent_s; int state; unsigned int flags; /* get state */ if (fixup_get_isvalue( req, (gparam_p)state_v, &state, &agent_s, &flags)!=0 || ((flags|GPARAM_INT_VALUE_FLAG)==0) ) { LM_ERR("unable to evaluate state spec \n"); return -1; } /* get agent */ if (fixup_get_svalue( req, (gparam_p)agent_v, &agent_s)!=0) { LM_ERR("unable to evaluate agent spec \n"); return -2; } /* block access to data */ lock_get( data->lock ); /* name of the agent */ agent = get_agent_by_name( data, &agent_s, &prev_agent); if (agent==NULL) { lock_release( data->lock ); LM_DBG("agent <%.*s> not found\n",agent_s.len,agent_s.s); return -3; } if (agent->loged_in != state) { if(state && (agent->state==CC_AGENT_WRAPUP) && (get_ticks() - agent->last_call_end > wrapup_time)) agent->state = CC_AGENT_FREE; if(state && data->agents[CC_AG_ONLINE] == NULL) data->last_online_agent = agent; agent_switch_login(data, agent, prev_agent); if(state) { data->logedin_agents++; log_agent_to_flows( data, agent, 1); } else { data->logedin_agents--; log_agent_to_flows(data, agent, 0); } } /* release access to data */ lock_release( data->lock ); return 1; }
/* FORMAT : agent_id log_state */ static struct mi_root* mi_agent_login(struct mi_root *cmd_tree, void *param) { struct mi_node *node; struct cc_agent *agent; unsigned int loged_in; struct cc_agent* prev_agent= 0; node = cmd_tree->node.kids; if (node==NULL || node->next==NULL || node->next->next!=NULL) return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); /* block access to data */ lock_get( data->lock ); /* name of the agent */ agent = get_agent_by_name( data, &node->value, &prev_agent); if (agent==NULL) { lock_release( data->lock ); return init_mi_tree( 404, MI_SSTR("Agent not found") ); } /* login state */ node = node->next; if (str2int( &node->value , &loged_in)!=0 ) { lock_release( data->lock ); return init_mi_tree( 400, MI_SSTR("Bad loged_in state") ); } if (agent->loged_in != loged_in) { if(loged_in && (agent->state==CC_AGENT_WRAPUP) && (get_ticks() - agent->last_call_end > wrapup_time)) agent->state = CC_AGENT_FREE; if(loged_in && data->agents[CC_AG_ONLINE] == NULL) data->last_online_agent = agent; agent_switch_login(data, agent, prev_agent); if(loged_in) { data->logedin_agents++; log_agent_to_flows( data, agent, 1); } else { data->logedin_agents--; log_agent_to_flows(data, agent, 0); } } /* release the readers */ lock_release( data->lock ); return init_mi_tree( 200, MI_OK_S, MI_OK_LEN); }
int add_cc_agent( struct cc_data *data, str *id, str *location, str *skills, unsigned int logstate, unsigned int last_call_end) { struct cc_agent *agent, *prev_agent= 0; struct sip_uri uri; str skill; char *p; unsigned int n,skill_id; #ifdef STATISTICS char *name; str s; #endif /* is the agent a new one? - search by ID */ agent = get_agent_by_name( data, id, &prev_agent); if (agent==NULL) { /* new agent -> create and populate one */ agent = (struct cc_agent*)shm_malloc(sizeof(struct cc_agent)+id->len); if (agent==NULL) { LM_ERR("not enough shmem for a new agent\n"); goto error; } memset( agent, 0, sizeof(struct cc_agent) ); /* id */ agent->id.s = (char*)(agent+1); memcpy( agent->id.s, id->s, id->len); agent->id.len = id->len; /* location */ agent->location.s = (char*)shm_malloc(location->len); if (agent->location.s==NULL) { LM_ERR("not enough shmem for the location of the agent\n"); goto error; } memcpy( agent->location.s, location->s, location->len); agent->location.len = location->len; if (parse_uri( agent->location.s, agent->location.len, &uri)<0) { LM_ERR("location of the agent is not a SIP URI\n"); goto error; } agent->did = uri.user; /* LOG STATE */ agent->loged_in = logstate; /* set of skills */ if (skills && skills->len) { p = skills->s; while (p) { skill.s = p; p = q_memchr(skill.s, ',', skills->s+skills->len-skill.s); skill.len = p?(p-skill.s):(skills->s+skills->len-skill.s); trim(&skill); if (skill.len) { skill_id = get_skill_id(data,&skill); if (skill_id==0) { LM_ERR("cannot get skill id\n"); goto error; } n = agent->no_skills++; agent->skills[n] = skill_id; } if(p) p++; } } /* statistics */ #ifdef STATISTICS s.s = "cca_dist_incalls";s.len = 16 ; if ( (name=build_stat_name( &s, id->s))==0 || register_stat("call_center", name, &agent->st_dist_incalls, STAT_SHM_NAME)!=0 ) { LM_ERR("failed to add stat variable\n"); goto error; } s.s = "cca_answ_incalls";s.len = 16 ; if ( (name=build_stat_name( &s, id->s))==0 || register_stat("call_center", name, &agent->st_answ_incalls, STAT_SHM_NAME)!=0 ) { LM_ERR("failed to add stat variable\n"); goto error; } s.s = "cca_aban_incalls";s.len = 16 ; if ( (name=build_stat_name( &s, id->s))==0 || register_stat("call_center", name, &agent->st_aban_incalls, STAT_SHM_NAME)!=0 ) { LM_ERR("failed to add stat variable\n"); goto error; } s.s = "cca_att";s.len = 7 ; if ( (name=build_stat_name( &s, id->s))==0 || register_stat2("call_center", name, (stat_var **)cc_agent_get_att, STAT_SHM_NAME|STAT_IS_FUNC, (void*)agent, 0)!=0) { LM_ERR("failed to add stat variable\n"); goto error; } #endif if(last_call_end && (last_call_end + wrapup_time < (int)time(NULL))) { agent->state = CC_AGENT_WRAPUP; agent->last_call_end = last_call_end - startup_time; /* it will be a negative value */ } agent->is_new = 1; /* link the agent */ add_cc_agent_top(data, agent); data->totalnr_agents++; } else { /* agent already exists -> update only */ /* location - needs to be changed ? */ if ( agent->location.len!=location->len || memcmp(agent->location.s,location->s,location->len)!=0 ) { /* set new location */ if (agent->location.len < location->len ){ shm_free(agent->location.s); agent->location.s = (char*)shm_malloc(location->len); if (agent->location.s==NULL) { LM_ERR("not enough shmem for the location of the agent\n"); goto error1; } } memcpy( agent->location.s, location->s, location->len); agent->location.len = location->len; if (parse_uri( agent->location.s, agent->location.len, &uri)<0) { LM_ERR("location of the agent is not a SIP URI\n"); goto error1; } agent->did = uri.user; } /* if logstate changed - move between the lists TODO */ if(logstate != agent->loged_in) { agent_switch_login(data, agent, prev_agent); } /* skills - needs to be changed ? */ agent->no_skills = 0; if (skills && skills->len) { p = skills->s; while (p) { skill.s = p; p = q_memchr(skill.s, ',', skills->s+skills->len-skill.s); skill.len = p?(p-skill.s):(skills->s+skills->len-skill.s); trim(&skill); if (skill.len) { skill_id = get_skill_id(data,&skill); if (skill_id==0) { LM_ERR("cannot get skill id\n"); goto error1; } n = agent->no_skills++; agent->skills[n] = skill_id; } if(p) p++; } } agent->is_new = 1; } return 0; error1: remove_cc_agent(data, agent, prev_agent); error: if (agent) free_cc_agent(agent); return 0; }