Commit 007bf313 authored by Simon Morlat's avatar Simon Morlat

add date header.

parent c0f1c137
......@@ -28,6 +28,8 @@
**/
BELLE_SIP_DECLARE_TYPES_BEGIN(belle_sip,1)
BELLE_SIP_TYPE_ID(belle_sip_stack_t),
BELLE_SIP_TYPE_ID(belle_sip_hop_t),
BELLE_SIP_TYPE_ID(belle_sip_object_pool_t),
BELLE_SIP_TYPE_ID(belle_sip_listening_point_t),
BELLE_SIP_TYPE_ID(belle_sip_datagram_listening_point_t),
BELLE_SIP_TYPE_ID(belle_sip_udp_listening_point_t),
......@@ -104,8 +106,8 @@ BELLE_SIP_DECLARE_TYPES_BEGIN(belle_sip,1)
BELLE_SIP_TYPE_ID(belle_sip_header_refer_to_t),
BELLE_SIP_TYPE_ID(belle_sip_header_referred_by_t),
BELLE_SIP_TYPE_ID(belle_sip_header_replaces_t),
BELLE_SIP_TYPE_ID(belle_sip_hop_t),
BELLE_SIP_TYPE_ID(belle_sip_object_pool_t)
BELLE_SIP_TYPE_ID(belle_sip_header_date_t)
BELLE_SIP_DECLARE_TYPES_END
......
......@@ -22,6 +22,7 @@
#include "belle-sip/defs.h"
#include "belle-sip/uri.h"
#include <time.h>
/***************************************************************************************
......@@ -564,6 +565,26 @@ BELLESIP_EXPORT char* belle_sip_header_replaces_value_to_escaped_string(const be
#define BELLE_SIP_HEADER_REPLACES(t) BELLE_SIP_CAST(t,belle_sip_header_replaces_t)
#define BELLE_SIP_REPLACES "Replaces"
/*******
* Date header
*******/
typedef struct belle_sip_header_date belle_sip_header_date_t;
BELLESIP_EXPORT belle_sip_header_date_t* belle_sip_header_date_new();
BELLESIP_EXPORT belle_sip_header_date_t* belle_sip_header_date_parse(const char* date) ;
BELLESIP_EXPORT belle_sip_header_date_t* belle_sip_header_date_create_from_time(const time_t *utc_time);
BELLESIP_EXPORT time_t belle_sip_header_date_get_time(belle_sip_header_date_t *obj);
BELLESIP_EXPORT void belle_sip_header_date_set_time(belle_sip_header_date_t *obj, const time_t *utc_time);
BELLESIP_EXPORT const char * belle_sip_header_date_get_date(const belle_sip_header_date_t *obj);
BELLESIP_EXPORT void belle_sip_header_date_set_date(belle_sip_header_date_t *obj, const char *date);
#define BELLE_SIP_HEADER_DATE(obj) BELLE_SIP_CAST(obj,belle_sip_header_date_t)
#define BELLE_SIP_DATE "Date"
#endif /* HEADERS_H_ */
......@@ -1235,7 +1235,7 @@ HEADER_TO_LIKE_IMPL(referred_by,BELLE_SIP_REFERRED_BY)
*/
struct _belle_sip_header_replaces {
belle_sip_parameters_t parameters;
const char* call_id;
char* call_id;
};
static void belle_sip_header_replaces_destroy(belle_sip_header_replaces_t* replaces) {
......@@ -1289,6 +1289,7 @@ char* belle_sip_header_replaces_value_to_escaped_string(const belle_sip_header_r
buff[current_offset]='\0';
return belle_sip_to_escaped_string(buff);
}
belle_sip_header_replaces_t* belle_sip_header_replaces_create(const char* call_id,const char* from_tag,const char* to_tag) {
belle_sip_header_replaces_t* replaces=belle_sip_header_replaces_new();
belle_sip_header_replaces_set_call_id(replaces,call_id);
......@@ -1296,3 +1297,88 @@ belle_sip_header_replaces_t* belle_sip_header_replaces_create(const char* call_i
belle_sip_header_replaces_set_to_tag(replaces,to_tag);
return replaces;
}
struct belle_sip_header_date{
belle_sip_header_t base;
char *date;
};
static void belle_sip_header_date_destroy(belle_sip_header_date_t* obj) {
DESTROY_STRING(obj,date);
}
static void belle_sip_header_date_clone(belle_sip_header_date_t* obj,
const belle_sip_header_date_t *orig ) {
CLONE_STRING(belle_sip_header_date,date,obj,orig);
}
int belle_sip_header_date_marshal(belle_sip_header_date_t* obj, char* buff,unsigned int offset,unsigned int buff_size) {
unsigned int current_offset=offset;
current_offset+=belle_sip_header_marshal(BELLE_SIP_HEADER(obj), buff,current_offset, buff_size);
current_offset+=snprintf(buff+current_offset,buff_size-current_offset,"%s",obj->date);
return current_offset-offset;
}
BELLE_SIP_NEW_HEADER(header_date,header,BELLE_SIP_DATE)
BELLE_SIP_PARSE(header_date)
BELLESIP_EXPORT belle_sip_header_date_t* belle_sip_header_date_create_from_time(const time_t *utc_time){
belle_sip_header_date_t *obj=belle_sip_header_date_new();
belle_sip_header_date_set_time(obj,utc_time);
return obj;
}
static const char *days[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
static const char *months[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
BELLESIP_EXPORT time_t belle_sip_header_date_get_time(belle_sip_header_date_t *obj){
struct tm ret={0};
char tmp1[16]={0};
char tmp2[16]={0};
int i,j;
time_t seconds;
sscanf(obj->date,"%3c,%d %16s %d %d:%d:%d",tmp1,&ret.tm_mday,tmp2,
&ret.tm_year,&ret.tm_hour,&ret.tm_min,&ret.tm_sec);
ret.tm_year-=1900;
for(i=0;i<7;i++) {
if(strcmp(tmp1,days[i])==0) {
ret.tm_wday=i;
for(j=0;j<12;j++) {
if(strcmp(tmp2,months[j])==0) {
ret.tm_mon=j;
goto success;
}
}
}
}
belle_sip_warning("Failed to parse date %s",obj->date);
return (time_t)-1;
success:
ret.tm_isdst=0;
seconds=mktime(&ret);
if (seconds==(time_t)-1){
belle_sip_error("mktime() failed: %s",strerror(errno));
return (time_t)-1;
}
return seconds-timezone;
}
BELLESIP_EXPORT void belle_sip_header_date_set_time(belle_sip_header_date_t *obj, const time_t *utc_time){
struct tm *ret;
#ifndef WIN32
struct tm gmt;
ret=gmtime_r(utc_time,&gmt);
#else
ret=gmtime(utc_time);
#endif
/*cannot use strftime because it is locale dependant*/
belle_sip_header_date_set_date(obj,
belle_sip_strdup_printf("%s, %i %s %i %02i:%02i:%02i GMT",
days[ret->tm_wday],ret->tm_mday,months[ret->tm_mon],1900+ret->tm_year,ret->tm_hour,ret->tm_min,ret->tm_sec));
}
GET_SET_STRING(belle_sip_header_date,date);
......@@ -183,6 +183,7 @@ BELLE_SIP_DECLARE_VPTR(belle_sip_header_service_route_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_refer_to_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_referred_by_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_replaces_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_header_date_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_hop_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_object_pool_t);
......@@ -258,8 +259,7 @@ BELLESIP_INTERNAL_EXPORT char *belle_sip_strdup_printf(const char *fmt,...);
void object_type##_set_##attribute (object_type##_t* obj,const char* value) {\
if (obj->attribute != NULL) belle_sip_free((void*)obj->attribute);\
if (value) {\
obj->attribute=belle_sip_malloc(strlen(value)+1);\
strcpy((char*)(obj->attribute),value);\
obj->attribute=belle_sip_strdup(value); \
} else obj->attribute=NULL;\
}
/*#define GET_SET_STRING_PARAM_NULL_ALLOWED(object_type,attribute) \
......
......@@ -606,11 +606,32 @@ catch [ANTLR3_MISMATCHED_TOKEN_EXCEPTION]
$ret=NULL;
}
seq_number:DIGIT+;
/*Date header*/
date_token: {IS_TOKEN(Date)}? token;
header_date returns [belle_sip_header_date_t* ret]
scope { belle_sip_header_date_t* current; }
@init {$header_date::current = belle_sip_header_date_new(); $ret=$header_date::current; }
: date_token /*( 'Date' )*/ hcolon sip_date{belle_sip_header_date_set_date($header_date::current,(const char*) $sip_date.text->chars); };
catch [ANTLR3_MISMATCHED_TOKEN_EXCEPTION]
{
belle_sip_message("[\%s] reason [\%s]",(const char*)EXCEPTION->name,(const char*)EXCEPTION->message);
belle_sip_object_unref($header_date::current);
$ret=NULL;
}
date
: sip_date;
sip_date
: ~(CRLF)* ;
/*
date
: 'Date' HCOLON sip_date;
sip_date
: token;// rfc1123-date
// rfc1123-date
//rfc1123-date = wkday "," SP date1 SP time SP "GMT"
//date1 = 2DIGIT SP month SP 4DIGIT
// ; day month year (e.g., 02 Jun 1982)
......
......@@ -665,10 +665,21 @@ static void test_replaces_escaped_header(void) {
CU_ASSERT_STRING_EQUAL(belle_sip_header_replaces_get_call_id(L_replaces), "12345@192.168.118.3");
CU_ASSERT_STRING_EQUAL(belle_sip_header_replaces_get_from_tag(L_replaces), "5FFE-3994");
CU_ASSERT_STRING_EQUAL(belle_sip_header_replaces_get_to_tag(L_replaces), "12345");
belle_sip_object_unref(BELLE_SIP_OBJECT(L_replaces));
}
static void test_date_header(void){
belle_sip_header_date_t *date,*date2;
time_t utc;
#define DATE_EXAMPLE "Thu, 21 Feb 2002 13:02:03 GMT"
date=belle_sip_header_date_parse("Date: " DATE_EXAMPLE);
CU_ASSERT_PTR_NOT_NULL(date);
utc=belle_sip_header_date_get_time(date);
CU_ASSERT_TRUE(utc!=(time_t)-1);
date2=belle_sip_header_date_create_from_time(&utc);
CU_ASSERT_PTR_NOT_NULL(date2);
CU_ASSERT_TRUE(strcmp(belle_sip_header_date_get_date(date2),DATE_EXAMPLE)==0);
}
......@@ -686,6 +697,7 @@ test_t headers_tests[] = {
{ "Content-Length", test_content_length_header },
{ "Content-Type", test_content_type_header },
{ "CSeq", test_cseq_header },
{ "Date", test_date_header },
{ "Expires", test_expires_header },
{ "From", test_from_header },
{ "From (Param-less address spec)", test_from_header_with_paramless_address_spec },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment