Use name unions to overcome C99 limitation.

This commit is contained in:
bossiel 2010-05-25 11:13:21 +00:00
parent b77b4815f2
commit 16749d42b5
42 changed files with 175 additions and 209 deletions

View File

@ -62,12 +62,6 @@ int stack_callback(const tsip_event_t *sipevent)
return -1;
}
/* check if it's for our stack */
if(sipevent->stack != ctx->stack){
TSK_DEBUG_ERROR("We have received an event for another stack");
return -2;
}
tsk_safeobj_lock(ctx);
switch(sipevent->type){

View File

@ -4,9 +4,9 @@
%%domain ericsson.com
%%user bob
%%pwd bob
%%proxy_ip 192.168.0.13 # IP address or FQDN
%%proxy_port 5081
%%proxy_trans tcp # udp, tcp, tls or sctp
%%proxy_ip 192.168.16.104 # IP address or FQDN
%%proxy_port 5060
%%proxy_trans udp # udp, tcp, tls or sctp
%%expires 100 # expires used by all dialogs
%%sleep-sec 1.0 # number of seconds to wait before sending next sip message
@ -20,7 +20,7 @@
# Configure the stack
# Realm, IMPI and IMPU are mandatory
++cst --realm $$(domain) --impi $$(user)@$$(domain) --impu sip:$$(user)@$$(domain) --pwd $$(pwd) \
--pcscf-ip $$(proxy_ip) --pcscf-port $$(proxy_port) --pcscf-trans $$(proxy_trans) \
--pcscf-ip $$(proxy_ip) --pcscf-port $$(proxy_port) --pcscf-trans $$(proxy_trans) --local-ip 10.0.2.15 \
--header Privacy=header;id --header Allow=INVITE, ACK, CANCEL, BYE, MESSAGE, OPTIONS, NOTIFY, PRACK, UPDATE, REFER \
--header P-Access-Network-Info=ADSL;utran-cell-id-3gpp=00000000 \
--header User-Agent=IM-client/OMA1.0 doubango/v1.0.0 # last should not have backslash

View File

@ -35,39 +35,39 @@
#++sleep --sec $$(sleep-sec)
# subscribe to reg event package
#++sub --to sip:$$(user)@$$(domain) --xp $$(expires) --header Event=reg --header Accept=application/reginfo+xml \
# --header Allow-Events=refer, presence, presence.winfo, xcap-diff, conference >>(sub-reg-sid)
++sub --to sip:$$(user)@$$(domain) --xp $$(expires) --header Event=reg --header Accept=application/reginfo+xml \
--header Allow-Events=refer, presence, presence.winfo, xcap-diff, conference >>(sub-reg-sid)
#subscribe to presence event package (alice)
#++sub --to sip:alice@$$(domain) --xp $$(expires) --header Event=presence --header Supported=eventlist\
# --header Accept=multipart/related, application/rlmi+xml, application/pidf+xml, application/rpid+xml, application/xcap-diff+xml, message/external-body \
# --header Allow-Events=refer, presence, presence.winfo, xcap-diff, conference >>(sub-pres-sid)
++sub --to sip:alice@$$(domain) --xp $$(expires) --header Event=presence --header Supported=eventlist\
--header Accept=multipart/related, application/rlmi+xml, application/pidf+xml, application/rpid+xml, application/xcap-diff+xml, message/external-body \
--header Allow-Events=refer, presence, presence.winfo, xcap-diff, conference >>(sub-pres-sid)
#publish
#++sn --path ./publish.sn
++sn --path ./publish.sn
++sleep --sec -1 # Press ENTER
# MESSAGE
#++m --to sip:mercuro2@$$(domain) --pay Test SMS-RPDATA --header Content-Type=application/vnd.3gpp.sms --header Transfer-Encoding=binary
++m --to sip:mercuro2@$$(domain) --pay Test SMS-RPDATA --header Content-Type=application/vnd.3gpp.sms --header Transfer-Encoding=binary
# sleep
++sleep --sec -1 # Press ENTER
# unsunscribe (reg and pres)
#++hu --sid $$(sub-reg-sid)
#++hu --sid $$(sub-pres-sid)
#++hu --sid $$(pub-sid)
++hu --sid $$(sub-reg-sid)
++hu --sid $$(sub-pres-sid)
++hu --sid $$(pub-sid)
# sleep
#++sleep --sec $$(sleep-sec)
++sleep --sec $$(sleep-sec)
# unregister
#++hu --sid $$(reg-sid)
++hu --sid $$(reg-sid)
# sleep
#++sleep --sec $$(sleep-sec)
++sleep --sec $$(sleep-sec)
# Exit the application
++e

View File

@ -5,13 +5,13 @@
#++sn --path ./core-colibria.sn
# Ericsson
++sn --path ./core-ericsson.sn
#++sn --path ./core-ericsson.sn
# Inexbee
#++sn --path ./core-inexbee.sn
# Micromethod
#++sn --path ./core-micromethod.sn
++sn --path ./core-micromethod.sn
# Nokia Siemens Networks
#++sn --path ./core-nsn.sn

View File

@ -100,7 +100,7 @@ typedef enum thttp_stack_param_type_e
/* User Data */
pname_userdata,
#define THHTP_STACK_SET_USERDATA(USERDATA_PTR) pname_userdata, (const void*)USERDATA_PTR
#define THTTP_STACK_SET_USERDATA(USERDATA_PTR) pname_userdata, (const void*)USERDATA_PTR
}
thttp_stack_param_type_t;

View File

@ -2591,4 +2591,4 @@ _again:
577
/* #line 488 "./ragel/thttp_parser_header.rl" */
) ? 0 : -1;
}
}

View File

