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

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

View File

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

View File

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

View File

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