diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-02-17 22:16:14 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-02-17 22:16:14 +0000 |
commit | ee5e2548fb13a2eacb92c80168310f46d4d7579c (patch) | |
tree | 8a168fe4e80fbbf5480cb2df8112e0bb81ca2d77 /channels | |
parent | d07601c72aefa87b7791ba67220cc6d5c9410604 (diff) |
Use call numbers instead of pointers in IAX2
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@2186 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rwxr-xr-x | channels/chan_iax2.c | 205 |
1 files changed, 108 insertions, 97 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index cbde7d9f2..cd4eee6bb 100755 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -71,6 +71,8 @@ #define BRIDGE_OPTIMIZATION +#define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) +#define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a)) #define DEFAULT_RETRY_TIME 1000 #define MEMORY_SIZE 100 @@ -480,7 +482,7 @@ static struct timeval lastused[IAX_MAX_CALLS]; static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, char *, int, int); -static int send_command_locked(struct chan_iax2_pvt *, char, int, unsigned int, char *, int, int); +static int send_command_locked(unsigned short callno, char, int, unsigned int, char *, int, int); static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, char *, int, int); static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, char *, int, int); static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, char *, int); @@ -1499,30 +1501,35 @@ static int iax2_transmit(struct iax_frame *fr) static int iax2_digit(struct ast_channel *c, char digit) { - return send_command_locked(c->pvt->pvt, AST_FRAME_DTMF, digit, 0, NULL, 0, -1); + return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_DTMF, digit, 0, NULL, 0, -1); } static int iax2_sendtext(struct ast_channel *c, char *text) { - return send_command_locked(c->pvt->pvt, AST_FRAME_TEXT, + return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_TEXT, 0, 0, text, strlen(text) + 1, -1); } static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img) { - return send_command_locked(c->pvt->pvt, AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); + return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); } static int iax2_sendhtml(struct ast_channel *c, int subclass, char *data, int datalen) { - return send_command_locked(c->pvt->pvt, AST_FRAME_HTML, subclass, 0, data, datalen, -1); + return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_HTML, subclass, 0, data, datalen, -1); } static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan) { - struct chan_iax2_pvt *pvt = newchan->pvt->pvt; - pvt->owner = newchan; + unsigned short callno = PTR_TO_CALLNO(newchan->pvt->pvt); + ast_mutex_lock(&iaxsl[callno]); + if (iaxs[callno]) + iaxs[callno]->owner = newchan; + else + ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); + ast_mutex_unlock(&iaxsl[callno]); return 0; } @@ -1747,7 +1754,7 @@ static int create_addr(struct sockaddr_in *sin, int *capability, int *sendani, i static int auto_congest(void *nothing) { - int callno = (int)(long)(nothing); + int callno = PTR_TO_CALLNO(nothing); struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; ast_mutex_lock(&iaxsl[callno]); if (iaxs[callno]) { @@ -1791,7 +1798,7 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout) char context[AST_MAX_EXTENSION] =""; char *portno = NULL; char *opts = ""; - struct chan_iax2_pvt *p = c->pvt->pvt; + unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt); char *stringp=NULL; char storedsecret[80]; if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { @@ -1863,7 +1870,7 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout) iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); if (n) iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); - if (p->sendani && c->ani) { + if (iaxs[callno]->sendani && c->ani) { l = n = NULL; strncpy(cid, c->ani, sizeof(cid) - 1); ast_callerid_parse(cid, &n, &l); @@ -1882,18 +1889,19 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout) iax_ie_append_str(&ied, IAX_IE_USERNAME, username); if (!secret && strlen(storedsecret)) secret = storedsecret; + ast_mutex_lock(&iaxsl[callno]); if (secret) { if (secret[0] == '[') { /* This is an RSA key, not a normal secret */ - strncpy(p->outkey, secret + 1, sizeof(p->secret)-1); - if (strlen(p->outkey)) { - p->outkey[strlen(p->outkey) - 1] = '\0'; + strncpy(iaxs[callno]->outkey, secret + 1, sizeof(iaxs[callno]->secret)-1); + if (strlen(iaxs[callno]->outkey)) { + iaxs[callno]->outkey[strlen(iaxs[callno]->outkey) - 1] = '\0'; } } else - strncpy(p->secret, secret, sizeof(p->secret)-1); + strncpy(iaxs[callno]->secret, secret, sizeof(iaxs[callno]->secret)-1); } iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); - iax_ie_append_int(&ied, IAX_IE_CAPABILITY, p->capability); + iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime()); /* Transmit the string in a "NEW" request */ @@ -1902,13 +1910,14 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout) if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Calling using options '%s'\n", requeststr); #endif - if (p->maxtime) { + if (iaxs[callno]->maxtime) { /* Initialize pingtime and auto-congest time */ - p->pingtime = p->maxtime / 2; - p->initid = ast_sched_add(sched, p->maxtime * 2, auto_congest, (void *)(long)p->callno); + iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; + iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); } - send_command_locked(p, AST_FRAME_IAX, + send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); + ast_mutex_unlock(&iaxsl[callno]); ast_setstate(c, AST_STATE_RINGING); return 0; } @@ -1916,16 +1925,15 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout) static int iax2_hangup(struct ast_channel *c) { struct chan_iax2_pvt *pvt = c->pvt->pvt; + unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt); int alreadygone; - int callno; - if (pvt) { - callno = pvt->callno; - ast_mutex_lock(&iaxsl[callno]); + ast_mutex_lock(&iaxsl[callno]); + if (callno && iaxs[callno]) { ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name); - alreadygone = pvt->alreadygone; + alreadygone = iaxs[callno]->alreadygone; /* Send the hangup unless we have had a transmission error or are already gone */ if (!pvt->error && !alreadygone) - send_command_final(pvt, AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, NULL, 0, -1); + send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, NULL, 0, -1); /* Explicitly predestroy it */ iax2_predestroy_nolock(callno); /* If we were already gone to begin with, destroy us now */ @@ -1933,8 +1941,8 @@ static int iax2_hangup(struct ast_channel *c) ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); iax2_destroy_nolock(callno); } - ast_mutex_unlock(&iaxsl[callno]); } + ast_mutex_unlock(&iaxsl[callno]); if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); return 0; @@ -1949,7 +1957,7 @@ static int iax2_setoption(struct ast_channel *c, int option, void *data, int dat h->flag = AST_OPTION_FLAG_REQUEST; h->option = htons(option); memcpy(h->data, data, datalen); - res = send_command_locked((struct chan_iax2_pvt *)c->pvt->pvt, AST_FRAME_CONTROL, + res = send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_CONTROL, AST_CONTROL_OPTION, 0, (char *)h, datalen + sizeof(struct ast_option_header), -1); free(h); return res; @@ -1957,6 +1965,7 @@ static int iax2_setoption(struct ast_channel *c, int option, void *data, int dat ast_log(LOG_WARNING, "Out of memory\n"); return -1; } + static struct ast_frame *iax2_read(struct ast_channel *c) { static struct ast_frame f = { AST_FRAME_NULL, }; @@ -1964,49 +1973,47 @@ static struct ast_frame *iax2_read(struct ast_channel *c) return &f; } -static int iax2_start_transfer(struct ast_channel *c0, struct ast_channel *c1) +static int iax2_start_transfer(unsigned short callno0, unsigned short callno1) { int res; struct iax_ie_data ied0; struct iax_ie_data ied1; - struct chan_iax2_pvt *p0 = c0->pvt->pvt; - struct chan_iax2_pvt *p1 = c1->pvt->pvt; unsigned int transferid = rand(); memset(&ied0, 0, sizeof(ied0)); - iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &p1->addr); - iax_ie_append_short(&ied0, IAX_IE_CALLNO, p1->peercallno); + iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); + iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); memset(&ied1, 0, sizeof(ied1)); - iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &p0->addr); - iax_ie_append_short(&ied1, IAX_IE_CALLNO, p0->peercallno); + iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); + iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); - res = send_command(p0, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); + res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); if (res) return -1; - res = send_command(p1, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); + res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); if (res) return -1; - p0->transferring = TRANSFER_BEGIN; - p1->transferring = TRANSFER_BEGIN; + iaxs[callno0]->transferring = TRANSFER_BEGIN; + iaxs[callno1]->transferring = TRANSFER_BEGIN; return 0; } -static void lock_both(struct chan_iax2_pvt *p0, struct chan_iax2_pvt *p1) +static void lock_both(unsigned short callno0, unsigned short callno1) { - ast_mutex_lock(&iaxsl[p0->callno]); - while (ast_mutex_trylock(&iaxsl[p1->callno])) { - ast_mutex_unlock(&iaxsl[p0->callno]); + ast_mutex_lock(&iaxsl[callno0]); + while (ast_mutex_trylock(&iaxsl[callno1])) { + ast_mutex_unlock(&iaxsl[callno0]); usleep(10); - ast_mutex_lock(&iaxsl[p0->callno]); + ast_mutex_lock(&iaxsl[callno0]); } } -static void unlock_both(struct chan_iax2_pvt *p0, struct chan_iax2_pvt *p1) +static void unlock_both(unsigned short callno0, unsigned short callno1) { - ast_mutex_unlock(&iaxsl[p1->callno]); - ast_mutex_unlock(&iaxsl[p0->callno]); + ast_mutex_unlock(&iaxsl[callno1]); + ast_mutex_unlock(&iaxsl[callno0]); } static int iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc) @@ -2017,15 +2024,15 @@ static int iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags int res = -1; int transferstarted=0; struct ast_frame *f; - struct chan_iax2_pvt *p0 = c0->pvt->pvt; - struct chan_iax2_pvt *p1 = c1->pvt->pvt; + unsigned short callno0 = PTR_TO_CALLNO(c0->pvt->pvt); + unsigned short callno1 = PTR_TO_CALLNO(c1->pvt->pvt); struct timeval waittimer = {0, 0}, tv; - lock_both(p0, p1); + lock_both(callno0, callno1); /* Put them in native bridge mode */ - p0->bridgecallno = p1->callno; - p1->bridgecallno = p0->callno; - unlock_both(p0, p1); + iaxs[callno0]->bridgecallno = callno1; + iaxs[callno1]->bridgecallno = callno0; + unlock_both(callno0, callno1); /* If not, try to bridge until we can execute a transfer, if we can */ cs[0] = c0; @@ -2037,34 +2044,34 @@ static int iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); /* Remove from native mode */ if (c0->type == type) { - ast_mutex_lock(&iaxsl[p0->callno]); - p0->bridgecallno = 0; - ast_mutex_unlock(&iaxsl[p0->callno]); + ast_mutex_lock(&iaxsl[callno0]); + iaxs[callno0]->bridgecallno = 0; + ast_mutex_unlock(&iaxsl[callno0]); } if (c1->type == type) { - ast_mutex_lock(&iaxsl[p1->callno]); - p1->bridgecallno = 0; - ast_mutex_unlock(&iaxsl[p1->callno]); + ast_mutex_lock(&iaxsl[callno1]); + iaxs[callno1]->bridgecallno = 0; + ast_mutex_unlock(&iaxsl[callno1]); } return -2; } if (c0->nativeformats != c1->nativeformats) { ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs, can't native bridge...\n"); /* Remove from native mode */ - lock_both(p0, p1); - p0->bridgecallno = 0; - p1->bridgecallno = 0; - unlock_both(p0, p1); + lock_both(callno0, callno1); + iaxs[callno0]->bridgecallno = 0; + iaxs[callno1]->bridgecallno = 0; + unlock_both(callno0, callno1); return -2; } /* check if transfered and if we really want native bridging */ - if (!transferstarted && !p0->notransfer && !p1->notransfer) { + if (!transferstarted && !iaxs[callno0]->notransfer && !iaxs[callno1]->notransfer) { /* Try the transfer */ - if (iax2_start_transfer(c0, c1)) + if (iax2_start_transfer(callno0, callno1)) ast_log(LOG_WARNING, "Unable to start the transfer\n"); transferstarted = 1; } - if ((p0->transferring == TRANSFER_RELEASED) && (p1->transferring == TRANSFER_RELEASED)) { + if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { /* Call has been transferred. We're no longer involved */ gettimeofday(&tv, NULL); if (!waittimer.tv_sec && !waittimer.tv_usec) { @@ -2150,32 +2157,32 @@ tackygoto: cs[0] = cs[1]; cs[1] = cs[2]; } - lock_both(p0, p1); - p0->bridgecallno = 0; - p1->bridgecallno = 0; - unlock_both(p0, p1); + lock_both(callno0, callno1); + iaxs[callno0]->bridgecallno = 0; + iaxs[callno1]->bridgecallno = 0; + unlock_both(callno0, callno1); return res; } static int iax2_answer(struct ast_channel *c) { - struct chan_iax2_pvt *pvt = c->pvt->pvt; + unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt); if (option_debug) ast_log(LOG_DEBUG, "Answering\n"); - return send_command(pvt, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); + return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); } static int iax2_indicate(struct ast_channel *c, int condition) { - struct chan_iax2_pvt *pvt = c->pvt->pvt; + unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt); if (option_debug) ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); - return send_command(pvt, AST_FRAME_CONTROL, condition, 0, NULL, 0, -1); + return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, NULL, 0, -1); } static int iax2_transfer(struct ast_channel *c, char *dest) { - struct chan_iax2_pvt *pvt = c->pvt->pvt; + unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt); struct iax_ie_data ied; char tmp[256] = "", *context; strncpy(tmp, dest, sizeof(tmp) - 1); @@ -2190,7 +2197,7 @@ static int iax2_transfer(struct ast_channel *c, char *dest) iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); if (option_debug) ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); - return send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); + return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); } @@ -2769,27 +2776,31 @@ static struct ast_cli_entry cli_no_debug = static int iax2_write(struct ast_channel *c, struct ast_frame *f) { - struct chan_iax2_pvt *i = c->pvt->pvt; - if (!i) - return -1; + unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt); + int res = -1; + ast_mutex_lock(&iaxsl[callno]); + if (iaxs[callno]) { /* If there's an outstanding error, return failure now */ - if (i->error) { - ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); - return -1; + if (!iaxs[callno]->error) { + if (iaxs[callno]->alreadygone) + res = 0; + /* Don't waste bandwidth sending null frames */ + else if (f->frametype == AST_FRAME_NULL) + res = 0; + else if ((f->frametype == AST_FRAME_VOICE) && iaxs[callno]->quelch) + res = 0; + else if (!(iaxs[callno]->state & IAX_STATE_STARTED)) + res = 0; + else + /* Simple, just queue for transmission */ + res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); + } else { + ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); + } } /* If it's already gone, just return */ - if (i->alreadygone) - return 0; - /* Don't waste bandwidth sending null frames */ - if (f->frametype == AST_FRAME_NULL) - return 0; - /* If we're quelching voice, don't bother sending it */ - if ((f->frametype == AST_FRAME_VOICE) && i->quelch) - return 0; - if (!(i->state & IAX_STATE_STARTED)) - return 0; - /* Simple, just queue for transmission */ - return iax2_send(i, f, 0, -1, 0, 0, 0); + ast_mutex_unlock(&iaxsl[callno]); + return res; } static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, char *data, int datalen, int seqno, @@ -2812,12 +2823,12 @@ static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigne return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); } -static int send_command_locked(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, char *data, int datalen, int seqno) +static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, char *data, int datalen, int seqno) { int res; - ast_mutex_lock(&iaxsl[i->callno]); - res = send_command(i, type, command, ts, data, datalen, seqno); - ast_mutex_unlock(&iaxsl[i->callno]); + ast_mutex_lock(&iaxsl[callno]); + res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); + ast_mutex_unlock(&iaxsl[callno]); return res; } |