Cleanup all CCBS/CCNR/peerlink IDs correctly.

This commit is contained in:
MelwareDE 2007-04-22 10:03:52 +00:00
parent 246e5b21cb
commit 14abf19bb2
4 changed files with 75 additions and 6 deletions

View File

@ -5693,6 +5693,8 @@ int unload_module(void)
cc_mutex_unlock(&iflock);
ast_channel_unregister(&capi_tech);
cleanup_ccbsnr();
return 0;
}

View File

@ -23,6 +23,51 @@
static struct ccbsnr_s *ccbsnr_list = NULL;
AST_MUTEX_DEFINE_STATIC(ccbsnr_lock);
/*
* remove too old CCBS/CCNR entries
* (must be called with ccbsnr_lock held)
*/
static void del_old_ccbsnr(void)
{
struct ccbsnr_s *ccbsnr;
struct ccbsnr_s *tmp = NULL;
ccbsnr = ccbsnr_list;
while (ccbsnr) {
if ((ccbsnr->age + 86400) < time(NULL)) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "CAPI: CCBS/CCNR handle=%d timeout.\n",
ccbsnr->handle);
if (!tmp) {
ccbsnr_list = ccbsnr->next;
} else {
tmp->next = ccbsnr->next;
}
free(ccbsnr);
break;
}
tmp = ccbsnr;
ccbsnr = ccbsnr->next;
}
}
/*
* cleanup CCBS/CCNR ids
*/
void cleanup_ccbsnr(void)
{
struct ccbsnr_s *ccbsnr;
struct ccbsnr_s *tmp = NULL;
cc_mutex_lock(&ccbsnr_lock);
ccbsnr = ccbsnr_list;
while (ccbsnr) {
tmp = ccbsnr;
ccbsnr = ccbsnr->next;
free(tmp);
}
cc_mutex_unlock(&ccbsnr_lock);
}
/*
* a new CCBS/CCNR id was received
*/
@ -39,6 +84,7 @@ static void new_ccbsnr_id(char type, unsigned int plci,
}
memset(ccbsnr, 0, sizeof(struct ccbsnr_s));
ccbsnr->age = time(NULL);
ccbsnr->type = type;
ccbsnr->id = id;
ccbsnr->rbref = 0xdead;
@ -54,6 +100,7 @@ static void new_ccbsnr_id(char type, unsigned int plci,
}
cc_mutex_lock(&ccbsnr_lock);
del_old_ccbsnr();
ccbsnr->next = ccbsnr_list;
ccbsnr_list = ccbsnr;
cc_mutex_unlock(&ccbsnr_lock);
@ -457,7 +504,7 @@ void handle_facility_confirmation_supplementary(
}
break;
case 0x000f: /* CCBS request */
cc_verbose(2, 0, VERBOSE_PREFIX_3 "%s: CCBS request info=0x%04x (PLCI=%#x)\n",
cc_verbose(2, 0, VERBOSE_PREFIX_3 "%s: CCBS request confirmation (0x%04x) (PLCI=%#x)\n",
name, serviceinfo, PLCI);
break;
default:

View File

@ -33,6 +33,7 @@ struct ccbsnr_s {
char context[AST_MAX_CONTEXT];
char exten[AST_MAX_EXTENSION];
int priority;
time_t age;
struct ccbsnr_s *next;
};
@ -47,5 +48,6 @@ extern void handle_facility_confirmation_supplementary(
extern int pbx_capi_ccbs(struct ast_channel *c, char *data);
extern int pbx_capi_ccbsstop(struct ast_channel *c, char *data);
extern int pbx_capi_ccpartybusy(struct ast_channel *c, char *data);
extern void cleanup_ccbsnr(void);
#endif

View File

@ -26,11 +26,15 @@ char *emptyid = "\0";
AST_MUTEX_DEFINE_STATIC(verbose_lock);
AST_MUTEX_DEFINE_STATIC(messagenumber_lock);
AST_MUTEX_DEFINE_STATIC(capi_put_lock);
AST_MUTEX_DEFINE_STATIC(peerlink_lock);
static _cword capi_MessageNumber;
#define CAPI_MAX_PEERLINKCHANNELS 32
static struct ast_channel *peerlinkchannel[CAPI_MAX_PEERLINKCHANNELS];
static struct peerlink_s {
struct ast_channel *channel;
time_t age;
} peerlinkchannel[CAPI_MAX_PEERLINKCHANNELS];
/*
* helper for <pbx>_verbose with different verbose settings
@ -854,12 +858,22 @@ int cc_add_peer_link_id(struct ast_channel *c)
{
int a;
cc_mutex_lock(&peerlink_lock);
for (a = 0; a < CAPI_MAX_PEERLINKCHANNELS; a++) {
if (peerlinkchannel[a] == NULL) {
peerlinkchannel[a] = c;
if (peerlinkchannel[a].channel == NULL) {
peerlinkchannel[a].channel = c;
peerlinkchannel[a].age = time(NULL);
break;
} else {
/* remove too old entries */
if ((peerlinkchannel[a].age + 60) < time(NULL)) {
peerlinkchannel[a].channel = NULL;
cc_verbose(3, 1, VERBOSE_PREFIX_4 "capi: peerlink %d timeout-erase\n",
a);
}
}
}
cc_mutex_unlock(&peerlink_lock);
if (a == CAPI_MAX_PEERLINKCHANNELS) {
return -1;
}
@ -878,10 +892,14 @@ struct ast_channel *cc_get_peer_link_id(const char *p)
id = (int)strtol(p, NULL, 0);
}
cc_mutex_lock(&peerlink_lock);
if ((id >= 0) && (id < CAPI_MAX_PEERLINKCHANNELS)) {
chan = peerlinkchannel[id];
peerlinkchannel[id] = NULL;
chan = peerlinkchannel[id].channel;
peerlinkchannel[id].channel = NULL;
}
cc_mutex_unlock(&peerlink_lock);
cc_verbose(3, 1, VERBOSE_PREFIX_4 "capi: peerlink %d allocated, peer is %s\n",
id, (chan)?chan->name:"unlinked");
return chan;
}