Use provided by Diva hardware status information for distribution of outgoing calls between CAPI controllers
This commit is contained in:
parent
f7e19c4cad
commit
e534562827
105
chan_capi.c
105
chan_capi.c
|
@ -211,6 +211,8 @@ static char global_mohinterpret[MAX_MUSICCLASS] = "default";
|
|||
#endif
|
||||
|
||||
/* local prototypes */
|
||||
#define CC_B_INTERFACE_NOT_FREE(__x__) (((__x__)->used) || ((__x__)->channeltype != CAPI_CHANNELTYPE_B))
|
||||
|
||||
static int pbx_capi_hold(struct ast_channel *c, char *param);
|
||||
static int pbx_capi_retrieve(struct ast_channel *c, char *param);
|
||||
#ifdef CC_AST_HAS_INDICATE_DATA
|
||||
|
@ -226,6 +228,10 @@ static void pbx_capi_add_diva_protocol_independent_extension(
|
|||
unsigned char *facilityarray,
|
||||
struct ast_channel *c,
|
||||
const char* variable);
|
||||
#ifdef DIVA_STATUS
|
||||
static void pbx_capi_interface_status_changed(int controller, diva_status_interface_state_t newInterfaceState);
|
||||
#endif
|
||||
static int pbx_capi_check_controller_status(struct capi_pvt *currentChannel, ast_group_t capigroup);
|
||||
|
||||
/*
|
||||
* B protocol settings
|
||||
|
@ -2478,7 +2484,7 @@ pbx_capi_request(const char *type, int format, void *data, int *cause)
|
|||
cc_mutex_lock(&iflock);
|
||||
|
||||
for (i = capi_iflist; i; i = i->next) {
|
||||
if ((i->used) || (i->channeltype != CAPI_CHANNELTYPE_B)) {
|
||||
if (CC_B_INTERFACE_NOT_FREE(i)) {
|
||||
/* if already in use or no real channel */
|
||||
continue;
|
||||
}
|
||||
|
@ -2488,17 +2494,22 @@ pbx_capi_request(const char *type, int format, void *data, int *cause)
|
|||
if (i->controller != controller) {
|
||||
/* keep on running! */
|
||||
continue;
|
||||
} else if (pbx_capi_check_controller_status(i, 0) != 0) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* DIAL(CAPI/gX/...) */
|
||||
if ((interface[0] == 'g') && (!(i->group & capigroup))) {
|
||||
/* keep on running! */
|
||||
continue;
|
||||
}
|
||||
if (interface[0] == 'g') {
|
||||
if ((i->group & capigroup) == 0)
|
||||
continue; /* not in group, keep on running! */
|
||||
if (pbx_capi_check_controller_status(i, capigroup) != 0)
|
||||
continue; /* not active or better interface found, keep on running! */
|
||||
} else if (strcmp(interface, i->name) != 0) {
|
||||
/* DIAL(CAPI/<interface-name>/...) */
|
||||
if ((interface[0] != 'g') && (strcmp(interface, i->name))) {
|
||||
/* keep on running! */
|
||||
continue;
|
||||
} else if (pbx_capi_check_controller_status(i, 0) != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* when we come here, we found a free controller match */
|
||||
|
@ -7556,6 +7567,9 @@ static void *capidev_loop(void *data)
|
|||
if (lastcall != newtime) {
|
||||
lastcall = newtime;
|
||||
capidev_run_secondly(newtime);
|
||||
#ifdef DIVA_STATUS
|
||||
diva_status_process_events();
|
||||
#endif
|
||||
}
|
||||
#ifdef DIVA_STREAMING
|
||||
divaStreamingWakeup ();
|
||||
|
@ -8479,6 +8493,9 @@ static int cc_post_init_capi(void)
|
|||
cc_verbose(2, 0, VERBOSE_PREFIX_3 "enable extended voice features on contr%d\n",
|
||||
controller);
|
||||
}
|
||||
#ifdef DIVA_STATUS
|
||||
capi_controllers[controller]->interfaceState = diva_status_init_interface(controller, pbx_capi_interface_status_changed);
|
||||
#endif
|
||||
/*
|
||||
Register MWI mailboxes and refresh MWI info
|
||||
*/
|
||||
|
@ -8890,6 +8907,9 @@ int unload_module(void)
|
|||
for (controller = 1; controller <= CAPI_MAX_CONTROLLERS; controller++) {
|
||||
if (capi_controllers[controller]) {
|
||||
pbx_capi_cleanup_mwi(capi_controllers[controller]);
|
||||
#ifdef DIVA_STATUS
|
||||
diva_status_cleanup_interface(controller);
|
||||
#endif
|
||||
ast_free(capi_controllers[controller]);
|
||||
}
|
||||
}
|
||||
|
@ -9095,3 +9115,76 @@ struct cc_capi_controller *pbx_capi_get_controller (int controller) {
|
|||
return ((controller > 0 && controller <= capi_num_controllers) ? capi_controllers[controller] : 0);
|
||||
}
|
||||
|
||||
#ifdef DIVA_STATUS
|
||||
/*!
|
||||
\brief Notify about interface state change
|
||||
|
||||
\note No locks are taken at time this function is called
|
||||
\note called from the context of CAPI thread
|
||||
*/
|
||||
static void pbx_capi_interface_status_changed(int controller, diva_status_interface_state_t newInterfaceState)
|
||||
{
|
||||
int currentInterfaceState;
|
||||
|
||||
cc_mutex_lock(&iflock);
|
||||
currentInterfaceState = capi_controllers[controller]->interfaceState;
|
||||
capi_controllers[controller]->interfaceState = newInterfaceState;
|
||||
cc_mutex_unlock(&iflock);
|
||||
|
||||
printf("CAPI%d: interface state changed %s -> %s\n",
|
||||
controller,
|
||||
diva_status_interface_state_name((diva_status_interface_state_t)currentInterfaceState),
|
||||
diva_status_interface_state_name((diva_status_interface_state_t)newInterfaceState));
|
||||
cc_verbose(1, 0, VERBOSE_PREFIX_1 "CAPI%d: interface state changed %s -> %s\n",
|
||||
controller,
|
||||
diva_status_interface_state_name((diva_status_interface_state_t)currentInterfaceState),
|
||||
diva_status_interface_state_name((diva_status_interface_state_t)newInterfaceState));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! \brief Check interface is operational. If the state of the interface
|
||||
is not known then check if one with known state is available.
|
||||
|
||||
\note Called with iflock taken
|
||||
|
||||
\note The core runs twice over the interface list, but this allows to preserve
|
||||
the structure of the original code which uses this function.
|
||||
*/
|
||||
static int pbx_capi_check_controller_status(struct capi_pvt *currentChannel, ast_group_t capigroup)
|
||||
{
|
||||
#ifdef DIVA_STATUS
|
||||
int capiController = currentChannel->controller;
|
||||
struct capi_pvt *newChannel;
|
||||
|
||||
if (capi_controllers[capiController]->interfaceState == (int)DivaStatusInterfaceStateOK) /* known, OK */
|
||||
return 0;
|
||||
|
||||
if (capi_controllers[capiController]->interfaceState == (int)DivaStatusInterfaceStateERROR) /* known, not OK */
|
||||
return -1;
|
||||
|
||||
/*
|
||||
The state of interface is unknown. Look if it is other interface which belongs
|
||||
to requested group with known state and free capi_pvt associated with this interface
|
||||
*/
|
||||
if ((capigroup == 0) || (diva_status_available() != 0))
|
||||
return (0); /* Status information not available, use this interface */
|
||||
|
||||
for (newChannel = currentChannel->next; (newChannel != 0); newChannel = newChannel->next) {
|
||||
if (CC_B_INTERFACE_NOT_FREE(newChannel)) {
|
||||
continue;
|
||||
}
|
||||
if ((newChannel->controller != capiController) &&
|
||||
((newChannel->group & capigroup) != 0) &&
|
||||
(capi_controllers[newChannel->controller]->interfaceState == (int)DivaStatusInterfaceStateOK)) {
|
||||
return (-1); /* Found better interface */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
No better channel found, use this interface
|
||||
*/
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -700,6 +700,9 @@ struct cc_capi_controller {
|
|||
int divaStreaming;
|
||||
#endif
|
||||
AST_LIST_HEAD_NOLOCK(, _cc_capi_mwi_mailbox) mwiSubscribtions;
|
||||
#ifdef DIVA_STATUS
|
||||
int interfaceState;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* ETSI 300 102-1 Numbering Plans */
|
||||
|
|
|
@ -28,8 +28,12 @@
|
|||
*
|
||||
*/
|
||||
#include "divastreaming/platform.h"
|
||||
#include "chan_capi_platform.h"
|
||||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -38,7 +42,9 @@
|
|||
#include "divastatus_parameters.h"
|
||||
#include "divastatus_ifc.h"
|
||||
#include "divastatus.h"
|
||||
#define CC_USE_INOTIFY
|
||||
#ifdef CC_USE_INOTIFY
|
||||
#include <fcntl.h>
|
||||
#include <sys/inotify.h>
|
||||
#endif
|
||||
|
||||
|
@ -46,6 +52,7 @@ typedef const char* pcchar;
|
|||
|
||||
static pcchar DIVA_STATUS_PATH = "/usr/lib/eicon/divas/registry/ifc";
|
||||
static pcchar DIVA_STATUS_FILE = "ifcstate";
|
||||
static pcchar DIVA_INFO_FILE = "info";
|
||||
static pcchar DIVA_CONFIG_FILE = "info/Config";
|
||||
static pcchar DIVA_SERIAL_FILE = "serial";
|
||||
static pcchar DIVA_READ_ALARM_FILE = "info/Red Alarm";
|
||||
|
@ -55,9 +62,223 @@ static pcchar DIVA_BLUE_ALARM_FILE = "info/Blue Alarm";
|
|||
/*
|
||||
LOCALS
|
||||
*/
|
||||
struct _diva_status_ifc;
|
||||
static int diva_status_active(void);
|
||||
static int diva_status_get_controller_state(int controller, diva_status_ifc_state_t *state);
|
||||
static char* diva_status_read_file(unsigned int controller, const char* fileName);
|
||||
static void diva_status_create_wd(int* wd, int controller, const char* fileName, int isDir);
|
||||
static diva_status_interface_state_t diva_status_get_interface_state_from_idi_state (diva_status_ifc_state_t* state);
|
||||
static int diva_status_map_CAPI2XDI(int capiController);
|
||||
static void diva_status_process_event(struct _diva_status_ifc *controllerState, int initialStateIndex, int newStateIndex);
|
||||
#ifdef CC_USE_INOTIFY
|
||||
static pcchar DIVA_DIVA_FS_PATH = "/usr/lib/eicon/divas/registry/ifc";
|
||||
static void diva_status_cleanup_wd(int wd);
|
||||
static int divaFsWd = -1; /*! \brief Diva fs state */
|
||||
#endif
|
||||
|
||||
static int inotifyFd = -1; /*! \brief inotify descriptor */
|
||||
static diva_entity_queue_t controller_q; /*! \brief Active controllers. \note List changed only while CAPI thread is not running */
|
||||
|
||||
typedef struct _diva_status_ifc {
|
||||
diva_entity_link_t link;
|
||||
int capiController;
|
||||
int idiController;
|
||||
diva_status_ifc_state_t state[2];
|
||||
int currentState;
|
||||
int ifstateWd;
|
||||
int infoWd;
|
||||
diva_status_changed_cb_proc_t status_changed_notify_proc;
|
||||
time_t changeTime;
|
||||
} diva_status_ifc_t;
|
||||
|
||||
diva_status_interface_state_t diva_status_init_interface (int controller, diva_status_changed_cb_proc_t fn)
|
||||
{
|
||||
int idiController = diva_status_map_CAPI2XDI(controller);
|
||||
diva_status_ifc_t* controllerState = idiController > 0 ? (ast_malloc(sizeof(*controllerState))) : 0;
|
||||
diva_status_interface_state_t ret = DivaStatusInterfaceStateNotAvailable;
|
||||
|
||||
if (controllerState != 0) {
|
||||
controllerState->capiController = controller;
|
||||
controllerState->idiController = idiController;
|
||||
controllerState->status_changed_notify_proc = fn;
|
||||
controllerState->ifstateWd = -1;
|
||||
controllerState->infoWd = -1;
|
||||
diva_status_create_wd(&controllerState->ifstateWd, idiController, DIVA_STATUS_FILE, 0);
|
||||
diva_status_create_wd(&controllerState->infoWd, idiController, DIVA_INFO_FILE, 1);
|
||||
controllerState->currentState = 0;
|
||||
controllerState->changeTime = time(NULL);
|
||||
diva_status_get_controller_state(idiController, &controllerState->state[controllerState->currentState]);
|
||||
diva_q_add_tail(&controller_q, &controllerState->link);
|
||||
ret = diva_status_get_interface_state_from_idi_state(&controllerState->state[controllerState->currentState]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void diva_status_cleanup_interface (int controller)
|
||||
{
|
||||
diva_entity_link_t* link;
|
||||
|
||||
for (link = diva_q_get_head(&controller_q); link != 0; link = diva_q_get_next(link)) {
|
||||
diva_status_ifc_t *controllerState = DIVAS_CONTAINING_RECORD(link, diva_status_ifc_t, link);
|
||||
|
||||
if (controllerState->capiController == controller) {
|
||||
diva_q_remove(&controller_q, link);
|
||||
#ifdef CC_USE_INOTIFY
|
||||
if (controllerState->ifstateWd >= 0)
|
||||
inotify_rm_watch(inotifyFd, controllerState->ifstateWd);
|
||||
if (controllerState->infoWd >= 0)
|
||||
inotify_rm_watch(inotifyFd, controllerState->infoWd);
|
||||
#endif
|
||||
ast_free (controllerState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CC_USE_INOTIFY
|
||||
if (diva_q_get_head(&controller_q) == 0) {
|
||||
if (divaFsWd >= 0) {
|
||||
inotify_rm_watch(inotifyFd, divaFsWd);
|
||||
divaFsWd = -1;
|
||||
}
|
||||
if (inotifyFd >= 0) {
|
||||
close(inotifyFd);
|
||||
inotifyFd = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int diva_status_get_waitable_object(void)
|
||||
{
|
||||
return inotifyFd;
|
||||
}
|
||||
|
||||
void diva_status_process_events(void)
|
||||
{
|
||||
diva_entity_link_t* link;
|
||||
|
||||
/*
|
||||
Polling
|
||||
*/
|
||||
for (link = diva_q_get_head(&controller_q); link != 0; link = diva_q_get_next(link)) {
|
||||
diva_status_ifc_t *controllerState = DIVAS_CONTAINING_RECORD(link, diva_status_ifc_t, link);
|
||||
if ((controllerState->ifstateWd < 0) || (controllerState->infoWd < 0)) {
|
||||
int currentState = controllerState->currentState;
|
||||
diva_status_create_wd(&controllerState->ifstateWd, controllerState->idiController, DIVA_STATUS_FILE, 0);
|
||||
diva_status_create_wd(&controllerState->infoWd, controllerState->idiController, DIVA_INFO_FILE, 1);
|
||||
controllerState->currentState = (controllerState->currentState + 1) % 2;
|
||||
diva_status_get_controller_state(controllerState->idiController, &controllerState->state[controllerState->currentState]);
|
||||
diva_status_process_event(controllerState, currentState, controllerState->currentState);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Events
|
||||
*/
|
||||
#ifdef CC_USE_INOTIFY
|
||||
if (inotifyFd >= 0 && divaFsWd >= 0) {
|
||||
unsigned char buffer[1024];
|
||||
int length;
|
||||
int i;
|
||||
|
||||
while ((length = read(inotifyFd, buffer, sizeof(buffer))) > 0) {
|
||||
i = 0;
|
||||
while (i < length) {
|
||||
struct inotify_event *event = (struct inotify_event*)&buffer[i];
|
||||
|
||||
if ((event->mask & (IN_IGNORED|IN_DELETE_SELF|IN_UNMOUNT|IN_Q_OVERFLOW)) != 0) {
|
||||
diva_status_cleanup_wd((event->mask & IN_IGNORED) == 0 ? event->wd : -1);
|
||||
break;
|
||||
}
|
||||
if (event->wd != divaFsWd) {
|
||||
for (link = diva_q_get_head(&controller_q); link != 0; link = diva_q_get_next(link)) {
|
||||
diva_status_ifc_t *controllerState = DIVAS_CONTAINING_RECORD(link, diva_status_ifc_t, link);
|
||||
if ((controllerState->ifstateWd == event->wd) || (controllerState->infoWd == event->wd)) {
|
||||
int currentState = controllerState->currentState;
|
||||
controllerState->currentState = (controllerState->currentState + 1) % 2;
|
||||
diva_status_get_controller_state(controllerState->idiController, &controllerState->state[controllerState->currentState]);
|
||||
diva_status_process_event(controllerState, currentState, controllerState->currentState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i += sizeof(*event) + event->len;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CC_USE_INOTIFY
|
||||
static void diva_status_cleanup_wd(int wd)
|
||||
{
|
||||
diva_entity_link_t* link;
|
||||
|
||||
for (link = diva_q_get_head(&controller_q); link != 0; link = diva_q_get_next(link)) {
|
||||
diva_status_ifc_t *controllerState = DIVAS_CONTAINING_RECORD(link, diva_status_ifc_t, link);
|
||||
|
||||
if ((controllerState->ifstateWd >= 0) && (wd != controllerState->ifstateWd)) {
|
||||
inotify_rm_watch(inotifyFd, controllerState->ifstateWd);
|
||||
}
|
||||
controllerState->ifstateWd = -1;
|
||||
if ((controllerState->infoWd >= 0) && (wd != controllerState->infoWd)) {
|
||||
inotify_rm_watch(inotifyFd, controllerState->infoWd);
|
||||
}
|
||||
controllerState->infoWd = -1;
|
||||
}
|
||||
|
||||
if ((divaFsWd >= 0) && (wd != divaFsWd)) {
|
||||
inotify_rm_watch(inotifyFd, divaFsWd);
|
||||
}
|
||||
divaFsWd = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void diva_status_process_event(diva_status_ifc_t *controllerState, int initialStateIndex, int newStateIndex)
|
||||
{
|
||||
diva_status_ifc_state_t* initialState = &controllerState->state[initialStateIndex];
|
||||
diva_status_ifc_state_t* newState = &controllerState->state[newStateIndex];
|
||||
diva_status_interface_state_t initialIfcState = diva_status_get_interface_state_from_idi_state (initialState);
|
||||
diva_status_interface_state_t newIfcState = diva_status_get_interface_state_from_idi_state (newState);
|
||||
|
||||
if (initialIfcState != newIfcState) {
|
||||
controllerState->changeTime = time(NULL);
|
||||
controllerState->status_changed_notify_proc(controllerState->capiController, newIfcState);
|
||||
}
|
||||
}
|
||||
|
||||
static void diva_status_create_wd(int* wd, int controller, const char* fileName, int isDir)
|
||||
{
|
||||
#ifdef CC_USE_INOTIFY
|
||||
if (inotifyFd < 0) {
|
||||
inotifyFd = inotify_init();
|
||||
if (inotifyFd >= 0)
|
||||
fcntl(inotifyFd, F_SETFL, O_NONBLOCK);
|
||||
}
|
||||
if (inotifyFd >= 0 && divaFsWd < 0) {
|
||||
divaFsWd = inotify_add_watch (inotifyFd, DIVA_DIVA_FS_PATH, IN_DELETE_SELF | IN_UNMOUNT | IN_IGNORED);
|
||||
}
|
||||
|
||||
if (*wd >= 0)
|
||||
return;
|
||||
|
||||
if (inotifyFd >= 0 && divaFsWd >= 0) {
|
||||
int name_len = strlen(DIVA_STATUS_PATH) + strlen(fileName) + 32;
|
||||
char name[name_len];
|
||||
|
||||
snprintf(name, name_len, "%s/adapter%u/%s", DIVA_STATUS_PATH, controller, fileName);
|
||||
name[name_len-1] = 0;
|
||||
|
||||
*wd = inotify_add_watch (inotifyFd, name,
|
||||
IN_CLOSE_WRITE | IN_DELETE_SELF | IN_IGNORED | ((isDir != 0) ? IN_DELETE : 0));
|
||||
|
||||
return;
|
||||
}
|
||||
#else
|
||||
*wd = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Check divalogd is available
|
||||
|
@ -92,18 +313,20 @@ static char* diva_status_read_file(unsigned int controller, const char* fileName
|
|||
|
||||
length = MIN(v.st_size, 16U*1024U);
|
||||
|
||||
data = diva_os_malloc(0, length+1);
|
||||
data = ast_malloc(length+1);
|
||||
if (data == 0) {
|
||||
close (fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (read(fd, data, length) != length) {
|
||||
diva_os_free(0, data);
|
||||
ast_free(data);
|
||||
close(fd);
|
||||
return (0);
|
||||
}
|
||||
|
||||
close (fd);
|
||||
|
||||
data[length] = 0;
|
||||
|
||||
while (((p = strchr(data, '\n')) != 0) || ((p = strchr(data, '\r')))) {
|
||||
|
@ -119,6 +342,12 @@ static int diva_status_get_controller_state(int controller, diva_status_ifc_stat
|
|||
int i, pri;
|
||||
const char* v;
|
||||
|
||||
memset (state, 0x00, sizeof(*state));
|
||||
state->ifcType = DivaStatusIfcNotPri;
|
||||
state->hwState = DivaStatusHwStateUnknown;
|
||||
state->ifcL1State = DivaStatusIfcL2DoNotApply;
|
||||
state->ifcL2State = DivaStatusIfcL2DoNotApply;
|
||||
|
||||
if (diva_status_active() != 0)
|
||||
return -1;
|
||||
|
||||
|
@ -128,6 +357,15 @@ static int diva_status_get_controller_state(int controller, diva_status_ifc_stat
|
|||
for (i = 0, pri = 0, p = data, v = strsep(&p, ",");
|
||||
v != 0 && i < DivaStateIfcConfig_Max;
|
||||
v = strsep(&p, ","), i++) {
|
||||
if (v[0] == '\'' && v[strlen(v)-1] != '\'') {
|
||||
const char *tmp;
|
||||
do {
|
||||
if ((p != 0) && (*p != 0))
|
||||
p[-1] = ',';
|
||||
tmp = strsep (&p, ",");
|
||||
} while ((tmp != 0) && (tmp[strlen(tmp)-1] != '\''));
|
||||
}
|
||||
|
||||
switch ((diva_state_ifc_config_parameters_t)i) {
|
||||
case DivaStateIfcConfig_TYPE:
|
||||
pri += (strcmp ("PRI", v) == 0);
|
||||
|
@ -141,20 +379,24 @@ static int diva_status_get_controller_state(int controller, diva_status_ifc_stat
|
|||
break;
|
||||
}
|
||||
}
|
||||
diva_os_free(0, data);
|
||||
ast_free(data);
|
||||
|
||||
state->ifcType = (pri == 2) ? DivaStatusIfcPri : DivaStatusIfcNotPri;
|
||||
|
||||
if ((data = diva_status_read_file(controller, DIVA_STATUS_FILE)) == 0)
|
||||
return (-1);
|
||||
|
||||
memset (state, 0x00, sizeof(*state));
|
||||
state->ifcType = (pri == 2) ? DivaStatusIfcPri : DivaStatusIfcNotPri;
|
||||
state->hwState = DivaStatusHwStateUnknown;
|
||||
state->ifcL1State = DivaStatusIfcL2DoNotApply;
|
||||
state->ifcL2State = DivaStatusIfcL2DoNotApply;
|
||||
|
||||
for (i = 0, p = data, v = strsep (&p, ","); v != 0 && i < (int)DivaStateIfcState_Max; v = strsep (&p, ","), i++) {
|
||||
switch ((diva_state_ifcstate_parameters_t)i) {
|
||||
if (v[0] == '\'' && v[strlen(v)-1] != '\'') {
|
||||
const char *tmp;
|
||||
do {
|
||||
if ((p != 0) && (*p != 0))
|
||||
p[-1] = ',';
|
||||
tmp = strsep (&p, ",");
|
||||
} while ((tmp != 0) && (tmp[strlen(tmp)-1] != '\''));
|
||||
}
|
||||
|
||||
switch ((diva_state_ifcstate_parameters_t)i) {
|
||||
case DivaStateIfcState_LAYER1_STATE:
|
||||
if (state->ifcType == DivaStatusIfcPri) {
|
||||
state->ifcL1State = (strcmp ("'Activated'", v) == 0) ? DivaStatusIfcL1OK : DivaStatusIfcL1Error;
|
||||
|
@ -168,35 +410,35 @@ static int diva_status_get_controller_state(int controller, diva_status_ifc_stat
|
|||
break;
|
||||
|
||||
case DivaStateIfcState_D2_X_FRAMES:
|
||||
state->ifcTxDStatistics.Frames = (unsigned int)atol(data);
|
||||
state->ifcTxDStatistics.Frames = (unsigned int)atol(v);
|
||||
break;
|
||||
case DivaStateIfcState_D2_X_BYTES:
|
||||
state->ifcTxDStatistics.Bytes = (unsigned int)atol(data);
|
||||
state->ifcTxDStatistics.Bytes = (unsigned int)atol(v);
|
||||
break;
|
||||
case DivaStateIfcState_D2_X_ERRORS:
|
||||
state->ifcTxDStatistics.Errors = (unsigned int)atol(data);
|
||||
state->ifcTxDStatistics.Errors = (unsigned int)atol(v);
|
||||
break;
|
||||
case DivaStateIfcState_D2_R_FRAMES:
|
||||
state->ifcRxDStatistics.Frames = (unsigned int)atol(data);
|
||||
state->ifcRxDStatistics.Frames = (unsigned int)atol(v);
|
||||
break;
|
||||
case DivaStateIfcState_D2_R_BYTES:
|
||||
state->ifcRxDStatistics.Bytes = (unsigned int)atol(data);
|
||||
state->ifcRxDStatistics.Bytes = (unsigned int)atol(v);
|
||||
break;
|
||||
case DivaStateIfcState_D2_R_ERRORS:
|
||||
state->ifcRxDStatistics.Errors = (unsigned int)atol(data);
|
||||
state->ifcRxDStatistics.Errors = (unsigned int)atol(v);
|
||||
break;
|
||||
|
||||
case DivaStateIfcState_MAX_TEMPERATURE:
|
||||
state->maxTemperature = (unsigned int)atoi(data);
|
||||
state->maxTemperature = (unsigned int)atoi(v);
|
||||
break;
|
||||
case DivaStateIfcState_TEMPERATURE:
|
||||
state->currentTemperature = (unsigned int)atoi(data);
|
||||
state->currentTemperature = (unsigned int)atoi(v);
|
||||
break;
|
||||
|
||||
case DivaStateIfcState_HARDWARE_STATE:
|
||||
if (strcmp("'Active'", data) == 0)
|
||||
if (strcmp("'Active'", v) == 0)
|
||||
state->hwState = DivaStateHwStateActive;
|
||||
else if (strcmp("'Inactive'", data) == 0)
|
||||
else if (strcmp("'Inactive'", v) == 0)
|
||||
state->hwState = DivaStateHwStateInactive;
|
||||
break;
|
||||
|
||||
|
@ -204,23 +446,23 @@ static int diva_status_get_controller_state(int controller, diva_status_ifc_stat
|
|||
break;
|
||||
}
|
||||
}
|
||||
diva_os_free (0, data);
|
||||
ast_free (data);
|
||||
|
||||
if ((data = diva_status_read_file(controller, DIVA_READ_ALARM_FILE)) != 0) {
|
||||
state->ifcAlarms.Red = strcmp("TRUE", data);
|
||||
diva_os_free(0, data);
|
||||
ast_free(data);
|
||||
}
|
||||
if ((data = diva_status_read_file(controller, DIVA_YELLOW_ALARM_FILE)) != 0) {
|
||||
state->ifcAlarms.Yellow = strcmp("TRUE", data);
|
||||
diva_os_free(0, data);
|
||||
ast_free(data);
|
||||
}
|
||||
if ((data = diva_status_read_file(controller, DIVA_BLUE_ALARM_FILE)) != 0) {
|
||||
state->ifcAlarms.Blue = strcmp("TRUE", data);
|
||||
diva_os_free(0, data);
|
||||
ast_free(data);
|
||||
}
|
||||
if ((data = diva_status_read_file(controller, DIVA_SERIAL_FILE)) != 0) {
|
||||
state->serialNumber = (unsigned int)(atol(data)) & 0x00ffffff;
|
||||
diva_os_free(0, data);
|
||||
ast_free(data);
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
@ -254,3 +496,53 @@ diva_status_interface_state_t diva_status_get_interface_state(int controller)
|
|||
return DivaStatusInterfaceStateERROR;
|
||||
}
|
||||
|
||||
static diva_status_interface_state_t diva_status_get_interface_state_from_idi_state (diva_status_ifc_state_t* state) {
|
||||
if ((state->ifcType != DivaStatusIfcPri) ||
|
||||
(state->ifcL1State == DivaStatusIfcL2DoNotApply) ||
|
||||
(state->hwState == DivaStatusHwStateUnknown)) {
|
||||
return (DivaStatusInterfaceStateNotAvailable);
|
||||
}
|
||||
|
||||
if ((state->ifcAlarms.Red == 0) &&
|
||||
(state->ifcAlarms.Yellow == 0) &&
|
||||
(state->ifcAlarms.Blue == 0) &&
|
||||
(state->hwState == DivaStateHwStateActive) &&
|
||||
(state->ifcL1State == DivaStatusIfcL1OK)) {
|
||||
return DivaStatusInterfaceStateOK;
|
||||
}
|
||||
|
||||
return DivaStatusInterfaceStateERROR;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Map CAPI controller to Diva hardware
|
||||
|
||||
\note In most cases chan_capi uses 1:1 mappimg
|
||||
between CAPI controller and Diva hardware
|
||||
|
||||
\todo Read CAPI2DIva mapping table from CAPI
|
||||
*/
|
||||
static int diva_status_map_CAPI2XDI(int capiController)
|
||||
{
|
||||
return ((capiController > 0) ? capiController : -1);
|
||||
}
|
||||
|
||||
int diva_status_available(void)
|
||||
{
|
||||
return (diva_status_active());
|
||||
}
|
||||
|
||||
const char* diva_status_interface_state_name(diva_status_interface_state_t state)
|
||||
{
|
||||
switch (state) {
|
||||
case DivaStatusInterfaceStateOK:
|
||||
return "active";
|
||||
|
||||
case DivaStatusInterfaceStateERROR:
|
||||
return "inactive";
|
||||
|
||||
case DivaStatusInterfaceStateNotAvailable:
|
||||
default:
|
||||
return "not available";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,28 +27,35 @@
|
|||
#define __DIVA_STATUS_IFC_H__
|
||||
|
||||
typedef enum _diva_status_interface_state {
|
||||
DivaStatusInterfaceStateNotAvailable = -1,
|
||||
DivaStatusInterfaceStateOK = 0,
|
||||
DivaStatusInterfaceStateERROR = 1,
|
||||
DivaStatusInterfaceStateNotAvailable = 0,
|
||||
DivaStatusInterfaceStateOK = 1,
|
||||
DivaStatusInterfaceStateERROR = -1,
|
||||
} diva_status_interface_state_t;
|
||||
|
||||
/*!
|
||||
\brief Check if Diva interface is available
|
||||
*/
|
||||
int diva_status_available(void);
|
||||
|
||||
typedef void (*diva_status_changed_cb_proc_t)(int controller, diva_status_interface_state_t state);
|
||||
|
||||
/*!
|
||||
\brief activate event based status notifications
|
||||
*/
|
||||
void diva_status_init_interface (int controller);
|
||||
diva_status_interface_state_t diva_status_init_interface(int controller, diva_status_changed_cb_proc_t fn);
|
||||
/*!
|
||||
\brief deactivate event based status notifications
|
||||
*/
|
||||
void diva_status_cleanup_interface (int controller);
|
||||
void diva_status_cleanup_interface(int controller);
|
||||
/*!
|
||||
\brief retrieve file handle to be used in async
|
||||
I/O operations
|
||||
*/
|
||||
int diva_status_get_waitable_object (void);
|
||||
int diva_status_get_waitable_object(void);
|
||||
/*!
|
||||
\brief process status change events
|
||||
*/
|
||||
void diva_status_process_events (void);
|
||||
void diva_status_process_events(void);
|
||||
|
||||
/*!
|
||||
\brief Retrieve state of interface
|
||||
|
@ -57,8 +64,9 @@ void diva_status_process_events (void);
|
|||
DivaStatusInterfaceStateERROR - interface state verified and
|
||||
can not be used to create calls
|
||||
*/
|
||||
diva_status_interface_state_t diva_status_get_interface_state (int controller);
|
||||
diva_status_interface_state_t diva_status_get_interface_state(int controller);
|
||||
|
||||
const char* diva_status_interface_state_name(diva_status_interface_state_t state);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ typedef enum _diva_state_ifcstate_parameters {
|
|||
} diva_state_ifcstate_parameters_t;
|
||||
|
||||
typedef enum diva_state_ifc_config_parameters {
|
||||
DivaStateIfcConfig_TYPE,
|
||||
DivaStateIfcConfig_TYPE = 0,
|
||||
DivaStateIfcConfig_CHANNELS,
|
||||
DivaStateIfcConfig_PROTOCOL,
|
||||
DivaStateIfcConfig_NT_MODE,
|
||||
|
|
Loading…
Reference in New Issue