Add support for MSRP report and complete the receiver.

This commit is contained in:
bossiel 2010-03-26 17:56:55 +00:00
parent 5edccf775d
commit fcfd6878d8
39 changed files with 3760 additions and 3016 deletions

View File

@ -41,7 +41,7 @@ TMSRP_BEGIN_DECLS
*/
#define TMSRP_HEADER_CONTENT_TYPE_VA_ARGS(type) tmsrp_header_Content_Type_def_t, (const char*)type
#define TMSRP_HEADER_CONTENT_TYPE_CREATE(type) tsk_object_new(TMSRP_HEADER_CONTENT_TYPE_VA_ARGS(type))
#define TMSRP_HEADER_CONTENT_TYPE_CREATE_NULL() TMSRP_HEADER_CONTENT_TYPE_CREATE(TMSRP_NULL)
#define TMSRP_HEADER_CONTENT_TYPE_CREATE_NULL() TMSRP_HEADER_CONTENT_TYPE_CREATE(tsk_null)
////////////////////////////////////////////////////////////////////////////////////////////////////
/// @struct

View File

@ -41,7 +41,7 @@ TMSRP_BEGIN_DECLS
*/
#define TMSRP_HEADER_DUMMY_VA_ARGS(name, value) tmsrp_header_Dummy_def_t, (const char*)name, (const char*)value
#define TMSRP_HEADER_DUMMY_CREATE(name, value) tsk_object_new(TMSRP_HEADER_DUMMY_VA_ARGS(name, value))
#define TMSRP_HEADER_DUMMY_CREATE_NULL() TMSRP_HEADER_DUMMY_CREATE(TMSRP_NULL, TMSRP_NULL)
#define TMSRP_HEADER_DUMMY_CREATE_NULL() TMSRP_HEADER_DUMMY_CREATE(tsk_null, tsk_null)
////////////////////////////////////////////////////////////////////////////////////////////////////
/// @struct

View File

@ -43,7 +43,7 @@ TMSRP_BEGIN_DECLS
*/
#define TMSRP_HEADER_FROM_PATH_VA_ARGS(uri) tmsrp_header_From_Path_def_t, (const tmsrp_uri_t*)uri
#define TMSRP_HEADER_FROM_PATH_CREATE(uri) tsk_object_new(TMSRP_HEADER_FROM_PATH_VA_ARGS(uri))
#define TMSRP_HEADER_FROM_PATH_CREATE_NULL() TMSRP_HEADER_FROM_PATH_CREATE(TMSRP_NULL)
#define TMSRP_HEADER_FROM_PATH_CREATE_NULL() TMSRP_HEADER_FROM_PATH_CREATE(tsk_null)
////////////////////////////////////////////////////////////////////////////////////////////////////
/// @struct

View File

@ -41,7 +41,7 @@ TMSRP_BEGIN_DECLS
*/
#define TMSRP_HEADER_MESSAGE_ID_VA_ARGS(value) tmsrp_header_Message_ID_def_t, (const char*)value
#define TMSRP_HEADER_MESSAGE_ID_CREATE(value) tsk_object_new(TMSRP_HEADER_MESSAGE_ID_VA_ARGS(value))
#define TMSRP_HEADER_MESSAGE_ID_CREATE_NULL() TMSRP_HEADER_MESSAGE_ID_CREATE(TMSRP_NULL)
#define TMSRP_HEADER_MESSAGE_ID_CREATE_NULL() TMSRP_HEADER_MESSAGE_ID_CREATE(tsk_null)
////////////////////////////////////////////////////////////////////////////////////////////////////
/// @struct

View File

@ -41,7 +41,7 @@ TMSRP_BEGIN_DECLS
*/
#define TMSRP_HEADER_STATUS_VA_ARGS(namespace, code, reason) tmsrp_header_Status_def_t, (short)namespace, (short)code, (const char*)reason
#define TMSRP_HEADER_STATUS_CREATE(namespace, code, reason) tsk_object_new(TMSRP_HEADER_STATUS_VA_ARGS(namespace, code, reason))
#define TMSRP_HEADER_STATUS_CREATE_NULL() TMSRP_HEADER_STATUS_CREATE(0, 200, TMSRP_NULL)
#define TMSRP_HEADER_STATUS_CREATE_NULL() TMSRP_HEADER_STATUS_CREATE(0, 200, tsk_null)
////////////////////////////////////////////////////////////////////////////////////////////////////
/// @struct

View File

@ -43,7 +43,7 @@ TMSRP_BEGIN_DECLS
*/
#define TMSRP_HEADER_TO_PATH_VA_ARGS(uri) tmsrp_header_To_Path_def_t, (const tmsrp_uri_t*)uri
#define TMSRP_HEADER_TO_PATH_CREATE(uri) tsk_object_new(TMSRP_HEADER_TO_PATH_VA_ARGS(uri))
#define TMSRP_HEADER_TO_PATH_CREATE_NULL() TMSRP_HEADER_TO_PATH_CREATE(TMSRP_NULL)
#define TMSRP_HEADER_TO_PATH_CREATE_NULL() TMSRP_HEADER_TO_PATH_CREATE(tsk_null)
////////////////////////////////////////////////////////////////////////////////////////////////////
/// @struct

View File

@ -43,7 +43,7 @@ TMSRP_BEGIN_DECLS
*/
#define TMSRP_HEADER_USE_PATH_VA_ARGS(uri) tmsrp_header_Use_Path_def_t, (const tmsrp_uri_t*)uri
#define TMSRP_HEADER_USE_PATH_CREATE(uri) tsk_object_new(TMSRP_HEADER_USE_PATH_VA_ARGS(uri))
#define TMSRP_HEADER_USE_PATH_CREATE_NULL() TMSRP_HEADER_USE_PATH_CREATE(TMSRP_NULL)
#define TMSRP_HEADER_USE_PATH_CREATE_NULL() TMSRP_HEADER_USE_PATH_CREATE(tsk_null)
////////////////////////////////////////////////////////////////////////////////////////////////////
/// @struct

View File

@ -36,6 +36,7 @@
TMSRP_BEGIN_DECLS
TINYMSRP_API tmsrp_message_t* tmsrp_message_parse_2(const void *input, size_t size, size_t* msg_size);
TINYMSRP_API tmsrp_message_t* tmsrp_message_parse(const void *input, size_t size);
TMSRP_END_DECLS

View File

@ -39,18 +39,15 @@
TMSRP_BEGIN_DECLS
#define TMSRP_DATA(self) ((tmsrp_data_t*)(self))
#define TMSRP_DATA_IS_FILE_TRANSFER(self) (TMSRP_DATA(self)->file != tsk_null)
#define TMSRP_DATA_IS_DATA_TRANSFER(self) (TMSRP_DATA(self)->buffer != tsk_null)
#define TMSRP_DATA_IS_OUTGOING(self) (TMSRP_DATA(self)->outgoing)
#define _TMSRP_DATA_IN_CREATE(pdata, size, isfilepath) tsk_object_new(tmsrp_data_in_def_t, (const void*)pdata, (size_t)size, (tsk_bool_t)isfilepath)
#define TMSRP_DATA_IN_CREATE(pdata, size) _TMSRP_DATA_IN_CREATE(pdata, size, tsk_false)
#define TMSRP_DATA_IN_FILE_CREATE(pdata, size) _TMSRP_DATA_IN_CREATE(pdata, size, tsk_true)
#define TMSRP_DATA_IN_CREATE() tsk_object_new(tmsrp_data_in_def_t)
#define _TMSRP_DATA_OUT_CREATE(pdata, size, isfilepath) tsk_object_new(tmsrp_data_out_def_t, (const void*)pdata, (size_t)size, (tsk_bool_t)isfilepath)
#define TMSRP_DATA_OUT_CREATE(pdata, size) _TMSRP_DATA_OUT_CREATE(pdata, size, tsk_false)
#define TMSRP_DATA_OUT_FILE_CREATE(filepath) _TMSRP_DATA_OUT_CREATE(filepath, strlen(filepath), tsk_true)
typedef struct tmsrp_data_s
{
TSK_DECLARE_OBJECT;
@ -60,33 +57,30 @@ typedef struct tmsrp_data_s
char* id;
char* ctype;
FILE* file;
tsk_buffer_t* buffer;
}
tmsrp_data_t;
#define TMSRP_DECLARE_DATA tmsrp_data_t data
typedef tsk_list_t tmsrp_datas_L_t;
int tmsrp_data_init(tmsrp_data_t* self, tsk_bool_t outgoing, const void* pdata, size_t size, tsk_bool_t isfile, const char* ctype);
int tmsrp_data_deinit(tmsrp_data_t* self);
typedef struct tmsrp_data_in_s
{
TMSRP_DECLARE_DATA;
tsk_buffer_t* buffer;
}
tmsrp_data_in_t;
int tmsrp_data_in_put(tmsrp_data_in_t* self, const void* pdata, size_t size);
tmsrp_request_t* tmsrp_data_in_get(tmsrp_data_in_t* self);
tmsrp_message_t* tmsrp_data_in_get(tmsrp_data_in_t* self);
typedef struct tmsrp_data_out_s
{
TMSRP_DECLARE_DATA;
FILE* file;
tsk_buffer_t* message;
size_t size; // File/message size
}
tmsrp_data_out_t;