@ -52,8 +52,7 @@ thttp_event_t* thttp_event_create(thttp_event_type_t type, const thttp_session_h
static void* thttp_event_ctor(void * self, va_list * app)
{
thttp_event_t *httpevent = self;
if(httpevent)
{
if(httpevent){
httpevent->type = va_arg(*app, thttp_event_type_t);
httpevent->session = va_arg(*app, const thttp_session_handle_t*);
httpevent->description = tsk_strdup( va_arg(*app, const char *) );
@ -65,8 +64,7 @@ static void* thttp_event_ctor(void * self, va_list * app)
static void* thttp_event_dtor(void * self)
{
thttp_event_t *httpevent = self;
if(httpevent)
{
if(httpevent){
TSK_FREE(httpevent->description);
TSK_OBJECT_SAFE_FREE(httpevent->message);
}

View File

@ -116,7 +116,7 @@ typedef struct tmsrp_message_s
tmsrp_message_type_t type;
char* tid;
/*union*/struct{
union{
struct{
char* method;
tmsrp_request_type_t type;

View File

@ -55,7 +55,7 @@ typedef struct tsip_invite_event_e
}
tsip_invite_event_t;
int tsip_invite_event_signal(tsip_invite_event_type_t type, struct tsip_stack_s *stack, tsip_ssession_handle_t* SSESSION, short status_code, const char *phrase, const struct tsip_message_s* sipmessage);
int tsip_invite_event_signal(tsip_invite_event_type_t type, tsip_ssession_handle_t* ss, short status_code, const char *phrase, const struct tsip_message_s* sipmessage);
TINYSIP_GEXTERN const tsk_object_def_t *tsip_invite_event_def_t;

View File

@ -55,7 +55,7 @@ typedef struct tsip_message_event_e
}
tsip_message_event_t;
int tsip_message_event_signal(tsip_message_event_type_t type, struct tsip_stack_s *stack, tsip_ssession_handle_t* ss, short status_code, const char *phrase, const struct tsip_message_s* sipmessage);
int tsip_message_event_signal(tsip_message_event_type_t type, tsip_ssession_handle_t* ss, short status_code, const char *phrase, const struct tsip_message_s* sipmessage);
TINYSIP_API int tsip_action_MESSAGE(const tsip_ssession_handle_t *ss, ...);

View File

@ -57,7 +57,7 @@ typedef struct tsip_options_event_e
}
tsip_options_event_t;
int tsip_options_event_signal(tsip_options_event_type_t type, struct tsip_stack_s *stack, tsip_ssession_handle_t* SSESSION, short status_code, const char *phrase, const struct tsip_message_s* sipmessage);
int tsip_options_event_signal(tsip_options_event_type_t type, tsip_ssession_handle_t* ss, short status_code, const char *phrase, const struct tsip_message_s* sipmessage);
TINYSIP_API int tsip_action_OPTIONS(const tsip_ssession_handle_t *ss, ...);

View File

@ -60,7 +60,7 @@ typedef struct tsip_publish_event_e
}
tsip_publish_event_t;
int tsip_publish_event_signal(tsip_publish_event_type_t type, struct tsip_stack_s *stack, tsip_ssession_handle_t* SSESSION, short status_code, const char *phrase, const struct tsip_message_s* sipmessage);
int tsip_publish_event_signal(tsip_publish_event_type_t type, tsip_ssession_handle_t* ss, short status_code, const char *phrase, const struct tsip_message_s* sipmessage);
TINYSIP_API int tsip_action_PUBLISH(const tsip_ssession_handle_t *ss, ...);
TINYSIP_API int tsip_action_UNPUBLISH(const tsip_ssession_handle_t *ss, ...);

View File

@ -60,7 +60,7 @@ typedef struct tsip_register_event_e
}
tsip_register_event_t;
int tsip_register_event_signal(tsip_register_event_type_t type, struct tsip_stack_s *stack, tsip_ssession_t* ss, short status_code, const char *phrase, const struct tsip_message_s* sipmessage);
int tsip_register_event_signal(tsip_register_event_type_t type, tsip_ssession_t* ss, short status_code, const char *phrase, const struct tsip_message_s* sipmessage);
TINYSIP_API int tsip_action_REGISTER(const tsip_ssession_handle_t *ss, ...);
TINYSIP_API int tsip_action_UNREGISTER(const tsip_ssession_handle_t *ss, ...);

View File

@ -65,7 +65,7 @@ typedef struct tsip_subscribe_event_e
}
tsip_subscribe_event_t;
int tsip_subscribe_event_signal(tsip_subscribe_event_type_t type, struct tsip_stack_s *stack, tsip_ssession_t* ss, short status_code, const char *phrase, const struct tsip_message_s* sipmessage);
int tsip_subscribe_event_signal(tsip_subscribe_event_type_t type, tsip_ssession_t* ss, short status_code, const char *phrase, const struct tsip_message_s* sipmessage);
TINYSIP_API int tsip_action_SUBSCRIBE(const tsip_ssession_handle_t *ss, ...);
TINYSIP_API int tsip_action_UNSUBSCRIBE(const tsip_ssession_handle_t *ss, ...);

View File

@ -61,7 +61,7 @@ TSIP_BEGIN_DECLS
self->timer##TX.id = tsk_timer_manager_schedule(TSIP_DIALOG_GET_STACK(self)->timer_mgr, self->timer##TX.timeout, TSK_TIMER_CALLBACK_F(tsip_dialog_##name##_timer_callback), self)
#define TSIP_DIALOG_SIGNAL(self, type, code, phrase) \
tsip_event_signal(type, TSIP_DIALOG_GET_STACK(self), TSIP_DIALOG(self)->ss, code, phrase)
tsip_event_signal(type, TSIP_DIALOG(self)->ss, code, phrase)
#define TSIP_DIALOG_SHUTDOWN_TIMEOUT 2000 /* miliseconds. */

View File

@ -75,7 +75,6 @@ typedef struct tsip_event_s
{
TSK_DECLARE_OBJECT;
tsip_stack_handle_t * stack;
tsip_ssession_handle_t* ss;
short code;
@ -89,8 +88,8 @@ tsip_event_t;
TINYSIP_GEXTERN const tsk_object_def_t *tsip_event_def_t;
int tsip_event_init(tsip_event_t* self, struct tsip_stack_s *stack, tsip_ssession_t* ss, short code, const char *phrase, const struct tsip_message_s* sipmessage, tsip_event_type_t type);
int tsip_event_signal(tsip_event_type_t type, struct tsip_stack_s *stack, tsip_ssession_t* ss, short code, const char *phrase);
int tsip_event_init(tsip_event_t* self, tsip_ssession_t* ss, short code, const char *phrase, const struct tsip_message_s* sipmessage, tsip_event_type_t type);
int tsip_event_signal(tsip_event_type_t type, tsip_ssession_t* ss, short code, const char *phrase);
int tsip_event_deinit(tsip_event_t* self);
typedef int (*tsip_stack_callback_f)(const tsip_event_t *sipevent);

View File

@ -63,11 +63,11 @@ TSIP_BEGIN_DECLS
#define TSIP_MESSAGE_AS_REQUEST(self) ((tsip_request_t*)(self))
#define TSIP_RESPONSE_CODE(self) (TSIP_MESSAGE_IS_RESPONSE((self)) ? (self)->status_code : 0)
#define TSIP_RESPONSE_PHRASE(self) (TSIP_MESSAGE_IS_RESPONSE((self)) ? (self)->reason_phrase : tsk_null)
#define TSIP_RESPONSE_CODE(self) (TSIP_MESSAGE_IS_RESPONSE((self)) ? (self)->line.response.status_code : 0)
#define TSIP_RESPONSE_PHRASE(self) (TSIP_MESSAGE_IS_RESPONSE((self)) ? (self)->line.response.reason_phrase : tsk_null)
#define TSIP_REQUEST_METHOD(self) ((self)->method)
#define TSIP_REQUEST_URI(self) ((self)->uri)
#define TSIP_REQUEST_METHOD(self) ((self)->line.request.method)
#define TSIP_REQUEST_URI(self) ((self)->line.request.uri)
#define TSIP_MESSAGE_CSEQ_METHOD(self) ((self)->CSeq ? (self)->CSeq->method : tsk_null)
#define TSIP_MESSAGE_HAS_CONTENT(self) ((self) && (self)->Content && (self)->Content->data)
@ -76,20 +76,20 @@ TSIP_BEGIN_DECLS
#define TSIP_MESSAGE_CONTENT(self) (TSIP_MESSAGE_HAS_CONTENT(self) ? (self)->Content : tsk_null)
#define TSIP_MESSAGE_CONTENT_TYPE(self) (((self) && (self)->Content_Type) ? (self)->Content_Type->type : tsk_null)
#define TSIP_REQUEST_IS_ACK(self) ((self) &&((self)->request_type==tsip_ACK))
#define TSIP_REQUEST_IS_BYE(self) ((self) &&((self)->request_type==tsip_BYE))
#define TSIP_REQUEST_IS_CANCEL(self) ((self) &&((self)->request_type==tsip_CANCEL))
#define TSIP_REQUEST_IS_INVITE(self) ((self) &&((self)->request_type==tsip_INVITE))
#define TSIP_REQUEST_IS_OPTIONS(self) ((self) &&((self)->request_type==tsip_OPTIONS))
#define TSIP_REQUEST_IS_REGISTER(self) ((self) &&((self)->request_type==tsip_REGISTER))
#define TSIP_REQUEST_IS_SUBSCRIBE(self) ((self) &&((self)->request_type==tsip_SUBSCRIBE))
#define TSIP_REQUEST_IS_NOTIFY(self) ((self) &&((self)->request_type==tsip_NOTIFY))
#define TSIP_REQUEST_IS_REFER(self) ((self) &&((self)->request_type==tsip_REFER))
#define TSIP_REQUEST_IS_INFO(self) ((self) &&((self)->request_type==tsip_INFO))
#define TSIP_REQUEST_IS_UPDATE(self) ((self) &&((self)->request_type==tsip_UPDATE))
#define TSIP_REQUEST_IS_MESSAGE(self) ((self) &&((self)->request_type==tsip_MESSAGE))
#define TSIP_REQUEST_IS_PUBLISH(self) ((self) &&((self)->request_type==tsip_PUBLISH))
#define TSIP_REQUEST_IS_PRACK(self) ((self) &&((self)->request_type==tsip_PRACK))
#define TSIP_REQUEST_IS_ACK(self) ((self) &&((self)->line.request.request_type==tsip_ACK))
#define TSIP_REQUEST_IS_BYE(self) ((self) &&((self)->line.request.request_type==tsip_BYE))
#define TSIP_REQUEST_IS_CANCEL(self) ((self) &&((self)->line.request.request_type==tsip_CANCEL))
#define TSIP_REQUEST_IS_INVITE(self) ((self) &&((self)->line.request.request_type==tsip_INVITE))
#define TSIP_REQUEST_IS_OPTIONS(self) ((self) &&((self)->line.request.request_type==tsip_OPTIONS))
#define TSIP_REQUEST_IS_REGISTER(self) ((self) &&((self)->line.request.request_type==tsip_REGISTER))
#define TSIP_REQUEST_IS_SUBSCRIBE(self) ((self) &&((self)->line.request.request_type==tsip_SUBSCRIBE))
#define TSIP_REQUEST_IS_NOTIFY(self) ((self) &&((self)->line.request.request_type==tsip_NOTIFY))
#define TSIP_REQUEST_IS_REFER(self) ((self) &&((self)->line.request.request_type==tsip_REFER))
#define TSIP_REQUEST_IS_INFO(self) ((self) &&((self)->line.request.request_type==tsip_INFO))
#define TSIP_REQUEST_IS_UPDATE(self) ((self) &&((self)->line.request.request_type==tsip_UPDATE))
#define TSIP_REQUEST_IS_MESSAGE(self) ((self) &&((self)->line.request.request_type==tsip_MESSAGE))
#define TSIP_REQUEST_IS_PUBLISH(self) ((self) &&((self)->line.request.request_type==tsip_PUBLISH))
#define TSIP_REQUEST_IS_PRACK(self) ((self) &&((self)->line.request.request_type==tsip_PRACK))
#define TSIP_RESPONSE_IS(self, code) (TSIP_RESPONSE_CODE((self)) == code)
#define TSIP_RESPONSE_IS_NXX(self, N) (TSIP_MESSAGE_IS_RESPONSE((self)) && N##00<= TSIP_RESPONSE_CODE((self)) && TSIP_RESPONSE_CODE((self)) <= N##99)
@ -189,29 +189,22 @@ typedef struct tsip_message_s
char *sip_version; /**< The SIP version. Only 'SIP/2.0' is supported. */
tsip_message_type_t type; /**< The type of this SIP message. */
#if !defined(__C99__) /* C99 does not allow unnamed structs/unions */
union
{
struct
{
#endif
/* Request Line */
union{
struct{
char *method; /**< SIP method name. e.g REGISTER, ACK or INVITE.*/
tsip_uri_t *uri; /**< The Request-URI is a SIP or SIPS URI as described in Section 19.1 or a general URI (RFC 2396 [5]). It indicates
the user or service to which this request is being addressed. The Request-URI MUST NOT contain unescaped spaces or control
characters and MUST NOT be enclosed in "<>". */
tsip_request_type_t request_type;
#if !defined(__C99__)
};
struct
{
#endif
} request;
struct{
short status_code; /**< 3-digit integer result code that indicates the outcome of an attempt to understand and satisfy a request. */
char *reason_phrase; /**< Textual description related to the status code. */
#if !defined(__C99__)
};
};
} response;
} line;
#endif
/*== MOST COMMON HEADERS. */
tsip_header_Via_t *firstVia; /**< First Via header. */
tsip_header_From_t *From;

View File

@ -53,6 +53,9 @@ typedef uint64_t tsip_ssession_id_t;
# define TSIP_SSESSION_EXPIRES_DEFAULT 600000000
#endif
#define TSIP_SSESSION(self) ((tsip_ssession_t*)(self))
typedef enum tsip_ssession_param_type_e
{
sstype_null = tsk_null,

View File

@ -79,7 +79,7 @@
//
// action parse_uri
// {
// TSK_PARSER_SET_STRING(hdr_Authorization->uri);
// TSK_PARSER_SET_STRING(hdr_Authorization->line.request.uri);
// }
//
// action parse_response
@ -174,9 +174,9 @@
// Authorization->nonce ? Authorization->nonce : "",
// Authorization->nonce ? "\"" : "",
//
// Authorization->uri ? ",uri=\"" : "",
// Authorization->uri ? Authorization->uri : "",
// Authorization->uri ? "\"" : "",
// Authorization->line.request.uri ? ",uri=\"" : "",
// Authorization->line.request.uri ? Authorization->line.request.uri : "",
// Authorization->line.request.uri ? "\"" : "",
//
// Authorization->response ? ",response=\"" : "",
// Authorization->response ? Authorization->response : "",
@ -260,7 +260,7 @@
// TSK_FREE(Authorization->username);
// TSK_FREE(Authorization->realm);
// TSK_FREE(Authorization->nonce);
// TSK_FREE(Authorization->uri);
// TSK_FREE(Authorization->line.request.uri);
// TSK_FREE(Authorization->response);
// TSK_FREE(Authorization->algorithm);
// TSK_FREE(Authorization->cnonce);

View File

@ -79,7 +79,7 @@
//
// action parse_uri
// {
// TSK_PARSER_SET_STRING(hdr_Proxy_Authorization->uri);
// TSK_PARSER_SET_STRING(hdr_Proxy_Authorization->line.request.uri);
// }
//
// action parse_response
@ -175,9 +175,9 @@
// Proxy_Authorization->nonce ? Proxy_Authorization->nonce : "",
// Proxy_Authorization->nonce ? "\"" : "",
//
// Proxy_Authorization->uri ? ",uri=\"" : "",
// Proxy_Authorization->uri ? Proxy_Authorization->uri : "",
// Proxy_Authorization->uri ? "\"" : "",
// Proxy_Authorization->line.request.uri ? ",uri=\"" : "",
// Proxy_Authorization->line.request.uri ? Proxy_Authorization->line.request.uri : "",
// Proxy_Authorization->line.request.uri ? "\"" : "",
//
// Proxy_Authorization->response ? ",response=\"" : "",
// Proxy_Authorization->response ? Proxy_Authorization->response : "",
@ -261,7 +261,7 @@
// TSK_FREE(Proxy_Authorization->username);
// TSK_FREE(Proxy_Authorization->realm);
// TSK_FREE(Proxy_Authorization->nonce);
// TSK_FREE(Proxy_Authorization->uri);
// TSK_FREE(Proxy_Authorization->line.request.uri);
// TSK_FREE(Proxy_Authorization->response);
// TSK_FREE(Proxy_Authorization->algorithm);
// TSK_FREE(Proxy_Authorization->cnonce);

View File

@ -61,11 +61,11 @@ static void tsip_message_parser_eoh(tsk_ragel_state_t *state, tsip_message_t *me
if(message->type == tsip_unknown)
{
message->type = tsip_request;
if(!message->method)
if(!message->line.request.method)
{
message->method = tsk_calloc(1, len+1);
memcpy(message->method, state->tag_start, len);
message->request_type = tsip_request_get_type(message->method);
message->line.request.method = tsk_calloc(1, len+1);
memcpy(message->line.request.method, state->tag_start, len);
message->line.request.request_type = tsip_request_get_type(message->line.request.method);
}
}
else
@ -81,9 +81,9 @@ static void tsip_message_parser_eoh(tsk_ragel_state_t *state, tsip_message_t *me
state->tag_end = p;
len = (int)(state->tag_end - state->tag_start);
if(!message->uri)
if(!message->line.request.uri)
{
message->uri = tsip_uri_parse(state->tag_start, (tsk_size_t)len);
message->line.request.uri = tsip_uri_parse(state->tag_start, (tsk_size_t)len);
}
}
@ -111,7 +111,7 @@ static void tsip_message_parser_eoh(tsk_ragel_state_t *state, tsip_message_t *me
if(message->type == tsip_unknown)
{
message->type = tsip_response;
message->status_code = atoi(state->tag_start);
message->line.response.status_code = atoi(state->tag_start);
}
else
{
@ -126,10 +126,10 @@ static void tsip_message_parser_eoh(tsk_ragel_state_t *state, tsip_message_t *me
state->tag_end = p;
len = (int)(state->tag_end - state->tag_start);
if(!message->reason_phrase)
if(!message->line.response.reason_phrase)
{
message->reason_phrase = tsk_calloc(1, len+1);
memcpy(message->reason_phrase, state->tag_start, len);
message->line.response.reason_phrase = tsk_calloc(1, len+1);
memcpy(message->line.response.reason_phrase, state->tag_start, len);
}
}

View File

@ -39,12 +39,12 @@
#define TSIP_INVITE_EVENT_CREATE( type) tsk_object_new(tsip_invite_event_def_t, type)
int tsip_invite_event_signal(tsip_invite_event_type_t type, struct tsip_stack_s *stack, tsip_ssession_handle_t* SSESSION, short status_code, const char *phrase, const tsip_message_t* sipmessage)
int tsip_invite_event_signal(tsip_invite_event_type_t type, tsip_ssession_handle_t* ss, short status_code, const char *phrase, const tsip_message_t* sipmessage)
{
tsip_invite_event_t* sipevent = TSIP_INVITE_EVENT_CREATE(type);
tsip_event_init(TSIP_EVENT(sipevent), stack, SSESSION, status_code, phrase, sipmessage, tsip_event_invite);
tsip_event_init(TSIP_EVENT(sipevent), ss, status_code, phrase, sipmessage, tsip_event_invite);
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(stack), sipevent);
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(TSIP_SSESSION(ss)->stack), sipevent);
return 0;
}

View File

@ -41,12 +41,12 @@
extern tsip_action_t* _tsip_action_create(tsip_action_type_t type, va_list* app);
int tsip_message_event_signal(tsip_message_event_type_t type, struct tsip_stack_s *stack, tsip_ssession_handle_t* ss, short status_code, const char *phrase, const tsip_message_t* sipmessage)
int tsip_message_event_signal(tsip_message_event_type_t type, tsip_ssession_handle_t* ss, short status_code, const char *phrase, const tsip_message_t* sipmessage)
{
tsip_message_event_t* sipevent = TSIP_MESSAGE_EVENT_CREATE(type);
tsip_event_init(TSIP_EVENT(sipevent), stack, ss, status_code, phrase, sipmessage, tsip_event_message);
tsip_event_init(TSIP_EVENT(sipevent), ss, status_code, phrase, sipmessage, tsip_event_message);
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(stack), sipevent);
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(TSIP_SSESSION(ss)->stack), sipevent);
return 0;
}

View File

@ -41,12 +41,12 @@
extern tsip_action_t* _tsip_action_create(tsip_action_type_t type, va_list* app);
int tsip_options_event_signal(tsip_options_event_type_t type, struct tsip_stack_s *stack, tsip_ssession_handle_t* SSESSION, short status_code, const char *phrase, const tsip_message_t* sipmessage)
int tsip_options_event_signal(tsip_options_event_type_t type, tsip_ssession_handle_t* ss, short status_code, const char *phrase, const tsip_message_t* sipmessage)
{
tsip_options_event_t* sipevent = TSIP_OPTIONS_EVENT_CREATE(type);
tsip_event_init(TSIP_EVENT(sipevent), stack, SSESSION, status_code, phrase, sipmessage, tsip_event_options);
tsip_event_init(TSIP_EVENT(sipevent), ss, status_code, phrase, sipmessage, tsip_event_options);
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(stack), sipevent);
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(TSIP_SSESSION(ss)->stack), sipevent);
return 0;
}

View File

@ -41,12 +41,12 @@
extern tsip_action_t* _tsip_action_create(tsip_action_type_t type, va_list* app);
int tsip_publish_event_signal(tsip_publish_event_type_t type, struct tsip_stack_s *stack, tsip_ssession_handle_t* SSESSION, short status_code, const char *phrase, const tsip_message_t* sipmessage)
int tsip_publish_event_signal(tsip_publish_event_type_t type, tsip_ssession_handle_t* ss, short status_code, const char *phrase, const tsip_message_t* sipmessage)
{
tsip_publish_event_t* sipevent = TSIP_PUBLISH_EVENT_CREATE(type);
tsip_event_init(TSIP_EVENT(sipevent), stack, SSESSION, status_code, phrase, sipmessage, tsip_event_publish);
tsip_event_init(TSIP_EVENT(sipevent), ss, status_code, phrase, sipmessage, tsip_event_publish);
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(stack), sipevent);
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(TSIP_SSESSION(ss)->stack), sipevent);
return 0;
}

