Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 233389) +++ channels/chan_sip.c (working copy) @@ -1840,7 +1840,7 @@ struct sip_pkt *packets; /*!< Packets scheduled for re-transmission */ struct sip_history_head *history; /*!< History of this SIP dialog */ size_t history_entries; /*!< Number of entires in the history */ - struct ast_variable *chanvars; /*!< Channel variables to set for inbound call */ + struct ast_variable *chanvars; /*!< Channel variables to set for inbound / outbound calls */ AST_LIST_HEAD_NOLOCK(request_queue, sip_request) request_queue; /*!< Requests that arrived but could not be processed immediately */ struct sip_invite_param *options; /*!< Options for INVITE */ struct sip_st_dlg *stimer; /*!< SIP Session-Timers */ @@ -2059,6 +2059,7 @@ struct ast_ha *ha; /*!< Access control list */ struct ast_ha *contactha; /*!< Restrict what IPs are allowed in the Contact header (for registration) */ struct ast_variable *chanvars; /*!< Variables to set for channel created by user */ + struct ast_variable *chanvarsout; /*!< Variables to set for channel created by calls to peer */ struct sip_pvt *mwipvt; /*!< Subscription for MWI */ struct sip_st_cfg stimer; /*!< SIP Session-Timers */ int timer_t1; /*!< The maximum T1 value for the peer */ @@ -2555,6 +2556,7 @@ static void ast_quiet_chan(struct ast_channel *chan); static int attempt_transfer(struct sip_dual *transferer, struct sip_dual *target); static int do_magic_pickup(struct ast_channel *channel, const char *extension, const char *context); +static struct ast_variable *copy_vars(struct ast_variable *src); @@ -4933,6 +4935,11 @@ ast_variables_destroy(peer->chanvars); peer->chanvars = NULL; } + + if (peer->chanvarsout) { + ast_variables_destroy(peer->chanvarsout); + peer->chanvarsout = NULL; + } register_peer_exten(peer, FALSE); ast_free_ha(peer->ha); @@ -5591,6 +5598,10 @@ int res; if (newdialog) { set_socket_transport(&dialog->socket, 0); + if(!dialog->chanvars) { + /* copy channel vars */ + dialog->chanvars = copy_vars(peer->chanvarsout); + } } res = create_addr_from_peer(dialog, peer); if (!ast_strlen_zero(port)) { @@ -5598,6 +5609,7 @@ dialog->sa.sin_port = dialog->recv.sin_port = htons(portno); } } + unref_peer(peer, "create_addr: unref peer from find_peer hashtab lookup"); return res; } @@ -16161,6 +16173,11 @@ for (v = peer->chanvars ; v ; v = v->next) ast_cli(fd, " %s = %s\n", v->name, v->value); } + if (peer->chanvarsout) { + ast_cli(fd, " Variables out:\n"); + for (v = peer->chanvarsout ; v ; v = v->next) + ast_cli(fd, " %s = %s\n", v->name, v->value); + } ast_cli(fd, " Sess-Timers : %s\n", stmode2str(peer->stimer.st_mode_oper)); ast_cli(fd, " Sess-Refresh : %s\n", strefresher2str(peer->stimer.st_ref)); @@ -16244,6 +16261,11 @@ if (x < 63 && ast_codec_pref_index(pref, x+1)) astman_append(s, ","); } + if (peer->chanvarsout) { + for (v = peer->chanvarsout ; v ; v = v->next) { + astman_append(s, "ChanVariableOut: %s=%s\r\n", v->name, v->value); + } + } astman_append(s, "\r\n"); astman_append(s, "Status: "); @@ -16369,6 +16391,11 @@ for (v = user->chanvars ; v ; v = v->next) ast_cli(a->fd, " %s = %s\n", v->name, v->value); } + if (user->chanvarsout) { + ast_cli(a->fd, " Variables out:\n"); + for (v = user->chanvarsout ; v ; v = v->next) + ast_cli(a->fd, " %s = %s\n", v->name, v->value); + } ast_cli(a->fd, "\n"); @@ -18029,6 +18056,16 @@ ast_copy_string(buf, v->value, len); } } + } else if (!strncasecmp(colname, "chanvarout[", 8)) { + char *chanvar=colname + 8; + struct ast_variable *v; + + chanvar = strsep(&chanvar, "]"); + for (v = peer->chanvarsout ; v ; v = v->next) { + if (!strcasecmp(v->name, chanvar)) { + ast_copy_string(buf, v->value, len); + } + } } else if (!strncasecmp(colname, "codec[", 6)) { char *codecnum; format_t codec = 0; @@ -24837,6 +24874,11 @@ peer->chanvars = NULL; /* XXX should unregister ? */ } + if (peer->chanvarsout) { + ast_variables_destroy(peer->chanvarsout); + peer->chanvarsout = NULL; + /* XXX should unregister ? */ + } if (found) peer->portinuri = 0; @@ -25098,6 +25140,8 @@ } } else if (!strcasecmp(v->name, "setvar")) { peer->chanvars = add_var(v->value, peer->chanvars); + } else if (!strcasecmp(v->name, "setvarout")) { + peer->chanvarsout = add_var(v->value, peer->chanvarsout); } else if (!strcasecmp(v->name, "header")) { char tmp[4096]; snprintf(tmp, sizeof(tmp), "__SIPADDHEADERpre%2d=%s", ++headercount, v->value); Index: configs/sip.conf.sample =================================================================== --- configs/sip.conf.sample (revision 233389) +++ configs/sip.conf.sample (working copy) @@ -959,6 +959,7 @@ ; useclientcode ; accountcode ; setvar +; setvarout ; callerid ; amaflags ; callcounter @@ -1213,11 +1214,16 @@ ;defaultip=192.168.0.4 ; IP address to use until registration ;defaultuser=goran ; Username to use when calling this device before registration ; Normally you do NOT need to set this parameter -;setvar=CUSTID=5678 ; Channel variable to be set for all calls from or to this device +;setvar=CUSTID=5678 ; Channel variable to be set for all calls from this device +;setvarout=CUSTID=5678 ; Channel variable to be set for all calls to this device ;setvar=ATTENDED_TRANSFER_COMPLETE_SOUND=beep ; This channel variable will ; cause the given audio file to ; be played upon completion of ; an attended transfer. + ; The next line is required to make + ; it work for outbound (from PBX to peer) + ; calls too. +;setvarout=ATTENDED_TRANSFER_COMPLETE_SOUND=beep ;[pre14-asterisk] ;type=friend