View File

@ -35,6 +35,8 @@
#include "tinyMSRP/session/tmsrp_sender.h"
#include "tinyMSRP/session/tmsrp_receiver.h"
#include "tnet_transport.h"
#include "tinyMEDIA/tmedia.h"
#include "tsdp.h"
@ -55,14 +57,15 @@ typedef struct tmsrp_media_s
{
TMED_DECLARE_MEDIA;
tnet_transport_t *transport;
tmsrp_config_t* config;
tmsrp_session_setup_t setup;
tnet_fd_t connectedFD; // FullDuplex Socket
tmsrp_sender_t* sender;
tmsrp_receiver_t* receiver;
struct{
struct tsdp_header_M_s* M;
tnet_socket_t* socket;
}local;
struct{

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)yahoo.fr>
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
/**@file tmsrp_receiver.h
* @brief MSRP receiver.
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
*
* @date Created: Sat Nov 8 16:54:58 2009 mdiop
*/
#ifndef TINYMSRP_RECEIVER_H
#define TINYMSRP_RECEIVER_H
#include "tinyMSRP_config.h"
#include "tinyMSRP/session/tmsrp_data.h"
#include "tinyMSRP/session/tmsrp_config.h"
#include "tnet_types.h"
#include "tnet_transport.h"
TMSRP_BEGIN_DECLS
#define TMSRP_RECEIVER_CREATE(config, fd) tsk_object_new(tmsrp_receiver_def_t, (tmsrp_config_t*)config, (tnet_fd_t) fd)
int tmsrp_transport_layer_stream_cb(const tnet_transport_event_t* e);
typedef struct tmsrp_receiver_s
{
TSK_DECLARE_OBJECT;
tmsrp_data_in_t* data_in;
tmsrp_config_t* config;
tnet_fd_t fd;
}
tmsrp_receiver_t;
int tmsrp_receiver_start(tmsrp_receiver_t* self);
int tmsrp_receiver_stop(tmsrp_receiver_t* self);
const tsk_object_def_t *tmsrp_receiver_def_t;
TMSRP_END_DECLS
#endif /* TINYMSRP_RECEIVER_H */

View File

@ -47,7 +47,7 @@ typedef struct tmsrp_sender_s
{
TSK_DECLARE_RUNNABLE;
tmsrp_datas_L_t* outputList;
tmsrp_datas_L_t* outgoingList;
tmsrp_config_t* config;
tnet_fd_t fd;
}

View File

@ -45,8 +45,8 @@
TMSRP_BEGIN_DECLS
#define TMSRP_MESSAGE_IS_REQUEST(self) ((self) ? (self)->type == tmsrp_request : 0)
#define TMSRP_MESSAGE_IS_RESPONSE(self) ((self) ? (self)->type == tmsrp_response : 0)
#define TMSRP_MESSAGE_IS_REQUEST(self) ((self) ? (self)->type == tmsrp_request : tsk_false)
#define TMSRP_MESSAGE_IS_RESPONSE(self) ((self) ? (self)->type == tmsrp_response : tsk_false)
#define TMSRP_MESSAGE(self) ((tmsrp_message_t*)(self))
#define TMSRP_MESSAGE_AS_RESPONSE(self) ((tmsrp_response_t*)(self))
@ -61,17 +61,20 @@ TMSRP_BEGIN_DECLS
#define TMSRP_MESSAGE_CREATE(type, tid, method, status, comment)\
tsk_object_new(tmsrp_message_def_t, (tmsrp_message_type_t)type, (const char*)tid, (const char*)method, (short)status, (const char*)comment)
#define TMSRP_REQUEST_CREATE(tid, method)\
TMSRP_MESSAGE_CREATE(tmsrp_request, tid, method, 0, TMSRP_NULL)
TMSRP_MESSAGE_CREATE(tmsrp_request, tid, method, 0, tsk_null)
#define TMSRP_RESPONSE_CREATE(tid, status, comment)\
TMSRP_MESSAGE_CREATE(tmsrp_response, tid, TMSRP_NULL, status, comment)
TMSRP_MESSAGE_CREATE(tmsrp_response, tid, tsk_null, status, comment)
#define TMSRP_MESSAGE_CREATE_NULL()\
TMSRP_MESSAGE_CREATE(tmsrp_unknown, TMSRP_NULL, TMSRP_NULL, 0, TMSRP_NULL)
TMSRP_MESSAGE_CREATE(tmsrp_unknown, tsk_null, tsk_null, 0, tsk_null)
#define TMSRP_RESPONSE_CODE(self) (TMSRP_MESSAGE_IS_RESPONSE((self)) ? (self)->status_code : 0)
#define TMSRP_RESPONSE_PHRASE(self) ((self)->reason_phrase)
#define TMSRP_REQUEST_METHOD(self) ((self)->method)
#define TMSRP_REQUEST_URI(self) ((self)->uri)
#define TMSRP_REQUEST_IS_SEND(self) (TMSRP_MESSAGE_IS_REQUEST(self) && (self)->line.request.type == tmsrp_SEND)
#define TMSRP_REQUEST_IS_REPORT(self) (TMSRP_MESSAGE_IS_REQUEST(self) && (self)->line.request.type == tmsrp_REPORT)
#define TMSRP_REQUEST_IS_AUTH(self) (TMSRP_MESSAGE_IS_REQUEST(self) && (self)->line.request.type == tmsrp_AUTH)
#define TMSRP_MESSAGE_HAS_CONTENT(message) ((message) && (message)->Content && (message)->Content->data)
#define TMSRP_MESSAGE_CONTENT(message) (TMSRP_MESSAGE_HAS_CONTENT(message) ? (message)->Content->data : 0)
@ -96,6 +99,17 @@ typedef enum tmsrp_message_type_e
}
tmsrp_message_type_t;
typedef enum tmsrp_request_type_e
{
tmsrp_NONE = 0,
tmsrp_SEND,
tmsrp_REPORT,
tmsrp_AUTH
//...
}
tmsrp_request_type_t;
typedef struct tmsrp_message_s
{
TSK_DECLARE_OBJECT;
@ -105,6 +119,7 @@ typedef struct tmsrp_message_s
/*union*/struct{
struct{
char* method;
tmsrp_request_type_t type;
} request;
struct{
@ -169,6 +184,7 @@ static void TMSRP_MESSAGE_ADD_HEADER(tmsrp_message_t *self, ...)
}
#endif
TINYMSRP_API tmsrp_request_type_t tmsrp_request_get_type(const char* method);
TINYMSRP_API const tmsrp_header_t *tmsrp_message_get_headerAt(const tmsrp_message_t *self, tmsrp_header_type_t type, size_t index);
TINYMSRP_API const tmsrp_header_t *tmsrp_message_get_header(const tmsrp_message_t *self, tmsrp_header_type_t type);
TINYMSRP_API const tmsrp_header_t *tmsrp_message_get_headerByName(const tmsrp_message_t *self, char name);

View File

@ -52,7 +52,7 @@ TMSRP_BEGIN_DECLS
#define TMSRP_URI_CREATE(scheme, host, host_type, port, session_id, transport)\
tsk_object_new(tmsrp_uri_def_t, (const char*)scheme, (const char*)host, (tmsrp_host_type_t)host_type, (int32_t)port, (const char*)session_id, (const char*)transport)
#define TMSRP_URI_CREATE_NULL() TMSRP_URI_CREATE(TMSRP_NULL, TMSRP_NULL, host_unknown, -1, TMSRP_NULL, TMSRP_NULL)
#define TMSRP_URI_CREATE_NULL() TMSRP_URI_CREATE(tsk_null, tsk_null, host_unknown, -1, tsk_null, tsk_null)
#define TMSRP_URI_IS_SECURE(uri) ((uri) && (tsk_striequals(uri->scheme, "msrps") ? 1 : 0))
#define TMSRP_URI(self) ((tmsrp_uri_t*)(self))

View File

@ -81,8 +81,5 @@
#include <stdint.h>
#include <stddef.h>
/* FIXME */
#define TMSRP_NULL 0
#endif /* _TINYMSRP_H_ */

View File

@ -36,10 +36,10 @@
TMSRP_BEGIN_DECLS
TINYMSRP_API tmsrp_request_t* tmsrp_create_bodiless();
TINYMSRP_API tmsrp_request_t* tmsrp_create_bodiless(const tmsrp_uri_t* To, const tmsrp_uri_t* From);
TINYMSRP_API tmsrp_response_t* tmsrp_create_response(const tmsrp_request_t* request, short status, const char* comment);
TINYMSRP_API tmsrp_request_t* tmsrp_create_report(const tmsrp_request_t* request, short status, const char* reason);
TINYMSRP_API int tmsrp_isReportRequired(const tmsrp_request_t* request);
TINYMSRP_API tmsrp_request_t* tmsrp_create_report(const tmsrp_request_t* SEND, short status, const char* reason);
TINYMSRP_API tsk_bool_t tmsrp_isReportRequired(const tmsrp_request_t* request, tsk_bool_t failed);
TMSRP_END_DECLS

View File

@ -63,7 +63,7 @@
action parse_total{
if(tag_start && *tag_start == '*'){
hdr_Byte_Range->end = -1;
hdr_Byte_Range->total = -1;
}
else{
TSK_PARSER_SET_INTEGER_EX(hdr_Byte_Range->total, int64_t, atoi64);

View File

@ -118,7 +118,7 @@ tmsrp_header_From_Path_t *tmsrp_header_From_Path_parse(const char *data, size_t
tmsrp_header_From_Path_t *tmsrp_header_From_Path_clone(const tmsrp_header_From_Path_t* From_Path)
{
tmsrp_header_From_Path_t* clone = TMSRP_NULL;
tmsrp_header_From_Path_t* clone = tsk_null;
if(!From_Path){
goto bail;

View File

@ -117,7 +117,7 @@ tmsrp_header_To_Path_t *tmsrp_header_To_Path_parse(const char *data, size_t size
tmsrp_header_To_Path_t *tmsrp_header_To_Path_clone(const tmsrp_header_To_Path_t* To_Path)
{
tmsrp_header_To_Path_t* clone = TMSRP_NULL;
tmsrp_header_To_Path_t* clone = tsk_null;
if(!To_Path){
goto bail;

View File

@ -35,8 +35,10 @@
#include "tinyMSRP/headers/tmsrp_header_Use-Path.h"
#include "tinyMSRP/headers/tmsrp_header_WWW-Authenticate.h"
#include "tsk_debug.h"
#include "tsk_string.h"
#include "tsk_memory.h"
#include "tsk_debug.h"
#define TMSRP_MSG_PARSER_ADD_HEADER(name) \
if((header = (tmsrp_header_t*)tmsrp_header_##name##_parse(tag_start, (p - tag_start)))){ \
@ -132,6 +134,7 @@
if(msrp_msg->type == tmsrp_unknown){
msrp_msg->type = tmsrp_request;
TSK_PARSER_SET_STRING(msrp_msg->line.request.method);
msrp_msg->line.request.type = tmsrp_request_get_type(msrp_msg->line.request.method);
}
else{
//cs = %%{ write first_final; }%%;
@ -160,8 +163,14 @@
action parse_data{
int len = (int)(p - tag_start);
if(len>0 && !msrp_msg->Content){
msrp_msg->Content = TSK_BUFFER_CREATE(tag_start, (size_t)len);
if(len>0){
if(msrp_msg->Content){
tsk_buffer_cleanup(msrp_msg->Content);
tsk_buffer_append(msrp_msg->Content, tag_start, (size_t)len);
}
else{
msrp_msg->Content = TSK_BUFFER_CREATE(tag_start, (size_t)len);
}
}
}
@ -176,6 +185,17 @@
else msrp_msg->end_line.cflag = '#';
}
action outside_endline{
*msg_size = (p - (const char*)input) + 1;
}
action into_endline{
into_endline = tsk_true;
}
action endtid_match{
( into_endline || (((pe-p) >7/*seven hyphens*/) && (msrp_msg->tid) && tsk_strniequals(msrp_msg->tid, (p+7), strlen(msrp_msg->tid))) )
}
###########################################
# Headers
@ -224,8 +244,8 @@
###########################################
req_start = "MSRP" SP transact_id>tag %parse_tid SP method>tag %parse_method CRLF;
#content_stuff = (Other_Mime_header)* CRLF data>tag %parse_data :>CRLF;
content_stuff = CRLF<: data>tag %parse_data :>CRLF;
msrp_request = req_start headers>1 (content_stuff)?>0 end_line;
content_stuff = data>tag %parse_data;
msrp_request = req_start headers>10 (CRLF content_stuff CRLF)?>5 :>end_line when endtid_match >into_endline;
###########################################
# Response
@ -236,7 +256,7 @@
###########################################
# Message
###########################################
msrp_req_or_resp = (msrp_request | msrp_response);
msrp_req_or_resp = (msrp_request | msrp_response)>1 @outside_endline any*>0;
###########################################
# Entry Point
@ -249,18 +269,27 @@
tmsrp_message_t* tmsrp_message_parse(const void *input, size_t size)
{
tmsrp_message_t* msrp_msg = TMSRP_NULL;
const char* tag_start = TMSRP_NULL;
tmsrp_header_t* header = TMSRP_NULL;
size_t msg_size;
return tmsrp_message_parse_2(input, size, &msg_size);
}
tmsrp_message_t* tmsrp_message_parse_2(const void *input, size_t size, size_t* msg_size)
{
tmsrp_message_t* msrp_msg = tsk_null;
const char* tag_start = tsk_null;
tmsrp_header_t* header = tsk_null;
tsk_bool_t into_endline = tsk_false;
/* Ragel variables */
int cs = 0;
const char* p = input;
const char* pe = p + size;
const char* eof = TMSRP_NULL;
const char* eof = tsk_null;
*msg_size = 0;
if(!input || !size){
TSK_DEBUG_ERROR("Null or empty buffer.");
//TSK_DEBUG_ERROR("Null or empty buffer."); // --> very common case(stream): do not bother us...
goto bail;
}
@ -276,11 +305,11 @@ tmsrp_message_t* tmsrp_message_parse(const void *input, size_t size)
/* Check result */
if( cs < %%{ write first_final; }%% ){
TSK_DEBUG_ERROR("Failed to parse MSRP message.");
//TSK_DEBUG_ERROR("Failed to parse MSRP message."); --> very common case(stream): do not bother us...
TSK_OBJECT_SAFE_FREE(msrp_msg);
goto bail;
}
bail:
return msrp_msg;
}
}

View File

@ -269,7 +269,7 @@ _match:
/* #line 64 "tmsrp_parser_header_Byte-Range.rl" */
{
if(tag_start && *tag_start == '*'){
hdr_Byte_Range->end = -1;
hdr_Byte_Range->total = -1;
}
else{
TSK_PARSER_SET_INTEGER_EX(hdr_Byte_Range->total, int64_t, atoi64);
@ -296,7 +296,7 @@ _again:
/* #line 64 "tmsrp_parser_header_Byte-Range.rl" */
{
if(tag_start && *tag_start == '*'){
hdr_Byte_Range->end = -1;
hdr_Byte_Range->total = -1;
}
else{
TSK_PARSER_SET_INTEGER_EX(hdr_Byte_Range->total, int64_t, atoi64);

View File

@ -311,7 +311,7 @@ _again:
tmsrp_header_From_Path_t *tmsrp_header_From_Path_clone(const tmsrp_header_From_Path_t* From_Path)
{
tmsrp_header_From_Path_t* clone = TMSRP_NULL;
tmsrp_header_From_Path_t* clone = tsk_null;
if(!From_Path){
goto bail;

View File

@ -304,7 +304,7 @@ _again:
tmsrp_header_To_Path_t *tmsrp_header_To_Path_clone(const tmsrp_header_To_Path_t* To_Path)
{
tmsrp_header_To_Path_t* clone = TMSRP_NULL;
tmsrp_header_To_Path_t* clone = tsk_null;
if(!To_Path){
goto bail;

File diff suppressed because it is too large Load Diff

View File

@ -28,70 +28,69 @@
* @date Created: Sat Nov 8 16:54:58 2009 mdiop
*/
#include "tinyMSRP/session/tmsrp_data.h"
#include "tinyMSRP/session/tmsrp_config.h"
#include "tinyMSRP/parsers/tmsrp_parser_message.h"
#include "tsk_string.h"
#include "tsk_memory.h"
#include "tsk_debug.h"
#include <stdio.h> /* fopen, fclose ... */
#define TMSRP_DATA_IN_MAX_BUFFER 0xFFFF
/* =========================== Common ============================= */
int tmsrp_data_init(tmsrp_data_t* self, tsk_bool_t outgoing, const void* pdata, size_t size, tsk_bool_t isfilepath, const char* ctype)
{
tsk_istr_t id;
if(!self || !pdata || !size){
return -1;
}
if(isfilepath){
if(self->file){
fclose(self->file);
}
if(outgoing){
if(!(self->file = fopen((const char*)pdata, "rb"))){
TSK_DEBUG_ERROR("Failed to open(rb) this file:%s", pdata);
return -2;
}
}
else{
if(!(self->file = fopen((const char*)pdata, "wb"))){
TSK_DEBUG_ERROR("Failed to open(wb) this file:%s", pdata);
return -3;
}
}
}
else{
self->buffer = TSK_BUFFER_CREATE(pdata, size);
}
// ctype
tsk_strupdate(&self->ctype, ctype);
// random id
tsk_strrandom(&id);
tsk_strupdate(&self->id, id);
//int tmsrp_data_init(tmsrp_data_t* self, tsk_bool_t outgoing, const void* pdata, size_t size, tsk_bool_t isfilepath, const char* ctype)
//{
// if(!self || !pdata || !size){
// return -1;
// }
//
// if(isfilepath){
// if(self->file){
// fclose(self->file);
// }
// if(outgoing){
// if(!(self->file = fopen((const char*)pdata, "rb"))){
// TSK_DEBUG_ERROR("Failed to open(rb) this file:%s", pdata);
// return -2;
// }
// }
// else{
// if(!(self->file = fopen((const char*)pdata, "wb"))){
// TSK_DEBUG_ERROR("Failed to open(wb) this file:%s", pdata);
// return -3;
// }
// }
// }
// else{
// self->buffer = TSK_BUFFER_CREATE(pdata, size);
// }
// // ctype
// tsk_strupdate(&self->ctype, ctype);
//
// return 0;
//}
return 0;
}
int tmsrp_data_deinit(tmsrp_data_t* self)
{
if(!self){
return -1;
}
TSK_FREE(self->id);
TSK_FREE(self->ctype);
TSK_OBJECT_SAFE_FREE(self->buffer);
if(self->file){
fclose(self->file);
self->file = tsk_null;
}
return 0;
}
//int tmsrp_data_deinit(tmsrp_data_t* self)
//{
// if(!self){
// return -1;
// }
//
// TSK_FREE(self->id);
// TSK_FREE(self->ctype);
// TSK_OBJECT_SAFE_FREE(self->buffer);
//
// if(self->file){
// fclose(self->file);
// self->file = tsk_null;
// }
//
// return 0;
//}
@ -102,22 +101,41 @@ int tmsrp_data_deinit(tmsrp_data_t* self)
int tmsrp_data_in_put(tmsrp_data_in_t* self, const void* pdata, size_t size)
{
if(!self || !pdata || !size){
return -1;
int ret = -1;
if(!self || !self->buffer || !pdata || !size){
return ret;
}
return 0;
if((ret = tsk_buffer_append(self->buffer, pdata, size))){
tsk_buffer_cleanup(self->buffer);
return ret;
}
else{
if(TSK_BUFFER_SIZE(self->buffer) > TMSRP_DATA_IN_MAX_BUFFER){
tsk_buffer_cleanup(self->buffer);
TSK_DEBUG_ERROR("Too many bytes are waiting.");
return -3;
}
}
return ret;
}
tmsrp_request_t* tmsrp_data_in_get(tmsrp_data_in_t* self)
tmsrp_message_t* tmsrp_data_in_get(tmsrp_data_in_t* self)
{
tmsrp_request_t* ret = tsk_null;
tmsrp_message_t* ret;
size_t msg_size;
if(!self){
if(!self || !self->buffer || !TSK_BUFFER_DATA(self->buffer) || !TSK_BUFFER_SIZE(self->buffer)){
//...this is not an error
return tsk_null;
}
return ret;
if((ret = tmsrp_message_parse_2(self->buffer->data, self->buffer->size, &msg_size))){
tsk_buffer_remove(self->buffer, 0, msg_size);
return ret;
}
return tsk_null;
}
@ -132,13 +150,13 @@ tsk_buffer_t* tmsrp_data_out_get(tmsrp_data_out_t* self)
return tsk_null;
}
if(TMSRP_DATA_IS_DATA_TRANSFER(self)){
if((toread = TSK_BUFFER_SIZE(TMSRP_DATA(self)->buffer) > TMSRP_MAX_CHUNK_SIZE ? TMSRP_MAX_CHUNK_SIZE : TSK_BUFFER_SIZE(TMSRP_DATA(self)->buffer))){
ret = TSK_BUFFER_CREATE(TSK_BUFFER_DATA(TMSRP_DATA(self)->buffer), toread);
tsk_buffer_remove(TMSRP_DATA(self)->buffer, 0, toread);
if(self->message){
if((toread = TSK_BUFFER_SIZE(self->message) > TMSRP_MAX_CHUNK_SIZE ? TMSRP_MAX_CHUNK_SIZE : TSK_BUFFER_SIZE(self->message))){
ret = TSK_BUFFER_CREATE(TSK_BUFFER_DATA(self->message), toread);
tsk_buffer_remove(self->message, 0, toread);
}
}
else if(TMSRP_DATA_IS_FILE_TRANSFER(self)){
else if(self->file){
}
@ -159,16 +177,7 @@ static void* tmsrp_data_in_create(void * self, va_list * app)
{
tmsrp_data_in_t *data_in = self;
if(data_in){
const void* pdata = va_arg(*app, const void*);
size_t size = va_arg(*app, size_t);
tsk_bool_t isfilepath = va_arg(*app, tsk_bool_t);
if(tmsrp_data_init(TMSRP_DATA(data_in), tsk_false, pdata, size, isfilepath, "text/plain")){
TMSRP_DATA(data_in)->isOK = tsk_false;
}
else{
TMSRP_DATA(data_in)->isOK = tsk_true;
}
data_in->buffer = TSK_BUFFER_CREATE_NULL();
}
return self;
}
@ -177,7 +186,10 @@ static void* tmsrp_data_in_destroy(void * self)
{
tmsrp_data_in_t *data_in = self;
if(data_in){
tmsrp_data_deinit(TMSRP_DATA(data_in));
TSK_FREE(TMSRP_DATA(data_in)->id);
TSK_FREE(TMSRP_DATA(data_in)->ctype);
TSK_OBJECT_SAFE_FREE(data_in->buffer);
}
return self;
@ -199,16 +211,25 @@ static void* tmsrp_data_out_create(void * self, va_list * app)
{
tmsrp_data_out_t *data_out = self;
if(data_out){
tsk_istr_t id;
const void* pdata = va_arg(*app, const void*);
size_t size = va_arg(*app, size_t);
tsk_bool_t isfilepath = va_arg(*app, tsk_bool_t);
if(tmsrp_data_init(TMSRP_DATA(data_out), tsk_true, pdata, size, isfilepath, "text/plain")){
TMSRP_DATA(data_out)->isOK = tsk_false;
if(isfilepath){
}
else{
TMSRP_DATA(data_out)->isOK = tsk_true;
if((data_out->message = TSK_BUFFER_CREATE(pdata, size))){
TMSRP_DATA(data_out)->isOK = (data_out->message->size == size);
data_out->size = data_out->message->size;
}
}
// content type
TMSRP_DATA(data_out)->ctype = tsk_strdup("text/plain");
// random id
tsk_strrandom(&id);
TMSRP_DATA(data_out)->id = tsk_strdup(id);
}
return self;
}
@ -217,7 +238,14 @@ static void* tmsrp_data_out_destroy(void * self)
{
tmsrp_data_out_t *data_out = self;
if(data_out){
tmsrp_data_deinit(TMSRP_DATA(data_out));
TSK_FREE(TMSRP_DATA(data_out)->id);
TSK_FREE(TMSRP_DATA(data_out)->ctype);
TSK_OBJECT_SAFE_FREE(data_out->message);
if(data_out->file){
fclose(data_out->file);
data_out->file = tsk_null;
}
}
return self;

View File

@ -33,6 +33,8 @@
#include "tinySDP/headers/tsdp_header_C.h"
#include "tinySDP/headers/tsdp_header_M.h"
#include "tmsrp.h"
#include "tnet_utils.h"
#include "tsk_string.h"
@ -83,10 +85,10 @@ const char* setup_to_string(tmsrp_session_setup_t setup)
int tmsrp_media_start(tmedia_t* self)
{
int ret = -1;
tsk_bool_t send_bodiless = tsk_false;
tmsrp_media_t *msrp = TMSRP_MEDIA(self);
struct sockaddr_storage to;
if(!msrp || !msrp->local.socket || msrp->local.socket->fd <= 0){
if(!msrp){
goto bail;
}
@ -99,7 +101,12 @@ int tmsrp_media_start(tmedia_t* self)
ret = -3;
goto bail;
}
// start the transport
if((ret = tnet_transport_start(msrp->transport))){
goto bail;
}
switch(msrp->setup){
case setup_active:
case setup_actpass:
@ -107,28 +114,24 @@ int tmsrp_media_start(tmedia_t* self)
//
// ACTIVE
//
if((ret = tnet_sockaddr_init(msrp->remote.M->C->addr, msrp->remote.M->port, msrp->local.socket->type, &to))){
if((msrp->connectedFD = tnet_transport_connectto_2(msrp->transport, msrp->remote.M->C->addr, msrp->remote.M->port)) == TNET_INVALID_FD){
goto bail;
}
if((ret = tnet_sockfd_connetto(msrp->local.socket->fd, &to))){
goto bail;
}
else{
msrp->connectedFD = msrp->local.socket->fd;
if((ret = tnet_sockfd_waitUntilWritable(msrp->connectedFD, TMSRP_CONNECT_TIMEOUT))){
TSK_DEBUG_ERROR("%d milliseconds elapsed and the socket is still not connected.", TMSRP_CONNECT_TIMEOUT);
goto bail;
}
/* draft-denis-simple-msrp-comedia-02 - 4.2.3. Setting up the connection
Once the TCP session is established, and if the answerer was the
active connection endpoint, it MUST send an MSRP request. In
particular, if it has no pending data to send, it MUST send an empty
MSRP SEND request. That is necessary for the other endpoint to
authenticate this TCP session.
else{
if((ret = tnet_sockfd_waitUntilWritable(msrp->connectedFD, TMSRP_CONNECT_TIMEOUT))){
TSK_DEBUG_ERROR("%d milliseconds elapsed and the socket is still not connected.", TMSRP_CONNECT_TIMEOUT);
goto bail;
}
/* draft-denis-simple-msrp-comedia-02 - 4.2.3. Setting up the connection
Once the TCP session is established, and if the answerer was the
active connection endpoint, it MUST send an MSRP request. In
particular, if it has no pending data to send, it MUST send an empty
MSRP SEND request. That is necessary for the other endpoint to
authenticate this TCP session.
...RFC 4975 - 7.1
*/
// ... send bodiless message
...RFC 4975 - 7.1
*/
send_bodiless = tsk_true;
}
break;
}
@ -140,6 +143,16 @@ int tmsrp_media_start(tmedia_t* self)
break;
}
}
// create and start the receiver
if(!msrp->receiver){
if((msrp->receiver = TMSRP_RECEIVER_CREATE(msrp->config, msrp->connectedFD))){
tnet_transport_set_callback(msrp->transport, TNET_TRANSPORT_CB_F(tmsrp_transport_layer_stream_cb), msrp->receiver);
if((ret = tmsrp_receiver_start(msrp->receiver))){
goto bail;
}
}
}
// create and start the sender
if(!msrp->sender){
@ -147,6 +160,23 @@ int tmsrp_media_start(tmedia_t* self)
if((ret = tmsrp_sender_start(msrp->sender))){
goto bail;
}
else if(send_bodiless){
// ... send bodiless message
tmsrp_request_t* BODILESS;
if(msrp->config->To_Path && msrp->config->From_Path){
if((BODILESS = tmsrp_create_bodiless(msrp->config->To_Path->uri, msrp->config->From_Path->uri))){
char* str;
if((str = tmsrp_message_tostring(BODILESS))){
if(tnet_sockfd_send(msrp->connectedFD, str, strlen(str), 0)){
TSK_DEBUG_WARN("Failed to send bodiless request.");
}
TSK_FREE(str);
}
TSK_OBJECT_SAFE_FREE(BODILESS);
}
}
}
}
}
@ -169,6 +199,13 @@ int tmsrp_media_stop(tmedia_t* self)
if(msrp->sender){
tmsrp_sender_stop(msrp->sender);
}
if(msrp->receiver){
tmsrp_receiver_stop(msrp->receiver);
}
if(msrp->transport){
tnet_transport_shutdown(msrp->transport);
}
return 0;
}
@ -182,17 +219,24 @@ const tsdp_header_M_t* tmsrp_media_get_local_offer(tmedia_t* self)
tsk_bool_t answer;
tsk_bool_t ipv6;
tsk_istr_t sessionid;
tnet_socket_type_t type;
tnet_ip_t ip = "127.0.0.1";
tnet_port_t port = 0;
if(!msrp || !msrp->local.socket || msrp->local.socket->fd <= 0){
if(!msrp || !msrp->transport){
goto bail;
}
// get socket type
type = tnet_transport_get_type(msrp->transport);
// get ip and port
tnet_transport_get_ip_n_port_2(msrp->transport, &ip, &port);
// answer or initial offer?
answer = (msrp->remote.M != tsk_null);
// using ipv6?
ipv6 = TNET_SOCKET_TYPE_IS_IPV6(msrp->local.socket->type);
ipv6 = TNET_SOCKET_TYPE_IS_IPV6(type);
if(TNET_SOCKET_TYPE_IS_TLS(msrp->local.socket->type)){
if(TNET_SOCKET_TYPE_IS_TLS(type)){
proto = "TCP/TLS/MSRP";
sheme = "msrps";
}
@ -201,12 +245,12 @@ const tsdp_header_M_t* tmsrp_media_get_local_offer(tmedia_t* self)
char* path = tsk_null;
tmsrp_uri_t* uri;
tsk_strrandom(&sessionid);
tsk_sprintf(&path, "%s://%s:%u/%s;tcp", sheme, msrp->local.socket->ip, msrp->local.socket->port, sessionid); //tcp is ok even if tls is used.
tsk_sprintf(&path, "%s://%s:%u/%s;tcp", sheme, ip, port, sessionid); //tcp is ok even if tls is used.
if((msrp->local.M = TSDP_HEADER_M_CREATE(self->plugin->media, msrp->local.socket->port, proto))){
if((msrp->local.M = TSDP_HEADER_M_CREATE(self->plugin->media, port, proto))){
tsdp_header_M_add_headers(msrp->local.M,
TSDP_FMT_VA_ARGS("*"),
TSDP_HEADER_C_VA_ARGS("IN", ipv6?"IP6":"IP4", &msrp->local.socket->ip),
TSDP_HEADER_C_VA_ARGS("IN", ipv6?"IP6":"IP4", ip),
TSDP_HEADER_A_VA_ARGS("sendrecv", tsk_null),
TSDP_HEADER_A_VA_ARGS("path", path),
@ -293,7 +337,7 @@ int tmsrp_media_set_remote_offer(tmedia_t* self, const tsdp_message_t* offer)
tsk_bool_t found = tsk_false;
tsk_bool_t answer;
if(!offer || !msrp || !msrp->local.socket || msrp->local.socket->fd <= 0){
if(!offer || !msrp){
goto bail;
}
@ -458,10 +502,10 @@ static void* tmsrp_media_create(tsk_object_t *self, va_list * app)
// if this is not used then the host address will be equal to "0.0.0.0" or "::"
// when used with SIP, the stack will provide a routable IP (e.g. 192.168.16.104)
tnet_gethostname(&local);
msrp->local.socket = TNET_SOCKET_CREATE(local, TNET_SOCKET_PORT_ANY, socket_type);
msrp->transport = TNET_TRANSPORT_CREATE(local, TNET_SOCKET_PORT_ANY, socket_type, "MSRP/MSRPS transport");
}
else{
msrp->local.socket = TNET_SOCKET_CREATE(host, TNET_SOCKET_PORT_ANY, socket_type);
msrp->transport = TNET_TRANSPORT_CREATE(host, TNET_SOCKET_PORT_ANY, socket_type, "MSRP/MSRPS transport");
}
}
else{
@ -474,14 +518,12 @@ static void* tmsrp_media_destroy(tsk_object_t *self)
{
tmsrp_media_t *msrp = self;
if(msrp){
tsk_bool_t closeFD = (msrp->local.socket && msrp->local.socket->fd != msrp->connectedFD);
tmedia_deinit(TMEDIA(msrp));
TSK_OBJECT_SAFE_FREE(msrp->config);
// local
TSK_OBJECT_SAFE_FREE(msrp->local.M);
TSK_OBJECT_SAFE_FREE(msrp->local.socket);
// remote
TSK_OBJECT_SAFE_FREE(msrp->remote.M);
//TSK_OBJECT_SAFE_FREE(msrp->remote.C);
@ -490,10 +532,13 @@ static void* tmsrp_media_destroy(tsk_object_t *self)
// sender
TSK_OBJECT_SAFE_FREE(msrp->sender);
// receiver
TSK_OBJECT_SAFE_FREE(msrp->receiver);
// transrport
TSK_OBJECT_SAFE_FREE(msrp->transport);
if(closeFD){
tnet_sockfd_close(&msrp->connectedFD);
}
// do not close the connectedFD ...it's uo to the transport
}
else{
TSK_DEBUG_ERROR("Null dummy media.");
@ -501,17 +546,13 @@ static void* tmsrp_media_destroy(tsk_object_t *self)
return self;
}
static int tmsrp_media_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2)
{
return -1;
}
static const tsk_object_def_t tmsrp_media_def_s =
{
sizeof(tmsrp_media_t),
tmsrp_media_create,
tmsrp_media_destroy,
tmsrp_media_cmp
tsk_null
};
const tsk_object_def_t *tmsrp_media_def_t = &tmsrp_media_def_s;

View File

@ -0,0 +1,146 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)yahoo.fr>
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
/**@file tmsrp_receiver.c
* @brief MSRP receiver.
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
*
* @date Created: Sat Nov 8 16:54:58 2009 mdiop
*/
#include "tinyMSRP/session/tmsrp_receiver.h"
#include "tmsrp.h"
#include "tnet_utils.h"
#include "tsk_memory.h"
#include "tsk_string.h"
#include "tsk_debug.h"
int tmsrp_receiver_start(tmsrp_receiver_t* self)
{
return 0;
}
int tmsrp_receiver_stop(tmsrp_receiver_t* self)
{
return 0;
}
int tmsrp_transport_layer_stream_cb(const tnet_transport_event_t* e)
{
const tmsrp_receiver_t *receiver = e->callback_data;
tmsrp_message_t* message;
switch(e->type){
case event_data: {
break;
}
case event_closed:
case event_connected:
default:{
return 0;
}
}
// put the data
tmsrp_data_in_put(receiver->data_in, e->data, e->size);
// get msrp messages
while((message = tmsrp_data_in_get(receiver->data_in))){
//
// SEND
//
if(TMSRP_REQUEST_IS_SEND(message)){
tmsrp_response_t* r2xx;
tmsrp_request_t* REPORT;
char* str;
// send 200 OK
if((r2xx = tmsrp_create_response(message, 200, "I got it"))){
if((str = tmsrp_message_tostring(r2xx))){
tnet_sockfd_send(receiver->fd, str, strlen(str), 0);
TSK_FREE(str);
}
TSK_OBJECT_SAFE_FREE(r2xx);
}
// send REPORT
if(tmsrp_isReportRequired(message, tsk_false)){
if((REPORT = tmsrp_create_report(message, 200, "I got it"))){
if((str = tmsrp_message_tostring(REPORT))){
tnet_sockfd_send(receiver->fd, str, strlen(str), 0);
TSK_FREE(str);
}
TSK_OBJECT_SAFE_FREE(REPORT);
}
}
}
// alert user layer
TSK_OBJECT_SAFE_FREE(message);
}
return 0;
}
//=================================================================================================
// MSRP receiver object definition
//
static void* tmsrp_receiver_create(void * self, va_list *app)
{
tmsrp_receiver_t *receiver = self;
if(receiver){
receiver->config = tsk_object_ref(va_arg(*app, tmsrp_config_t*));
receiver->fd = va_arg(*app, tnet_fd_t);
receiver->data_in = TMSRP_DATA_IN_CREATE();
}
return self;
}
static void* tmsrp_receiver_destroy(void * self)
{
tmsrp_receiver_t *receiver = self;
if(receiver){
/* Stop */
tmsrp_receiver_stop(receiver);
TSK_OBJECT_SAFE_FREE(receiver->config);
TSK_OBJECT_SAFE_FREE(receiver->data_in);
// the FD is owned by the transport ...do not close it
}
return self;
}
static const tsk_object_def_t tmsrp_receiver_def_s =
{
sizeof(tmsrp_receiver_t),
tmsrp_receiver_create,
tmsrp_receiver_destroy,
tsk_null,
};
const tsk_object_def_t *tmsrp_receiver_def_t = &tmsrp_receiver_def_s;

View File

@ -128,7 +128,7 @@ void *run(void* self)
while((chunck = tmsrp_data_out_get(data_out))){
tmsrp_request_t* SEND;
// set end
end = start + chunck->size;
end = (start + chunck->size) - 1;
// compute new transaction id
tsk_strrandom(&tid);
// create SEND request
@ -139,7 +139,7 @@ void *run(void* self)
// add other headers
tmsrp_message_add_headers(SEND,
TMSRP_HEADER_MESSAGE_ID_VA_ARGS(TMSRP_DATA(data_out)->id),
TMSRP_HEADER_BYTE_RANGE_VA_ARGS(start, end, -1),
TMSRP_HEADER_BYTE_RANGE_VA_ARGS(start, end, data_out->size),
TMSRP_HEADER_FAILURE_REPORT_VA_ARGS(sender->config->Failure_Report ? freport_yes : freport_no),
TMSRP_HEADER_SUCCESS_REPORT_VA_ARGS(sender->config->Success_Report),
//TMSRP_HEADER_CONTENT_TYPE_VA_ARGS(TMSRP_DATA(data_out)->ctype),
@ -154,7 +154,7 @@ void *run(void* self)
}
// set start
start = end;
start = (end + 1);
// cleanup
TSK_OBJECT_SAFE_FREE(chunck);
TSK_OBJECT_SAFE_FREE(SEND);
@ -183,7 +183,7 @@ static void* tmsrp_sender_create(void * self, va_list *app)
sender->config = tsk_object_ref(va_arg(*app, tmsrp_config_t*));
sender->fd = va_arg(*app, tnet_fd_t);
sender->outputList = TSK_LIST_CREATE();
sender->outgoingList = TSK_LIST_CREATE();
}
return self;
}
@ -196,8 +196,8 @@ static void* tmsrp_sender_destroy(void * self)
tmsrp_sender_stop(sender);
TSK_OBJECT_SAFE_FREE(sender->config);
TSK_OBJECT_SAFE_FREE(sender->outputList);
// the FD is owned by the media ...do not close it
TSK_OBJECT_SAFE_FREE(sender->outgoingList);
// the FD is owned by the transport ...do not close it
}
return self;
}

View File

@ -32,11 +32,9 @@
#include "tsk_time.h"
#include "tsk_string.h"
#include <stdlib.h> /* rand() */
#define TMSR_DEFAULT_NAMESPACE 0 // "000"
tmsrp_request_t* tmsrp_create_bodiless()
tmsrp_request_t* tmsrp_create_bodiless(const tmsrp_uri_t* To, const tmsrp_uri_t* From)
{
/* RFC 4975 - 7.1. Constructing Requests
Requests with no bodies are useful when a client wishes to send
@ -52,29 +50,33 @@ tmsrp_request_t* tmsrp_create_bodiless()
value and will generally be rendered to the recipient according to
the rules for that type.
*/
tmsrp_request_t* bodiless = TMSRP_NULL;
tmsrp_request_t* BODILESS = tsk_null;
tsk_istr_t tid;
tsk_istr_t mid;
tsk_strrandom(&tid);
tsk_strrandom(&mid);
if(!(bodiless = TMSRP_REQUEST_CREATE(tid, "SEND"))){
if(!(BODILESS = TMSRP_REQUEST_CREATE(tid, "SEND"))){
goto bail;
}
//FIXME: To-Path
//FIXME: From-Path
/* Message-ID */
TMSRP_MESSAGE_ADD_HEADER(bodiless, TMSRP_HEADER_MESSAGE_ID_VA_ARGS(mid));
// To-Path
// From-Path
// Message-ID
tmsrp_message_add_headers(BODILESS,
TMSRP_HEADER_TO_PATH_VA_ARGS(To),
TMSRP_HEADER_FROM_PATH_VA_ARGS(From),
TMSRP_HEADER_MESSAGE_ID_VA_ARGS(mid),
tsk_null);
bail:
return bodiless;
return BODILESS;
}
tmsrp_response_t* tmsrp_create_response(const tmsrp_request_t* request, short status, const char* comment)
{
tmsrp_response_t* response = TMSRP_NULL;
tmsrp_response_t* response = tsk_null;
if(!request){
goto bail;
@ -95,7 +97,7 @@ bail:
return response;
}
tmsrp_request_t* tmsrp_create_report(const tmsrp_request_t* request, short status, const char* reason)
tmsrp_request_t* tmsrp_create_report(const tmsrp_request_t* SEND, short status, const char* reason)
{
/* RFC 4975 - 7.1.2. Sending REPORT Requests
@ -104,10 +106,13 @@ tmsrp_request_t* tmsrp_create_report(const tmsrp_request_t* request, short statu
* fields, and MUST contain a Status header field. REPORT requests MUST
* contain the Message-ID header field from the original SEND request.
*/
tmsrp_request_t* report = TMSRP_NULL;
tmsrp_request_t* REPORT = tsk_null;
tsk_istr_t tid;
if(!request || !request->MessageID){
/* If an MSRP element receives a REPORT for a Message-ID it does not
recognize, it SHOULD silently ignore the REPORT.
*/
if(!SEND || !SEND->MessageID){
goto bail;
}
@ -115,45 +120,44 @@ tmsrp_request_t* tmsrp_create_report(const tmsrp_request_t* request, short statu
tsk_strrandom(&tid);
/* MSRP response will have the same tid ==> nothing to do */
if(!(report = TMSRP_REQUEST_CREATE(tid, "REPORT"))){
if(!(REPORT = TMSRP_REQUEST_CREATE(tid, "REPORT"))){
goto bail;
}
/* reverse To-Path and From-Path */
report->To = (tmsrp_header_To_Path_t*)tmsrp_header_From_Path_clone(request->From);
TMSRP_HEADER(report->To)->type = tmsrp_htype_To_Path; /* as it's a clone we shall change type */
report->From = (tmsrp_header_From_Path_t*)tmsrp_header_To_Path_clone(request->To);
TMSRP_HEADER(report->From)->type = tmsrp_htype_From_Path; /* as it's a clone we shall change type */
/* Message ID */
TMSRP_MESSAGE_ADD_HEADER(report, TMSRP_HEADER_MESSAGE_ID_VA_ARGS(request->MessageID->value));
/* Byte-Range */
report->ByteRange = tsk_object_ref((void*)request->ByteRange);
/* Status */
TMSRP_MESSAGE_ADD_HEADER(report, TMSRP_HEADER_STATUS_VA_ARGS(TMSR_DEFAULT_NAMESPACE, status, reason));
/* reverse To-Path and From-Path */
REPORT->To = (tmsrp_header_To_Path_t*)tmsrp_header_From_Path_clone(SEND->From);
TMSRP_HEADER(REPORT->To)->type = tmsrp_htype_To_Path; /* as it's a clone we shall change type */
REPORT->From = (tmsrp_header_From_Path_t*)tmsrp_header_To_Path_clone(SEND->To);
TMSRP_HEADER(REPORT->From)->type = tmsrp_htype_From_Path; /* as it's a clone we shall change type */
/* Byte-Range */
REPORT->ByteRange = tsk_object_ref((void*)SEND->ByteRange);
/* Message ID */
/* Status */
tmsrp_message_add_headers(REPORT,
TMSRP_HEADER_MESSAGE_ID_VA_ARGS(SEND->MessageID->value),
TMSRP_HEADER_STATUS_VA_ARGS(TMSR_DEFAULT_NAMESPACE, status, reason),
tsk_null);
bail:
return report;
return REPORT;
}
int tmsrp_isReportRequired(const tmsrp_request_t* request)
tsk_bool_t tmsrp_isReportRequired(const tmsrp_request_t* request, tsk_bool_t failed)
{
if(!request){
return 0;
return tsk_false;
}
/* Success Report. */
if(request->SuccessReport && request->SuccessReport->yes){
if(request->Status && (request->Status->code>199 && request->Status->code<300)){
return 1;
}
return tsk_true;
}
/* Failure Report */
if(!request->FailureReport || (request->FailureReport && request->FailureReport->type != freport_no)){
if(request->Status && (request->Status->code<=199 && request->Status->code>=300)){
return 1;
}
return failed;
}
return 0;
return tsk_false;
}

View File

@ -117,6 +117,22 @@ int tmsrp_message_add_headers(tmsrp_message_t *self, ...)
return 0;
}
tmsrp_request_type_t tmsrp_request_get_type(const char* method)
{
if(method){
if(tsk_strequals(method, "SEND")){
return tmsrp_SEND;
}
else if(tsk_strequals(method, "REPORT")){
return tmsrp_REPORT;
}
else if(tsk_strequals(method, "AUTH")){
return tmsrp_AUTH;
}
}
return tmsrp_NONE;
}
const tmsrp_header_t *tmsrp_message_get_headerAt(const tmsrp_message_t *self, tmsrp_header_type_t type, size_t index)
{
size_t pos = 0;
@ -199,7 +215,7 @@ const tmsrp_header_t *tmsrp_message_get_headerByName(const tmsrp_message_t *self
return item->data;
}
}
return TMSRP_NULL;
return tsk_null;
}
int tmsrp_message_add_content(tmsrp_message_t *self, const char* content_type, const void* content, size_t size)
@ -368,6 +384,8 @@ static void* tmsrp_message_create(tsk_object_t * self, va_list * app)
message->end_line.tid = tsk_strdup(message->tid);
message->end_line.cflag = '$';
message->line.request.type = tmsrp_request_get_type(message->line.request.method);
}
return self;
}

View File

@ -37,14 +37,14 @@
"Success-Report: yes\r\n" \
"Content-Type: text/plain;charset=utf8\r\n" \
"\r\n" \
"-------fake-tid+ Hey Bob, are you there?\r\n" \
"-------a786hjs2$\r\n"
"\r\n-------fake-tid+\r\n Hey Bob, are you there?\r\n" \
"-------a786hjs2$\r\nMSRP 000"
#define MSRP_MSG_RESPONSE \
"MSRP a786hjs2 200 OK\r\n" \
"To-Path: msrp://atlanta.example.com:7654/jshA7weztas;tcp\r\n" \
"From-Path: msrp://biloxi.example.com:12763/kjhd37s2s20w2a;tcp\r\n" \
"-------a786hjs2$\r\n"
"-------a786hjs2$\r\nMSRP 000"
#define MSRP_MSG_REPORT \
"MSRP dkei38sd REPORT\r\n" \
@ -53,20 +53,21 @@
"Message-ID: 12339sdqwer\r\n" \
"Byte-Range: 1-106/106\r\n" \
"Status: 000 200 OK\r\n" \
"-------dkei38sd$\r\n"
"-------dkei38sd$\r\nMSRP 000"
#define MSRP_MSG_TO_TEST MSRP_MSG_REQUEST
void test_parser()
{
tmsrp_message_t *message = 0;
size_t msg_size;
char* str;
//
// Serialization / Deserialization
//
/* deserialize the message */
if((message = tmsrp_message_parse(MSRP_MSG_TO_TEST, strlen(MSRP_MSG_TO_TEST)))){
if((message = tmsrp_message_parse_2(MSRP_MSG_TO_TEST, strlen(MSRP_MSG_TO_TEST), &msg_size))){
/* serialize the message */
if((str = tmsrp_message_tostring(message))){
@ -119,7 +120,7 @@ void test_parser()
// Create bodiless Request
//
{
tmsrp_request_t* bodiless = tmsrp_create_bodiless();
tmsrp_request_t* bodiless = tmsrp_create_bodiless(tsk_null, tsk_null);
if((str = tmsrp_message_tostring(bodiless))){
TSK_DEBUG_INFO("\nMSRP Bodiless=\n%s\n\n", str);

View File

@ -26,7 +26,7 @@
#include "tinySDP/parsers/tsdp_parser_message.h"
#define REMOTE_SDP1 \
"c=IN IP4 192.168.0.15\r\n" \
"c=IN IP4 192.168.16.33\r\n" \
"m=message 2000 TCP/MSRP *\r\n" \
"a=accept-types:text/plain\r\n" \
"a=path:msrp://atlanta.example.com:7654/jshA7weztas;tcp\r\n" \
@ -35,7 +35,7 @@
#define REMOTE_SDP2 \
"m=message 2000 TCP/MSRP *\r\n" \
"c=IN IP4 192.168.0.15\r\n" \
"c=IN IP4 192.168.16.33\r\n" \
"a=accept-types:text/plain\r\n" \
"a=path:msrp://atlanta.example.com:7654/jshA7weztas;tcp\r\n" \
"a=setup:passive\r\n" \
@ -73,13 +73,12 @@ void test_session()
tmedia_start(msrp);
//tmedia_pause(msrp);
tmedia_perform(msrp, tma_msrp_send_data,
TSK_PARAM_VA_ARGS("content", "hello world!"),
TSK_PARAM_VA_ARGS("content-type", "text/plain"),
tsk_null);
/*
tmedia_perform(msrp, tma_msrp_send_file,
TSK_PARAM_VA_ARGS("path", "C:\\ppppp"),

View File

@ -114,6 +114,20 @@ int tnet_transport_get_ip_n_port(const tnet_transport_handle_t *handle, tnet_fd_
return -1;
}
int tnet_transport_get_ip_n_port_2(const tnet_transport_handle_t *handle, tnet_ip_t *ip, tnet_port_t *port)
{
const tnet_transport_t *transport = handle;
if(transport){
// do not check the master, let the apllication die if "null"
memcpy(*ip, transport->master->ip, sizeof(transport->master->ip));
*port = transport->master->port;
}
else{
TSK_DEBUG_ERROR("NULL transport object.");
}
return -1;
}
tnet_socket_type_t tnet_transport_get_type(const tnet_transport_handle_t *handle)
{
if(handle){

View File

@ -79,6 +79,7 @@ TINYNET_API int tnet_transport_isready(const tnet_transport_handle_t *handle);
TINYNET_API int tnet_transport_issecure(const tnet_transport_handle_t *handle);
TINYNET_API const char* tnet_transport_get_description(const tnet_transport_handle_t *handle);
TINYNET_API int tnet_transport_get_ip_n_port(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_ip_t *ip, tnet_port_t *port);
TINYNET_API int tnet_transport_get_ip_n_port_2(const tnet_transport_handle_t *handle, tnet_ip_t *ip, tnet_port_t *port);
TINYNET_API int tnet_transport_isconnected(const tnet_transport_handle_t *handle, tnet_fd_t fd);
TINYNET_API int tnet_transport_have_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd);
@ -86,7 +87,7 @@ TINYNET_API const tnet_tls_socket_handle_t* tnet_transport_get_tlshandle(const t
TINYNET_API int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, int take_ownership, int isClient);
TINYNET_API int tnet_transport_remove_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd);
TINYNET_API tnet_fd_t tnet_transport_connectto(const tnet_transport_handle_t *handle, const char* host, tnet_port_t port, tnet_socket_type_t type);
#define tnet_transport_connectto2(handle, host, port) tnet_transport_connectto(handle, host, port, tnet_transport_get_type(handle))
#define tnet_transport_connectto_2(handle, host, port) tnet_transport_connectto(handle, host, port, tnet_transport_get_type(handle))
TINYNET_API size_t tnet_transport_send(const tnet_transport_handle_t *handle, tnet_fd_t from, const void* buf, size_t size);
TINYNET_API size_t tnet_transport_sendto(const tnet_transport_handle_t *handle, tnet_fd_t from, const struct sockaddr *to, const void* buf, size_t size);

View File

@ -50,7 +50,7 @@ typedef struct tsk_object_header_s{
int refCount; /**< Reference counter. */
}
tsk_object_header_t;
#define TSK_OBJECT_HEADER_GET(object) ((tsk_object_header_t*)object)
#define TSK_OBJECT_HEADER(object) ((tsk_object_header_t*)object)
/**@ingroup tsk_object_group
* Creates new object. The object MUST be declared using @ref TSK_DECLARE_OBJECT macro.
@ -61,11 +61,12 @@ tsk_object_header_t;
*/
tsk_object_t* tsk_object_new(const tsk_object_def_t *objdef, ...)
{
// Do not check "objdef", let the application die if it's null
tsk_object_t *newobj = tsk_calloc(1, objdef->size);
if(newobj)
{
(*(const tsk_object_def_t **) newobj) = objdef;
TSK_OBJECT_HEADER_GET(newobj)->refCount = 1;
TSK_OBJECT_HEADER(newobj)->refCount = 1;
if(objdef->constructor){
va_list ap;
va_start(ap, objdef);
@ -100,7 +101,7 @@ tsk_object_t* tsk_object_new2(const tsk_object_def_t *objdef, va_list* ap)
if(newobj)
{
(*(const tsk_object_def_t **) newobj) = objdef;
TSK_OBJECT_HEADER_GET(newobj)->refCount = 1;
TSK_OBJECT_HEADER(newobj)->refCount = 1;
if(objdef->constructor){
newobj = objdef->constructor(newobj, ap);
@ -166,7 +167,7 @@ int tsk_object_cmp(const tsk_object_t *object1, const tsk_object_t *object2)
tsk_object_t* tsk_object_ref(tsk_object_t *self)
{
if(self){
TSK_OBJECT_HEADER_GET(self)->refCount++;
TSK_OBJECT_HEADER(self)->refCount++;
return self;
}
return tsk_null;
@ -185,7 +186,8 @@ tsk_object_t* tsk_object_unref(tsk_object_t *self)
{
if(self)
{
if(0 == --(TSK_OBJECT_HEADER_GET(self)->refCount)){ // If refCount is < 0 then, nothing should happen.
tsk_object_header_t* objhdr = TSK_OBJECT_HEADER(self);
if(!--objhdr->refCount){ // If refCount is < 0 then, nothing should happen.
tsk_object_delete(self);
return 0;
}

View File

@ -59,10 +59,14 @@ TSK_BEGIN_DECLS
/**@ingroup tsk_ragel_state_group
*/
#define TSK_PARSER_SET_STRING(string) \
if(!string) \
{ \
{ \
int len = (int)(p - tag_start); \
string = tsk_calloc(len+1, sizeof(char)), memcpy(string, tag_start, len); \
if(len && tag_start){ \
if(string){ \
TSK_FREE(string); \
} \
string = tsk_calloc(len+1, sizeof(char)), memcpy(string, tag_start, len); \
} \
}
/**@ingroup tsk_ragel_state_group

View File

@ -125,7 +125,7 @@ tsip_message_type_t;
typedef enum tsip_request_type_e
{
tsip_NONE,
tsip_NONE = 0,
tsip_ACK,
tsip_BYE,

View File

@ -491,7 +491,7 @@ int tsip_stack_stop(tsip_stack_handle_t *self)
/* Do not Stop timer manager ==> Dialogs have ref to the stack and rely on the timer manager(to gracefully shutdown).*/
//ret = tsk_timer_manager_stop(stack->timer_mgr);
if((ret = tsk_runnable_stop(TSK_RUNNABLE(stack)))){
//return ret;
}

View File

@ -288,6 +288,10 @@
<Filter
Name="session"
>
<File
RelativePath="..\..\tinyMSRP\include\tinyMSRP\session\tmsrp_config.h"
>
</File>
<File
RelativePath="..\..\tinyMSRP\include\tinyMSRP\session\tmsrp_data.h"
>
@ -414,6 +418,10 @@
<Filter
Name="session"
>
<File
RelativePath="..\..\tinyMSRP\src\session\tmsrp_config.c"
>
</File>
<File
RelativePath="..\..\tinyMSRP\src\session\tmsrp_data.c"
>