Newer
Older
ast_log(LOG_ERROR, "Couldn't create rtp structure\n");
return -1;
}
ast_mutex_unlock(&p->lock);
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "+++ ooh323_onReceivedSetup - Determined context %s, "
"extension %s\n", p->context, p->exten);
return OO_OK;
}
int onOutgoingCall(ooCallData *call)
{
struct ooh323_pvt *p = NULL;
int i = 0;
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "--- onOutgoingCall %lx: %s\n", (long unsigned int) call, call->callToken);
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
if (!strcmp(call->callType, "outgoing")) {
p = find_call(call);
if (!p) {
ast_log(LOG_ERROR, "Failed to find a matching call.\n");
return -1;
}
ast_mutex_lock(&p->lock);
if (!ast_strlen_zero(p->callerid_name)) {
ooCallSetCallerId(call, p->callerid_name);
}
if (!ast_strlen_zero(p->callerid_num)) {
i = 0;
while (*(p->callerid_num + i) != '\0') {
if(!isdigit(*(p->callerid_num+i))) { break; }
i++;
}
if(*(p->callerid_num+i) == '\0')
ooCallSetCallingPartyNumber(call, p->callerid_num);
else {
if(!p->callerid_name)
ooCallSetCallerId(call, p->callerid_num);
}
}
if (!ast_strlen_zero(p->caller_h323id))
ooCallAddAliasH323ID(call, p->caller_h323id);
if (!ast_strlen_zero(p->caller_dialedDigits)) {
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, "Setting dialed digits %s\n", p->caller_dialedDigits);
}
ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
} else if (!ast_strlen_zero(p->callerid_num)) {
Tilghman Lesher
committed
ast_verb(0, "setting callid number %s\n", p->callerid_num);
}
ooCallAddAliasDialedDigits(call, p->callerid_num);
} else if (ast_strlen_zero(p->caller_h323id)) {
ooCallAddAliasH323ID(call, p->callerid_num);
}
}
if (p->rtpmask && p->rtpmaskstr[0]) {
call->rtpMask = p->rtpmask;
ast_mutex_lock(&call->rtpMask->lock);
call->rtpMask->inuse++;
ast_mutex_unlock(&call->rtpMask->lock);
ast_copy_string(call->rtpMaskStr, p->rtpmaskstr, sizeof(call->rtpMaskStr));
}
if (!p->rtp && !configure_local_rtp(p, call)) {
ast_mutex_unlock(&p->lock);
return OO_FAILED;
}
ast_mutex_unlock(&p->lock);
}
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "+++ onOutgoingCall %s\n", call->callToken);
int onNewCallCreated(ooCallData *call)
{
struct ooh323_pvt *p = NULL;
int i = 0;
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "--- onNewCallCreated %lx: %s\n", (long unsigned int) call, call->callToken);
ast_mutex_lock(&call->Lock);
if (ooh323c_start_call_thread(call)) {
ast_log(LOG_ERROR,"Failed to create call thread.\n");
ast_mutex_unlock(&call->Lock);
return -1;
}
if (!strcmp(call->callType, "outgoing")) {
p = find_call(call);
if (!p) {
ast_log(LOG_ERROR, "Failed to find a matching call.\n");
ast_mutex_unlock(&call->Lock);
return -1;
}
ast_mutex_lock(&p->lock);
if (!ast_strlen_zero(p->callerid_name)) {
ooCallSetCallerId(call, p->callerid_name);
}
if (!ast_strlen_zero(p->callerid_num)) {
i = 0;
while (*(p->callerid_num + i) != '\0') {
if(!isdigit(*(p->callerid_num+i))) { break; }
i++;
}
if(*(p->callerid_num+i) == '\0')
ooCallSetCallingPartyNumber(call, p->callerid_num);
if(ast_strlen_zero(p->callerid_name))
ooCallSetCallerId(call, p->callerid_num);
}
}
if (!ast_strlen_zero(p->caller_h323id))
ooCallAddAliasH323ID(call, p->caller_h323id);
if (!ast_strlen_zero(p->caller_dialedDigits)) {
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, "Setting dialed digits %s\n", p->caller_dialedDigits);
}
ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
} else if (!ast_strlen_zero(p->callerid_num)) {
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, "setting callid number %s\n", p->callerid_num);
}
ooCallAddAliasDialedDigits(call, p->callerid_num);
} else if (ast_strlen_zero(p->caller_h323id)) {
ooCallAddAliasH323ID(call, p->callerid_num);
}
}
if (!ast_strlen_zero(p->exten)) {
ooCallSetCalledPartyNumber(call, p->exten);
ooCallAddRemoteAliasDialedDigits(call, p->exten);
} else {
ooCallAddRemoteAliasH323ID(call, p->exten);
}
}
if (gH323Debug) {
Alexander Traud
committed
struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
ast_verb(0, " Outgoing call %s(%s) - Codec prefs - %s\n",
p->username?p->username:"NULL", call->callToken,
ast_format_cap_get_names(p->cap, &codec_buf));
}
ooh323c_set_capability_for_call(call, p->cap,
p->dtmfmode, p->dtmfcodec, p->t38support, p->g729onlyA);
configure_local_rtp(p, call);
ast_cond_signal(&p->rtpcond);
ast_mutex_unlock(&p->lock);
}
ast_mutex_unlock(&call->Lock);
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "+++ onNewCallCreated %s\n", call->callToken);
return OO_OK;
}
int onCallEstablished(ooCallData *call)
{
struct ooh323_pvt *p = NULL;
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "--- onCallEstablished %s\n", call->callToken);
if (!(p = find_call(call))) {
ast_log(LOG_ERROR, "Failed to find a matching call.\n");
return -1;
}
ast_mutex_lock(&p->lock);
if (!p->owner) {
ast_mutex_unlock(&p->lock);
ast_log(LOG_ERROR, "Channel has no owner\n");
return -1;
}
while (p->owner && ast_channel_trylock(p->owner)) {
ast_debug(1, "Failed to grab lock, trying again\n");
DEADLOCK_AVOIDANCE(&p->lock);
}
if (p->owner) {
struct ast_channel* c = p->owner;
if (call->remoteDisplayName) {
struct ast_party_connected_line connected;
struct ast_set_party_connected_line update_connected;
memset(&update_connected, 0, sizeof(update_connected));
update_connected.id.name = 1;
ast_party_connected_line_init(&connected);
connected.id.name.valid = 1;
connected.id.name.str = (char *) call->remoteDisplayName;
connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
ast_channel_queue_connected_line_update(c, &connected, &update_connected);
}
ast_queue_control(c, AST_CONTROL_ANSWER);
ast_channel_publish_snapshot(c);
ast_channel_unlock(p->owner);
ast_mutex_unlock(&p->lock);
}
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "+++ onCallEstablished %s\n", call->callToken);
return OO_OK;
}
int onCallCleared(ooCallData *call)
{
struct ooh323_pvt *p = NULL;
int ownerLock = 0;
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "--- onCallCleared %s \n", call->callToken);
if ((p = find_call(call))) {
ast_mutex_lock(&p->lock);
while (p->owner) {
if (ast_channel_trylock(p->owner)) {
ooTrace(OOTRCLVLINFO, "Failed to grab lock, trying again\n");
ast_debug(1, "Failed to grab lock, trying again\n");
} else {
}
}
if (ownerLock) {
if (!ast_test_flag(p, H323_ALREADYGONE)) {
ast_set_flag(p, H323_ALREADYGONE);
ast_channel_hangupcause_set(p->owner, call->q931cause);
ast_channel_softhangup_internal_flag_add(p->owner, AST_SOFTHANGUP_DEV);
ast_queue_hangup_with_cause(p->owner,call->q931cause);
ast_channel_tech_pvt_set(p->owner, NULL);
ast_channel_unlock(p->owner);
if (!p->rtp) {
ast_cond_signal(&p->rtpcond);
}
ast_set_flag(p, H323_NEEDDESTROY);
ast_mutex_unlock(&p->lock);
ast_mutex_lock(&usecnt_lock);
usecnt--;
ast_mutex_unlock(&usecnt_lock);
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "+++ onCallCleared\n");
return OO_OK;
}
/* static void ooh323_delete_user(struct ooh323_user *user)
{
struct ooh323_user *prev = NULL, *cur = NULL;
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "--- ooh323_delete_user\n");
cur = userl.users;
ast_mutex_lock(&userl.lock);
while (cur) {
if (cur == user) break;
prev = cur;
cur = cur->next;
}
if (cur) {
if (prev)
prev->next = cur->next;
else
userl.users = cur->next;
}
ast_mutex_unlock(&userl.lock);
ast_free(user);
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "+++ ooh323_delete_user\n");
void ooh323_delete_peer(struct ooh323_peer *peer)
{
struct ooh323_peer *prev = NULL, *cur = NULL;
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "--- ooh323_delete_peer\n");
ast_mutex_lock(&peerl.lock);
while(cur) {
if(cur==peer) break;
prev = cur;
cur = cur->next;
}
if (cur) {
prev->next = cur->next;
peerl.peers = cur->next;
}
ast_mutex_unlock(&peerl.lock);
ast_free(peer->h323id);
ast_free(peer->email);
ast_free(peer->url);
ast_free(peer->e164);
ao2_cleanup(peer->cap);
ast_free(peer);
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "+++ ooh323_delete_peer\n");
}
static struct ooh323_user *build_user(const char *name, struct ast_variable *v)
{
struct ooh323_user *user = NULL;
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "--- build_user\n");
user = ast_calloc(1,sizeof(struct ooh323_user));
if (user) {
memset(user, 0, sizeof(struct ooh323_user));
if (!(user->cap = ast_format_cap_alloc(0))) {
ast_free(user);
return NULL;
}
ast_mutex_init(&user->lock);
ast_copy_string(user->name, name, sizeof(user->name));
ast_format_cap_append_from_cap(user->cap, gCap, AST_MEDIA_TYPE_UNKNOWN);
user->rtptimeout = gRTPTimeout;
user->dtmfmode = gDTMFMode;
user->faxdetect = gFAXdetect;
user->faststart = gFastStart;
user->h245tunneling = gTunneling;
user->directrtp = gDirectRTP;
user->earlydirect = gEarlyDirect;
user->g729onlyA = g729onlyA;
/* set default context */
ast_copy_string(user->context, gContext, sizeof(user->context));
ast_copy_string(user->accountcode, gAccountcode, sizeof(user->accountcode));
user->amaflags = gAMAFLAGS;
while (v) {
if (!strcasecmp(v->name, "context")) {
ast_copy_string(user->context, v->value, sizeof(user->context));
} else if (!strcasecmp(v->name, "incominglimit")) {
user->incominglimit = atoi(v->value);
if (user->incominglimit < 0)
user->incominglimit = 0;
} else if (!strcasecmp(v->name, "accountcode")) {
ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
} else if (!strcasecmp(v->name, "roundtrip")) {
sscanf(v->value, "%d,%d", &user->rtdrcount, &user->rtdrinterval);
} else if (!strcasecmp(v->name, "faststart")) {
user->faststart = ast_true(v->value);
} else if (!strcasecmp(v->name, "h245tunneling")) {
user->h245tunneling = ast_true(v->value);
} else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
user->directrtp = ast_true(v->value);
user->earlydirect = ast_true(v->value);
} else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
user->earlydirect = ast_true(v->value);
} else if (!strcasecmp(v->name, "g729onlyA")) {
user->g729onlyA = ast_true(v->value);
} else if (!strcasecmp(v->name, "nat")) {
user->nat = ast_true(v->value);
} else if (!strcasecmp(v->name, "rtptimeout")) {
user->rtptimeout = atoi(v->value);
if (user->rtptimeout < 0)
user->rtptimeout = gRTPTimeout;
} else if (!strcasecmp(v->name, "rtpmask")) {
if ((user->rtpmask = ast_calloc(1, sizeof(struct OOH323Regex))) &&
(regcomp(&user->rtpmask->regex, v->value, REG_EXTENDED)
== 0)) {
ast_mutex_init(&user->rtpmask->lock);
user->rtpmask->inuse = 1;
ast_copy_string(user->rtpmaskstr, v->value,
sizeof(user->rtpmaskstr));
} else user->rtpmask = NULL;
} else if (!strcasecmp(v->name, "disallow")) {
ast_format_cap_update_by_allow_disallow(user->cap, v->value, 0);
} else if (!strcasecmp(v->name, "allow")) {
const char* tcodecs = v->value;
if (!strcasecmp(v->value, "all")) {
tcodecs = "ulaw,alaw,g729,g723,gsm";
}
ast_format_cap_update_by_allow_disallow(user->cap, tcodecs, 1);
} else if (!strcasecmp(v->name, "amaflags")) {
user->amaflags = ast_channel_string2amaflag(v->value);
} else if (!strcasecmp(v->name, "ip") || !strcasecmp(v->name, "host")) {
struct ast_sockaddr p;
if (!ast_parse_arg(v->value, PARSE_ADDR, &p)) {
ast_copy_string(user->mIP, ast_sockaddr_stringify_addr(&p), sizeof(user->mIP)-1);
ast_copy_string(user->mIP, v->value, sizeof(user->mIP)-1);
}
user->mUseIP = 1;
} else if (!strcasecmp(v->name, "dtmfmode")) {
if (!strcasecmp(v->value, "rfc2833"))
user->dtmfmode = H323_DTMF_RFC2833;
if (!strcasecmp(v->value, "cisco"))
user->dtmfmode = H323_DTMF_CISCO;
else if (!strcasecmp(v->value, "q931keypad"))
user->dtmfmode = H323_DTMF_Q931;
else if (!strcasecmp(v->value, "h245alphanumeric"))
user->dtmfmode = H323_DTMF_H245ALPHANUMERIC;
else if (!strcasecmp(v->value, "h245signal"))
user->dtmfmode = H323_DTMF_H245SIGNAL;
else if (!strcasecmp(v->value, "inband"))
user->dtmfmode = H323_DTMF_INBAND;
} else if (!strcasecmp(v->name, "relaxdtmf")) {
user->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
} else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
user->dtmfcodec = atoi(v->value);
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
} else if (!strcasecmp(v->name, "faxdetect")) {
if (ast_true(v->value)) {
user->faxdetect = FAXDETECT_CNG | FAXDETECT_T38;
} else if (ast_false(v->value)) {
user->faxdetect = 0;
} else {
char *buf = ast_strdupa(v->value);
char *word, *next = buf;
user->faxdetect = 0;
while ((word = strsep(&next, ","))) {
if (!strcasecmp(word, "cng")) {
user->faxdetect |= FAXDETECT_CNG;
} else if (!strcasecmp(word, "t38")) {
user->faxdetect |= FAXDETECT_T38;
} else {
ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
}
}
}
} else if (!strcasecmp(v->name, "t38support")) {
if (!strcasecmp(v->value, "disabled"))
user->t38support = T38_DISABLED;
if (!strcasecmp(v->value, "no"))
user->t38support = T38_DISABLED;
else if (!strcasecmp(v->value, "faxgw"))
user->t38support = T38_FAXGW;
else if (!strcasecmp(v->value, "yes"))
user->t38support = T38_ENABLED;
Alexandr Anikin
committed
} else if (!strcasecmp(v->name, "aniasdni")) {
user->aniasdni = ast_true(v->value);
}
v = v->next;
}
}
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "+++ build_user\n");
return user;
}
static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v, int friend_type)
{
struct ooh323_peer *peer = NULL;
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "--- build_peer\n");
peer = ast_calloc(1, sizeof(*peer));
if (peer) {
memset(peer, 0, sizeof(struct ooh323_peer));
if (!(peer->cap = ast_format_cap_alloc(0))) {
ast_free(peer);
return NULL;
}
ast_mutex_init(&peer->lock);
ast_copy_string(peer->name, name, sizeof(peer->name));
ast_format_cap_append_from_cap(peer->cap, gCap, AST_MEDIA_TYPE_UNKNOWN);
peer->rtptimeout = gRTPTimeout;
ast_copy_string(peer->accountcode, gAccountcode, sizeof(peer->accountcode));
peer->amaflags = gAMAFLAGS;
peer->dtmfmode = gDTMFMode;
peer->faxdetect = gFAXdetect;
peer->faststart = gFastStart;
peer->h245tunneling = gTunneling;
peer->directrtp = gDirectRTP;
peer->earlydirect = gEarlyDirect;
peer->g729onlyA = g729onlyA;
if (0 == friend_type) {
peer->mFriend = 1;
}
while (v) {
if (!strcasecmp(v->name, "h323id")) {
if (!(peer->h323id = ast_strdup(v->value))) {
ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
"peer %s\n", name);
ooh323_delete_peer(peer);
return NULL;
}
} else if (!strcasecmp(v->name, "e164")) {
Alexandr Anikin
committed
int valid = 1;
const char *tmp;
for(tmp = v->value; *tmp; tmp++) {
if (!isdigit(*tmp)) {
valid = 0;
break;
}
}
if (valid) {
if (!(peer->e164 = ast_strdup(v->value))) {
ast_log(LOG_ERROR, "Could not allocate memory for e164 of "
"peer %s\n", name);
Alexandr Anikin
committed
ooh323_delete_peer(peer);
return NULL;
}
} else {
ast_log(LOG_ERROR, "Invalid e164: %s for peer %s\n", v->value, name);
}
} else if (!strcasecmp(v->name, "email")) {
if (!(peer->email = ast_strdup(v->value))) {
ast_log(LOG_ERROR, "Could not allocate memory for email of "
"peer %s\n", name);
ooh323_delete_peer(peer);
return NULL;
}
} else if (!strcasecmp(v->name, "url")) {
if (!(peer->url = ast_strdup(v->value))) {
ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
"peer %s\n", name);
ooh323_delete_peer(peer);
return NULL;
}
} else if (!strcasecmp(v->name, "port")) {
peer->port = atoi(v->value);
} else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "ip")) {
struct ast_sockaddr p;
if (!ast_parse_arg(v->value, PARSE_ADDR, &p)) {
ast_copy_string(peer->ip, ast_sockaddr_stringify_host(&p), sizeof(peer->ip));
ast_copy_string(peer->ip, v->value, sizeof(peer->ip));
}
} else if (!strcasecmp(v->name, "outgoinglimit")) {
int val = atoi(v->value);
if (val < 0) {
peer->outgoinglimit = 0;
} else {
peer->outgoinglimit = val;
}
} else if (!strcasecmp(v->name, "accountcode")) {
ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
} else if (!strcasecmp(v->name, "faststart")) {
peer->faststart = ast_true(v->value);
} else if (!strcasecmp(v->name, "h245tunneling")) {
peer->h245tunneling = ast_true(v->value);
} else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
peer->directrtp = ast_true(v->value);
peer->earlydirect = ast_true(v->value);
} else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
peer->earlydirect = ast_true(v->value);
} else if (!strcasecmp(v->name, "g729onlyA")) {
peer->g729onlyA = ast_true(v->value);
} else if (!strcasecmp(v->name, "nat")) {
peer->nat = ast_true(v->value);
} else if (!strcasecmp(v->name, "rtptimeout")) {
peer->rtptimeout = atoi(v->value);
if(peer->rtptimeout < 0)
peer->rtptimeout = gRTPTimeout;
} else if (!strcasecmp(v->name, "rtpmask")) {
if ((peer->rtpmask = ast_calloc(1, sizeof(struct OOH323Regex))) &&
(regcomp(&peer->rtpmask->regex, v->value, REG_EXTENDED)
== 0)) {
ast_mutex_init(&peer->rtpmask->lock);
peer->rtpmask->inuse = 1;
ast_copy_string(peer->rtpmaskstr, v->value,
sizeof(peer->rtpmaskstr));
} else peer->rtpmask = NULL;
} else if (!strcasecmp(v->name, "disallow")) {
ast_format_cap_update_by_allow_disallow(peer->cap, v->value, 0);
} else if (!strcasecmp(v->name, "allow")) {
const char* tcodecs = v->value;
if (!strcasecmp(v->value, "all")) {
tcodecs = "ulaw,alaw,g729,g723,gsm";
}
ast_format_cap_update_by_allow_disallow(peer->cap, tcodecs, 1);
} else if (!strcasecmp(v->name, "amaflags")) {
peer->amaflags = ast_channel_string2amaflag(v->value);
} else if (!strcasecmp(v->name, "roundtrip")) {
sscanf(v->value, "%d,%d", &peer->rtdrcount, &peer->rtdrinterval);
} else if (!strcasecmp(v->name, "dtmfmode")) {
if (!strcasecmp(v->value, "rfc2833"))
peer->dtmfmode = H323_DTMF_RFC2833;
if (!strcasecmp(v->value, "cisco"))
peer->dtmfmode = H323_DTMF_CISCO;
else if (!strcasecmp(v->value, "q931keypad"))
peer->dtmfmode = H323_DTMF_Q931;
else if (!strcasecmp(v->value, "h245alphanumeric"))
peer->dtmfmode = H323_DTMF_H245ALPHANUMERIC;
else if (!strcasecmp(v->value, "h245signal"))
peer->dtmfmode = H323_DTMF_H245SIGNAL;
else if (!strcasecmp(v->value, "inband"))
peer->dtmfmode = H323_DTMF_INBAND;
} else if (!strcasecmp(v->name, "relaxdtmf")) {
peer->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
} else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
peer->dtmfcodec = atoi(v->value);
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
} else if (!strcasecmp(v->name, "faxdetect")) {
if (ast_true(v->value)) {
peer->faxdetect = FAXDETECT_CNG | FAXDETECT_T38;
} else if (ast_false(v->value)) {
peer->faxdetect = 0;
} else {
char *buf = ast_strdupa(v->value);
char *word, *next = buf;
peer->faxdetect = 0;
while ((word = strsep(&next, ","))) {
if (!strcasecmp(word, "cng")) {
peer->faxdetect |= FAXDETECT_CNG;
} else if (!strcasecmp(word, "t38")) {
peer->faxdetect |= FAXDETECT_T38;
} else {
ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
}
}
}
} else if (!strcasecmp(v->name, "t38support")) {
if (!strcasecmp(v->value, "disabled"))
peer->t38support = T38_DISABLED;
if (!strcasecmp(v->value, "no"))
peer->t38support = T38_DISABLED;
else if (!strcasecmp(v->value, "faxgw"))
peer->t38support = T38_FAXGW;
else if (!strcasecmp(v->value, "yes"))
peer->t38support = T38_ENABLED;
}
v = v->next;
}
}
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "+++ build_peer\n");
return peer;
}
static int ooh323_do_reload(void)
{
Alexandr Anikin
committed
struct ooAliases * pNewAlias = NULL;
struct ooh323_peer *peer = NULL;
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, "--- ooh323_do_reload\n");
}
/* Gatekeeper */
if (gH323ep.gkClient) {
ooGkClientDestroy();
}
/* Gatekeeper */
if (gRasGkMode == RasUseSpecificGatekeeper ||
gRasGkMode == RasDiscoverGatekeeper) {
ooGkClientInit(gRasGkMode, (gRasGkMode == RasUseSpecificGatekeeper) ?
gGatekeeper : 0, gRASIP, 0);
ooGkClientStart(gH323ep.gkClient);
}
Alexandr Anikin
committed
/* Set aliases if any */
if (gH323Debug) {
ast_verb(0, "updating local aliases\n");
}
for (pNewAlias = gAliasList; pNewAlias; pNewAlias = pNewAlias->next) {
switch (pNewAlias->type) {
case T_H225AliasAddress_h323_ID:
ooH323EpAddAliasH323ID(pNewAlias->value);
break;
case T_H225AliasAddress_dialedDigits:
Alexandr Anikin
committed
ooH323EpAddAliasDialedDigits(pNewAlias->value);
break;
case T_H225AliasAddress_email_ID:
Alexandr Anikin
committed
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
ooH323EpAddAliasEmailID(pNewAlias->value);
break;
default:
;
}
}
ast_mutex_lock(&peerl.lock);
peer = peerl.peers;
while (peer) {
if(peer->h323id) {
ooH323EpAddAliasH323ID(peer->h323id);
}
if(peer->email) {
ooH323EpAddAliasEmailID(peer->email);
}
if(peer->e164) {
ooH323EpAddAliasDialedDigits(peer->e164);
}
if(peer->url) {
ooH323EpAddAliasURLID(peer->url);
}
peer = peer->next;
}
ast_mutex_unlock(&peerl.lock);
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, "+++ ooh323_do_reload\n");
}
return 0;
}
/*--- h323_reload: Force reload of module from cli ---*/
char *handle_cli_ooh323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
switch (cmd) {
case CLI_INIT:
e->command = "ooh323 reload";
e->usage =
"Usage: ooh323 reload\n"
" Reload OOH323 config.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != 2)
return CLI_SHOWUSAGE;
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "--- ooh323_reload\n");
ast_mutex_lock(&h323_reload_lock);
if (h323_reloading) {
Tilghman Lesher
committed
ast_verb(0, "Previous OOH323 reload not yet done\n");
h323_reloading = 1;
}
ast_mutex_unlock(&h323_reload_lock);
restart_monitor();
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "+++ ooh323_reload\n");
return 0;
}
int reload_config(int reload)
{
int format;
struct ooAliases *pNewAlias = NULL, *cur, *prev;
struct ast_config *cfg;
struct ast_variable *v;
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
struct ooh323_user *user = NULL;
struct ooh323_peer *peer = NULL;
char *cat;
const char *utype;
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "--- reload_config\n");
cfg = ast_config_load((char*)config, config_flags);
/* We *must* have a config file otherwise stop immediately */
if (!cfg) {
ast_log(LOG_NOTICE, "Unable to load config %s, OOH323 disabled\n", config);
return 1;
} else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
return RESULT_SUCCESS;
if (reload) {
delete_users();
delete_peers();
Tilghman Lesher
committed
ast_verb(0, " reload_config - Freeing up alias list\n");
}
cur = gAliasList;
while (cur) {
prev = cur;
cur = cur->next;
ast_free(prev->value);
ast_free(prev);
Alexandr Anikin
committed
ooH323EpClearAllAliases();
}
/* Inintialize everything to default */
snprintf(gLogFile, sizeof(gLogFile), "%s/%s", ast_config_AST_LOG_DIR, DEFAULT_LOGFILE);
gPort = 1720;
gIP[0] = '\0';
strcpy(gCallerID, DEFAULT_H323ID);
ast_format_cap_remove_by_type(gCap, AST_MEDIA_TYPE_UNKNOWN);
ast_format_cap_append(gCap, ast_format_ulaw, 0);
gDTMFMode = H323_DTMF_RFC2833;
gT38Support = T38_FAXGW;
gTRCLVL = OOTRCLVLERR;
gRasGkMode = RasNoGatekeeper;
gGatekeeper[0] = '\0';
gRTPTimeout = 60;
gRTDRInterval = 0;
gRTDRCount = 0;
strcpy(gAccountcode, DEFAULT_H323ACCNT);
gFastStart = 1;
gTunneling = 1;
gTOS = 0;
strcpy(gContext, DEFAULT_CONTEXT);
gAliasList = NULL;
gMediaWaitForConnect = 0;
ooconfig.mTCPPortStart = 12030;
ooconfig.mTCPPortEnd = 12230;
memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
v = ast_variable_browse(cfg, "general");
while (v) {
if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
v = v->next;
continue;
}
if (!strcasecmp(v->name, "port")) {
gPort = (int)strtol(v->value, NULL, 10);
} else if (!strcasecmp(v->name, "bindaddr")) {
ast_copy_string(gIP, v->value, sizeof(gIP));
if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) {
ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
ast_config_destroy(cfg);
return 1;
}
if (ast_sockaddr_is_ipv6(&bindaddr)) {
v6mode = 1;
}
} else if (!strcasecmp(v->name, "h225portrange")) {
char* endlimit = 0;
ast_copy_string(temp, v->value, sizeof(temp));
endlimit = strchr(temp, ',');
if (endlimit) {
*endlimit = '\0';
endlimit++;
ooconfig.mTCPPortStart = atoi(temp);
ooconfig.mTCPPortEnd = atoi(endlimit);
} else {
ast_log(LOG_ERROR, "h225portrange: Invalid format, separate port range with \",\"\n");
}
} else if (!strcasecmp(v->name, "gateway")) {
gIsGateway = ast_true(v->value);
} else if (!strcasecmp(v->name, "faststart")) {
gFastStart = ast_true(v->value);
if (gFastStart)
ooH323EpEnableFastStart();
else
ooH323EpDisableFastStart();
} else if (!strcasecmp(v->name, "mediawaitforconnect")) {
gMediaWaitForConnect = ast_true(v->value);
if (gMediaWaitForConnect)
ooH323EpEnableMediaWaitForConnect();
ooH323EpDisableMediaWaitForConnect();
} else if (!strcasecmp(v->name, "h245tunneling")) {
gTunneling = ast_true(v->value);
if (gTunneling)
ooH323EpEnableH245Tunneling();
else
ooH323EpDisableH245Tunneling();
} else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
gDirectRTP = ast_true(v->value);
gEarlyDirect = ast_true(v->value);
} else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
gEarlyDirect = ast_true(v->value);
} else if (!strcasecmp(v->name, "g729onlyA")) {
g729onlyA = ast_true(v->value);
} else if (!strcasecmp(v->name, "roundtrip")) {
sscanf(v->value, "%d,%d", &gRTDRCount, &gRTDRInterval);
} else if (!strcasecmp(v->name, "trybemaster")) {
gBeMaster = ast_true(v->value);
if (gBeMaster)
ooH323EpTryBeMaster(1);
} else if (!strcasecmp(v->name, "h323id")) {
pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
if (!pNewAlias) {
ast_log(LOG_ERROR, "Failed to allocate memory for h323id alias\n");
ast_config_destroy(cfg);
return 1;
}
if (gAliasList == NULL) { /* first h323id - set as callerid if callerid is not set */
ast_copy_string(gCallerID, v->value, sizeof(gCallerID));
}
pNewAlias->type = T_H225AliasAddress_h323_ID;
pNewAlias->value = ast_strdup(v->value);
pNewAlias->next = gAliasList;
gAliasList = pNewAlias;
pNewAlias = NULL;
} else if (!strcasecmp(v->name, "e164")) {
Alexandr Anikin
committed
int valid = 1;
const char *tmp;
for(tmp = v->value; *tmp; tmp++) {
if (!isdigit(*tmp)) {
valid = 0;
break;
}
}
if (valid) {
pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
if (!pNewAlias) {
ast_log(LOG_ERROR, "Failed to allocate memory for e164 alias\n");
ast_config_destroy(cfg);
return 1;
}
pNewAlias->type = T_H225AliasAddress_dialedDigits;
pNewAlias->value = ast_strdup(v->value);
Alexandr Anikin
committed
pNewAlias->next = gAliasList;
gAliasList = pNewAlias;
pNewAlias = NULL;
} else {
ast_log(LOG_ERROR, "Invalid e164: %s\n", v->value);
}
} else if (!strcasecmp(v->name, "email")) {
pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
if (!pNewAlias) {
ast_log(LOG_ERROR, "Failed to allocate memory for email alias\n");
ast_config_destroy(cfg);
return 1;
}
pNewAlias->type = T_H225AliasAddress_email_ID;
pNewAlias->value = ast_strdup(v->value);