Index: asterisk/channel.c =================================================================== RCS file: /usr/cvsroot/asterisk/channel.c,v retrieving revision 1.243 diff -u -r1.243 channel.c --- asterisk/channel.c 29 Sep 2005 17:40:24 -0000 1.243 +++ asterisk/channel.c 3 Oct 2005 17:30:10 -0000 @@ -273,6 +273,31 @@ return; } +/*--- ast_channel_cmpwhentohangup: Compare a offset with when to hangup channel */ +int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset) +{ + time_t whentohangup; + + if (chan->whentohangup == 0) { + if (offset == 0) + return (0); + else + return (-1); + } else { + if (offset == 0) + return (1); + else { + whentohangup = offset + time (NULL); + if (chan->whentohangup < whentohangup) + return (1); + else if (chan->whentohangup == whentohangup) + return (0); + else + return (-1); + } + } +} + /*--- ast_channel_register: Register a new telephony channel in Asterisk */ int ast_channel_register(const struct ast_channel_tech *tech) { Index: asterisk/channels/chan_sip.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v retrieving revision 1.872 diff -u -r1.872 chan_sip.c --- asterisk/channels/chan_sip.c 29 Sep 2005 17:41:00 -0000 1.872 +++ asterisk/channels/chan_sip.c 3 Oct 2005 17:30:11 -0000 @@ -637,6 +637,7 @@ #ifdef OSP_SUPPORT int osphandle; /* OSP Handle for call */ time_t ospstart; /* OSP Start time */ + unsigned int osptimelimit; /* OSP call duration limit */ #endif struct sip_request initreq; /* Initial request */ @@ -2666,6 +2667,10 @@ struct ast_channel *tmp; struct ast_variable *v = NULL; int fmt; +#ifdef OSP_SUPPORT + char iabuf[INET_ADDRSTRLEN]; + char peer[MAXHOSTNAMELEN]; +#endif ast_mutex_unlock(&i->lock); /* Don't hold a sip pvt lock while we allocate a channel */ @@ -2757,6 +2762,10 @@ if (!ast_strlen_zero(i->callid)) { pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid); } +#ifdef OSP_SUPPORT + snprintf(peer, sizeof(peer), "[%s]:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), i->sa.sin_addr), ntohs(i->sa.sin_port)); + pbx_builtin_setvar_helper(tmp, "OSPPEER", peer); +#endif ast_setstate(tmp, state); if (state != AST_STATE_DOWN) { if (ast_pbx_start(tmp)) { @@ -2975,6 +2984,7 @@ p->timer_t1 = 500; /* Default SIP retransmission timer T1 (RFC 3261) */ #ifdef OSP_SUPPORT p->osphandle = -1; + p->osptimelimit = 0; #endif if (sin) { memcpy(&p->sa, sin, sizeof(p->sa)); @@ -5957,6 +5967,22 @@ list_route(p->route); } +#ifdef OSP_SUPPORT +/*--- check_osptoken: Validate OSP token for user authrroization ---*/ +static int check_osptoken (struct sip_pvt *p, char *token) +{ + char tmp[80]; + + if (ast_osp_validate (NULL, token, &p->osphandle, &p->osptimelimit, p->cid_num, p->sa.sin_addr, p->exten) < 1) { + return (-1); + } else { + snprintf (tmp, sizeof (tmp), "%d", p->osphandle); + pbx_builtin_setvar_helper (p->owner, "_OSPHANDLE", tmp); + return (0); + } +} +#endif + /*--- check_auth: Check user authorization from peer definition ---*/ /* Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set) */ @@ -5968,9 +5994,7 @@ char *respheader = "Proxy-Authenticate"; char *authtoken; #ifdef OSP_SUPPORT - char tmp[80]; char *osptoken; - unsigned int osptimelimit; #endif /* Always OK if no secret */ if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret) @@ -6002,14 +6026,7 @@ } } else { - if (ast_osp_validate (NULL, osptoken, &p->osphandle, &osptimelimit, p->cid_num, p->sa.sin_addr, p->exten) < 1) { - return (-1); - } - else { - snprintf (tmp, sizeof (tmp), "%d", p->osphandle); - pbx_builtin_setvar_helper (p->owner, "_OSPHANDLE", tmp); - return (0); - } + return (check_osptoken (p, osptoken)); } break; case SIP_OSPAUTH_PROXY: @@ -6017,14 +6034,7 @@ return (0); } else { - if (ast_osp_validate (NULL, osptoken, &p->osphandle, &osptimelimit, p->cid_num, p->sa.sin_addr, p->exten) < 1) { - return (-1); - } - else { - snprintf (tmp, sizeof (tmp), "%d", p->osphandle); - pbx_builtin_setvar_helper (p->owner, "_OSPHANDLE", tmp); - return (0); - } + return (check_osptoken (p, osptoken)); } break; case SIP_OSPAUTH_EXCLUSIVE: @@ -6032,14 +6042,7 @@ return (-1); } else { - if (ast_osp_validate (NULL, osptoken, &p->osphandle, &osptimelimit, p->cid_num, p->sa.sin_addr, p->exten) < 1) { - return (-1); - } - else { - snprintf (tmp, sizeof (tmp), "%d", p->osphandle); - pbx_builtin_setvar_helper (p->owner, "_OSPHANDLE", tmp); - return (0); - } + return (check_osptoken (p, osptoken)); } break; default: @@ -10238,6 +10241,9 @@ if (!ignore && p) p->lastinvite = seqno; if (c) { +#ifdef OSP_SUPPORT + ast_channel_setwhentohangup (c, p->osptimelimit); +#endif switch(c->_state) { case AST_STATE_DOWN: transmit_response(p, "100 Trying", req); Index: asterisk/include/asterisk/channel.h =================================================================== RCS file: /usr/cvsroot/asterisk/include/asterisk/channel.h,v retrieving revision 1.102 diff -u -r1.102 channel.h --- asterisk/include/asterisk/channel.h 26 Sep 2005 17:17:56 -0000 1.102 +++ asterisk/include/asterisk/channel.h 3 Oct 2005 17:30:11 -0000 @@ -562,6 +562,18 @@ */ int ast_check_hangup(struct ast_channel *chan); +/*! Compare a offset with the settings of when to hang a channel up */ +/*! + * \param chan channel on which to check for hang up + * \param offset offset in seconds from current time + * \return 1, 0, or -1 + * This function compares a offset from current time with the absolute time + * out on a channel (when to hang up). If the absolute time out on a channel + * is earlier than current time plus the offset, it returns 1, if the two + * time values are equal, it return 0, otherwise, it retturn -1. + */ +int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset); + /*! Set when to hang a channel up */ /*! * \param chan channel on which to check for hang up Index: asterisk/res/res_osp.c =================================================================== RCS file: /usr/cvsroot/asterisk/res/res_osp.c,v retrieving revision 1.23 diff -u -r1.23 res_osp.c --- asterisk/res/res_osp.c 14 Sep 2005 21:24:50 -0000 1.23 +++ asterisk/res/res_osp.c 3 Oct 2005 17:30:11 -0000 @@ -521,7 +521,6 @@ int tokenlen; unsigned int dummy=0; unsigned int timelimit; - char* sipcallid; unsigned int callidlen; char callidstr[OSPC_CALLID_MAXSIZE] = ""; struct osp_provider *osp; @@ -531,9 +530,9 @@ char destination[2048]=""; char token[2000]; char tmp[256]="", *l, *n; - OSPTCALLID *callid; OSPE_DEST_PROT prot; OSPE_DEST_OSP_ENABLED ospenabled; + char *devinfo = NULL; result->handle = -1; result->numresults = 0; @@ -558,8 +557,6 @@ callerid = l; if (chan) { - sipcallid = pbx_builtin_getvar_helper (chan, "SIPCALLID"); - ast_copy_string(callidstr, sipcallid, sizeof(callidstr)); cres = ast_autoservice_start(chan); if (cres < 0) return cres; @@ -581,67 +578,71 @@ ast_mutex_unlock(&osplock); if (res) { res = 0; - callid = OSPPCallIdNew(strlen(callidstr), callidstr); - if (callid) { - /* No more than 10 back */ - counts = 10; - dummy = 0; - callidlen = sizeof(callidstr); - if (!OSPPTransactionRequestAuthorisation(result->handle, source, "", - callerid,OSPC_E164, extension, OSPC_E164, NULL, 1, &callid, NULL, &counts, &dummy, NULL)) { - if (counts) { - tokenlen = sizeof(token); - result->numresults = counts - 1; - if (!OSPPTransactionGetFirstDestination(result->handle, 0, NULL, NULL, &timelimit, &callidlen, callidstr, - sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) { - ast_log(LOG_DEBUG, "Got destination '%s' and called: '%s' calling: '%s' for '%s' (provider '%s')\n", - destination, callednum, callingnum, extension, provider); - ast_channel_setwhentohangup (chan, timelimit); /* Only support OSP server with only one duration limit */ - do { - if (!OSPPTransactionIsDestOSPEnabled (result->handle, &ospenabled) && (ospenabled == OSPE_OSP_FALSE)) { - result->token[0] = 0; - } - else { - ast_base64encode(result->token, token, tokenlen, sizeof(result->token) - 1); + /* No more than 10 back */ + counts = 10; + dummy = 0; + devinfo = pbx_builtin_getvar_helper (chan, "OSPPEER"); + if (!devinfo) { + devinfo = ""; + } + if (!OSPPTransactionRequestAuthorisation(result->handle, source, devinfo, + callerid,OSPC_E164, extension, OSPC_E164, NULL, 0, NULL, NULL, &counts, &dummy, NULL)) { + if (counts) { + tokenlen = sizeof(token); + result->numresults = counts - 1; + callidlen = sizeof(callidstr); + if (!OSPPTransactionGetFirstDestination(result->handle, 0, NULL, NULL, &timelimit, &callidlen, callidstr, + sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) { + ast_log(LOG_DEBUG, "Got destination '%s' and called: '%s' calling: '%s' for '%s' (provider '%s')\n", + destination, callednum, callingnum, extension, provider); + /* Only support OSP server with only one duration limit */ + if (ast_channel_cmpwhentohangup (chan, timelimit) < 0) { + ast_channel_setwhentohangup (chan, timelimit); + } + do { + if (!OSPPTransactionIsDestOSPEnabled (result->handle, &ospenabled) && (ospenabled == OSPE_OSP_FALSE)) { + result->token[0] = 0; + } + else { + ast_base64encode(result->token, token, tokenlen, sizeof(result->token) - 1); + } + if ((strlen(destination) > 2) && !OSPPTransactionGetDestProtocol(result->handle, &prot)) { + res = 1; + /* Strip leading and trailing brackets */ + destination[strlen(destination) - 1] = '\0'; + switch(prot) { + case OSPE_DEST_PROT_H323_SETUP: + ast_copy_string(result->tech, "H323", sizeof(result->tech)); + snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1); + break; + case OSPE_DEST_PROT_SIP: + ast_copy_string(result->tech, "SIP", sizeof(result->tech)); + snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1); + break; + case OSPE_DEST_PROT_IAX: + ast_copy_string(result->tech, "IAX", sizeof(result->tech)); + snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1); + break; + default: + ast_log(LOG_DEBUG, "Unknown destination protocol '%d', skipping...\n", prot); + res = 0; } - if ((strlen(destination) > 2) && !OSPPTransactionGetDestProtocol(result->handle, &prot)) { - res = 1; - /* Strip leading and trailing brackets */ - destination[strlen(destination) - 1] = '\0'; - switch(prot) { - case OSPE_DEST_PROT_H323_SETUP: - ast_copy_string(result->tech, "H323", sizeof(result->tech)); - snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1); - break; - case OSPE_DEST_PROT_SIP: - ast_copy_string(result->tech, "SIP", sizeof(result->tech)); - snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1); - break; - case OSPE_DEST_PROT_IAX: - ast_copy_string(result->tech, "IAX", sizeof(result->tech)); - snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1); - break; - default: - ast_log(LOG_DEBUG, "Unknown destination protocol '%d', skipping...\n", prot); - res = 0; - } - if (!res && result->numresults) { - result->numresults--; - if (OSPPTransactionGetNextDestination(result->handle, OSPC_FAIL_INCOMPATIBLE_DEST, 0, NULL, NULL, &timelimit, &callidlen, callidstr, - sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) { - break; - } + if (!res && result->numresults) { + result->numresults--; + callidlen = sizeof(callidstr); + if (OSPPTransactionGetNextDestination(result->handle, OSPC_FAIL_INCOMPATIBLE_DEST, 0, NULL, NULL, &timelimit, &callidlen, callidstr, + sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) { + break; } - } else { - ast_log(LOG_DEBUG, "Missing destination protocol\n"); - break; } - } while(!res && result->numresults); - } + } else { + ast_log(LOG_DEBUG, "Missing destination protocol\n"); + break; + } + } while(!res && result->numresults); } - } - OSPPCallIdDelete(&callid); + } if (!res) { OSPPTransactionDelete(result->handle); @@ -680,11 +681,11 @@ if (result->handle > -1) { dummy = 0; - callidlen = sizeof(callidstr); if (result->numresults) { tokenlen = sizeof(token); while(!res && result->numresults) { result->numresults--; + callidlen = sizeof(callidstr); if (!OSPPTransactionGetNextDestination(result->handle, OSPC_FAIL_INCOMPATIBLE_DEST, 0, NULL, NULL, &timelimit, &callidlen, callidstr, sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) { if (!OSPPTransactionIsDestOSPEnabled (result->handle, &ospenabled) && (ospenabled == OSPE_OSP_FALSE)) {