View File

@ -45,12 +45,12 @@ extern tsip_action_t* _tsip_action_create(tsip_action_type_t type, va_list* app)
extern int _tsip_action_ANY(const tsip_ssession_handle_t *ss, tsip_action_type_t type, va_list* app);
/* internal function used to signal evant from REGISTER dialog to user app */
int tsip_register_event_signal(tsip_register_event_type_t type, struct tsip_stack_s *stack, tsip_ssession_t* ss, short status_code, const char *phrase, const tsip_message_t* sipmessage)
int tsip_register_event_signal(tsip_register_event_type_t type, tsip_ssession_t* ss, short status_code, const char *phrase, const tsip_message_t* sipmessage)
{
tsip_register_event_t* sipevent = TSIP_REGISTER_EVENT_CREATE(type);
tsip_event_init(TSIP_EVENT(sipevent), stack, ss, status_code, phrase, sipmessage, tsip_event_register);
tsip_event_init(TSIP_EVENT(sipevent), ss, status_code, phrase, sipmessage, tsip_event_register);
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(stack), sipevent);
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(ss->stack), sipevent);
return 0;
}

View File

@ -42,12 +42,12 @@
extern tsip_action_t* _tsip_action_create(tsip_action_type_t type, va_list* app);
int tsip_subscribe_event_signal(tsip_subscribe_event_type_t type, struct tsip_stack_s *stack, tsip_ssession_t* ss, short status_code, const char *phrase, const tsip_message_t* sipmessage)
int tsip_subscribe_event_signal(tsip_subscribe_event_type_t type, tsip_ssession_t* ss, short status_code, const char *phrase, const tsip_message_t* sipmessage)
{
tsip_subscribe_event_t* sipevent = TSIP_SUBSCRIBE_EVENT_CREATE(type);
tsip_event_init(TSIP_EVENT(sipevent), stack, ss, status_code, phrase, sipmessage, tsip_event_subscribe);
tsip_event_init(TSIP_EVENT(sipevent), ss, status_code, phrase, sipmessage, tsip_event_subscribe);
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(stack), sipevent);
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(TSIP_SSESSION(ss)->stack), sipevent);
return 0;
}

