Use provided by Diva hardware status information for distribution of outgoing calls between CAPI controllers

This commit is contained in:
MelwareDE 2010-10-22 22:44:50 +00:00
parent f7e19c4cad
commit e534562827
5 changed files with 436 additions and 40 deletions

View File

@ -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;
}

View File

@ -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 */

View File

@ -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";
}
}

View File

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

View File

@ -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,