diff -r d28596246336 -r f27769b5f771 src/epa.cpp --- a/src/epa.cpp Wed Sep 24 14:13:38 2008 +0200 +++ b/src/epa.cpp Wed Nov 26 19:57:30 2008 +0100 @@ -90,6 +90,9 @@ if (!etag.empty()) { r->hdr_sip_if_match.set_etag(etag); } + + // Service-Route + phone_user->add_service_route(r); // Body if (body) { diff -r d28596246336 -r f27769b5f771 src/parser/Makefile.am --- a/src/parser/Makefile.am Wed Sep 24 14:13:38 2008 +0200 +++ b/src/parser/Makefile.am Wed Nov 26 19:57:30 2008 +0100 @@ -80,7 +80,9 @@ hdr_proxy_authorization.cpp\ hdr_proxy_require.cpp\ hdr_rack.cpp\ + route.cpp\ hdr_record_route.cpp\ + hdr_service_route.cpp\ hdr_refer_sub.cpp\ hdr_refer_to.cpp\ hdr_referred_by.cpp\ @@ -155,7 +157,9 @@ hdr_proxy_authorization.h\ hdr_proxy_require.h\ hdr_rack.h\ + route.h\ hdr_record_route.h\ + hdr_service_route.h\ hdr_refer_sub.h\ hdr_refer_to.h\ hdr_referred_by.h\ diff -r d28596246336 -r f27769b5f771 src/parser/hdr_record_route.cpp --- a/src/parser/hdr_record_route.cpp Wed Sep 24 14:13:38 2008 +0200 +++ b/src/parser/hdr_record_route.cpp Wed Nov 26 19:57:30 2008 +0100 @@ -20,32 +20,6 @@ #include "hdr_record_route.h" #include "parse_ctrl.h" #include "util.h" - -void t_route::add_param(const t_parameter &p) { - params.push_back(p); -} - -void t_route::set_params(const list &l) { - params = l; -} - -string t_route::encode(void) const { - string s; - - if (display.size() > 0) { - s += '"'; - s += escape(display, '"'); - s += '"'; - s += ' '; - } - - s += '<'; - s += uri.encode(); - s += '>'; - - s += param_list2str(params); - return s; -} t_hdr_record_route::t_hdr_record_route() : t_header("Record-Route") {} diff -r d28596246336 -r f27769b5f771 src/parser/hdr_record_route.h --- a/src/parser/hdr_record_route.h Wed Sep 24 14:13:38 2008 +0200 +++ b/src/parser/hdr_record_route.h Wed Nov 26 19:57:30 2008 +0100 @@ -23,22 +23,12 @@ #include #include +#include "route.h" #include "header.h" #include "parameter.h" #include "sockets/url.h" using namespace std; - -class t_route { -public: - string display; - t_url uri; - list params; - - void add_param(const t_parameter &p); - void set_params(const list &l); - string encode(void) const; -}; class t_hdr_record_route : public t_header { public: diff -r d28596246336 -r f27769b5f771 src/parser/hdr_service_route.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parser/hdr_service_route.cpp Wed Nov 26 19:57:30 2008 +0100 @@ -0,0 +1,66 @@ +/* + Copyright (C) 2005-2008 Michel de Boer + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "definitions.h" +#include "hdr_service_route.h" +#include "parse_ctrl.h" +#include "util.h" + +t_hdr_service_route::t_hdr_service_route() : t_header("Service-Route") {} + +void t_hdr_service_route::add_route(const t_route &r) { + populated = true; + route_list.push_back(r); +} + +string t_hdr_service_route::encode(void) const { + return (t_parser::multi_values_as_list ? + t_header::encode() : encode_multi_header()); +} + +string t_hdr_service_route::encode_multi_header(void) const { + string s; + + if (!populated) return s; + + for (list::const_iterator i = route_list.begin(); + i != route_list.end(); i++) + { + s += header_name; + s += ": "; + s += i->encode(); + s += CRLF; + } + + return s; +} + +string t_hdr_service_route::encode_value(void) const { + string s; + + if (!populated) return s; + + for (list::const_iterator i = route_list.begin(); + i != route_list.end(); i++) + { + if (i != route_list.begin()) s += ","; + s += i->encode(); + } + + return s; +} diff -r d28596246336 -r f27769b5f771 src/parser/hdr_service_route.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parser/hdr_service_route.h Wed Nov 26 19:57:30 2008 +0100 @@ -0,0 +1,44 @@ +/* + Copyright (C) 2005-2008 Michel de Boer + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// Service-Route header + +#ifndef _H_HDR_SERVICE_ROUTE +#define _H_HDR_SERVICE_ROUTE + +#include +#include +#include "route.h" +#include "header.h" +#include "parameter.h" +#include "sockets/url.h" + +using namespace std; + +class t_hdr_service_route : public t_header { +public: + list route_list; + + t_hdr_service_route(); + void add_route(const t_route &r); + string encode(void) const; + string encode_multi_header(void) const; + string encode_value(void) const; +}; + +#endif diff -r d28596246336 -r f27769b5f771 src/parser/parser.yxx --- a/src/parser/parser.yxx Wed Sep 24 14:13:38 2008 +0200 +++ b/src/parser/parser.yxx Wed Nov 26 19:57:30 2008 +0100 @@ -128,6 +128,7 @@ %token T_HDR_PROXY_REQUIRE %token T_HDR_RACK %token T_HDR_RECORD_ROUTE +%token T_HDR_SERVICE_ROUTE %token T_HDR_REFER_SUB %token T_HDR_REFER_TO %token T_HDR_REFERRED_BY @@ -200,6 +201,7 @@ %type parameters %type q_factor %type rec_route +%type serv_route %type sent_protocol %type server %type sip_version @@ -232,6 +234,7 @@ %destructor { MEMMAN_DELETE($$); delete $$; } parameter_val %destructor { MEMMAN_DELETE($$); delete $$; } parameters %destructor { MEMMAN_DELETE($$); delete $$; } rec_route +%destructor { MEMMAN_DELETE($$); delete $$; } serv_route %destructor { MEMMAN_DELETE($$); delete $$; } sent_protocol %destructor { MEMMAN_DELETE($$); delete $$; } server %destructor { MEMMAN_DELETE($$); delete $$; } sip_version @@ -353,6 +356,7 @@ | hd_proxy_require hdr_proxy_require T_CRLF | hd_rack hdr_rack T_CRLF | hd_record_route hdr_record_route T_CRLF + | hd_service_route hdr_service_route T_CRLF | hd_refer_sub hdr_refer_sub T_CRLF | hd_refer_to hdr_refer_to T_CRLF | hd_referred_by hdr_referred_by T_CRLF @@ -360,7 +364,8 @@ | hd_reply_to hdr_reply_to T_CRLF | hd_require hdr_require T_CRLF | hd_retry_after hdr_retry_after T_CRLF - | hd_route hdr_route T_CRLF + | hd_route hdr_route_rec T_CRLF + | hd_route hdr_route_serv T_CRLF | hd_rseq hdr_rseq T_CRLF | hd_server hdr_server T_CRLF | hd_sip_etag hdr_sip_etag T_CRLF @@ -451,6 +456,8 @@ { PARSE_ERROR("RAck"); } | hd_record_route error T_CRLF { PARSE_ERROR("Record-Route"); } + | hd_service_route error T_CRLF + { PARSE_ERROR("Service-Route"); } | hd_refer_sub error T_CRLF { PARSE_ERROR("Refer-Sub"); } | hd_refer_to error T_CRLF @@ -577,6 +584,8 @@ hd_rack: T_HDR_RACK ':' { CTXT_NUM; } ; hd_record_route: T_HDR_RECORD_ROUTE ':' { CTXT_URI; } +; +hd_service_route: T_HDR_SERVICE_ROUTE ':' { CTXT_URI; } ; hd_refer_sub: T_HDR_REFER_SUB ':' ; @@ -1067,6 +1076,32 @@ MEMMAN_DELETE($7); delete $7; } ; +hdr_service_route: serv_route { + MSG->hdr_service_route.add_route(*$1); + MEMMAN_DELETE($1); delete $1; } + | hdr_service_route ',' serv_route { + MSG->hdr_service_route.add_route(*$3); + MEMMAN_DELETE($3); delete $3; } +; + +serv_route: { CTXT_URI; } display_name '<' T_URI { CTXT_INITIAL; } '>' + parameters { + $$ = new t_route; + MEMMAN_NEW($$); + $$->display = *$2; + $$->uri.set_url(*$4); + $$->set_params(*$7); + + if (!$$->uri.is_valid()) { + MEMMAN_DELETE($$); delete $$; + YYERROR; + } + + MEMMAN_DELETE($2); delete $2; + MEMMAN_DELETE($4); delete $4; + MEMMAN_DELETE($7); delete $7; } +; + hdr_replaces: { CTXT_WORD; } call_id { CTXT_INITIAL; } parameters { MSG->hdr_replaces.set_call_id(*$2); @@ -1126,10 +1161,18 @@ $$ = $3; } ; -hdr_route: rec_route { +hdr_route_rec: rec_route { MSG->hdr_route.add_route(*$1); MEMMAN_DELETE($1); delete $1; } - | hdr_route ',' rec_route { + | hdr_route_rec ',' rec_route { + MSG->hdr_route.add_route(*$3); + MEMMAN_DELETE($3); delete $3; } +; + +hdr_route_serv: serv_route { + MSG->hdr_route.add_route(*$1); + MEMMAN_DELETE($1); delete $1; } + | hdr_route_rec ',' serv_route { MSG->hdr_route.add_route(*$3); MEMMAN_DELETE($3); delete $3; } ; diff -r d28596246336 -r f27769b5f771 src/parser/route.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parser/route.cpp Wed Nov 26 19:57:30 2008 +0100 @@ -0,0 +1,48 @@ +/* + Copyright (C) 2005-2008 Michel de Boer + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "definitions.h" +#include "route.h" +#include "parse_ctrl.h" +#include "util.h" + +void t_route::add_param(const t_parameter &p) { + params.push_back(p); +} + +void t_route::set_params(const list &l) { + params = l; +} + +string t_route::encode(void) const { + string s; + + if (display.size() > 0) { + s += '"'; + s += escape(display, '"'); + s += '"'; + s += ' '; + } + + s += '<'; + s += uri.encode(); + s += '>'; + + s += param_list2str(params); + return s; +} diff -r d28596246336 -r f27769b5f771 src/parser/route.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parser/route.h Wed Nov 26 19:57:30 2008 +0100 @@ -0,0 +1,41 @@ +/* + Copyright (C) 2005-2008 Michel de Boer + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// Route item + +#ifndef _H_ROUTE +#define _H_ROUTE + +#include +#include +#include "parameter.h" + +using namespace std; + +class t_route { +public: + string display; + t_url uri; + list params; + + void add_param(const t_parameter &p); + void set_params(const list &l); + string encode(void) const; +}; + +#endif diff -r d28596246336 -r f27769b5f771 src/parser/scanner.lxx --- a/src/parser/scanner.lxx Wed Sep 24 14:13:38 2008 +0200 +++ b/src/parser/scanner.lxx Wed Nov 26 19:57:30 2008 +0100 @@ -109,6 +109,7 @@ ^Proxy-Require { return T_HDR_PROXY_REQUIRE; } ^RAck { return T_HDR_RACK; } ^Record-Route { return T_HDR_RECORD_ROUTE; } +^Service-Route { return T_HDR_SERVICE_ROUTE; } ^Refer-Sub { return T_HDR_REFER_SUB; } ^(Refer-To)|r { return T_HDR_REFER_TO; } ^(Referred-By)|b { return T_HDR_REFERRED_BY; } diff -r d28596246336 -r f27769b5f771 src/parser/sip_message.cpp --- a/src/parser/sip_message.cpp Wed Sep 24 14:13:38 2008 +0200 +++ b/src/parser/sip_message.cpp Wed Nov 26 19:57:30 2008 +0100 @@ -78,6 +78,7 @@ hdr_proxy_require(m.hdr_proxy_require), hdr_rack(m.hdr_rack), hdr_record_route(m.hdr_record_route), + hdr_service_route(m.hdr_service_route), hdr_refer_sub(m.hdr_refer_sub), hdr_refer_to(m.hdr_refer_to), hdr_referred_by(m.hdr_referred_by), diff -r d28596246336 -r f27769b5f771 src/parser/sip_message.h --- a/src/parser/sip_message.h Wed Sep 24 14:13:38 2008 +0200 +++ b/src/parser/sip_message.h Wed Nov 26 19:57:30 2008 +0100 @@ -60,6 +60,7 @@ #include "hdr_proxy_require.h" #include "hdr_rack.h" #include "hdr_record_route.h" +#include "hdr_service_route.h" #include "hdr_refer_sub.h" #include "hdr_refer_to.h" #include "hdr_referred_by.h" @@ -153,6 +154,7 @@ t_hdr_proxy_require hdr_proxy_require; t_hdr_rack hdr_rack; t_hdr_record_route hdr_record_route; + t_hdr_service_route hdr_service_route; t_hdr_refer_sub hdr_refer_sub; t_hdr_refer_to hdr_refer_to; t_hdr_referred_by hdr_referred_by; diff -r d28596246336 -r f27769b5f771 src/phone_user.cpp --- a/src/phone_user.cpp Wed Sep 24 14:13:38 2008 +0200 +++ b/src/phone_user.cpp Wed Nov 26 19:57:30 2008 +0100 @@ -403,7 +403,7 @@ t_request *req; bool is_register = false; t_buddy *buddy; - + if (r_register && r_register->get_tuid() == tuid) { current_cr = &r_register; is_register = true; @@ -721,6 +721,12 @@ // The maximum timer that we can handle however is 2^31-1 ms e = (expires > 2147483 ? 2147483 : expires); phone->start_set_timer(PTMR_REGISTRATION, e * 1000, this); + // Save the Service-Route if present the response contains any + + if (r->hdr_service_route.is_populated()) { + service_route = r->hdr_service_route; + } + first_success = !is_registered; is_registered = true; ui->cb_register_success(user_config, r, expires, first_success); @@ -1471,6 +1477,12 @@ return sys_config->get_sip_port(); } +void t_phone_user::add_service_route(t_request * r) { + for (list::const_iterator i = service_route.route_list.begin(); + i != service_route.route_list.end(); i++) + r->hdr_route.add_route(*i); +} + bool t_phone_user::match(t_response *r, t_tuid tuid) const { t_buddy *dummy; diff -r d28596246336 -r f27769b5f771 src/phone_user.h --- a/src/phone_user.h Wed Sep 24 14:13:38 2008 +0200 +++ b/src/phone_user.h Wed Nov 26 19:57:30 2008 +0100 @@ -114,6 +114,9 @@ /** Event publication agent for presence */ t_presence_epa *presence_epa; + + /** Service Route, collected from REGISTER responses */ + t_hdr_service_route service_route; /** * Resend the request: a new sequence number will be assigned and a new via @@ -421,6 +424,9 @@ */ unsigned short get_public_port_sip(void) const; + //Add the Service-Route (if present) as a Route header + void add_service_route(t_request * r); + // Try to match message with phone user bool match(t_response *r, t_tuid tuid) const; bool match(t_request *r) const;