Commit 85b0d43b authored by jehan's avatar jehan

Merge branch 'feature/100rel'

parents 0ccbe50e c380db61
belle-sip (Unreleased): Jully 2018
* rfc3262 (100rel) support
belle_sip-1.6.2 -- July 21th, 2017
* Build fix for Windows
......
......@@ -34,7 +34,6 @@ BELLESIP_EXPORT const char* belle_sip_dialog_state_to_string(const belle_sip_dia
BELLESIP_EXPORT belle_sip_request_t *belle_sip_dialog_create_ack(belle_sip_dialog_t *dialog, unsigned int cseq);
/**
* Create a request part of this dialog.
**/
......
......@@ -748,6 +748,20 @@ BELLESIP_EXPORT belle_sip_list_t* belle_sip_header_supported_get_supported(const
#define BELLE_SIP_HEADER_SUPPORTED(t) BELLE_SIP_CAST(t,belle_sip_header_supported_t)
#define BELLE_SIP_SUPPORTED "Supported"
/******************************
* Require header object inherent from header
*
******************************/
typedef struct _belle_sip_header_require belle_sip_header_require_t;
BELLESIP_EXPORT belle_sip_header_require_t* belle_sip_header_require_new(void);
BELLESIP_EXPORT belle_sip_header_require_t* belle_sip_header_require_parse(const char* require) ;
BELLESIP_EXPORT belle_sip_header_require_t* belle_sip_header_require_create(const char* require);
BELLESIP_EXPORT void belle_sip_header_require_add_require(belle_sip_header_require_t* require, const char* value);
BELLESIP_EXPORT void belle_sip_header_require_set_require(belle_sip_header_require_t* require, belle_sip_list_t* require_values);
BELLESIP_EXPORT belle_sip_list_t* belle_sip_header_require_get_require(const belle_sip_header_require_t* require);
#define BELLE_SIP_HEADER_REQUIRE(t) BELLE_SIP_CAST(t,belle_sip_header_require_t)
#define BELLE_SIP_REQUIRE "Require"
/******************************
* Content Disposition header object inherent from header
*
......
......@@ -144,6 +144,7 @@ BELLE_SIP_DECLARE_TYPES_BEGIN(belle_sip,1)
BELLE_SIP_TYPE_ID(belle_sip_multipart_body_handler_t),
BELLE_SIP_TYPE_ID(belle_sip_header_event_t),
BELLE_SIP_TYPE_ID(belle_sip_header_supported_t),
BELLE_SIP_TYPE_ID(belle_sip_header_require_t),
BELLE_SIP_TYPE_ID(belle_sip_header_content_disposition_t),
BELLE_SIP_TYPE_ID(belle_sip_header_accept_t),
BELLE_SIP_TYPE_ID(belle_sip_header_reason_t),
......
......@@ -79,6 +79,7 @@ static struct header_name_func_pair header_table[] = {
,{PROTO_SIP, BELLE_SIP_EVENT, (header_parse_func)belle_sip_header_event_parse}
,{PROTO_SIP, BELLE_SIP_SUPPORTED, (header_parse_func)belle_sip_header_supported_parse}
,{PROTO_SIP, "k", (header_parse_func)belle_sip_header_supported_parse}
,{PROTO_SIP, BELLE_SIP_REQUIRE, (header_parse_func)belle_sip_header_require_parse}
,{PROTO_SIP, BELLE_SIP_CONTENT_DISPOSITION, (header_parse_func)belle_sip_header_content_disposition_parse}
,{PROTO_SIP, BELLE_SIP_ACCEPT, (header_parse_func)belle_sip_header_accept_parse}
,{PROTO_SIP, BELLE_SIP_REASON, (header_parse_func)belle_sip_header_reason_parse}
......@@ -1959,6 +1960,12 @@ belle_sip_header_event_t* belle_sip_header_event_create (const char* package_nam
******************************/
PRIVACY_LIKE_HEADER(supported,BELLE_SIP_SUPPORTED,",")
/******************************
* Require header inherits from header
*
******************************/
PRIVACY_LIKE_HEADER(require,BELLE_SIP_REQUIRE,",")
/******************************
* Content-Disposition header inherits from header
*
......
......@@ -225,6 +225,7 @@ BELLE_SIP_DECLARE_VPTR(belle_tls_crypto_config_t);
BELLE_SIP_DECLARE_VPTR(belle_http_header_authorization_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_event_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_supported_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_require_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_content_disposition_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_accept_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_reason_t);
......
......@@ -450,6 +450,95 @@ static void belle_sip_dialog_update_remote_target(belle_sip_dialog_t *obj, belle
}
}
static void belle_sip_dialog_update_local_cseq(belle_sip_dialog_t *obj, const char *method){
if (obj->local_cseq==0) obj->local_cseq=110;
if (strcmp(method,"ACK")!=0) obj->local_cseq++;
}
static belle_sip_request_t *belle_sip_dialog_create_prack(belle_sip_dialog_t *dialog, unsigned int rseq, unsigned int cseq, const char* method){
belle_sip_request_t *prack;
belle_sip_request_t *invite = dialog->last_out_invite;
if (!invite){
belle_sip_error("No INVITE to PACK.");
return NULL;
}
prack = belle_sip_dialog_create_request(dialog, "PRACK");
if (prack){
//RAck
char header[50];
snprintf(header,sizeof(header),"%d %d %s", rseq, cseq, method);
belle_sip_header_t *rack = belle_sip_header_create("RAck", header);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(prack), rack);
//Contact
belle_sip_header_from_t* from_header = belle_sip_message_get_header_by_type(prack, belle_sip_header_from_t);
belle_sip_uri_t* req_uri = belle_sip_header_address_get_uri((belle_sip_header_address_t*)from_header);
belle_sip_header_contact_t* contact_header = belle_sip_header_contact_new();
belle_sip_header_address_set_uri((belle_sip_header_address_t*)contact_header, belle_sip_uri_new());
belle_sip_uri_set_user(belle_sip_header_address_get_uri((belle_sip_header_address_t*)contact_header),belle_sip_uri_get_user(req_uri));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(prack),BELLE_SIP_HEADER(contact_header));
const belle_sip_list_t *aut = belle_sip_message_get_headers((belle_sip_message_t*)invite, "Authorization");
const belle_sip_list_t *prx_aut = belle_sip_message_get_headers((belle_sip_message_t*)invite, "Proxy-Authorization");
if (aut)
belle_sip_message_add_headers((belle_sip_message_t*)prack, aut);
if (prx_aut)
belle_sip_message_add_headers((belle_sip_message_t*)prack, prx_aut);
}
return prack;
}
static void belle_sip_dialog_send_prack(belle_sip_dialog_t *dialog, belle_sip_request_t *request){
belle_sip_provider_send_request(dialog->provider, request);
}
static void belle_sip_dialog_process_response_100rel(belle_sip_dialog_t *obj, belle_sip_response_t *resp){
belle_sip_message_t* msg = (belle_sip_message_t*)resp;
belle_sip_header_cseq_t *header_cseq_resp = belle_sip_message_get_header_by_type(msg, belle_sip_header_cseq_t);
if (header_cseq_resp == NULL){
belle_sip_message("Message [%p] does not contain CSeq header!", msg);
}
belle_sip_header_require_t* header_require = belle_sip_message_get_header_by_type(msg, belle_sip_header_require_t);
if (header_require){
belle_sip_list_t* list = belle_sip_header_require_get_require(header_require);
int require_100rel = 0;
while (list){
if (strcmp(list->data, "100rel") == 0){
require_100rel = 1;
break;
}
list=list->next;
}
if (require_100rel){
belle_sip_message("Found header Require with value 100rel in message [%p].", msg);
belle_sip_header_t *header_rseq = belle_sip_message_get_header(msg, "RSeq");
if (header_rseq){
const char* header_rseq_value = belle_sip_header_get_unparsed_value(header_rseq);
long rseq = strtol(header_rseq_value, NULL, 10);
unsigned int cseq_resp = belle_sip_header_cseq_get_seq_number(header_cseq_resp);
const char* method_resp = belle_sip_header_cseq_get_method(header_cseq_resp);
/*send PRACK from callee */
belle_sip_request_t *prack = belle_sip_dialog_create_prack(obj, rseq, cseq_resp, method_resp);
if (prack){
belle_sip_dialog_send_prack(obj, prack);
}
else {
belle_sip_message("Failed to create PRACK message!");
}
}
else {
belle_sip_message("Message [%p] does not contain RSeq header! (required be with 100rel)", msg);
}
}
}
}
/*
* return 0 if message should be delivered to the next listener, otherwise, its a retransmision, just keep it
* */
......@@ -498,6 +587,9 @@ int belle_sip_dialog_update(belle_sip_dialog_t *obj, belle_sip_transaction_t* tr
belle_sip_dialog_establish(obj,req,resp);
if (code<200){
set_state(obj,BELLE_SIP_DIALOG_EARLY);
if ((code == 180 || code == 183) && !as_uas) {
belle_sip_dialog_process_response_100rel(obj, resp);
}
break;
}/* no break for code >200 because need to call belle_sip_dialog_establish_full*/
}
......@@ -532,6 +624,9 @@ int belle_sip_dialog_update(belle_sip_dialog_t *obj, belle_sip_transaction_t* tr
/*no response establishing the dialog, and transaction terminated (transport errors)*/
delete_dialog=TRUE;
}
if ((code == 180 || code == 183) && !as_uas) {
belle_sip_dialog_process_response_100rel(obj, resp);
}
break;
case BELLE_SIP_DIALOG_CONFIRMED:
if (code==481 && (is_invite || is_subscribe)) {
......@@ -710,20 +805,23 @@ belle_sip_dialog_t *belle_sip_dialog_new(belle_sip_transaction_t *t){
}
belle_sip_request_t *belle_sip_dialog_create_ack(belle_sip_dialog_t *obj, unsigned int cseq){
belle_sip_header_cseq_t *cseqh;
belle_sip_request_t *invite=obj->last_out_invite;
belle_sip_request_t *ack;
belle_sip_header_cseq_t* cseqh;
if (!invite){
belle_sip_error("No INVITE to ACK.");
return NULL;
}
cseqh=belle_sip_message_get_header_by_type(invite,belle_sip_header_cseq_t);
if (belle_sip_header_cseq_get_seq_number(cseqh)!=cseq){
belle_sip_error("No INVITE with cseq %i to create ack for.",cseq);
return NULL;
}
ack=create_request(obj,"ACK",TRUE);
belle_sip_message_set_header(BELLE_SIP_MESSAGE(ack), BELLE_SIP_HEADER(belle_sip_header_cseq_create(cseq, "ACK")));
/*
22 Usage of HTTP Authentication
22.1 Framework
......@@ -819,11 +917,6 @@ belle_sip_request_t * belle_sip_dialog_create_queued_request(belle_sip_dialog_t
return req;
}
static void belle_sip_dialog_update_local_cseq(belle_sip_dialog_t *obj, const char *method){
if (obj->local_cseq==0) obj->local_cseq=110;
if (strcmp(method,"ACK")!=0) obj->local_cseq++;
}
belle_sip_request_t *belle_sip_dialog_create_request(belle_sip_dialog_t *obj, const char *method){
belle_sip_request_t *req;
......
......@@ -2,7 +2,7 @@
* This C source file was generated by $ANTLR version 3.4
*
* - From the grammar source file : ../grammars/belle_sdp.g
* - On : 2018-01-22 10:48:20
* - On : 2018-07-11 16:46:26
* - for the lexer : belle_sdpLexerLexer
*
* Editing it, at least manually, is not wise.
......
......@@ -2,7 +2,7 @@
* This C header file was generated by $ANTLR version 3.4
*
* - From the grammar source file : ../grammars/belle_sdp.g
* - On : 2018-01-22 10:48:20
* - On : 2018-07-11 16:46:26
* - for the lexer : belle_sdpLexerLexer
*
* Editing it, at least manually, is not wise.
......
......@@ -2,7 +2,7 @@
* This C source file was generated by $ANTLR version 3.4
*
* - From the grammar source file : ../grammars/belle_sdp.g
* - On : 2018-01-22 10:48:19
* - On : 2018-07-11 16:46:24
* - for the parser : belle_sdpParserParser
*
* Editing it, at least manually, is not wise.
......
......@@ -2,7 +2,7 @@
* This C header file was generated by $ANTLR version 3.4
*
* - From the grammar source file : ../grammars/belle_sdp.g
* - On : 2018-01-22 10:48:19
* - On : 2018-07-11 16:46:24
* - for the parser : belle_sdpParserParser
*
* Editing it, at least manually, is not wise.
......
......@@ -1520,6 +1520,19 @@ catch [ANTLR3_RECOGNITION_EXCEPTION]
}
supported_val: token {belle_sip_header_supported_add_supported($header_supported::current,(const char*)$token.text->chars);};
//**********************************Require*******************************//
header_require returns [belle_sip_header_require_t* ret]
scope { belle_sip_header_require_t* current; }
@init { $header_require::current = belle_sip_header_require_new();$ret = $header_require::current;}
: {IS_TOKEN(Require)}? token /*'Require'*/ hcolon require_val (comma require_val)*;
catch [ANTLR3_RECOGNITION_EXCEPTION]
{
belle_sip_message("[\%s] reason [\%s]",(const char*)EXCEPTION->name,(const char*)EXCEPTION->message);
belle_sip_object_unref($ret);
$ret=NULL;
}
require_val: token {belle_sip_header_require_add_require($header_require::current,(const char*)$token.text->chars);};
//**********************************Content-Disposition*******************************//
content_disposition_value: token ;
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
* This C header file was generated by $ANTLR version 3.4
*
* - From the grammar source file : ../grammars/belle_sip_message.g
* - On : 2018-01-22 10:48:30
* - On : 2018-07-11 16:47:03
* - for the lexer : belle_sip_messageLexerLexer
*
* Editing it, at least manually, is not wise.
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
* This C header file was generated by $ANTLR version 3.4
*
* - From the grammar source file : ../grammars/belle_sip_message.g
* - On : 2018-01-22 10:48:29
* - On : 2018-07-11 16:46:55
* - for the parser : belle_sip_messageParserParser
*
* Editing it, at least manually, is not wise.
......@@ -587,6 +587,12 @@ has the callable functions (rules) shown below,
void
pbelle_sip_messageParser->supported_val(pbelle_sip_messageParser)
* -
belle_sip_header_require_t*
pbelle_sip_messageParser->header_require(pbelle_sip_messageParser)
* -
void
pbelle_sip_messageParser->require_val(pbelle_sip_messageParser)
* -
belle_sip_messageParser_content_disposition_value_return
pbelle_sip_messageParser->content_disposition_value(pbelle_sip_messageParser)
* -
......@@ -2861,6 +2867,35 @@ typedef struct belle_sip_messageParser_header_supported_SCOPE_struct
belle_sip_messageParser_header_supported_SCOPE, * pbelle_sip_messageParser_header_supported_SCOPE;
/* ruleAttributeScopeDecl(scope)
*/
/* makeScopeSet()
*/
/** Definition of the header_require scope variable tracking
* structure. An instance of this structure is created by calling
* belle_sip_messageParser_header_requirePush().
*/
typedef struct belle_sip_messageParser_header_require_SCOPE_struct
{
/** Function that the user may provide to be called when the
* scope is destroyed (so you can free pANTLR3_HASH_TABLES and so on)
*
* \param POinter to an instance of this typedef/struct
*/
void (ANTLR3_CDECL *free) (struct belle_sip_messageParser_header_require_SCOPE_struct * frame);
/* =============================================================================
* Programmer defined variables...
*/
belle_sip_header_require_t* current;
/* End of programmer defined variables
* =============================================================================
*/
}
belle_sip_messageParser_header_require_SCOPE, * pbelle_sip_messageParser_header_require_SCOPE;
/* ruleAttributeScopeDecl(scope)
*/
/* makeScopeSet()
......@@ -3869,6 +3904,17 @@ struct belle_sip_messageParser_Ctx_struct
pbelle_sip_messageParser_header_supported_SCOPE pbelle_sip_messageParser_header_supportedTop;
/* ruleAttributeScopeDef(scope)
*/
/** Pointer to the header_require stack for use by pbelle_sip_messageParser_header_requirePush()
* and pbelle_sip_messageParser_header_requirePop()
*/
pANTLR3_STACK pbelle_sip_messageParser_header_requireStack;
ANTLR3_UINT32 pbelle_sip_messageParser_header_requireStack_limit;
pbelle_sip_messageParser_header_require_SCOPE (*pbelle_sip_messageParser_header_requirePush)(struct belle_sip_messageParser_Ctx_struct * ctx);
pbelle_sip_messageParser_header_require_SCOPE pbelle_sip_messageParser_header_requireTop;
/* ruleAttributeScopeDef(scope)
*/
/** Pointer to the header_content_disposition stack for use by pbelle_sip_messageParser_header_content_dispositionPush()
......@@ -4627,6 +4673,12 @@ struct belle_sip_messageParser_Ctx_struct
void
(*supported_val) (struct belle_sip_messageParser_Ctx_struct * ctx);
belle_sip_header_require_t*
(*header_require) (struct belle_sip_messageParser_Ctx_struct * ctx);
void
(*require_val) (struct belle_sip_messageParser_Ctx_struct * ctx);
belle_sip_messageParser_content_disposition_value_return
(*content_disposition_value) (struct belle_sip_messageParser_Ctx_struct * ctx);
......
This diff is collapsed.
......@@ -452,6 +452,24 @@ static void test_route_header(void) {
}
static void test_rseq_header()
{
belle_sip_header_t* L_tmp;
belle_sip_header_t* L_rseq;
char* l_raw_header = NULL;
L_rseq = belle_sip_header_parse("RSeq: 3344");
l_raw_header = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_rseq));
belle_sip_object_unref(BELLE_SIP_OBJECT(L_rseq));
L_tmp = belle_sip_header_parse(l_raw_header);
L_rseq = BELLE_SIP_HEADER(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
belle_sip_free(l_raw_header);
BC_ASSERT_STRING_EQUAL(belle_sip_header_get_unparsed_value(L_rseq), "3344");
belle_sip_object_unref(L_rseq);
}
static void test_service_route_header(void) {
belle_sip_header_service_route_t* L_service_route = belle_sip_header_service_route_parse("Service-Route: <sip:orig@scscf.ims.linphone.com:6060;lr>");
belle_sip_uri_t* L_uri;
......@@ -560,6 +578,23 @@ static void test_proxy_authorization_header(void) {
BC_ASSERT_PTR_NULL(belle_sip_header_proxy_authorization_parse("nimportequoi"));
}
static void test_rack_header(void ) {
belle_sip_header_t* L_tmp;
belle_sip_header_t* L_rseq;
char* l_raw_header = NULL;
L_rseq = belle_sip_header_parse("RAck: 3344 101 INVITE");
l_raw_header = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_rseq));
belle_sip_object_unref(BELLE_SIP_OBJECT(L_rseq));
L_tmp = belle_sip_header_parse(l_raw_header);
L_rseq = BELLE_SIP_HEADER(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
belle_sip_free(l_raw_header);
BC_ASSERT_STRING_EQUAL(belle_sip_header_get_unparsed_value(L_rseq), "3344 101 INVITE");
belle_sip_object_unref(L_rseq);
}
static void check_header_authenticate(belle_sip_header_www_authenticate_t* authenticate) {
belle_sip_list_t* qop;
BC_ASSERT_PTR_NOT_NULL(authenticate);
......@@ -718,7 +753,7 @@ static void test_expires_header(void) {
static void test_allow_header(void) {
belle_sip_header_allow_t* L_tmp;
belle_sip_header_allow_t* L_allow = belle_sip_header_allow_parse("Allow:INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
belle_sip_header_allow_t* L_allow = belle_sip_header_allow_parse("Allow:INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, PRACK");
char* l_raw_header = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_allow));
belle_sip_object_unref(BELLE_SIP_OBJECT(L_allow));
L_tmp = belle_sip_header_allow_parse(l_raw_header);
......@@ -726,7 +761,7 @@ static void test_allow_header(void) {
belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
belle_sip_free(l_raw_header);
BC_ASSERT_STRING_EQUAL(belle_sip_header_allow_get_method(L_allow), "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
BC_ASSERT_STRING_EQUAL(belle_sip_header_allow_get_method(L_allow), "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, PRACK");
belle_sip_object_unref(BELLE_SIP_OBJECT(L_allow));
BC_ASSERT_PTR_NULL(belle_sip_header_allow_parse("nimportequoi"));
}
......@@ -983,6 +1018,41 @@ static void test_replaces_escaped_header(void) {
}
static void test_require(const char* header_name, const char * header_value, const char* values[],size_t number_values){
belle_sip_list_t* list;
belle_sip_header_require_t* L_tmp;
belle_sip_header_require_t* L_require = BELLE_SIP_HEADER_REQUIRE(belle_sip_header_create(header_name,header_value));
char* l_raw_header = belle_sip_object_to_string(BELLE_SIP_OBJECT(L_require));
size_t i=0;
belle_sip_object_unref(BELLE_SIP_OBJECT(L_require));
L_tmp = belle_sip_header_require_parse(l_raw_header);
L_require = BELLE_SIP_HEADER_REQUIRE(belle_sip_object_clone(BELLE_SIP_OBJECT(L_tmp)));
belle_sip_object_unref(BELLE_SIP_OBJECT(L_tmp));
belle_sip_free(l_raw_header);
list = belle_sip_header_require_get_require(L_require);
for(i=0;i<number_values;i++){
BC_ASSERT_PTR_NOT_NULL(list);
if (list) {
BC_ASSERT_STRING_EQUAL((const char *)(list->data),values[i]);
list=list->next;
}
}
belle_sip_object_unref(BELLE_SIP_OBJECT(L_require));
BC_ASSERT_PTR_NULL(belle_sip_header_require_parse("nimportequoi"));
}
static void test_header_require(void) {
const char* value1[] ={"user","critical"};
const char* value2[] ={"id"};
const char* value3[] ={"100rel"};
test_require("Require","user, critical",value1,2);
test_require("Require", "id",value2,1);
test_require("Require", "100rel", value3, 1);
}
#ifndef _WIN32
static void _test_date_header(void){
belle_sip_header_date_t *date,*date2;
......@@ -1122,11 +1192,14 @@ static void test_supported(const char* header_name, const char * header_value, c
belle_sip_object_unref(BELLE_SIP_OBJECT(L_supported));
BC_ASSERT_PTR_NULL(belle_sip_header_supported_parse("nimportequoi"));
}
static void test_supported_header(void) {
const char* value1[] ={"user","critical"};
const char* value2[] ={"id"};
const char* value3[] ={"100rel"};
test_supported("Supported","user, critical",value1,2);
test_supported("Supported", "id",value2,1);
test_supported("Supported", "100rel", value3, 1);
}
static void test_content_disposition_header(void) {
......@@ -1276,12 +1349,15 @@ test_t headers_tests[] = {
TEST_NO_TAG("P-Preferred-Identity", test_p_preferred_identity_header),
TEST_NO_TAG("Proxy-Authenticate", test_proxy_authenticate_header),
TEST_NO_TAG("Proxy-Authorization", test_proxy_authorization_header),
TEST_NO_TAG("RAck", test_rack_header),
TEST_NO_TAG("Record-Route", test_record_route_header),
TEST_NO_TAG("Refer-To", test_refer_to_header),
TEST_NO_TAG("Referred-By", test_referred_by_header),
TEST_NO_TAG("Replaces", test_replaces_header),
TEST_NO_TAG("Replaces (Escaped)", test_replaces_escaped_header),
TEST_NO_TAG("Require", test_header_require),
TEST_NO_TAG("Route", test_route_header),
TEST_NO_TAG("RSeq", test_rseq_header),
TEST_NO_TAG("Service-Route", test_service_route_header),
TEST_NO_TAG("Subscription-State", test_subscription_state_header),
TEST_NO_TAG("To", test_to_header),
......
......@@ -18,6 +18,7 @@
#include "belle-sip/belle-sip.h"
#include "belle_sip_tester.h"
#include "belle_sip_internal.h"
static void check_uri_and_headers(belle_sip_message_t* message) {
......@@ -97,9 +98,10 @@ static void testInviteMessage(void) {
"From: \"Benjamin Cheong\" <sip:bcheong@sip.linphone.org>;tag=7326e5f6\r\n"\
"Call-ID: Y2NlNzg0ODc0ZGIxODU1MWI5MzhkNDVkNDZhOTQ4YWU.\r\n"\
"CSeq: 1 INVITE\r\n"\
"Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO\r\n"\
"Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, PRACK\r\n"\
"c: application/sdp\r\n"\
"Supported: replaces\r\n"\
"Supported: 100rel\r\n"\
"Authorization: Digest username=\"003332176\", realm=\"sip.ovh.net\", nonce=\"24212965507cde726e8bc37e04686459\", uri=\"sip:sip.ovh.net\", response=\"896e786e9c0525ca3085322c7f1bce7b\", algorithm=MD5, opaque=\"241b9fb347752f2\"\r\n"\
"User-Agent: X-Lite 4 release 4.0 stamp 58832\r\n"\
"Content-Length: 230\r\n\r\n";
......@@ -113,6 +115,24 @@ static void testInviteMessage(void) {
BC_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Contact"));
BC_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Authorization"));
BC_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Content-Type"));
belle_sip_header_supported_t* header_support;
BC_ASSERT_PTR_NOT_NULL(header_support=BELLE_SIP_HEADER_SUPPORTED(belle_sip_message_get_header(message,"Supported")));
if (header_support) {
belle_sip_list_t* list;
list = belle_sip_header_supported_get_supported(header_support);
BC_ASSERT_PTR_NOT_NULL(list);
const char* value[] = {"replaces", "100rel"};
int num_supported = 2;
int i;
for(i = 0; i < num_supported; i++){
if (list) {
BC_ASSERT_STRING_EQUAL((const char *)(list->data), value[i]);
list=list->next;
}
}
}
check_uri_and_headers(message);
belle_sip_object_unref(message);
belle_sip_free(encoded_message);
......@@ -388,7 +408,6 @@ static void testMalformedMessageWithWrongStart(void) {
belle_sip_message_t* message = belle_sip_message_parse(raw_message);
BC_ASSERT_PTR_NULL(message);
}
#include "belle_sip_internal.h"
void channel_parser_tester_recovery_from_error_base (const char* prelude,const char* raw_message) {
......
......@@ -353,58 +353,66 @@ void unregister_user(belle_sip_stack_t * stack
belle_sip_provider_remove_sip_listener(prov,l);
}
belle_sip_request_t* try_register_user_at_domain(belle_sip_stack_t * stack
static belle_sip_request_t* create_registration_request(belle_sip_stack_t * stack
,belle_sip_provider_t *prov
,const char *transport
,int use_transaction
,const char* username
,const char* domain
,const char* outbound_proxy
,int success_expected) {
belle_sip_request_t *req,*copy;
,const char* domain) {
belle_sip_request_t *req;
char identity[256];
char uri[256];
int i;
char *outbound=NULL;
int do_manual_retransmissions = FALSE;
number_of_challenge=0;
if (transport)
snprintf(uri,sizeof(uri),"sip:%s;transport=%s",domain,transport);
else snprintf(uri,sizeof(uri),"sip:%s",domain);
if (transport && strcasecmp("tls",transport)==0 && belle_sip_provider_get_listening_point(prov,"tls")==NULL){
belle_sip_error("No TLS support, test skipped.");
return NULL;
}
if (outbound_proxy){
if (strstr(outbound_proxy,"sip:")==NULL && strstr(outbound_proxy,"sips:")==NULL){
outbound=belle_sip_strdup_printf("sip:%s",outbound_proxy);
}else outbound=belle_sip_strdup(outbound_proxy);
}
else snprintf(uri,sizeof(uri),"sip:%s",domain);
if (transport && strcasecmp("tls",transport)==0 && belle_sip_provider_get_listening_point(prov,"tls")==NULL){
belle_sip_error("No TLS support, test skipped.");
return NULL;
}
snprintf(identity,sizeof(identity),"Tester <sip:%s@%s>",username,domain);
req=belle_sip_request_create(
belle_sip_uri_parse(uri),
"REGISTER",
belle_sip_provider_create_call_id(prov),
belle_sip_header_cseq_create(20,"REGISTER"),
belle_sip_header_from_create2(identity,BELLE_SIP_RANDOM_TAG),
belle_sip_header_to_create2(identity,NULL),
belle_sip_header_via_new(),
70);
belle_sip_uri_parse(uri),
"REGISTER",
belle_sip_provider_create_call_id(prov),
belle_sip_header_cseq_create(20,"REGISTER"),
belle_sip_header_from_create2(identity,BELLE_SIP_RANDOM_TAG),
belle_sip_header_to_create2(identity,NULL),
belle_sip_header_via_new(),
70);
belle_sip_object_ref(req);
is_register_ok=0;
io_error_count=0;
using_transaction=0;
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(600)));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_contact_new()));
copy=(belle_sip_request_t*)belle_sip_object_ref(belle_sip_object_clone((belle_sip_object_t*)req));
return req;
}
static void execute_registration(belle_sip_stack_t * stack,
belle_sip_provider_t *prov,
belle_sip_client_transaction_t *trans,
belle_sip_request_t *req,
const char *transport,
const char* outbound_proxy,
int success_expected){
int do_manual_retransmissions = FALSE;
int use_transaction = trans ? 1 : 0;
int i;
char *outbound=NULL;
if (outbound_proxy){
if (strstr(outbound_proxy,"sip:")==NULL && strstr(outbound_proxy,"sips:")==NULL){
outbound=belle_sip_strdup_printf("sip:%s",outbound_proxy);
}else outbound=belle_sip_strdup(outbound_proxy);
}
belle_sip_provider_add_sip_listener(prov,l=BELLE_SIP_LISTENER(listener));
if (use_transaction){
belle_sip_client_transaction_t *t=belle_sip_provider_create_client_transaction(prov,req);
belle_sip_client_transaction_send_request_to(t,outbound?belle_sip_uri_parse(outbound):NULL);
if (trans){
belle_sip_client_transaction_send_request_to(trans,outbound?belle_sip_uri_parse(outbound):NULL);
}else{
belle_sip_provider_send_request(prov,req);
do_manual_retransmissions = (transport == NULL) || (strcasecmp(transport,"udp") == 0);
......@@ -418,10 +426,31 @@ belle_sip_request_t* try_register_user_at_domain(belle_sip_stack_t * stack
}
BC_ASSERT_EQUAL(is_register_ok,success_expected,int,"%d");
if (success_expected) BC_ASSERT_EQUAL(using_transaction,use_transaction,int,"%d");
belle_sip_object_unref(req);
belle_sip_provider_remove_sip_listener(prov,l);
if (outbound) belle_sip_free(outbound);
}
belle_sip_request_t* try_register_user_at_domain(belle_sip_stack_t * stack
,belle_sip_provider_t *prov
,const char *transport
,int use_transaction
,const char* username
,const char* domain
,const char* outbound_proxy
,int success_expected) {
belle_sip_request_t *req,*copy = NULL;
req = create_registration_request(stack, prov, transport, username, domain);
if (req)
{
copy = (belle_sip_request_t*)belle_sip_object_ref(belle_sip_object_clone((belle_sip_object_t*)req));
belle_sip_client_transaction_t *t = use_transaction ? belle_sip_provider_create_client_transaction(prov,req) : NULL;
execute_registration(stack, prov, t, req, transport, outbound_proxy, success_expected);
belle_sip_object_unref(req);
}
return copy;
}
......@@ -445,6 +474,25 @@ belle_sip_request_t* register_user(belle_sip_stack_t * stack
return register_user_at_domain(stack,prov,transport,use_transaction,username,test_domain,outbound);
}
belle_sip_client_transaction_t* register_user_with_transaction(belle_sip_stack_t * stack
,belle_sip_provider_t *prov
,const char *transport
,const char* username
,const char* outbound_proxy) {