Update support for QoS preconditions (RFC 3312).
This commit is contained in:
parent
118a165235
commit
8ffe9121e2
|
@ -97,7 +97,7 @@ const tsip_header_t* SipMessage::getSipHeader(const char* name, unsigned index /
|
|||
|
||||
|
||||
tsk_list_foreach(item, this->sipmessage->headers){
|
||||
if(tsk_striequals(tsip_header_get_name_2(TSIP_HEADER(item)), name)){
|
||||
if(tsk_striequals(tsip_header_get_name_2(TSIP_HEADER(item->data)), name)){
|
||||
if(pos++ >= index){
|
||||
hdr = (const tsip_header_t*)item->data;
|
||||
break;
|
||||
|
|
|
@ -33,6 +33,8 @@ namespace test
|
|||
this.textBoxDebug = new System.Windows.Forms.TextBox();
|
||||
this.buttonPublish = new System.Windows.Forms.Button();
|
||||
this.buttonUnPublish = new System.Windows.Forms.Button();
|
||||
this.buttonUnSub = new System.Windows.Forms.Button();
|
||||
this.buttonSub = new System.Windows.Forms.Button();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// buttonRegister
|
||||
|
@ -83,11 +85,32 @@ namespace test
|
|||
this.buttonUnPublish.UseVisualStyleBackColor = true;
|
||||
this.buttonUnPublish.Click += new System.EventHandler(this.buttonUnPublish_Click);
|
||||
//
|
||||
// buttonUnSub
|
||||
//
|
||||
this.buttonUnSub.Location = new System.Drawing.Point(199, 206);
|
||||
this.buttonUnSub.Name = "buttonUnSub";
|
||||
this.buttonUnSub.Size = new System.Drawing.Size(75, 23);
|
||||
this.buttonUnSub.TabIndex = 6;
|
||||
this.buttonUnSub.Text = "UnSubscribe";
|
||||
this.buttonUnSub.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// buttonSub
|
||||
//
|
||||
this.buttonSub.Location = new System.Drawing.Point(12, 205);
|
||||
this.buttonSub.Name = "buttonSub";
|
||||
this.buttonSub.Size = new System.Drawing.Size(75, 23);
|
||||
this.buttonSub.TabIndex = 5;
|
||||
this.buttonSub.Text = "Subscribe";
|
||||
this.buttonSub.UseVisualStyleBackColor = true;
|
||||
this.buttonSub.Click += new System.EventHandler(this.buttonSub_Click);
|
||||
//
|
||||
// Form1
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(286, 374);
|
||||
this.Controls.Add(this.buttonUnSub);
|
||||
this.Controls.Add(this.buttonSub);
|
||||
this.Controls.Add(this.buttonUnPublish);
|
||||
this.Controls.Add(this.buttonPublish);
|
||||
this.Controls.Add(this.textBoxDebug);
|
||||
|
@ -107,6 +130,8 @@ namespace test
|
|||
private System.Windows.Forms.TextBox textBoxDebug;
|
||||
private System.Windows.Forms.Button buttonPublish;
|
||||
private System.Windows.Forms.Button buttonUnPublish;
|
||||
private System.Windows.Forms.Button buttonUnSub;
|
||||
private System.Windows.Forms.Button buttonSub;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace test
|
|||
|
||||
RegistrationSession regSession = null;
|
||||
PublicationSession pubSession = null;
|
||||
SubscriptionSession subSession = null;
|
||||
MyCallback callback = null;
|
||||
SipStack stack = null;
|
||||
|
||||
|
@ -145,6 +146,19 @@ namespace test
|
|||
{
|
||||
this.textBoxDebug.Text = text;
|
||||
}
|
||||
|
||||
private void buttonSub_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (this.subSession == null)
|
||||
{
|
||||
this.subSession = new SubscriptionSession(stack);
|
||||
this.subSession.addHeader("Accept", "application/reginfo+xml");
|
||||
this.subSession.addHeader("Event", "reg");
|
||||
this.subSession.setExpires(30);
|
||||
|
||||
this.subSession.Subscribe();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -188,6 +202,20 @@ namespace test
|
|||
return 0;
|
||||
}
|
||||
|
||||
public override int OnSubscriptionEvent(SubscriptionEvent e)
|
||||
{
|
||||
switch (e.getType())
|
||||
{
|
||||
case tsip_subscribe_event_type_t.tsip_i_notify:
|
||||
String ev = e.getSipMessage().getSipHeaderValue("Event");
|
||||
Console.WriteLine("Event=%s", ev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return base.OnSubscriptionEvent(e);
|
||||
}
|
||||
|
||||
public override int OnPublicationEvent(PublicationEvent e)
|
||||
{
|
||||
short code = e.getCode();
|
||||
|
|
|
@ -101,6 +101,7 @@ tmedia_qos_tline_t;
|
|||
TINYMEDIA_API tmedia_qos_stype_t tmedia_qos_get_type(const tsdp_header_M_t* m);
|
||||
TINYMEDIA_API tmedia_qos_tline_t* tmedia_qos_tline_from_sdp(const tsdp_header_M_t* m);
|
||||
TINYMEDIA_API int tmedia_qos_tline_to_sdp(const tmedia_qos_tline_t* self, tsdp_header_M_t* m);
|
||||
TINYMEDIA_API tsk_bool_t tmedia_qos_tline_canresume(const tmedia_qos_tline_t* self);
|
||||
|
||||
/* QoS table-line for E2E type*/
|
||||
typedef struct tmedia_qos_tline_e2e_s
|
||||
|
@ -121,8 +122,8 @@ typedef struct tmedia_qos_tline_e2e_s
|
|||
} send;
|
||||
|
||||
struct{
|
||||
tsk_bool_t current:1;
|
||||
tsk_bool_t confirm:1;
|
||||
unsigned current:1;
|
||||
unsigned confirm:1;
|
||||
tmedia_qos_strength_t strength;
|
||||
} recv;
|
||||
}
|
||||
|
@ -131,6 +132,8 @@ tmedia_qos_tline_e2e_t;
|
|||
TINYMEDIA_API tmedia_qos_tline_e2e_t* tmedia_qos_tline_e2e_create(tmedia_qos_strength_t strength);
|
||||
TINYMEDIA_API tmedia_qos_tline_e2e_t* tmedia_qos_tline_e2e_from_sdp(const tsdp_header_M_t* m);
|
||||
TINYMEDIA_API int tmedia_qos_tline_e2e_to_sdp(const tmedia_qos_tline_e2e_t* self, tsdp_header_M_t* m);
|
||||
TINYMEDIA_API int tmedia_qos_tline_e2e_set_ro(tmedia_qos_tline_e2e_t* self, const tmedia_qos_tline_e2e_t* ro);
|
||||
TINYMEDIA_API tsk_bool_t tmedia_qos_tline_e2e_canresume(const tmedia_qos_tline_e2e_t* self);
|
||||
|
||||
/* QoS table-line for Segented type*/
|
||||
typedef struct tmedia_qos_tline_segmented_s
|
||||
|
@ -176,7 +179,8 @@ tmedia_qos_tline_segmented_t;
|
|||
TINYMEDIA_API tmedia_qos_tline_segmented_t* tmedia_qos_tline_segmented_create(tmedia_qos_strength_t strength);
|
||||
TINYMEDIA_API tmedia_qos_tline_segmented_t* tmedia_qos_tline_segmented_from_sdp(const tsdp_header_M_t* m);
|
||||
TINYMEDIA_API int tmedia_qos_tline_segmented_to_sdp(const tmedia_qos_tline_segmented_t* self, tsdp_header_M_t* m);
|
||||
|
||||
TINYMEDIA_API int tmedia_qos_tline_segmented_set_ro(tmedia_qos_tline_segmented_t* self, const tmedia_qos_tline_segmented_t* ro);
|
||||
TINYMEDIA_API tsk_bool_t tmedia_qos_tline_segmented_canresume(const tmedia_qos_tline_segmented_t* self);
|
||||
|
||||
TINYMEDIA_GEXTERN const tsk_object_def_t *tmedia_qos_tline_segmented_def_t;
|
||||
TINYMEDIA_GEXTERN const tsk_object_def_t *tmedia_qos_tline_e2e_def_t;
|
||||
|
|
|
@ -45,6 +45,8 @@ TMEDIA_BEGIN_DECLS
|
|||
/**Max number of plugins (session types) we can create */
|
||||
#define TMED_SESSION_MAX_PLUGINS 0x0F
|
||||
|
||||
#define TMEDIA_SESSION_SET();
|
||||
|
||||
/** Base objct used for all media sessions */
|
||||
typedef struct tmedia_session_s
|
||||
{
|
||||
|
@ -84,6 +86,7 @@ typedef struct tmedia_session_plugin_def_s
|
|||
//! the media name. e.g. "audio", "video", "message", "image" etc.
|
||||
const char* media;
|
||||
|
||||
int (*configure) (tmedia_session_t* , const va_list *app);
|
||||
int (* prepare) (tmedia_session_t* );
|
||||
int (* start) (tmedia_session_t* );
|
||||
int (* pause) (tmedia_session_t* );
|
||||
|
@ -195,6 +198,7 @@ tmedia_session_mgr_t;
|
|||
|
||||
TINYMEDIA_API tmedia_session_mgr_t* tmedia_session_mgr_create(tmedia_type_t type, const char* addr, tsk_bool_t ipv6);
|
||||
TINYMEDIA_API int tmedia_session_mgr_start(tmedia_session_mgr_t* self);
|
||||
TINYMEDIA_API int tmedia_session_mgr_configure(tmedia_session_mgr_t* self, tmedia_type_t type, ...);
|
||||
TINYMEDIA_API int tmedia_session_mgr_stop(tmedia_session_mgr_t* self);
|
||||
TINYMEDIA_API const tsdp_message_t* tmedia_session_mgr_get_lo(tmedia_session_mgr_t* self);
|
||||
TINYMEDIA_API int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t* sdp);
|
||||
|
|
|
@ -112,6 +112,11 @@ tmedia_qos_stype_t tmedia_qos_get_type(const tsdp_header_M_t* m)
|
|||
|
||||
tmedia_qos_tline_t* tmedia_qos_tline_from_sdp(const tsdp_header_M_t* m)
|
||||
{
|
||||
if(!m){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return tsk_null;
|
||||
}
|
||||
|
||||
switch(tmedia_qos_get_type(m)){
|
||||
case tmedia_qos_stype_e2e:
|
||||
return (tmedia_qos_tline_t*)tmedia_qos_tline_e2e_from_sdp(m);
|
||||
|
@ -124,7 +129,12 @@ tmedia_qos_tline_t* tmedia_qos_tline_from_sdp(const tsdp_header_M_t* m)
|
|||
|
||||
int tmedia_qos_tline_to_sdp(const tmedia_qos_tline_t* self, tsdp_header_M_t* m)
|
||||
{
|
||||
switch(tmedia_qos_get_type(m)){
|
||||
if(!self || !m){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return tsk_null;
|
||||
}
|
||||
|
||||
switch(self->type){
|
||||
case tmedia_qos_stype_e2e:
|
||||
return tmedia_qos_tline_e2e_to_sdp((tmedia_qos_tline_e2e_t*)self, m);
|
||||
case tmedia_qos_stype_segmented:
|
||||
|
@ -134,6 +144,21 @@ int tmedia_qos_tline_to_sdp(const tmedia_qos_tline_t* self, tsdp_header_M_t* m)
|
|||
}
|
||||
}
|
||||
|
||||
tsk_bool_t tmedia_qos_tline_canresume(const tmedia_qos_tline_t* self)
|
||||
{
|
||||
if(!self){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return tsk_true;
|
||||
}
|
||||
switch(self->type){
|
||||
case tmedia_qos_stype_segmented:
|
||||
return tmedia_qos_tline_segmented_canresume((const tmedia_qos_tline_segmented_t*)self);
|
||||
case tmedia_qos_stype_e2e:
|
||||
return tmedia_qos_tline_e2e_canresume((const tmedia_qos_tline_e2e_t*)self);
|
||||
default:
|
||||
return tsk_true;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================= E2E ==================================*/
|
||||
|
||||
|
@ -266,8 +291,9 @@ int tmedia_qos_tline_e2e_to_sdp(const tmedia_qos_tline_e2e_t* self, tsdp_header_
|
|||
a=des:qos mandatory e2e sendrecv
|
||||
*/
|
||||
|
||||
|
||||
/* curr */
|
||||
tsk_sprintf(&temp, "qos e2e %s", self->recv.current ? "recv" : (self->send.current ? "send" : "none"));
|
||||
tsk_sprintf(&temp, "qos e2e %s", (self->recv.current && self->send.current) ? "sendrecv" : (self->recv.current ? "recv" : (self->send.current ? "send" : "none")));
|
||||
tsdp_header_M_add_headers(m,
|
||||
TSDP_HEADER_A_VA_ARGS("curr", temp),
|
||||
tsk_null);
|
||||
|
@ -298,9 +324,84 @@ int tmedia_qos_tline_e2e_to_sdp(const tmedia_qos_tline_e2e_t* self, tsdp_header_
|
|||
TSK_FREE(temp);
|
||||
}
|
||||
|
||||
/* conf (should not request confirm on "send" direction)*/
|
||||
if(self->recv.confirm){
|
||||
tsdp_header_M_add_headers(m,
|
||||
TSDP_HEADER_A_VA_ARGS("conf", "qos e2e recv"),
|
||||
tsk_null);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tmedia_qos_tline_e2e_set_ro(tmedia_qos_tline_e2e_t* self, const tmedia_qos_tline_e2e_t* ro)
|
||||
{
|
||||
if(!self || !ro){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* We were the offerer
|
||||
* Remote asked for confirmation in its "recv" direction?
|
||||
* "recv" direction for remote is our "send" direction
|
||||
* As we don't support RSVP (under the way), confirm immediatly.
|
||||
* "send" direction should not requested for confirmation
|
||||
*/
|
||||
if(ro->recv.confirm){
|
||||
self->send.current = tsk_true;
|
||||
goto bail;
|
||||
}
|
||||
if(ro->send.current){
|
||||
self->recv.confirm = tsk_false; /* remote confirmed */
|
||||
self->recv.current = tsk_true; /* because ro confirmed */
|
||||
self->send.current = tsk_true; /* beacuse we don't support RSVP */
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* We are the answerer
|
||||
* As we don't support RSVP (under the way):
|
||||
* ==> request confirmation for "recv" direction if equal to "none" (not reserved)
|
||||
* =>
|
||||
*/
|
||||
if(!self->recv.current){
|
||||
self->recv.confirm = tsk_true;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
bail:
|
||||
/* all other cases: success */
|
||||
return 0;
|
||||
}
|
||||
|
||||
tsk_bool_t tmedia_qos_tline_e2e_canresume(const tmedia_qos_tline_e2e_t* self)
|
||||
{
|
||||
if(!self){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return tsk_true;
|
||||
}
|
||||
|
||||
/* Example
|
||||
a=curr:qos e2e none
|
||||
a=des:qos mandatory e2e sendrecv
|
||||
|
||||
Or
|
||||
|
||||
a=curr:qos e2e send
|
||||
a=des:qos mandatory e2e recv
|
||||
a=des:qos optional e2e send
|
||||
*/
|
||||
|
||||
/* only "mandatory" strength should force the application to continue nego. */
|
||||
if(self->recv.strength == tmedia_qos_strength_mandatory && !self->recv.current){
|
||||
return tsk_false;
|
||||
}
|
||||
/*else */if(self->send.strength == tmedia_qos_strength_mandatory && !self->send.current){
|
||||
return tsk_false;
|
||||
}
|
||||
|
||||
/* "optinal" and "none" strengths */
|
||||
return tsk_true;
|
||||
}
|
||||
|
||||
//
|
||||
// E2E QoS line object definition
|
||||
//
|
||||
|
@ -548,14 +649,14 @@ int tmedia_qos_tline_segmented_to_sdp(const tmedia_qos_tline_segmented_t* self,
|
|||
*/
|
||||
|
||||
/* curr:local */
|
||||
tsk_sprintf(&temp, "qos local %s", self->local_recv.current ? "recv" : (self->local_send.current ? "send" : "none"));
|
||||
tsk_sprintf(&temp, "qos local %s", (self->local_recv.current && self->local_send.current) ? "sendrecv" : (self->local_recv.current ? "recv" : (self->local_send.current ? "send" : "none")));
|
||||
tsdp_header_M_add_headers(m,
|
||||
TSDP_HEADER_A_VA_ARGS("curr", temp),
|
||||
tsk_null);
|
||||
TSK_FREE(temp);
|
||||
|
||||
/* curr:remote */
|
||||
tsk_sprintf(&temp, "qos remote %s", self->remote_recv.current ? "recv" : (self->remote_send.current ? "send" : "none"));
|
||||
tsk_sprintf(&temp, "qos remote %s", (self->remote_recv.current && self->remote_send.current) ? "sendrecv" : (self->remote_recv.current ? "recv" : (self->remote_send.current ? "send" : "none")));
|
||||
tsdp_header_M_add_headers(m,
|
||||
TSDP_HEADER_A_VA_ARGS("curr", temp),
|
||||
tsk_null);
|
||||
|
@ -613,9 +714,87 @@ int tmedia_qos_tline_segmented_to_sdp(const tmedia_qos_tline_segmented_t* self,
|
|||
TSK_FREE(temp);
|
||||
}
|
||||
|
||||
/* conf */
|
||||
if(self->remote_recv.confirm || self->remote_send.confirm){
|
||||
tsk_sprintf(&temp, "qos remote %s", (self->remote_recv.confirm && self->remote_send.confirm) ? "sendrecv" : (self->remote_recv.confirm ? "recv" : (self->remote_send.confirm ? "send" : "none")));
|
||||
tsdp_header_M_add_headers(m,
|
||||
TSDP_HEADER_A_VA_ARGS("conf", temp),
|
||||
tsk_null);
|
||||
TSK_FREE(temp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tmedia_qos_tline_segmented_set_ro(tmedia_qos_tline_segmented_t* self, const tmedia_qos_tline_segmented_t* ro)
|
||||
{
|
||||
if(!self || !ro){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//////////////
|
||||
if(!ro->local_recv.current && !ro->remote_recv.confirm){
|
||||
/* request confirmation */
|
||||
self->remote_recv.confirm = tsk_true;
|
||||
}
|
||||
else{
|
||||
self->remote_recv.confirm = tsk_false;
|
||||
self->local_recv.current = tsk_true;
|
||||
}
|
||||
if(!ro->local_send.current && !ro->remote_send.confirm){
|
||||
/* request confirmation */
|
||||
self->remote_send.confirm = tsk_true;
|
||||
}
|
||||
else{
|
||||
self->remote_send.confirm = tsk_false;
|
||||
self->local_send.current = tsk_true;
|
||||
}
|
||||
|
||||
//////////////
|
||||
if(ro->remote_recv.confirm){
|
||||
self->local_recv.current = tsk_true;
|
||||
}
|
||||
if(ro->remote_send.confirm){
|
||||
self->local_send.current = tsk_true;
|
||||
}
|
||||
|
||||
//////////////
|
||||
if(ro->local_recv.current){
|
||||
self->remote_recv.current = tsk_true;
|
||||
}
|
||||
if(ro->local_send.current){
|
||||
self->remote_send.current = tsk_true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
tsk_bool_t tmedia_qos_tline_segmented_canresume(const tmedia_qos_tline_segmented_t* self)
|
||||
{
|
||||
if(!self){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return tsk_true;
|
||||
}
|
||||
|
||||
/* only "mandatory" strength should force the application to continue nego. */
|
||||
if(self->local_recv.strength == tmedia_qos_strength_mandatory && !self->local_recv.current){
|
||||
return tsk_false;
|
||||
}
|
||||
else if(self->local_send.strength == tmedia_qos_strength_mandatory && !self->local_send.current){
|
||||
return tsk_false;
|
||||
}
|
||||
else if(self->remote_recv.strength == tmedia_qos_strength_mandatory && !self->remote_recv.current){
|
||||
return tsk_false;
|
||||
}
|
||||
else if(self->remote_send.strength == tmedia_qos_strength_mandatory && !self->remote_send.current){
|
||||
return tsk_false;
|
||||
}
|
||||
|
||||
/* "optinal" and "none" strengths */
|
||||
return tsk_true;
|
||||
}
|
||||
|
||||
//
|
||||
// Segmented QoS line object definition
|
||||
//
|
||||
|
|
|
@ -480,6 +480,45 @@ int tmedia_session_mgr_start(tmedia_session_mgr_t* self)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**@ingroup tmedia_session_group
|
||||
* Configures one or several sessions.
|
||||
* @param self The session manager
|
||||
* @param type The type of the sessions to configure
|
||||
* @param ... Any TMEDIA_SESSION_SET_*() macros
|
||||
* @retval Zero if succeed and non-zero error code otherwise
|
||||
*/
|
||||
int tmedia_session_mgr_configure(tmedia_session_mgr_t* self, tmedia_type_t type, ...)
|
||||
{
|
||||
tsk_list_item_t* item;
|
||||
tmedia_session_t* session;
|
||||
va_list ap;
|
||||
|
||||
if(!self){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
tsk_list_foreach(item, self->sessions){
|
||||
if(!(session = item->data)){
|
||||
TSK_DEBUG_ERROR("Invalid session");
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* does not support configure() */
|
||||
if(!session->plugin->configure){
|
||||
continue;
|
||||
}
|
||||
|
||||
va_start(ap, type);
|
||||
if(((session->type & type) == session->type) && session->plugin->configure(session, &ap)){
|
||||
TSK_DEBUG_ERROR("Failed to configue (%s) session", session->plugin->media);
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**@ingroup tmedia_session_group
|
||||
* Stops the session manager by stopping all underlying sessions.
|
||||
* @param self The session manager to stop.
|
||||
|
|
|
@ -34,6 +34,17 @@
|
|||
|
||||
/* ============ Audio Session ================= */
|
||||
|
||||
int tmedia_session_daudio_configure(tmedia_session_t* self, const va_list *app)
|
||||
{
|
||||
tmedia_session_daudio_t* daudio;
|
||||
|
||||
TSK_DEBUG_INFO("tmedia_session_daudio_prepare");
|
||||
|
||||
daudio = (tmedia_session_daudio_t*)self;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tmedia_session_daudio_prepare(tmedia_session_t* self)
|
||||
{
|
||||
tmedia_session_daudio_t* daudio;
|
||||
|
@ -139,6 +150,17 @@ int tmedia_session_daudio_set_ro(tmedia_session_t* self, const tsdp_header_M_t*
|
|||
|
||||
/* ============ Video Session ================= */
|
||||
|
||||
int tmedia_session_dvideo_configure(tmedia_session_t* self, const va_list *app)
|
||||
{
|
||||
tmedia_session_dvideo_t* dvideo;
|
||||
|
||||
TSK_DEBUG_INFO("tmedia_session_dvideo_configure");
|
||||
|
||||
dvideo = (tmedia_session_dvideo_t*)self;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tmedia_session_dvideo_prepare(tmedia_session_t* self)
|
||||
{
|
||||
tmedia_session_dvideo_t* dvideo;
|
||||
|
@ -244,6 +266,17 @@ int tmedia_session_dvideo_set_ro(tmedia_session_t* self, const tsdp_header_M_t*
|
|||
|
||||
/* ============ Msrp Session ================= */
|
||||
|
||||
int tmedia_session_dmsrp_configure(tmedia_session_t* self, const va_list *app)
|
||||
{
|
||||
tmedia_session_dmsrp_t* dmsrp;
|
||||
|
||||
TSK_DEBUG_INFO("tmedia_session_dmsrp_configure");
|
||||
|
||||
dmsrp = (tmedia_session_dmsrp_t*)self;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tmedia_session_dmsrp_prepare(tmedia_session_t* self)
|
||||
{
|
||||
TSK_DEBUG_INFO("tmedia_session_dmsrp_prepare");
|
||||
|
@ -326,6 +359,7 @@ static const tmedia_session_plugin_def_t tmedia_session_daudio_plugin_def_s =
|
|||
tmedia_audio,
|
||||
"audio",
|
||||
|
||||
tmedia_session_daudio_configure,
|
||||
tmedia_session_daudio_prepare,
|
||||
tmedia_session_daudio_start,
|
||||
tmedia_session_daudio_stop,
|
||||
|
@ -378,6 +412,7 @@ static const tmedia_session_plugin_def_t tmedia_session_dvideo_plugin_def_s =
|
|||
tmedia_video,
|
||||
"video",
|
||||
|
||||
tmedia_session_dvideo_configure,
|
||||
tmedia_session_dvideo_prepare,
|
||||
tmedia_session_dvideo_start,
|
||||
tmedia_session_dvideo_stop,
|
||||
|
@ -430,6 +465,7 @@ static const tmedia_session_plugin_def_t tmedia_session_dmsrp_plugin_def_s =
|
|||
tmedia_msrp,
|
||||
"message",
|
||||
|
||||
tmedia_session_dmsrp_configure,
|
||||
tmedia_session_dmsrp_prepare,
|
||||
tmedia_session_dmsrp_start,
|
||||
tmedia_session_dmsrp_stop,
|
||||
|
|
|
@ -132,6 +132,7 @@ static const tmedia_session_plugin_def_t tmedia_session_ghost_plugin_def_s =
|
|||
tmedia_ghost,
|
||||
"ghost",
|
||||
|
||||
tsk_null,
|
||||
tmedia_session_ghost_prepare,
|
||||
tmedia_session_ghost_start,
|
||||
tmedia_session_ghost_stop,
|
||||
|
|
|
@ -22,13 +22,33 @@
|
|||
#ifndef _TEST_QOS_H_
|
||||
#define _TEST_QOS_H_
|
||||
|
||||
void test_qos()
|
||||
char* test_qos_tostring(const tmedia_qos_tline_t* tline)
|
||||
{
|
||||
char* ret = tsk_null;
|
||||
tsdp_header_M_t* M;
|
||||
|
||||
if(!tline){
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return tsk_null;
|
||||
}
|
||||
|
||||
M = tsdp_header_M_create("audio", 20000, "RTP/AVP");
|
||||
tmedia_qos_tline_to_sdp(tline, M);
|
||||
|
||||
ret = tsdp_header_tostring(TSDP_HEADER(M));
|
||||
TSK_OBJECT_SAFE_FREE(M);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void test_qos_parser()
|
||||
{
|
||||
tsdp_header_M_t* M;
|
||||
tmedia_qos_tline_e2e_t* e2e;
|
||||
tmedia_qos_tline_segmented_t* segmented;
|
||||
char* temp = tsk_null;
|
||||
tmedia_qos_stype_t type;
|
||||
tsk_bool_t canresume;
|
||||
|
||||
/* test E2E */
|
||||
M = tsdp_header_M_create("audio", 20000, "RTP/AVP");
|
||||
|
@ -45,6 +65,7 @@ void test_qos()
|
|||
// from_sdp
|
||||
TSK_OBJECT_SAFE_FREE(e2e);
|
||||
e2e = tmedia_qos_tline_e2e_from_sdp(M);
|
||||
canresume = tmedia_qos_tline_e2e_canresume(e2e);
|
||||
tmedia_qos_tline_e2e_to_sdp(e2e, M);
|
||||
if((temp = tsdp_header_tostring(TSDP_HEADER(M)))){
|
||||
TSK_DEBUG_INFO("e2e from_sdp: %s", temp);
|
||||
|
@ -71,6 +92,7 @@ void test_qos()
|
|||
// from_sdp
|
||||
TSK_OBJECT_SAFE_FREE(segmented);
|
||||
segmented = tmedia_qos_tline_segmented_from_sdp(M);
|
||||
canresume = tmedia_qos_tline_segmented_canresume(segmented);
|
||||
tmedia_qos_tline_segmented_to_sdp(segmented, M);
|
||||
if((temp = tsdp_header_tostring(TSDP_HEADER(M)))){
|
||||
TSK_DEBUG_INFO("Segmented from_sdp: %s", temp);
|
||||
|
@ -83,4 +105,163 @@ void test_qos()
|
|||
TSK_OBJECT_SAFE_FREE(M);
|
||||
}
|
||||
|
||||
|
||||
void test_qos_e2e_neg()
|
||||
{
|
||||
tmedia_qos_tline_e2e_t *e2eA = tsk_null, *e2eB = tsk_null;
|
||||
char* temp = tsk_null;
|
||||
|
||||
/* SDP1: A includes end-to-end quality of service preconditions in the
|
||||
initial offer.
|
||||
|
||||
m=audio 20000 RTP/AVP 0
|
||||
c=IN IP4 192.0.2.1
|
||||
a=curr:qos e2e none
|
||||
a=des:qos mandatory e2e sendrecv
|
||||
*/
|
||||
e2eA = tmedia_qos_tline_e2e_create(tmedia_qos_strength_mandatory);
|
||||
if((temp = test_qos_tostring((const tmedia_qos_tline_t*)e2eA))){
|
||||
TSK_DEBUG_INFO("SDP1=\n%s", temp);
|
||||
TSK_FREE(temp);
|
||||
}
|
||||
|
||||
/* SDP2: Since B uses RSVP, it can know when resources in its "send"
|
||||
direction are available, because it will receive RESV messages from
|
||||
the network. However, it does not know the status of the
|
||||
reservations in the other direction. B requests confirmation for
|
||||
resource reservations in its "recv" direction to the peer user agent
|
||||
A in its answer.
|
||||
|
||||
m=audio 30000 RTP/AVP 0
|
||||
c=IN IP4 192.0.2.4
|
||||
a=curr:qos e2e none
|
||||
a=des:qos mandatory e2e sendrecv
|
||||
a=conf:qos e2e recv
|
||||
*/
|
||||
e2eB = tmedia_qos_tline_e2e_create(tmedia_qos_strength_mandatory);
|
||||
tmedia_qos_tline_e2e_set_ro(e2eB, e2eA);
|
||||
if((temp = test_qos_tostring((const tmedia_qos_tline_t*)e2eB))){
|
||||
TSK_DEBUG_INFO("SDP2=\n%s", temp);
|
||||
TSK_FREE(temp);
|
||||
}
|
||||
|
||||
/* SDP3: When A receives RESV messages, it sends an updated offer (5) to B:
|
||||
|
||||
m=audio 20000 RTP/AVP 0
|
||||
c=IN IP4 192.0.2.1
|
||||
a=curr:qos e2e send
|
||||
a=des:qos mandatory e2e sendrecv
|
||||
*/
|
||||
tmedia_qos_tline_e2e_set_ro(e2eA, e2eB);
|
||||
if((temp = test_qos_tostring((const tmedia_qos_tline_t*)e2eA))){
|
||||
TSK_DEBUG_INFO("SDP3=\n%s", temp);
|
||||
TSK_FREE(temp);
|
||||
}
|
||||
|
||||
/* SDP4: B responds with an answer (6) which contains the current status
|
||||
of the resource reservation (i.e., sendrecv):
|
||||
|
||||
m=audio 30000 RTP/AVP 0
|
||||
c=IN IP4 192.0.2.4
|
||||
a=curr:qos e2e sendrecv
|
||||
a=des:qos mandatory e2e sendrecv
|
||||
*/
|
||||
tmedia_qos_tline_e2e_set_ro(e2eB, e2eA);
|
||||
if((temp = test_qos_tostring((const tmedia_qos_tline_t*)e2eB))){
|
||||
TSK_DEBUG_INFO("SDP4=\n%s", temp);
|
||||
TSK_FREE(temp);
|
||||
}
|
||||
|
||||
/* A receive B's response */
|
||||
tmedia_qos_tline_e2e_set_ro(e2eA, e2eB);
|
||||
if((temp = test_qos_tostring((const tmedia_qos_tline_t*)e2eA))){
|
||||
TSK_DEBUG_INFO("SDP5=\n%s", temp);
|
||||
TSK_FREE(temp);
|
||||
}
|
||||
|
||||
if(tmedia_qos_tline_e2e_canresume(e2eA)){
|
||||
TSK_DEBUG_INFO("A can resume");
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("A can't resume");
|
||||
}
|
||||
|
||||
if(tmedia_qos_tline_e2e_canresume(e2eB)){
|
||||
TSK_DEBUG_INFO("B can resume");
|
||||
}
|
||||
else{
|
||||
TSK_DEBUG_ERROR("B can't resume");
|
||||
}
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(e2eB);
|
||||
TSK_OBJECT_SAFE_FREE(e2eA);
|
||||
}
|
||||
|
||||
|
||||
void test_qos_segmented_neg()
|
||||
{
|
||||
tmedia_qos_tline_segmented_t *segA = tsk_null, *segB = tsk_null;
|
||||
char* temp = tsk_null;
|
||||
|
||||
/* INVITE
|
||||
a=curr:qos local none
|
||||
a=curr:qos remote none
|
||||
a=des:qos mandatory local sendrecv
|
||||
a=des:qos mandatory remote sendrecv
|
||||
*/
|
||||
segA = tmedia_qos_tline_segmented_create(tmedia_qos_strength_mandatory);
|
||||
if((temp = test_qos_tostring((const tmedia_qos_tline_t*)segA))){
|
||||
TSK_DEBUG_INFO("INVITE=\n%s", temp);
|
||||
TSK_FREE(temp);
|
||||
}
|
||||
|
||||
/* 183 Sesson progress
|
||||
a=curr:qos local none
|
||||
a=curr:qos remote none
|
||||
a=des:qos mandatory local sendrecv
|
||||
a=des:qos mandatory remote sendrecv
|
||||
a=conf:qos remote sendrecv
|
||||
*/
|
||||
segB = tmedia_qos_tline_segmented_create(tmedia_qos_strength_mandatory);
|
||||
tmedia_qos_tline_segmented_set_ro(segB, segA);
|
||||
if((temp = test_qos_tostring((const tmedia_qos_tline_t*)segB))){
|
||||
TSK_DEBUG_INFO("183=\n%s", temp);
|
||||
TSK_FREE(temp);
|
||||
}
|
||||
|
||||
/* UPDATE
|
||||
a=curr:qos local sendrecv
|
||||
a=curr:qos remote none
|
||||
a=des:qos mandatory local sendrecv
|
||||
a=des:qos mandatory remote sendrecv
|
||||
*/
|
||||
tmedia_qos_tline_segmented_set_ro(segA, segB);
|
||||
if((temp = test_qos_tostring((const tmedia_qos_tline_t*)segA))){
|
||||
TSK_DEBUG_INFO("UPDATE=\n%s", temp);
|
||||
TSK_FREE(temp);
|
||||
}
|
||||
|
||||
/* 200 OK
|
||||
a=curr:qos local sendrecv
|
||||
a=curr:qos remote sendrecv
|
||||
a=des:qos mandatory local sendrecv
|
||||
a=des:qos mandatory remote sendrecv
|
||||
*/
|
||||
tmedia_qos_tline_segmented_set_ro(segB, segA);
|
||||
if((temp = test_qos_tostring((const tmedia_qos_tline_t*)segB))){
|
||||
TSK_DEBUG_INFO("200OK=\n%s", temp);
|
||||
TSK_FREE(temp);
|
||||
}
|
||||
|
||||
TSK_OBJECT_SAFE_FREE(segA);
|
||||
TSK_OBJECT_SAFE_FREE(segB);
|
||||
}
|
||||
|
||||
void test_qos()
|
||||
{
|
||||
//test_qos_parser();
|
||||
//test_qos_e2e_neg();
|
||||
test_qos_segmented_neg();
|
||||
}
|
||||
|
||||
#endif /* _TEST_QOS_H_ */
|
||||
|
|
|
@ -67,7 +67,8 @@ typedef enum tsip_ssession_param_type_e
|
|||
sstype_from,
|
||||
sstype_nocontact,
|
||||
sstype_expires,
|
||||
sstype_silent_hangup
|
||||
sstype_silent_hangup,
|
||||
sstype_media
|
||||
}
|
||||
tsip_ssession_param_type_t;
|
||||
|
||||
|
@ -81,8 +82,27 @@ tsip_ssession_param_type_t;
|
|||
#define TSIP_SSESSION_SET_NO_CONTACT(ENABLED_BOOL) sstype_nocontact, (tsk_bool_t)ENABLED_BOOL
|
||||
#define TSIP_SSESSION_SET_EXPIRES(VALUE_UINT) sstype_expires, (unsigned)VALUE_UINT
|
||||
#define TSIP_SSESSION_SET_SILENT_HANGUP(ENABLED_BOOL) sstype_silent_hangup, (tsk_bool_t)ENABLED_BOOL
|
||||
#define TSIP_SSESSION_SET_MEDIA(...) sstype_media, ##__VA_ARGS__
|
||||
#define TSIP_SSESSION_SET_NULL() sstype_null
|
||||
|
||||
typedef enum tsip_msession_param_type_e
|
||||
{
|
||||
mstype_null = tsk_null,
|
||||
|
||||
mstype_set_qos,
|
||||
mstype_unset_qos,
|
||||
mstype_set_timers,
|
||||
mstype_unset_timers,
|
||||
}
|
||||
tsip_msession_param_type_t;
|
||||
|
||||
#define TSIP_MSESSION_SET_QOS()
|
||||
#define TSIP_MSESSION_UNSET_QOS()
|
||||
#define TSIP_MSESSION_SET_TIMERS()
|
||||
#define TSIP_MSESSION_UNSET_TIMERS() mstype_null
|
||||
|
||||
#define TSIP_MSESSION_SET_NULL()
|
||||
|
||||
typedef struct tsip_ssession_s
|
||||
{
|
||||
TSK_DECLARE_OBJECT;
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
#endif
|
||||
|
||||
/* Whether to use SIP Compact headers */
|
||||
#define TSIP_COMPACT_HEADERS 1
|
||||
#define TSIP_COMPACT_HEADERS 0
|
||||
|
||||
#include <stdint.h>
|
||||
#ifdef __SYMBIAN32__
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
"Content-Length: 0\r\n" \
|
||||
"Call-ID: 1261611941121\r\n" \
|
||||
"Min-Expires: 30\r\n" \
|
||||
"Event: reg\r\n" \
|
||||
"From: <sip:mamadou@open-ims.test>;tag=1261611941121\r\n" \
|
||||
"Contact: <sip:mamadou@192.168.0.12:58827;transport=udp>;mobility=fixed;+deviceid=\"DD1289FA-C3D7-47bd-A40D-F1F1B2CC5FFC\";expires=300,<sip:mamadou@192.168.0.12:58828;transport=udp>;mobility=fixed;+deviceid=\"DD1289FA-C3D7-47bd-A40D-F1F1B2CC5FFC\";expires=300,<sip:mamadou@192.168.0.12:58829;transport=udp>;mobility=fixed;+deviceid=\"DD1289FA-C3D7-47bd-A40D-F1F1B2CC5FFC\";expires=300\r\n"\
|
||||
"Contact: <sip:mamadou@192.168.0.11:63140>;expires=3600;q=1.0,<sip:mamadou@192.168.0.11:56717>;expires=3600;q=1.0\r\n" \
|
||||
|
|
|
@ -200,7 +200,7 @@ int ret = txcap_action_create_element(stack,
|
|||
#define TXCAP_ACTION_SET_OPTION(ID_INT, VALUE_STR) txcap_apt_option, (thttp_action_option_t)ID_INT, (const char*)VALUE_STR
|
||||
#define TXCAP_ACTION_SET_HEADER(NAME_STR, VALUE_STR) txcap_apt_header, (const char*)NAME_STR, (const char*)VALUE_STR
|
||||
#define TXCAP_ACTION_SET_PAYLOAD(PAY_PTR, PAY_SIZE) txcap_apt_payload, (const void*)PAY_PTR, (size_t)PAY_SIZE
|
||||
#define TXCAP_ACTION_SET_SELECTOR(AUID_STR, ...) txcap_apt_selector, (const char*)AUID_STR, __VA_ARGS__
|
||||
#define TXCAP_ACTION_SET_SELECTOR(AUID_STR, ...) txcap_apt_selector, (const char*)AUID_STR, ##__VA_ARGS__
|
||||
#define TXCAP_ACTION_SET_REQUEST_URI(URI_STR) txcap_apt_urlstring, (const char*)URI_STR
|
||||
#define TXCAP_ACTION_SET_NULL() txcap_apt_null
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinySDP", "..\tinySDP\tinyS
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinySMS", "..\tinySMS\tinySMS.vcproj", "{9A3A5AF3-2333-4477-B880-7F901F9D8972}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyDAV", "..\tinyDAV\tinyDAV.vcproj", "{8E2F0B2E-2596-4010-BF4A-2F688975B5C1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyRTP", "..\tinyRTP\tinyRTP.vcproj", "{99B7D02F-8C70-4B45-AF3C-92313C3CEE15}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
|
@ -105,6 +109,18 @@ Global
|
|||
{9A3A5AF3-2333-4477-B880-7F901F9D8972}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{9A3A5AF3-2333-4477-B880-7F901F9D8972}.Release|Win32.Build.0 = Release|Win32
|
||||
{9A3A5AF3-2333-4477-B880-7F901F9D8972}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32
|
||||
{8E2F0B2E-2596-4010-BF4A-2F688975B5C1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{8E2F0B2E-2596-4010-BF4A-2F688975B5C1}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{8E2F0B2E-2596-4010-BF4A-2F688975B5C1}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32
|
||||
{8E2F0B2E-2596-4010-BF4A-2F688975B5C1}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{8E2F0B2E-2596-4010-BF4A-2F688975B5C1}.Release|Win32.Build.0 = Release|Win32
|
||||
{8E2F0B2E-2596-4010-BF4A-2F688975B5C1}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32
|
||||
{99B7D02F-8C70-4B45-AF3C-92313C3CEE15}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{99B7D02F-8C70-4B45-AF3C-92313C3CEE15}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{99B7D02F-8C70-4B45-AF3C-92313C3CEE15}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Win32
|
||||
{99B7D02F-8C70-4B45-AF3C-92313C3CEE15}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{99B7D02F-8C70-4B45-AF3C-92313C3CEE15}.Release|Win32.Build.0 = Release|Win32
|
||||
{99B7D02F-8C70-4B45-AF3C-92313C3CEE15}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\thirdparties\win32\include;..\..\thirdparties\win32\include\smc;..\..\tinySIP\include;..\..\tinySAK\src;..\..\tinySMS\include;..\..\tinyHTTP\include;..\..\tinyNET\src"
|
||||
AdditionalIncludeDirectories="..\..\thirdparties\win32\include;..\..\tinySIP\include;..\..\tinySAK\src;..\..\tinySMS\include;..\..\tinyHTTP\include;..\..\tinyNET\src;..\..\tinyDAV\include;..\..\tinyMEDIA\include;..\..\tinySDP\include"
|
||||
PreprocessorDefinitions="DEBUG_LEVEL=DEBUG_LEVEL_INFO;WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
|
@ -62,7 +62,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="$(OutDir)\tinySAK.lib $(OutDir)\tinySIP.lib $(OutDir)\tinyNET.lib $(OutDir)\tinySMS.lib"
|
||||
AdditionalDependencies="$(OutDir)\tinySAK.lib $(OutDir)\tinySIP.lib $(OutDir)\tinyNET.lib $(OutDir)\tinySMS.lib $(OutDir)\tinyDAV.lib $(OutDir)\tinyMEDIA.lib"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
|
|
|
@ -203,6 +203,10 @@
|
|||
RelativePath="..\..\tinyMEDIA\test\test_codecs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\tinyMEDIA\test\test_qos.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\tinyMEDIA\test\test_sessions.h"
|
||||
>
|
||||
|
|
Loading…
Reference in New Issue