diff --git a/CHANGES b/CHANGES index fa95c0c..a06346c 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,8 @@ CHANGES HEAD ------------------ +- fixed controller count when creating NULL-PLCI interface. +- simplified check for unused controller. chan_capi-1.1.0 diff --git a/chan_capi.c b/chan_capi.c index 95cbb39..50ea6af 100644 --- a/chan_capi.c +++ b/chan_capi.c @@ -144,7 +144,6 @@ struct capi_pvt *capi_iflist = NULL; static struct cc_capi_controller *capi_controllers[CAPI_MAX_CONTROLLERS + 1]; static int capi_num_controllers = 0; static unsigned int capi_counter = 0; -static unsigned long capi_used_controllers = 0; static struct ast_channel *chan_for_task; static int channel_task; @@ -5222,19 +5221,21 @@ int mkif(struct cc_capi_conf *conf) unit = capi_num_controllers; } - if (unit > capi_num_controllers){ + /* always range check user input */ + if (unit > CAPI_MAX_CONTROLLERS) + unit = CAPI_MAX_CONTROLLERS; + + if ((unit > capi_num_controllers) || + (!(capi_controllers[unit]))) { free(tmp); cc_verbose(2, 0, VERBOSE_PREFIX_3 "controller %d invalid, ignoring interface.\n", unit); return 0; } - /* always range check user input */ - if (unit > CAPI_MAX_CONTROLLERS) - unit = CAPI_MAX_CONTROLLERS; + capi_controllers[unit]->used = 1; tmp->controller = unit; - capi_used_controllers |= (1 << unit); tmp->doEC = conf->echocancel; tmp->doEC_global = conf->echocancel; tmp->ecOption = conf->ecoption; @@ -5590,9 +5591,10 @@ static int pbxcli_capi_info(int fd, int argc, char *argv[]) for (i = 1; i <= capi_num_controllers; i++) { if (capi_controllers[i] != NULL) { - ast_cli(fd, "Contr%d: %d B channels total, %d B channels free.\n", + ast_cli(fd, "Contr%d: %d B channels total, %d B channels free.%s\n", i, capi_controllers[i]->nbchannels, - capi_controllers[i]->nfreebchannels); + capi_controllers[i]->nfreebchannels, + (capi_controllers[i]->used) ? "":" (unused)"); } } #ifdef CC_AST_HAS_VERSION_1_6 @@ -5982,7 +5984,8 @@ static int cc_post_init_capi(void) } } for (controller = 1; controller <= capi_num_controllers; controller++) { - if (capi_controllers[controller] != NULL) { + if ((capi_controllers[controller] != NULL) && + (capi_controllers[controller]->used)) { needchannels += (capi_controllers[controller]->nbchannels + 1); } } @@ -5990,7 +5993,7 @@ static int cc_post_init_capi(void) return -1; for (controller = 1; controller <= capi_num_controllers; controller++) { - if (capi_used_controllers & (1 << controller)) { + if (capi_controllers[controller]->used) { if ((error = capi_ListenOnController(ALL_SERVICES, controller)) != 0) { cc_log(LOG_ERROR,"Unable to listen on contr%d (error=0x%x)\n", controller, error); @@ -6322,11 +6325,9 @@ int unload_module(void) cc_log(LOG_WARNING,"Unable to unregister from CAPI!\n"); } - for (controller = 1; controller <= capi_num_controllers; controller++) { - if (capi_used_controllers & (1 << controller)) { - if (capi_controllers[controller]) - free(capi_controllers[controller]); - } + for (controller = 1; controller <= CAPI_MAX_CONTROLLERS; controller++) { + if (capi_controllers[controller]) + free(capi_controllers[controller]); } i = capi_iflist; diff --git a/chan_capi.h b/chan_capi.h index cf70715..49f52d7 100644 --- a/chan_capi.h +++ b/chan_capi.h @@ -517,6 +517,8 @@ struct cc_capi_conf { struct cc_capi_controller { /* which controller is this? */ int controller; + /* is this controller used? */ + int used; /* how many bchans? */ int nbchannels; /* free bchans */ diff --git a/chan_capi_chat.c b/chan_capi_chat.c index a582bf6..e596e5d 100644 --- a/chan_capi_chat.c +++ b/chan_capi_chat.c @@ -311,7 +311,7 @@ int pbx_capi_chat(struct ast_channel *c, char *param) char *p; struct capichat_s *room; ast_group_t tmpcntr; - unsigned long contr = 0; + unsigned long long contr = 0; unsigned int flags = 0; roomname = strsep(¶m, "|"); @@ -328,7 +328,7 @@ int pbx_capi_chat(struct ast_channel *c, char *param) if (*p == '|') *p = ','; } tmpcntr = ast_get_group(controller); - contr = (unsigned long)(tmpcntr >> 1); + contr = (unsigned long long)(tmpcntr >> 1); } while ((options) && (*options)) { @@ -345,7 +345,7 @@ int pbx_capi_chat(struct ast_channel *c, char *param) } cc_verbose(3, 1, VERBOSE_PREFIX_3 CC_MESSAGE_NAME " chat: %s: roomname=%s " - "options=%s controller=%s (0x%x)\n", + "options=%s controller=%s (0x%llx)\n", c->name, roomname, options, controller, contr); if (c->tech == &capi_tech) { diff --git a/chan_capi_utils.c b/chan_capi_utils.c index a40fcb9..8a1eed1 100644 --- a/chan_capi_utils.c +++ b/chan_capi_utils.c @@ -129,17 +129,19 @@ void capi_remove_nullif(struct capi_pvt *i) /* * create new null-interface */ -struct capi_pvt *capi_mknullif(struct ast_channel *c, unsigned long controllermask) +struct capi_pvt *capi_mknullif(struct ast_channel *c, unsigned long long controllermask) { struct capi_pvt *tmp; unsigned int controller = 1; int contrcount; int channelcount = 0xffff; + int maxcontr = (CAPI_MAX_CONTROLLERS > sizeof(controllermask)) ? + sizeof(controllermask) : CAPI_MAX_CONTROLLERS; cc_verbose(3, 1, VERBOSE_PREFIX_4 "capi_mknullif: find controller for mask 0x%lx\n", controllermask); /* find the next controller of mask with least plcis used */ - for (contrcount = 0; contrcount < CAPI_MAX_CONTROLLERS; contrcount++) { + for (contrcount = 0; contrcount < maxcontr; contrcount++) { if ((controllermask & (1 << contrcount))) { if (controller_nullplcis[contrcount] < channelcount) { channelcount = controller_nullplcis[contrcount]; diff --git a/chan_capi_utils.h b/chan_capi_utils.h index d1ad169..a31f273 100644 --- a/chan_capi_utils.h +++ b/chan_capi_utils.h @@ -32,7 +32,7 @@ extern char *capi_number_func(unsigned char *data, unsigned int strip, char *buf extern int cc_add_peer_link_id(struct ast_channel *c); extern struct ast_channel *cc_get_peer_link_id(const char *p); extern void capi_remove_nullif(struct capi_pvt *i); -extern struct capi_pvt *capi_mknullif(struct ast_channel *c, unsigned long controllermask); +extern struct capi_pvt *capi_mknullif(struct ast_channel *c, unsigned long long controllermask); extern int capi_create_reader_writer_pipe(struct capi_pvt *i); extern struct ast_frame *capi_read_pipeframe(struct capi_pvt *i); extern int capi_write_frame(struct capi_pvt *i, struct ast_frame *f);