Cleanup all CCBS/CCNR/peerlink IDs correctly.
This commit is contained in:
parent
246e5b21cb
commit
14abf19bb2
|
@ -5694,6 +5694,8 @@ int unload_module(void)
|
||||||
|
|
||||||
ast_channel_unregister(&capi_tech);
|
ast_channel_unregister(&capi_tech);
|
||||||
|
|
||||||
|
cleanup_ccbsnr();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,51 @@
|
||||||
static struct ccbsnr_s *ccbsnr_list = NULL;
|
static struct ccbsnr_s *ccbsnr_list = NULL;
|
||||||
AST_MUTEX_DEFINE_STATIC(ccbsnr_lock);
|
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
|
* 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));
|
memset(ccbsnr, 0, sizeof(struct ccbsnr_s));
|
||||||
|
|
||||||
|
ccbsnr->age = time(NULL);
|
||||||
ccbsnr->type = type;
|
ccbsnr->type = type;
|
||||||
ccbsnr->id = id;
|
ccbsnr->id = id;
|
||||||
ccbsnr->rbref = 0xdead;
|
ccbsnr->rbref = 0xdead;
|
||||||
|
@ -54,6 +100,7 @@ static void new_ccbsnr_id(char type, unsigned int plci,
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_mutex_lock(&ccbsnr_lock);
|
cc_mutex_lock(&ccbsnr_lock);
|
||||||
|
del_old_ccbsnr();
|
||||||
ccbsnr->next = ccbsnr_list;
|
ccbsnr->next = ccbsnr_list;
|
||||||
ccbsnr_list = ccbsnr;
|
ccbsnr_list = ccbsnr;
|
||||||
cc_mutex_unlock(&ccbsnr_lock);
|
cc_mutex_unlock(&ccbsnr_lock);
|
||||||
|
@ -457,7 +504,7 @@ void handle_facility_confirmation_supplementary(
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x000f: /* CCBS request */
|
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);
|
name, serviceinfo, PLCI);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -33,6 +33,7 @@ struct ccbsnr_s {
|
||||||
char context[AST_MAX_CONTEXT];
|
char context[AST_MAX_CONTEXT];
|
||||||
char exten[AST_MAX_EXTENSION];
|
char exten[AST_MAX_EXTENSION];
|
||||||
int priority;
|
int priority;
|
||||||
|
time_t age;
|
||||||
struct ccbsnr_s *next;
|
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_ccbs(struct ast_channel *c, char *data);
|
||||||
extern int pbx_capi_ccbsstop(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 int pbx_capi_ccpartybusy(struct ast_channel *c, char *data);
|
||||||
|
extern void cleanup_ccbsnr(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,11 +26,15 @@ char *emptyid = "\0";
|
||||||
AST_MUTEX_DEFINE_STATIC(verbose_lock);
|
AST_MUTEX_DEFINE_STATIC(verbose_lock);
|
||||||
AST_MUTEX_DEFINE_STATIC(messagenumber_lock);
|
AST_MUTEX_DEFINE_STATIC(messagenumber_lock);
|
||||||
AST_MUTEX_DEFINE_STATIC(capi_put_lock);
|
AST_MUTEX_DEFINE_STATIC(capi_put_lock);
|
||||||
|
AST_MUTEX_DEFINE_STATIC(peerlink_lock);
|
||||||
|
|
||||||
static _cword capi_MessageNumber;
|
static _cword capi_MessageNumber;
|
||||||
|
|
||||||
#define CAPI_MAX_PEERLINKCHANNELS 32
|
#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
|
* helper for <pbx>_verbose with different verbose settings
|
||||||
|
@ -854,12 +858,22 @@ int cc_add_peer_link_id(struct ast_channel *c)
|
||||||
{
|
{
|
||||||
int a;
|
int a;
|
||||||
|
|
||||||
|
cc_mutex_lock(&peerlink_lock);
|
||||||
for (a = 0; a < CAPI_MAX_PEERLINKCHANNELS; a++) {
|
for (a = 0; a < CAPI_MAX_PEERLINKCHANNELS; a++) {
|
||||||
if (peerlinkchannel[a] == NULL) {
|
if (peerlinkchannel[a].channel == NULL) {
|
||||||
peerlinkchannel[a] = c;
|
peerlinkchannel[a].channel = c;
|
||||||
|
peerlinkchannel[a].age = time(NULL);
|
||||||
break;
|
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) {
|
if (a == CAPI_MAX_PEERLINKCHANNELS) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -878,10 +892,14 @@ struct ast_channel *cc_get_peer_link_id(const char *p)
|
||||||
id = (int)strtol(p, NULL, 0);
|
id = (int)strtol(p, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc_mutex_lock(&peerlink_lock);
|
||||||
if ((id >= 0) && (id < CAPI_MAX_PEERLINKCHANNELS)) {
|
if ((id >= 0) && (id < CAPI_MAX_PEERLINKCHANNELS)) {
|
||||||
chan = peerlinkchannel[id];
|
chan = peerlinkchannel[id].channel;
|
||||||
peerlinkchannel[id] = NULL;
|
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;
|
return chan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue