/* Attempt to pick up specified extension with context */ static int pickup_by_exten(struct ast_channel *chan, const char *exten, const char *context) { struct ast_channel *target = NULL;/*!< Potential pickup target */ struct ast_channel_iterator *iter; int res = -1; if (!(iter = ast_channel_iterator_by_exten_new(exten, context))) { return -1; } while ((target = ast_channel_iterator_next(iter))) { ast_channel_lock(target); if ((chan != target) && ast_can_pickup(target)) { ast_log(LOG_NOTICE, "%s pickup by %s\n", ast_channel_name(target), ast_channel_name(chan)); break; } ast_channel_unlock(target); target = ast_channel_unref(target); } ast_channel_iterator_destroy(iter); if (target) { res = ast_do_pickup(chan, target); ast_channel_unlock(target); target = ast_channel_unref(target); } return res; }
static struct ast_autochan *next_channel(struct ast_channel_iterator *iter, struct ast_autochan *autochan, struct ast_channel *chan) { struct ast_channel *next; struct ast_autochan *autochan_store; const size_t pseudo_len = strlen("DAHDI/pseudo"); if (!iter) { return NULL; } redo: if (!(next = ast_channel_iterator_next(iter))) { return NULL; } if (!strncmp(next->name, "DAHDI/pseudo", pseudo_len)) { goto redo; } else if (next == chan) { goto redo; } autochan_store = ast_autochan_setup(next); ast_channel_unref(next); return autochan_store; }
static u_char *ast_var_channel_bridge(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { static unsigned long long_ret; struct ast_channel *chan = NULL; struct ast_channel_iterator *iter; long_ret = 0; if (header_generic(vp, name, length, exact, var_len, write_method)) { return NULL; } if (!(iter = ast_channel_iterator_all_new())) { return NULL; } while ((chan = ast_channel_iterator_next(iter))) { ast_channel_lock(chan); if (ast_bridged_channel(chan)) { long_ret++; } ast_channel_unlock(chan); chan = ast_channel_unref(chan); } ast_channel_iterator_destroy(iter); *var_len = sizeof(long_ret); return (vp->magic == ASTCHANBRIDGECOUNT) ? (u_char *) &long_ret : NULL; }
static int func_channels_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen) { struct ast_channel *c = NULL; regex_t re; int res; size_t buflen = 0; struct ast_channel_iterator *iter; buf[0] = '\0'; if (!ast_strlen_zero(data)) { if ((res = regcomp(&re, data, REG_EXTENDED | REG_ICASE | REG_NOSUB))) { regerror(res, &re, buf, maxlen); ast_log(LOG_WARNING, "Error compiling regular expression for %s(%s): %s\n", function, data, buf); return -1; } } if (!(iter = ast_channel_iterator_all_new())) { if (!ast_strlen_zero(data)) { regfree(&re); } return -1; } while ((c = ast_channel_iterator_next(iter))) { ast_channel_lock(c); if (ast_strlen_zero(data) || regexec(&re, ast_channel_name(c), 0, NULL, 0) == 0) { size_t namelen = strlen(ast_channel_name(c)); if (buflen + namelen + (ast_strlen_zero(buf) ? 0 : 1) + 1 < maxlen) { if (!ast_strlen_zero(buf)) { strcat(buf, " "); buflen++; } strcat(buf, ast_channel_name(c)); buflen += namelen; } else { ast_log(LOG_WARNING, "Number of channels exceeds the available buffer space. Output will be truncated!\n"); } } ast_channel_unlock(c); c = ast_channel_unref(c); } ast_channel_iterator_destroy(iter); if (!ast_strlen_zero(data)) { regfree(&re); } return 0; }
static struct ast_autochan *next_channel(struct ast_channel_iterator *iter, struct ast_autochan *autochan, struct ast_channel *chan) { struct ast_channel *next; struct ast_autochan *autochan_store; const size_t pseudo_len = strlen("DAHDI/pseudo"); if (!iter) { return NULL; } for (; (next = ast_channel_iterator_next(iter)); ast_channel_unref(next)) { if (!strncmp(ast_channel_name(next), "DAHDI/pseudo", pseudo_len) || next == chan) { continue; } autochan_store = ast_autochan_setup(next); ast_channel_unref(next); return autochan_store; } return NULL; }
static u_char *ast_var_channel_types_table(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { const struct ast_channel_tech *tech = NULL; struct ast_variable *channel_types, *next; static unsigned long long_ret; struct ast_channel *chan; u_long i; if (header_simple_table(vp, name, length, exact, var_len, write_method, -1)) return NULL; channel_types = ast_channeltype_list(); for (i = 1, next = channel_types; next && i != name[*length - 1]; next = next->next, i++) ; if (next != NULL) tech = ast_get_channel_tech(next->name); ast_variables_destroy(channel_types); if (next == NULL || tech == NULL) return NULL; switch (vp->magic) { case ASTCHANTYPEINDEX: long_ret = name[*length - 1]; return (u_char *)&long_ret; case ASTCHANTYPENAME: *var_len = strlen(tech->type); return (u_char *)tech->type; case ASTCHANTYPEDESC: *var_len = strlen(tech->description); return (u_char *)tech->description; case ASTCHANTYPEDEVSTATE: long_ret = tech->devicestate ? 1 : 2; return (u_char *)&long_ret; case ASTCHANTYPEINDICATIONS: long_ret = tech->indicate ? 1 : 2; return (u_char *)&long_ret; case ASTCHANTYPETRANSFER: long_ret = tech->transfer ? 1 : 2; return (u_char *)&long_ret; case ASTCHANTYPECHANNELS: { struct ast_channel_iterator *iter; long_ret = 0; if (!(iter = ast_channel_iterator_all_new())) { return NULL; } while ((chan = ast_channel_iterator_next(iter))) { if (ast_channel_tech(chan) == tech) { long_ret++; } chan = ast_channel_unref(chan); } ast_channel_iterator_destroy(iter); return (u_char *)&long_ret; } default: break; } return NULL; }
static u_char *ast_var_channels_table(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { static unsigned long long_ret; static u_char bits_ret[2]; static char string_ret[256]; struct ast_channel *chan, *bridge; struct timeval tval; u_char *ret = NULL; int i, bit; struct ast_str *out = ast_str_alloca(2048); struct ast_channel_iterator *iter; if (header_simple_table(vp, name, length, exact, var_len, write_method, ast_active_channels())) return NULL; i = name[*length - 1] - 1; if (!(iter = ast_channel_iterator_all_new())) { return NULL; } while ((chan = ast_channel_iterator_next(iter)) && i) { ast_channel_unref(chan); i--; } iter = ast_channel_iterator_destroy(iter); if (chan == NULL) { return NULL; } *var_len = sizeof(long_ret); ast_channel_lock(chan); switch (vp->magic) { case ASTCHANINDEX: long_ret = name[*length - 1]; ret = (u_char *)&long_ret; break; case ASTCHANNAME: if (!ast_strlen_zero(ast_channel_name(chan))) { ast_copy_string(string_ret, ast_channel_name(chan), sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANLANGUAGE: if (!ast_strlen_zero(ast_channel_language(chan))) { ast_copy_string(string_ret, ast_channel_language(chan), sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANTYPE: ast_copy_string(string_ret, ast_channel_tech(chan)->type, sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; break; case ASTCHANMUSICCLASS: if (!ast_strlen_zero(ast_channel_musicclass(chan))) { ast_copy_string(string_ret, ast_channel_musicclass(chan), sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANBRIDGE: if ((bridge = ast_bridged_channel(chan)) != NULL) { ast_copy_string(string_ret, ast_channel_name(bridge), sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANMASQ: if (ast_channel_masq(chan) && !ast_strlen_zero(ast_channel_name(ast_channel_masq(chan)))) { ast_copy_string(string_ret, ast_channel_name(ast_channel_masq(chan)), sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANMASQR: if (ast_channel_masqr(chan) && !ast_strlen_zero(ast_channel_name(ast_channel_masqr(chan)))) { ast_copy_string(string_ret, ast_channel_name(ast_channel_masqr(chan)), sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANWHENHANGUP: if (!ast_tvzero(*ast_channel_whentohangup(chan))) { gettimeofday(&tval, NULL); long_ret = difftime(ast_channel_whentohangup(chan)->tv_sec, tval.tv_sec) * 100 - tval.tv_usec / 10000; ret= (u_char *)&long_ret; } break; case ASTCHANAPP: if (ast_channel_appl(chan)) { ast_copy_string(string_ret, ast_channel_appl(chan), sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANDATA: if (ast_channel_data(chan)) { ast_copy_string(string_ret, ast_channel_data(chan), sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANCONTEXT: ast_copy_string(string_ret, ast_channel_context(chan), sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; break; case ASTCHANMACROCONTEXT: ast_copy_string(string_ret, ast_channel_macrocontext(chan), sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; break; case ASTCHANMACROEXTEN: ast_copy_string(string_ret, ast_channel_macroexten(chan), sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; break; case ASTCHANMACROPRI: long_ret = ast_channel_macropriority(chan); ret = (u_char *)&long_ret; break; case ASTCHANEXTEN: ast_copy_string(string_ret, ast_channel_exten(chan), sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; break; case ASTCHANPRI: long_ret = ast_channel_priority(chan); ret = (u_char *)&long_ret; break; case ASTCHANACCOUNTCODE: if (!ast_strlen_zero(ast_channel_accountcode(chan))) { ast_copy_string(string_ret, ast_channel_accountcode(chan), sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANFORWARDTO: if (!ast_strlen_zero(ast_channel_call_forward(chan))) { ast_copy_string(string_ret, ast_channel_call_forward(chan), sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANUNIQUEID: ast_copy_string(string_ret, ast_channel_uniqueid(chan), sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; break; case ASTCHANCALLGROUP: long_ret = ast_channel_callgroup(chan); ret = (u_char *)&long_ret; break; case ASTCHANPICKUPGROUP: long_ret = ast_channel_pickupgroup(chan); ret = (u_char *)&long_ret; break; case ASTCHANSTATE: long_ret = ast_channel_state(chan) & 0xffff; ret = (u_char *)&long_ret; break; case ASTCHANMUTED: long_ret = ast_channel_state(chan) & AST_STATE_MUTE ? 1 : 2; ret = (u_char *)&long_ret; break; case ASTCHANRINGS: long_ret = ast_channel_rings(chan); ret = (u_char *)&long_ret; break; case ASTCHANCIDDNID: if (ast_channel_dialed(chan)->number.str) { ast_copy_string(string_ret, ast_channel_dialed(chan)->number.str, sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANCIDNUM: if (ast_channel_caller(chan)->id.number.valid && ast_channel_caller(chan)->id.number.str) { ast_copy_string(string_ret, ast_channel_caller(chan)->id.number.str, sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANCIDNAME: if (ast_channel_caller(chan)->id.name.valid && ast_channel_caller(chan)->id.name.str) { ast_copy_string(string_ret, ast_channel_caller(chan)->id.name.str, sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANCIDANI: if (ast_channel_caller(chan)->ani.number.valid && ast_channel_caller(chan)->ani.number.str) { ast_copy_string(string_ret, ast_channel_caller(chan)->ani.number.str, sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANCIDRDNIS: if (ast_channel_redirecting(chan)->from.number.valid && ast_channel_redirecting(chan)->from.number.str) { ast_copy_string(string_ret, ast_channel_redirecting(chan)->from.number.str, sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANCIDPRES: long_ret = ast_party_id_presentation(&ast_channel_caller(chan)->id); ret = (u_char *)&long_ret; break; case ASTCHANCIDANI2: long_ret = ast_channel_caller(chan)->ani2; ret = (u_char *)&long_ret; break; case ASTCHANCIDTON: long_ret = ast_channel_caller(chan)->id.number.plan; ret = (u_char *)&long_ret; break; case ASTCHANCIDTNS: long_ret = ast_channel_dialed(chan)->transit_network_select; ret = (u_char *)&long_ret; break; case ASTCHANAMAFLAGS: long_ret = ast_channel_amaflags(chan); ret = (u_char *)&long_ret; break; case ASTCHANADSI: long_ret = ast_channel_adsicpe(chan); ret = (u_char *)&long_ret; break; case ASTCHANTONEZONE: if (ast_channel_zone(chan)) { ast_copy_string(string_ret, ast_channel_zone(chan)->country, sizeof(string_ret)); *var_len = strlen(string_ret); ret = (u_char *)string_ret; } break; case ASTCHANHANGUPCAUSE: long_ret = ast_channel_hangupcause(chan); ret = (u_char *)&long_ret; break; case ASTCHANVARIABLES: if (pbx_builtin_serialize_variables(chan, &out)) { *var_len = ast_str_strlen(out); ret = (u_char *)ast_str_buffer(out); } break; case ASTCHANFLAGS: bits_ret[0] = 0; for (bit = 0; bit < 8; bit++) bits_ret[0] |= ((ast_channel_flags(chan)->flags & (1 << bit)) >> bit) << (7 - bit); bits_ret[1] = 0; for (bit = 0; bit < 8; bit++) bits_ret[1] |= (((ast_channel_flags(chan)->flags >> 8) & (1 << bit)) >> bit) << (7 - bit); *var_len = 2; ret = bits_ret; break; case ASTCHANTRANSFERCAP: long_ret = ast_channel_transfercapability(chan); ret = (u_char *)&long_ret; default: break; } ast_channel_unlock(chan); chan = ast_channel_unref(chan); return ret; }