View File

@ -305,28 +305,9 @@ tsip_header_t *tsip_challenge_create_header_authorization(tsip_challenge_t *self
goto bail;
}
/* Create the request uri string from uri object
*/
{
tsk_istr_t port;
if(request->uri->port) tsk_itoa(request->uri->port, &port);
tsk_sprintf(&uristring, "%s%s%s%s%s%s%s%s%s",
request->uri->scheme ? request->uri->scheme : "",
request->uri->scheme ? ":" : "",
request->uri->user_name ? request->uri->user_name : "",
request->uri->password ? ":" : "",
request->uri->password ? request->uri->password : "",
request->uri->host ? (request->uri->user_name ? "@" : "") : "",
request->uri->host ? request->uri->host : "",
request->uri->port ? ":" : "",
request->uri->port ? port : ""
);
if(!(uristring = tsip_uri_tostring(request->line.request.uri, tsk_true, tsk_true))){
TSK_DEBUG_ERROR("Failed to parse URI: %s", uristring);
goto bail;
}
/* We compute the nc here because @ref tsip_challenge_get_response function will increment it's value. */
@ -335,7 +316,7 @@ tsip_header_t *tsip_challenge_create_header_authorization(tsip_challenge_t *self
}
/* entity_body ==> request-content */
if(tsip_challenge_get_response(self, request->method, uristring, request->Content, &response)){
if(tsip_challenge_get_response(self, request->line.request.method, uristring, request->Content, &response)){
goto bail;
}

View File

@ -172,7 +172,7 @@ tsip_request_t *tsip_dialog_request_new(const tsip_dialog_t *self, const char* m
provide a new contact address, should its address change during the
duration of the dialog.
*/
switch(request->request_type){
switch(request->line.request.request_type){
case tsip_MESSAGE:
{
break;
@ -223,7 +223,7 @@ tsip_request_t *tsip_dialog_request_new(const tsip_dialog_t *self, const char* m
- the "response" header field parameter, set to an empty value;
*/
const char* realm = TSIP_DIALOG_GET_STACK(self)->network.realm ? TSIP_DIALOG_GET_STACK(self)->network.realm->host : "(null)";
char* request_uri = tsip_uri_tostring(request->uri, tsk_false, tsk_false);
char* request_uri = tsip_uri_tostring(request->line.request.uri, tsk_false, tsk_false);
tsip_header_t* auth_hdr = tsip_challenge_create_empty_header_authorization(TSIP_DIALOG_GET_STACK(self)->identity.impi, realm, request_uri);
tsip_message_add_header(request, auth_hdr);
tsk_object_unref(auth_hdr), auth_hdr = tsk_null;
@ -532,7 +532,7 @@ int tsip_dialog_update(tsip_dialog_t *self, const tsip_response_t* response)
{
if(self && TSIP_MESSAGE_IS_RESPONSE(response) && response->To)
{
short code = response->status_code;
short code = response->line.response.status_code;
const char *tag = response->To->tag;
tsk_bool_t isRegister = response->CSeq ? tsk_striequals(response->CSeq->method, "REGISTER") : tsk_false;
@ -789,7 +789,7 @@ int tsip_dialog_add_common_headers(const tsip_dialog_t *self, tsip_request_t* re
The UE shall use the temporary public user identity (IMSI-derived IMPU, cf. section 6.1.2) only in registration
messages (i.e. initial registration, re-registration or de-registration), but not in any other type of SIP requests.
*/
switch(request->request_type){
switch(request->line.request.request_type){
case tsip_BYE:
case tsip_INVITE:
case tsip_OPTIONS:
@ -813,7 +813,7 @@ int tsip_dialog_add_common_headers(const tsip_dialog_t *self, tsip_request_t* re
//
if(netinfo)
{
switch(request->request_type){
switch(request->line.request.request_type){
case tsip_BYE:
case tsip_INVITE:
case tsip_OPTIONS:

View File

@ -311,7 +311,7 @@ int tsip_dialog_layer_handle_incoming_msg(const tsip_dialog_layer_t *self, const
tsip_ssession_t* ss = tsk_null;
tsip_dialog_t* newdialog = tsk_null;
switch(message->request_type){
switch(message->line.request.request_type){
case tsip_MESSAGE:
{ /* Server incoming MESSAGE */
if((ss = tsip_ssession_create_2(self->stack, message))){

View File

@ -43,7 +43,7 @@
#define DEBUG_STATE_MACHINE 1
#define TSIP_DIALOG_MESSAGE_SIGNAL(self, type, code, phrase, message) \
tsip_message_event_signal(type, TSIP_DIALOG_GET_STACK(self), TSIP_DIALOG(self)->ss, code, phrase, message)
tsip_message_event_signal(type, TSIP_DIALOG(self)->ss, code, phrase, message)
/* ======================== internal functions ======================== */
int send_MESSAGE(tsip_dialog_message_t *self);

View File

@ -43,7 +43,7 @@
#define DEBUG_STATE_MACHINE 0
#define TSIP_DIALOG_OPTIONS_SIGNAL(self, type, code, phrase, options) \
tsip_options_event_signal(type, TSIP_DIALOG_GET_STACK(self), TSIP_DIALOG(self)->ss, code, phrase, options)
tsip_options_event_signal(type, TSIP_DIALOG(self)->ss, code, phrase, options)
/* ======================== internal functions ======================== */
int send_OPTIONS(tsip_dialog_options_t *self);

View File

@ -46,7 +46,7 @@
#define DEBUG_STATE_MACHINE 1
#define TSIP_DIALOG_PUBLISH_TIMER_SCHEDULE(TX) TSIP_DIALOG_TIMER_SCHEDULE(publish, TX)
#define TSIP_DIALOG_PUBLISH_SIGNAL(self, type, code, phrase, message) \
tsip_publish_event_signal(type, TSIP_DIALOG_GET_STACK(self), TSIP_DIALOG(self)->ss, code, phrase, message)
tsip_publish_event_signal(type, TSIP_DIALOG(self)->ss, code, phrase, message)
/* ======================== internal functions ======================== */
int send_PUBLISH(tsip_dialog_publish_t *self);

View File

@ -50,7 +50,7 @@
#define DEBUG_STATE_MACHINE 0
#define TSIP_DIALOG_REGISTER_TIMER_SCHEDULE(TX) TSIP_DIALOG_TIMER_SCHEDULE(register, TX)
#define TSIP_DIALOG_REGISTER_SIGNAL(self, type, code, phrase, message) \
tsip_register_event_signal(type, TSIP_DIALOG_GET_STACK(self), TSIP_DIALOG(self)->ss, code, phrase, message)
tsip_register_event_signal(type, TSIP_DIALOG(self)->ss, code, phrase, message)
/* ======================== internal functions ======================== */

View File

@ -46,7 +46,7 @@
#define DEBUG_STATE_MACHINE 0
#define TSIP_DIALOG_SUBSCRIBE_TIMER_SCHEDULE(TX) TSIP_DIALOG_TIMER_SCHEDULE(subscribe, TX)
#define TSIP_DIALOG_SUBSCRIBE_SIGNAL(self, type, code, phrase, message) \
tsip_subscribe_event_signal(type, TSIP_DIALOG_GET_STACK(self), TSIP_DIALOG(self)->ss, code, phrase, message)
tsip_subscribe_event_signal(type, TSIP_DIALOG(self)->ss, code, phrase, message)
/* ======================== internal functions ======================== */
int send_SUBSCRIBE(tsip_dialog_subscribe_t *self);

View File

@ -315,11 +315,11 @@ _match:
if(message->type == tsip_unknown)
{
message->type = tsip_request;
if(!message->method)
if(!message->line.request.method)
{
message->method = tsk_calloc(1, len+1);
memcpy(message->method, state->tag_start, len);
message->request_type = tsip_request_get_type(message->method);
message->line.request.method = tsk_calloc(1, len+1);
memcpy(message->line.request.method, state->tag_start, len);
message->line.request.request_type = tsip_request_get_type(message->line.request.method);
}
}
else
@ -335,9 +335,9 @@ _match:
state->tag_end = p;
len = (int)(state->tag_end - state->tag_start);
if(!message->uri)
if(!message->line.request.uri)
{
message->uri = tsip_uri_parse(state->tag_start, (tsk_size_t)len);
message->line.request.uri = tsip_uri_parse(state->tag_start, (tsk_size_t)len);
}
}
break;
@ -365,7 +365,7 @@ _match:
if(message->type == tsip_unknown)
{
message->type = tsip_response;
message->status_code = atoi(state->tag_start);
message->line.response.status_code = atoi(state->tag_start);
}
else
{
@ -380,10 +380,10 @@ _match:
state->tag_end = p;
len = (int)(state->tag_end - state->tag_start);
if(!message->reason_phrase)
if(!message->line.response.reason_phrase)
{
message->reason_phrase = tsk_calloc(1, len+1);
memcpy(message->reason_phrase, state->tag_start, len);
message->line.response.reason_phrase = tsk_calloc(1, len+1);
memcpy(message->line.response.reason_phrase, state->tag_start, len);
}
}
break;

View File

@ -722,7 +722,7 @@ int tsip_transac_ict_send_ACK(tsip_transac_ict_t *self, const tsip_response_t* r
// check lastINVITE
if( !self->request->firstVia ||
!self->request->From ||
!self->request->uri ||
!self->request->line.request.uri ||
!self->request->Call_ID ||
!self->request->CSeq)
{
@ -764,7 +764,7 @@ int tsip_transac_ict_send_ACK(tsip_transac_ict_t *self, const tsip_response_t* r
it was, the body in the ACK MAY be any type listed in the Accept
header field in the 415.
*/
if((request = tsip_request_new("ACK", self->request->uri, self->request->From->uri, response->To->uri, self->request->Call_ID->value, self->request->CSeq->seq))){
if((request = tsip_request_new("ACK", self->request->line.request.uri, self->request->From->uri, response->To->uri, self->request->Call_ID->value, self->request->CSeq->seq))){
// Via
request->firstVia = tsk_object_ref((void*)self->request->firstVia);
// tags

View File

@ -262,7 +262,7 @@ int tsip_transport_ipsec_updateMSG(tsip_transport_ipsec_t* self, tsip_message_t
}
/* Security-Client, Require, Proxy-Require and Security Verify */
switch(msg->request_type)
switch(msg->line.request.request_type)
{
case tsip_BYE:
case tsip_INVITE:

View File

@ -38,20 +38,19 @@
#include "tsk_debug.h"
/* internal function used to create base SIP event */
tsip_event_t* tsip_event_create(tsip_stack_t* stack, tsip_ssession_t* ss, short code, const char* phrase, const tsip_message_t* sipmessage, tsip_event_type_t type)
tsip_event_t* tsip_event_create(tsip_ssession_t* ss, short code, const char* phrase, const tsip_message_t* sipmessage, tsip_event_type_t type)
{
tsip_event_t* e;
if((e = tsk_object_new(tsip_event_def_t, stack, ss, code, phrase, sipmessage, type))){
tsip_event_init(e, stack, ss, code, phrase, sipmessage, type);
if((e = tsk_object_new(tsip_event_def_t, ss, code, phrase, sipmessage, type))){
tsip_event_init(e, ss, code, phrase, sipmessage, type);
}
return e;
}
/* initialize a sip sevent */
int tsip_event_init(tsip_event_t* self, struct tsip_stack_s *stack, tsip_ssession_t *ss, short code, const char *phrase, const tsip_message_t* sipmessage, tsip_event_type_t type)
int tsip_event_init(tsip_event_t* self, tsip_ssession_t *ss, short code, const char *phrase, const tsip_message_t* sipmessage, tsip_event_type_t type)
{
if(self && stack){
self->stack = tsk_object_ref(stack);
if(self && ss && ss->stack){
self->ss = tsk_object_ref(ss);
self->code = code;
tsk_strupdate(&(self->phrase), phrase);
@ -61,15 +60,18 @@ int tsip_event_init(tsip_event_t* self, struct tsip_stack_s *stack, tsip_ssessio
}
return 0;
}
return -1;
else{
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
}
/* signal new event (enque) */
int tsip_event_signal(tsip_event_type_t type, tsip_stack_t *stack, tsip_ssession_t* ss, short code, const char *phrase)
int tsip_event_signal(tsip_event_type_t type, tsip_ssession_t* ss, short code, const char *phrase)
{
tsip_event_t* e;
if((e = tsip_event_create(stack, ss, code, phrase, tsk_null, type))){
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(stack), e);
if((e = tsip_event_create(ss, code, phrase, tsk_null, type))){
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(ss->stack), e);
return 0;
}
return -1;
@ -78,7 +80,6 @@ int tsip_event_signal(tsip_event_type_t type, tsip_stack_t *stack, tsip_ssession
int tsip_event_deinit(tsip_event_t* self)
{
if(self){
TSK_OBJECT_SAFE_FREE(self->stack);
TSK_OBJECT_SAFE_FREE(self->ss);
TSK_FREE(self->phrase);

View File

@ -259,12 +259,9 @@ tsk_bool_t tsip_message_allowed(const tsip_message_t *self, const char* method)
int index = 0;
tsip_header_Allow_t *hdr_allow;
if(self)
{
while( hdr_allow = (tsip_header_Allow_t*)tsip_message_get_headerAt(self, tsip_htype_Allow, index++) )
{
if(tsk_list_find_item_by_pred(hdr_allow->methods, pred_find_string_by_value, method))
{
if(self){
while( hdr_allow = (tsip_header_Allow_t*)tsip_message_get_headerAt(self, tsip_htype_Allow, index++) ){
if(tsk_list_find_item_by_pred(hdr_allow->methods, pred_find_string_by_value, method)){
return tsk_true;
}
}
@ -338,9 +335,9 @@ int tsip_message_tostring(const tsip_message_t *self, tsk_buffer_t *output)
if(TSIP_MESSAGE_IS_REQUEST(self)){
/*Method SP Request_URI SP SIP_Version CRLF*/
/* Method */
tsk_buffer_append_2(output, "%s ", self->method);
tsk_buffer_append_2(output, "%s ", self->line.request.method);
/* Request URI */
tsip_uri_serialize(self->uri, tsk_false, tsk_false, output);
tsip_uri_serialize(self->line.request.uri, tsk_false, tsk_false, output);
/* SIP VERSION */
tsk_buffer_append_2(output, " %s\r\n", TSIP_MESSAGE_VERSION_DEFAULT);
}
@ -503,7 +500,7 @@ static tsk_object_t* tsip_message_ctor(tsk_object_t *self, va_list * app)
message->type = va_arg(*app, tsip_message_type_t);
message->headers = tsk_list_create();
message->sockfd = TNET_INVALID_FD;
message->request_type = tsip_NONE;
message->line.request.request_type = tsip_NONE;
switch(message->type)
@ -515,10 +512,10 @@ static tsk_object_t* tsip_message_ctor(tsk_object_t *self, va_list * app)
case tsip_request:
{
message->method = tsk_strdup(va_arg(*app, const char*));
message->uri = tsk_object_ref((void*)va_arg(*app, const tsip_uri_t*));
message->line.request.method = tsk_strdup(va_arg(*app, const char*));
message->line.request.uri = tsk_object_ref((void*)va_arg(*app, const tsip_uri_t*));
message->request_type = tsip_request_get_type(message->method);
message->line.request.request_type = tsip_request_get_type(message->line.request.method);
break;
}
@ -526,11 +523,11 @@ static tsk_object_t* tsip_message_ctor(tsk_object_t *self, va_list * app)
{
const tsip_request_t* request = va_arg(*app, const tsip_request_t*);
#if defined(__GNUC__)
message->status_code = (short)va_arg(*app, int);
message->line.response.status_code = (short)va_arg(*app, int);
#else
message->status_code = va_arg(*app, short);
message->line.response.status_code = va_arg(*app, short);
#endif
message->reason_phrase = tsk_strdup(va_arg(*app, const char*));
message->line.response.reason_phrase = tsk_strdup(va_arg(*app, const char*));
/* Copy sockfd */
message->sockfd = request->sockfd;
@ -602,12 +599,12 @@ static tsk_object_t* tsip_message_dtor(tsk_object_t *self)
{
if(TSIP_MESSAGE_IS_REQUEST(message))
{
TSK_FREE(message->method);
TSK_OBJECT_SAFE_FREE(message->uri);
TSK_FREE(message->line.request.method);
TSK_OBJECT_SAFE_FREE(message->line.request.uri);
}
else if(TSIP_MESSAGE_IS_RESPONSE(message))
{
TSK_FREE(message->reason_phrase);
TSK_FREE(message->line.response.reason_phrase);
}
TSK_FREE(message->sip_version);

View File

@ -171,29 +171,29 @@ int __tsip_ssession_set(tsip_ssession_t *self, va_list *app)
self->userdata = va_arg(*app, const void *);
break;
}
case sstype_to:
{ /* (const char*)TO_URI_STR */
case sstype_to:
{ /* (const char*)TO_URI_STR */
if((ret = __tsip_ssession_set_To(self, va_arg(*app, const char *)))){
return ret;
}
break;
}
case sstype_from:
{ /* (const char*)FROM_URI_STR */
}
break;
}
case sstype_from:
{ /* (const char*)FROM_URI_STR */
if((ret = __tsip_ssession_set_From(self, va_arg(*app, const char *)))){
return ret;
}
break;
}
case sstype_nocontact:
{ /* (tsk_bool_t)ENABLED_BOOL */
self->no_contact = va_arg(*app, tsk_bool_t);
break;
}
case sstype_expires:
{ /* (unsigned)VALUE_UINT */
self->expires = (((int64_t)va_arg(*app, unsigned)) * 1000) /* milliseconds */;
break;
}
break;
}
case sstype_nocontact:
{ /* (tsk_bool_t)ENABLED_BOOL */
self->no_contact = va_arg(*app, tsk_bool_t);
break;
}
case sstype_expires:
{ /* (unsigned)VALUE_UINT */
self->expires = (((int64_t)va_arg(*app, unsigned)) * 1000) /* milliseconds */;
break;
}
default:

View File

@ -353,7 +353,7 @@ void test_stack()
tsip_ssession_handle_t *op = tsip_ssession_create(stack,
TSIP_SSESSION_SET_OPTION(TSIP_SSESSION_OPTION_EXPIRES, "30"),
TSIP_SSESSION_SET_EXPIRES(30),
TSIP_SSESSION_SET_CAPS("+g.oma.sip-im", ""),
TSIP_SSESSION_SET_CAPS("+audio", ""),