From dd7e4ef47ad3e6b6407aa7a0be664f65b91f9c14 Mon Sep 17 00:00:00 2001 From: Mark Spencer Date: Sat, 12 Feb 2005 20:14:21 +0000 Subject: Merge SIP changes from oej git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5013 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_sip.c | 298 ++++++++++++++++++++++++++++++------------------ configs/sip.conf.sample | 4 +- 2 files changed, 187 insertions(+), 115 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index cff4aaa13..eb731dbd4 100755 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -203,7 +203,7 @@ static int tos = 0; static int videosupport = 0; -static int compactheaders = 0; /* send compact sip headers */ +static int compactheaders = 0; /* send compact sip headers */ static int recordhistory = 0; /* Record SIP history. Off by default */ @@ -260,7 +260,7 @@ struct sip_history { #define SIP_NEEDDESTROY (1 << 1) /* if we need to be destroyed */ #define SIP_NOVIDEO (1 << 2) /* Didn't get video in invite, don't offer */ #define SIP_RINGING (1 << 3) /* Have sent 180 ringing */ -#define SIP_PROGRESS_SENT (1 << 4) /* Have sent 183 message progress */ +#define SIP_PROGRESS_SENT (1 << 4) /* Have sent 183 message progress */ #define SIP_NEEDREINVITE (1 << 5) /* Do we need to send another reinvite? */ #define SIP_PENDINGBYE (1 << 6) /* Need to send bye after we ack? */ #define SIP_GOTREFER (1 << 7) /* Got a refer? */ @@ -317,10 +317,10 @@ static struct sip_pvt { ast_mutex_t lock; /* Channel private lock */ char callid[80]; /* Global CallID */ char randdata[80]; /* Random data */ - struct ast_codec_pref prefs; /* codec prefs */ + struct ast_codec_pref prefs; /* codec prefs */ unsigned int ocseq; /* Current outgoing seqno */ unsigned int icseq; /* Current incoming seqno */ - ast_group_t callgroup; /* Call group */ + ast_group_t callgroup; /* Call group */ ast_group_t pickupgroup; /* Pickup group */ int lastinvite; /* Last Cseq of invite */ unsigned int flags; /* SIP_ flags */ @@ -401,7 +401,7 @@ static struct sip_pvt { int stateid; int dialogver; - struct ast_dsp *vad; + struct ast_dsp *vad; /* Voice Activation Detection dsp */ struct sip_peer *peerpoke; /* If this calls is to poke a peer, which one */ struct sip_registry *registry; /* If this is a REGISTER call, to which registry */ @@ -409,7 +409,7 @@ static struct sip_pvt { struct ast_rtp *vrtp; /* Video RTP session */ struct sip_pkt *packets; /* Packets scheduled for re-transmission */ struct sip_history *history; /* History of this SIP dialog */ - struct ast_variable *vars; + struct ast_variable *chanvars; struct sip_pvt *next; /* Next call in chain */ } *iflist = NULL; @@ -418,13 +418,13 @@ static struct sip_pvt { /* sip packet - read in sipsock_read, transmitted in send_request */ struct sip_pkt { - struct sip_pkt *next; /* Next packet */ - int retrans; /* Retransmission number */ - int seqno; /* Sequence number */ - unsigned int flags; /* non-zero if this is a response packet (e.g. 200 OK) */ - struct sip_pvt *owner; /* Owner call */ - int retransid; /* Retransmission ID */ - int packetlen; /* Length of packet */ + struct sip_pkt *next; /* Next packet */ + int retrans; /* Retransmission number */ + int seqno; /* Sequence number */ + unsigned int flags; /* non-zero if this is a response packet (e.g. 200 OK) */ + struct sip_pvt *owner; /* Owner call */ + int retransid; /* Retransmission ID */ + int packetlen; /* Length of packet */ char data[0]; }; @@ -448,21 +448,23 @@ struct sip_user { int amaflags; /* AMA flags for billing */ int callingpres; /* Calling id presentation */ int capability; /* Codec capability */ - int inUse; - int incominglimit; - int outUse; - int outgoinglimit; + int inUse; /* Number of calls in use */ + int incominglimit; /* Limit of incoming calls */ + int outUse; /* disabled */ + int outgoinglimit; /* disabled */ struct ast_ha *ha; /* ACL setting */ - struct ast_variable *vars; + struct ast_variable *chanvars; /* Variables to set for channel created by user */ }; /* Structure for SIP peer data, we place calls to peers if registred or fixed IP address (host) */ struct sip_peer { - ASTOBJ_COMPONENTS(struct sip_peer); + ASTOBJ_COMPONENTS(struct sip_peer); /* name, refcount, objflags, object pointers */ + /* peer->name is the unique name of this object */ char secret[80]; /* Password */ char md5secret[80]; /* Password in MD5 */ char context[80]; /* Default context for incoming calls */ - char username[80]; /* Temporary username until registration */ + char username[80]; /* Temporary username until registration */ + char accountcode[20]; /* Account code */ char tohost[80]; /* If not dynamic, IP address */ char regexten[AST_MAX_EXTENSION]; /* Extension to register (if regcontext is used) */ char fromuser[80]; /* From: user when calling this peer */ @@ -474,18 +476,18 @@ struct sip_peer { char language[MAX_LANGUAGE]; /* Default language for prompts */ char musicclass[MAX_LANGUAGE]; /* Music on Hold class */ char useragent[256]; /* User agent in SIP request (saved from registration) */ - struct ast_codec_pref prefs; /* codec prefs */ + struct ast_codec_pref prefs; /* codec prefs */ int lastmsgssent; time_t lastmsgcheck; /* Last time we checked for MWI */ unsigned int flags; /* SIP_ flags */ - struct ast_flags flags_page2; /* SIP_PAGE2 flags */ + struct ast_flags flags_page2; /* SIP_PAGE2 flags */ int expire; /* Registration expiration */ int expiry; int capability; /* Codec capability */ - int rtptimeout; - int rtpholdtimeout; - int rtpkeepalive; /* Send RTP packets for keepalive */ - ast_group_t callgroup; /* Call group */ + int rtptimeout; /* RTP timeout */ + int rtpholdtimeout; /* RTP Hold Timeout */ + int rtpkeepalive; /* Send RTP packets for keepalive */ + ast_group_t callgroup; /* Call group */ ast_group_t pickupgroup; /* Pickup group */ struct sockaddr_in addr; /* IP address of peer */ struct in_addr mask; @@ -499,6 +501,7 @@ struct sip_peer { struct sockaddr_in defaddr; /* Default IP address, used until registration */ struct ast_ha *ha; /* Access control list */ + struct ast_variable *chanvars; /* Variables to set for channel created by user */ int lastmsg; }; @@ -595,6 +598,8 @@ static void free_old_route(struct sip_route *route); static int build_reply_digest(struct sip_pvt *p, char *orig_header, char *digest, int digest_len); static int update_user_counter(struct sip_pvt *fup, int event); static void prune_peers(void); +static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int realtime); +static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime); static int sip_do_reload(void); static int expire_register(void *data); static int callevents = 0; @@ -1065,6 +1070,7 @@ static int sip_sendtext(struct ast_channel *ast, char *text) return 0; } +/*--- realtime_update_peer: Update peer object in realtime storage ---*/ static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, const char *username, int expirey) { char port[10]; @@ -1080,6 +1086,7 @@ static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, "username", username, NULL); } +/*--- register_peer_exten: Automatically add peer extension to dial plan ---*/ static void register_peer_exten(struct sip_peer *peer, int onoff) { unsigned char multi[256]=""; @@ -1096,11 +1103,16 @@ static void register_peer_exten(struct sip_peer *peer, int onoff) } } +/*--- sip_destroy_peer: Destroy peer object from memory */ static void sip_destroy_peer(struct sip_peer *peer) { /* Delete it, it needs to disappear */ if (peer->call) sip_destroy(peer->call); + if(peer->chanvars) { + ast_variables_destroy(peer->chanvars); + peer->chanvars = NULL; + } if (peer->expire > -1) ast_sched_del(sched, peer->expire); if (peer->pokeexpire > -1) @@ -1125,17 +1137,19 @@ static void update_peer(struct sip_peer *p, int expiry) realtime_update_peer(p->name, &p->addr, p->username, expiry); } -static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int realtime); +/*--- realtime_peer: Get peer from realtime storage ---*/ +/* Checks the "sippeers" realtime family from extconfig.conf */ static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *sin) { struct sip_peer *peer=NULL; struct ast_variable *var; struct ast_variable *tmp; + /* First check on peer name */ if (peername) var = ast_load_realtime("sippeers", "name", peername, NULL); - else if (sin) { + else if (sin) { /* Then check on IP address */ char iabuf[80]; ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr); @@ -1147,6 +1161,7 @@ static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in * return NULL; tmp = var; + /* If this is type=user, then skip this object. */ while(tmp) { if (!strcasecmp(tmp->name, "type") && !strcasecmp(tmp->value, "user")) { @@ -1157,6 +1172,7 @@ static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in * } peer = build_peer(peername, var, ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS) ? 0 : 1); + if (peer) { if(ast_test_flag((&global_flags_page2), SIP_PAGE2_RTCACHEFRIENDS)) { ast_copy_flags((&peer->flags_page2),(&global_flags_page2), SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS); @@ -1172,6 +1188,7 @@ static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in * return peer; } +/*--- sip_addrcmp: Support routine for find_peer ---*/ static int sip_addrcmp(char *name, struct sockaddr_in *sin) { /* We know name is the first field, so we can cast */ @@ -1198,12 +1215,13 @@ static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int return(p); } +/*--- sip_destroy_user: Remove user object from in-memory storage ---*/ static void sip_destroy_user(struct sip_user *user) { ast_free_ha(user->ha); - if(user->vars) { - ast_variables_destroy(user->vars); - user->vars = NULL; + if(user->chanvars) { + ast_variables_destroy(user->chanvars); + user->chanvars = NULL; } if (ast_test_flag(user, SIP_REALTIME)) ruserobjs--; @@ -1212,7 +1230,9 @@ static void sip_destroy_user(struct sip_user *user) free(user); } -static struct sip_user *build_user(const char *name, struct ast_variable *v, int realtime); +/*--- realtime_user: Load user from realtime storage ---*/ +/* Loads user from "sipusers" category in realtime (extconfig.conf) */ +/* Users are matched on From: user name (the domain in skipped) */ static struct sip_user *realtime_user(const char *username) { struct ast_variable *var; @@ -1255,7 +1275,10 @@ static struct sip_user *realtime_user(const char *username) return user; } -/*--- find_user: Locate user by name */ +/*--- find_user: Locate user by name ---*/ +/* Locates user by name (From: sip uri user name part) first + from in-memory list (static configuration) then from + realtime storage (defined in extconfig.conf) */ static struct sip_user *find_user(const char *name) { struct sip_user *u = NULL; @@ -1304,9 +1327,9 @@ static int create_addr(struct sip_pvt *r, char *opeer) } strncpy(r->peername, p->username, sizeof(r->peername)-1); strncpy(r->authname, p->username, sizeof(r->authname)-1); + strncpy(r->username, p->username, sizeof(r->username)-1); strncpy(r->peersecret, p->secret, sizeof(r->peersecret)-1); strncpy(r->peermd5secret, p->md5secret, sizeof(r->peermd5secret)-1); - strncpy(r->username, p->username, sizeof(r->username)-1); strncpy(r->tohost, p->tohost, sizeof(r->tohost)-1); strncpy(r->fullcontact, p->fullcontact, sizeof(r->fullcontact)-1); if (!r->initreq.headers && !ast_strlen_zero(p->fromdomain)) { @@ -1473,6 +1496,8 @@ static int sip_call(struct ast_channel *ast, char *dest, int timeout) return res; } +/*--- sip_registry_destroy: Destroy registry object ---*/ +/* Objects created with the register= statement in static configuration */ static void sip_registry_destroy(struct sip_registry *reg) { /* Really delete */ @@ -1561,9 +1586,9 @@ static void __sip_destroy(struct sip_pvt *p, int lockowner) free(cp); } ast_mutex_destroy(&p->lock); - if(p->vars) { - ast_variables_destroy(p->vars); - p->vars = NULL; + if(p->chanvars) { + ast_variables_destroy(p->chanvars); + p->chanvars = NULL; } free(p); } @@ -1647,6 +1672,7 @@ static void sip_destroy(struct sip_pvt *p) static int transmit_response_reliable(struct sip_pvt *p, char *msg, struct sip_request *req, int fatal); +/*--- hangup_sip2cause: Convert SIP hangup causes to Asterisk hangup causes ---*/ static int hangup_sip2cause(int cause) { /* Possible values from causes.h @@ -1668,6 +1694,7 @@ static int hangup_sip2cause(int cause) return 0; } +/*--- hangup_cause2sip: Convert Asterisk hangup causes to SIP codes ---*/ static char *hangup_cause2sip(int cause) { switch(cause) @@ -1685,7 +1712,8 @@ static char *hangup_cause2sip(int cause) return 0; } -/*--- sip_hangup: Hangup SIP call */ +/*--- sip_hangup: Hangup SIP call ---*/ +/* Part of PBX interface */ static int sip_hangup(struct ast_channel *ast) { struct sip_pvt *p = ast->pvt->pvt; @@ -1775,7 +1803,8 @@ static int sip_hangup(struct ast_channel *ast) return 0; } -/*--- sip_answer: Answer SIP call , send 200 OK on Invite */ +/*--- sip_answer: Answer SIP call , send 200 OK on Invite ---*/ +/* Part of PBX interface */ static int sip_answer(struct ast_channel *ast) { int res = 0,fmt; @@ -1901,6 +1930,7 @@ static int sip_transfer(struct ast_channel *ast, char *dest) { struct sip_pvt *p = ast->pvt->pvt; int res; + ast_mutex_lock(&p->lock); res = transmit_refer(p, dest); ast_mutex_unlock(&p->lock); @@ -2089,7 +2119,8 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, char *title) tmp = NULL; } } - for (v = i->vars ; v ; v = v->next) + /* Set channel variables for this call from configuration */ + for (v = i->chanvars ; v ; v = v->next) pbx_builtin_setvar_helper(tmp,v->name,v->value); } else @@ -2097,6 +2128,7 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, char *title) return tmp; } +/* Structure for conversion between compressed SIP and "normal" SIP */ static struct cfalias { char *fullname; char *shortname; @@ -2325,9 +2357,9 @@ static struct sip_pvt *sip_alloc(char *callid, struct sockaddr_in *sin, int useg if (!p->rtp) { ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno)); ast_mutex_destroy(&p->lock); - if(p->vars) { - ast_variables_destroy(p->vars); - p->vars = NULL; + if(p->chanvars) { + ast_variables_destroy(p->chanvars); + p->chanvars = NULL; } free(p); return NULL; @@ -3612,63 +3644,67 @@ static int transmit_response_with_sdp(struct sip_pvt *p, char *msg, struct sip_r } /*--- determine_firstline_parts: parse first line of incoming SIP request */ -static int determine_firstline_parts( struct sip_request *req ) { - - char *e, *cmd; - int len; +static int determine_firstline_parts( struct sip_request *req ) +{ + char *e, *cmd; + int len; - cmd= req->header[0]; - while(*cmd && (*cmd < 33)) { - cmd++; - } - if (!*cmd) { - return -1; - } - e= cmd; - while(*e && (*e > 32)) { - e++; - } - /* Get the command */ - if (*e) { - *e = '\0'; - e++; - } - req->rlPart1= cmd; - while( *e && ( *e < 33 ) ) { - e++; - } - if( !*e ) { - return -1; - } + cmd = req->header[0]; + while(*cmd && (*cmd < 33)) { + cmd++; + } + if (!*cmd) { + return -1; + } + e = cmd; + while(*e && (*e > 32)) { + e++; + } + /* Get the command */ + if (*e) { + *e = '\0'; + e++; + } + req->rlPart1 = cmd; + while( *e && ( *e < 33 ) ) { + e++; + } + if( !*e ) { + return -1; + } - if ( !strcasecmp(cmd, "SIP/2.0") ) { - /* We have a response */ - req->rlPart2= e; - len= strlen( req->rlPart2 ); - if( len < 2 ) { return -1; } - e+= len - 1; - while( *e && *e<33 ) { - e--; - } - *(++e)= '\0'; - } else { - /* We have a request */ - if( *e == '<' ) { - e++; - if( !*e ) { return -1; } - } - req->rlPart2= e; /* URI */ - if( ( e= strrchr( req->rlPart2, 'S' ) ) == NULL ) { - return -1; - } - while( isspace( *(--e) ) ) {} - if( *e == '>' ) { - *e= '\0'; - } else { - *(++e)= '\0'; - } - } - return 1; + if ( !strcasecmp(cmd, "SIP/2.0") ) { + /* We have a response */ + req->rlPart2= e; + len= strlen( req->rlPart2 ); + if( len < 2 ) { + return -1; + } + e+= len - 1; + while( *e && *e<33 ) { + e--; + } + *(++e)= '\0'; + } else { + /* We have a request */ + if( *e == '<' ) { + e++; + if( !*e ) { + return -1; + } + } + req->rlPart2= e; /* URI */ + if( ( e= strrchr( req->rlPart2, 'S' ) ) == NULL ) { + return -1; + } + while( isspace( *(--e) ) ) {} + if( *e == '>' ) { + *e= '\0'; + } else { + *(++e)= '\0'; + } + } + return 1; } /*--- transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) ---*/ @@ -3756,7 +3792,7 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, char *cmd, c if (p->username && p->username[0] == '+') x=1; - for (;xusername);x++) { + for (; xusername); x++) { if (!strchr(AST_DIGIT_ANY, p->username[x])) { onlydigits = 0; break; @@ -4537,7 +4573,7 @@ static void reg_source_db(struct sip_peer *p) } if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "SIP Seeding '%s' at %s@%s:%d for %d\n", p->name, + ast_verbose(VERBOSE_PREFIX_3 "SIP Seeding peers from Astdb: '%s' at %s@%s:%d for %d\n", p->name, p->username, ast_inet_ntoa(iabuf, sizeof(iabuf), in), atoi(c), atoi(d)); expiry = atoi(d); memset(&p->addr, 0, sizeof(p->addr)); @@ -4737,10 +4773,12 @@ static int parse_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_req with */ memcpy(&p->addr, &pvt->recv, sizeof(p->addr)); } - if (c) + + if (c) /* Overwrite the default username from config at registration */ strncpy(p->username, c, sizeof(p->username) - 1); else p->username[0] = '\0'; + if (p->expire > -1) ast_sched_del(sched, p->expire); if ((expiry < 1) || (expiry > max_expiry)) @@ -5629,11 +5667,11 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, char *cmd /* Find user based on user name in the from header */ if (!mailbox && user && ast_apply_ha(user->ha, sin)) { ast_copy_flags(p, user, SIP_TRUSTRPID | SIP_USECLIENTCODE | SIP_NAT | SIP_PROG_INBAND | SIP_OSPAUTH); - /* copy vars */ - for (v = user->vars ; v ; v = v->next) { + /* copy channel vars */ + for (v = user->chanvars ; v ; v = v->next) { if((tmpvar = ast_variable_new(v->name, v->value))) { - tmpvar->next = p->vars; - p->vars = tmpvar; + tmpvar->next = p->chanvars; + p->chanvars = tmpvar; } } p->prefs = user->prefs; @@ -5734,10 +5772,18 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, char *cmd ast_copy_flags(p, peer, SIP_PROMISCREDIR | SIP_DTMF | SIP_REINVITE); strncpy(p->peername, peer->name, sizeof(p->peername) - 1); strncpy(p->authname, peer->name, sizeof(p->authname) - 1); + /* copy channel vars */ + for (v = peer->chanvars ; v ; v = v->next) { + if((tmpvar = ast_variable_new(v->name, v->value))) { + tmpvar->next = p->chanvars; + p->chanvars = tmpvar; + } + } if (mailbox) snprintf(mailbox, mailboxlen, ",%s,", peer->mailbox); if (!ast_strlen_zero(peer->username)) { strncpy(p->username, peer->username, sizeof(p->username) - 1); + /* Use the default username for authentication on outbound calls */ strncpy(p->authname, peer->username, sizeof(p->authname) - 1); } if (!ast_strlen_zero(peer->cid_num) && !ast_strlen_zero(p->cid_num)) { @@ -5752,6 +5798,7 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, char *cmd strncpy(p->peersecret, peer->secret, sizeof(p->peersecret) - 1); strncpy(p->peermd5secret, peer->md5secret, sizeof(p->peermd5secret) - 1); strncpy(p->language, peer->language, sizeof(p->language) -1); + strncpy(p->accountcode, peer->accountcode, sizeof(p->accountcode) - 1); p->callgroup = peer->callgroup; p->pickupgroup = peer->pickupgroup; p->capability = peer->capability; @@ -6114,6 +6161,7 @@ static int sip_show_peer(int fd, int argc, char *argv[]) struct sip_peer *peer; char codec_buf[512]; struct ast_codec_pref *pref; + struct ast_variable *v; int x = 0, codec = 0, load_realtime = 0; if (argc < 4) @@ -6128,8 +6176,12 @@ static int sip_show_peer(int fd, int argc, char *argv[]) ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"":""); ast_cli(fd, " Context : %s\n", peer->context); ast_cli(fd, " Language : %s\n", peer->language); - ast_cli(fd, " FromUser : %s\n", peer->fromuser); - ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); + if (!ast_strlen_zero(peer->accountcode)) + ast_cli(fd, " Accountcode : %s\n", peer->accountcode); + if (!ast_strlen_zero(peer->fromuser)) + ast_cli(fd, " FromUser : %s\n", peer->fromuser); + if (!ast_strlen_zero(peer->fromdomain)) + ast_cli(fd, " FromDomain : %s\n", peer->fromdomain); ast_cli(fd, " Callgroup : "); print_group(fd, peer->callgroup); ast_cli(fd, " Pickupgroup : "); @@ -6153,7 +6205,7 @@ static int sip_show_peer(int fd, int argc, char *argv[]) ast_cli(fd, " ToHost : %s\n", peer->tohost); ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port)); ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); - ast_cli(fd, " Username : %s\n", peer->username); + ast_cli(fd, " Def. Username: %s\n", peer->username); ast_cli(fd, " Codecs : "); ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); ast_cli(fd, "%s\n", codec_buf); @@ -6184,6 +6236,11 @@ static int sip_show_peer(int fd, int argc, char *argv[]) ast_cli(fd, "%s\n",status); ast_cli(fd, " Useragent : %s\n", peer->useragent); ast_cli(fd, " Full Contact : %s\n", peer->fullcontact); + if (peer->chanvars) { + ast_cli(fd, " Variables :\n"); + for (v = peer->chanvars ; v ; v = v->next) + ast_cli(fd, " %s = %s\n", v->name, v->value); + } ast_cli(fd,"\n"); ASTOBJ_UNREF(peer,sip_destroy_peer); } else { @@ -8797,8 +8854,8 @@ static struct sip_user *build_user(const char *name, struct ast_variable *v, int *varval = '\0'; varval++; if((tmpvar = ast_variable_new(varname, varval))) { - tmpvar->next = user->vars; - user->vars = tmpvar; + tmpvar->next = user->chanvars; + user->chanvars = tmpvar; } } @@ -8896,6 +8953,8 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int int obproxyfound=0; int found=0; time_t regseconds; + char *varname = NULL, *varval = NULL; + struct ast_variable *tmpvar = NULL; if (!realtime) /* Note we do NOT use find_peer here, to avoid realtime recursion */ @@ -9041,6 +9100,8 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int strncpy(peer->language, v->value, sizeof(peer->language)-1); } else if (!strcasecmp(v->name, "regexten")) { strncpy(peer->regexten, v->value, sizeof(peer->regexten)-1); + } else if (!strcasecmp(v->name, "accountcode")) { + strncpy(peer->accountcode, v->value, sizeof(peer->accountcode)-1); } else if (!strcasecmp(v->name, "musiconhold")) { strncpy(peer->musicclass, v->value, sizeof(peer->musicclass)-1); } else if (!strcasecmp(v->name, "mailbox")) { @@ -9068,6 +9129,17 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d. Using default.\n", v->value, v->lineno); peer->rtpkeepalive = global_rtpkeepalive; } + } else if (!strcasecmp(v->name, "setvar")) { + /* Set peer channel variable */ + varname = ast_strdupa(v->value); + if (varname && (varval = strchr(varname,'='))) { + *varval = '\0'; + varval++; + if((tmpvar = ast_variable_new(varname, varval))) { + tmpvar->next = peer->chanvars; + peer->chanvars = tmpvar; + } + } } else if (!strcasecmp(v->name, "qualify")) { if (!strcasecmp(v->value, "no")) { peer->maxms = 0; @@ -9855,9 +9927,9 @@ int unload_module() p = p->next; /* Free associated memory */ ast_mutex_destroy(&pl->lock); - if(pl->vars) { - ast_variables_destroy(pl->vars); - pl->vars = NULL; + if(pl->chanvars) { + ast_variables_destroy(pl->chanvars); + pl->chanvars = NULL; } free(pl); } diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample index d2d02ed23..b113f00ed 100755 --- a/configs/sip.conf.sample +++ b/configs/sip.conf.sample @@ -193,9 +193,9 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls ; progressinband progressinband ; promiscredir promiscredir ; useclientcode useclientcode -; setvar +; accountcode accountcode +; setvar setvar ; callerid -; accountcode ; amaflags ; incominglimit ; restrictcid -- cgit v1.2.3