Cleanup all CCBS/CCNR/peerlink IDs correctly.
parent
246e5b21cb
commit
14abf19bb2
|
@ -5693,6 +5693,8 @@ int unload_module(void)
|
|||
cc_mutex_unlock(&iflock);
|
||||
|
||||
ast_channel_unregister(&capi_tech);
|
||||
|
||||
cleanup_ccbsnr();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue