49 #include "asterisk/res_pjsip.h"
50 #include "asterisk/res_pjsip_session.h"
53 #define T38_AUTOMATIC_REJECTION_SECONDS 5
61 enum ast_sip_session_t38state
state;
77 ast_sip_session_media_state_free(state->
media_state);
103 ast_frfree(data->
frame);
132 enum ast_sip_session_t38state old_state = session->
t38state;
136 if (old_state == new_state) {
141 ast_debug(2,
"T.38 state changed to '%u' from '%u' on channel '%s'\n",
142 new_state, old_state,
143 session->
channel ? ast_channel_name(session->
channel) :
"<gone>");
145 if (pj_timer_heap_cancel_if_active(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()),
147 ast_debug(2,
"Automatic T.38 rejection on channel '%s' terminated\n",
148 session->
channel ? ast_channel_name(session->
channel) :
"<gone>");
157 case T38_PEER_REINVITE:
159 if (pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), &state->
timer, &delay) != PJ_SUCCESS) {
160 ast_log(LOG_WARNING,
"Scheduling of automatic T.38 rejection for channel '%s' failed\n",
161 ast_channel_name(session->
channel));
180 if (old_state == T38_ENABLED) {
182 }
else if (old_state == T38_LOCAL_REINVITE) {
186 case T38_LOCAL_REINVITE:
205 RAII_VAR(
struct ast_datastore *, datastore, ast_sip_session_get_datastore(session,
"t38"), ao2_cleanup);
211 ast_debug(2,
"Automatically rejecting T.38 request on channel '%s'\n",
212 session->channel ? ast_channel_name(session->channel) :
"<gone>");
215 ast_sip_session_resume_reinvite(session);
233 RAII_VAR(
struct ast_datastore *, datastore, ast_sip_session_get_datastore(session,
"t38"), ao2_cleanup);
238 return datastore->data;
241 if (!(datastore = ast_sip_session_alloc_datastore(&t38_datastore,
"t38"))
243 || ast_sip_session_add_datastore(session, datastore)) {
247 state = datastore->data;
261 if (session_media->
udptl) {
267 ast_debug(5,
"Endpoint %s: Binding UDPTL media to %s\n",
270 media_address = &temp_media_address;
272 ast_debug(5,
"Endpoint %s: UDPTL media address invalid: %s\n",
286 char hoststr[PJ_INET6_ADDRSTRLEN];
288 pj_sockaddr_print(&trans_state->
host, hoststr,
sizeof(hoststr), 0);
290 ast_debug(5,
"Transport %s bound to %s: Using it for UDPTL media.\n",
292 media_address = &temp_media_address;
294 ast_debug(5,
"Transport %s bound to %s: Invalid for UDPTL media.\n",
303 if (!(session_media->
udptl = ast_udptl_new_with_bindaddr(NULL, NULL, 0, media_address))) {
310 ast_debug(3,
"UDPTL initialized on session for %s\n", ast_channel_name(session->
channel));
333 struct pjsip_status_line status = rdata->msg_info.msg->line.status;
337 if (status.code / 100 <= 1) {
342 if (session->
t38state != T38_LOCAL_REINVITE) {
344 ast_debug(3,
"Received %d response to T.38 re-invite on '%s' but already had a final response (T.38 state:%d)\n",
346 session->
channel ? ast_channel_name(session->
channel) :
"unknown channel",
352 if (!session->
channel || !state) {
353 ast_log(LOG_WARNING,
"Received %d response to T.38 re-invite on '%s' but state unavailable\n",
355 session->
channel ? ast_channel_name(session->
channel) :
"unknown channel");
359 if (status.code / 100 == 2) {
369 if (session_media && !session_media->
udptl) {
370 session_media = NULL;
373 if (!session_media) {
374 ast_log(LOG_WARNING,
"Received %d response to T.38 re-invite on '%s' but no active session media\n",
375 status.code, session->
channel ? ast_channel_name(session->
channel) :
"unknown channel");
397 t38_change_state(session, NULL, state, session_media ? T38_REJECTED : T38_DISABLED);
400 ast_sip_session_media_state_free(state->
media_state);
415 media_state = ast_sip_session_media_state_alloc();
422 ast_sip_session_media_state_free(media_state);
428 ast_sip_session_media_state_free(media_state);
435 ast_sip_session_media_state_free(media_state);
441 ast_sip_session_media_state_free(media_state);
450 ast_sip_session_media_state_free(media_state);
454 session_media = ast_sip_session_media_state_add(session, media_state, AST_MEDIA_TYPE_IMAGE, 0);
455 if (!session_media) {
456 ast_sip_session_media_state_free(media_state);
461 ast_sip_session_media_state_free(media_state);
485 if (data->session->t38state == T38_PEER_REINVITE) {
487 ast_sip_session_resume_reinvite(data->session);
488 }
else if (data->session->t38state == T38_ENABLED) {
490 ast_sip_session_refresh(data->session, NULL, NULL, NULL,
491 AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1, state->
media_state);
495 }
else if (data->session->t38state == T38_PEER_REINVITE) {
511 session_media = data->session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
512 if (!session_media) {
513 ast_log(LOG_ERROR,
"Failed to negotiate parameters for reinvite on channel '%s' (No pending session media).\n",
514 data->session->channel ? ast_channel_name(data->session->channel) :
"unknown channel");
519 ast_sip_session_resume_reinvite(data->session);
520 }
else if ((data->session->t38state != T38_ENABLED) ||
521 ((data->session->t38state == T38_ENABLED) &&
531 if (!session_media) {
532 ast_log(LOG_ERROR,
"Failed to negotiate parameters on channel '%s' (No default session media).\n",
533 data->session->channel ? ast_channel_name(data->session->channel) :
"unknown channel");
539 AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1, media_state);
545 if (data->session->t38state == T38_PEER_REINVITE) {
547 ast_sip_session_resume_reinvite(data->session);
548 }
else if (data->session->t38state == T38_ENABLED) {
550 ast_sip_session_refresh(data->session, NULL, NULL, NULL, AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1, state->
media_state);
557 if (data->session->t38state == T38_PEER_REINVITE) {
558 session_media = data->session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
559 if (!session_media) {
560 ast_log(LOG_ERROR,
"Failed to request parameters for reinvite on channel '%s' (No pending session media).\n",
561 data->session->channel ? ast_channel_name(data->session->channel) :
"unknown channel");
609 ast_debug(2,
"T.38 support not enabled on %s, refusing T.38 negotiation\n",
610 ast_channel_name(chan));
612 &rsp_refused,
sizeof(rsp_refused));
615 ast_debug(2,
"T.38 support not enabled on %s, 'terminating' T.38 session\n",
616 ast_channel_name(chan));
618 &rsp_terminated,
sizeof(rsp_terminated));
629 static void t38_masq(
void *data,
int framehook_id,
646 .
type =
"T38 framehook",
655 .
version = AST_FRAMEHOOK_INTERFACE_VERSION,
657 .consume_cb = t38_consume,
658 .chan_fixup_cb = t38_masq,
659 .chan_breakdown_cb = t38_masq,
669 ast_channel_lock(session->
channel);
675 ast_channel_unlock(session->
channel);
680 if (framehook_id < 0) {
681 ast_log(LOG_WARNING,
"Could not attach T.38 Frame hook, T.38 will be unavailable on '%s'\n",
682 ast_channel_name(session->
channel));
683 ast_channel_unlock(session->
channel);
687 datastore = ast_datastore_alloc(&t38_framehook_datastore, NULL);
689 ast_log(LOG_ERROR,
"Could not alloc T.38 Frame hook datastore, T.38 will be unavailable on '%s'\n",
690 ast_channel_name(session->
channel));
692 ast_channel_unlock(session->
channel);
697 ast_channel_unlock(session->
channel);
717 case AST_T38_RATE_2400:
719 case AST_T38_RATE_4800:
721 case AST_T38_RATE_7200:
723 case AST_T38_RATE_9600:
725 case AST_T38_RATE_12000:
727 case AST_T38_RATE_14400:
737 .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL + 1,
744 const struct pjmedia_sdp_media *stream)
748 for (attr_i = 0; attr_i < stream->attr_count; attr_i++) {
749 pjmedia_sdp_attr *attr = stream->attr[attr_i];
751 if (!pj_stricmp2(&attr->name,
"t38faxmaxbuffer")) {
753 }
else if (!pj_stricmp2(&attr->name,
"t38maxbitrate") || !pj_stricmp2(&attr->name,
"t38faxmaxrate")) {
754 switch (pj_strtoul(&attr->value)) {
774 }
else if (!pj_stricmp2(&attr->name,
"t38faxversion")) {
776 }
else if (!pj_stricmp2(&attr->name,
"t38faxmaxdatagram") || !pj_stricmp2(&attr->name,
"t38maxdatagram")) {
780 }
else if (!pj_stricmp2(&attr->name,
"t38faxfillbitremoval")) {
782 }
else if (!pj_stricmp2(&attr->name,
"t38faxtranscodingmmr")) {
784 }
else if (!pj_stricmp2(&attr->name,
"t38faxtranscodingjbig")) {
786 }
else if (!pj_stricmp2(&attr->name,
"t38faxratemanagement")) {
787 if (!pj_stricmp2(&attr->value,
"localTCF")) {
789 }
else if (!pj_stricmp2(&attr->value,
"transferredTCF")) {
792 }
else if (!pj_stricmp2(&attr->name,
"t38faxudpec")) {
793 if (session->
t38state == T38_LOCAL_REINVITE) {
795 if (!pj_stricmp2(&attr->value,
"t38UDPFEC")) {
796 ast_udptl_set_error_correction_scheme(session_media->
udptl, UDPTL_ERROR_CORRECTION_FEC);
797 }
else if (!pj_stricmp2(&attr->value,
"t38UDPRedundancy")) {
798 ast_udptl_set_error_correction_scheme(session_media->
udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
800 ast_udptl_set_error_correction_scheme(session_media->
udptl, UDPTL_ERROR_CORRECTION_NONE);
803 if (!pj_stricmp2(&attr->value,
"t38UDPRedundancy")) {
804 ast_udptl_set_error_correction_scheme(session_media->
udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
806 ast_udptl_set_error_correction_scheme(session_media->
udptl, UDPTL_ERROR_CORRECTION_NONE);
809 ast_udptl_set_error_correction_scheme(session_media->
udptl, UDPTL_ERROR_CORRECTION_NONE);
812 if (!pj_stricmp2(&attr->value,
"t38UDPRedundancy")) {
813 ast_udptl_set_error_correction_scheme(session_media->
udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
814 }
else if (!pj_stricmp2(&attr->value,
"t38UDPFEC")) {
815 ast_udptl_set_error_correction_scheme(session_media->
udptl, UDPTL_ERROR_CORRECTION_FEC);
817 ast_udptl_set_error_correction_scheme(session_media->
udptl, UDPTL_ERROR_CORRECTION_NONE);
828 const struct pjmedia_sdp_session *sdp,
const struct pjmedia_sdp_media *stream)
833 ast_debug(3,
"Not deferring incoming SDP stream: T.38 not enabled on %s\n", ast_channel_name(session->
channel));
834 return AST_SIP_SESSION_SDP_DEFER_NOT_HANDLED;
838 ast_debug(3,
"Not deferring incoming SDP stream: Failed to initialize UDPTL on %s\n", ast_channel_name(session->
channel));
839 return AST_SIP_SESSION_SDP_DEFER_ERROR;
843 return AST_SIP_SESSION_SDP_DEFER_ERROR;
849 if (session->
t38state == T38_DISABLED) {
851 ast_debug(3,
"Deferring incoming SDP stream on %s for peer re-invite\n", ast_channel_name(session->
channel));
852 return AST_SIP_SESSION_SDP_DEFER_NEEDED;
855 return AST_SIP_SESSION_SDP_DEFER_NOT_NEEDED;
861 int index,
struct ast_stream *asterisk_stream)
864 char host[NI_MAXHOST];
865 pjmedia_sdp_media *stream = sdp->media[index];
869 ast_debug(3,
"Declining; T.38 not enabled on session\n");
877 if ((session->
t38state == T38_REJECTED) || (session->
t38state == T38_DISABLED)) {
878 ast_debug(3,
"Declining; T.38 state is rejected or declined\n");
883 ast_copy_pj_str(host, stream->conn ? &stream->conn->addr : &sdp->conn->addr,
sizeof(host));
888 ast_debug(3,
"Declining; provided host is invalid\n");
896 ast_debug(3,
"Declining, provided host does not match configured address family\n");
905 struct pjmedia_sdp_session *sdp,
const struct pjmedia_sdp_session *remote,
struct ast_stream *stream)
908 static const pj_str_t STR_IN = {
"IN", 2 };
909 static const pj_str_t STR_IP4 = {
"IP4", 3};
910 static const pj_str_t STR_IP6 = {
"IP6", 3};
911 static const pj_str_t STR_UDPTL = {
"udptl", 5 };
912 static const pj_str_t STR_T38 = {
"t38", 3 };
913 static const pj_str_t STR_TRANSFERREDTCF = {
"transferredTCF", 14 };
914 static const pj_str_t STR_LOCALTCF = {
"localTCF", 8 };
915 static const pj_str_t STR_T38UDPFEC = {
"t38UDPFEC", 9 };
916 static const pj_str_t STR_T38UDPREDUNDANCY = {
"t38UDPRedundancy", 16 };
918 pjmedia_sdp_media *media;
919 const char *hostip = NULL;
925 ast_debug(3,
"Not creating outgoing SDP stream: T.38 not enabled\n");
927 }
else if ((session->
t38state != T38_LOCAL_REINVITE) && (session->
t38state != T38_PEER_REINVITE) &&
928 (session->
t38state != T38_ENABLED)) {
929 ast_debug(3,
"Not creating outgoing SDP stream: T.38 not enabled\n");
934 ast_debug(3,
"Not creating outgoing SDP stream: Failed to initialize T.38 session\n");
938 if (!(media = pj_pool_zalloc(pool,
sizeof(
struct pjmedia_sdp_media))) ||
939 !(media->conn = pj_pool_zalloc(pool,
sizeof(
struct pjmedia_sdp_conn)))) {
944 media->desc.transport = STR_UDPTL;
947 hostip = ast_sip_get_host_ip_string(session->
endpoint->
media.
t38.
ipv6 ? pj_AF_INET6() : pj_AF_INET());
952 if (ast_strlen_zero(hostip)) {
953 ast_debug(3,
"Not creating outgoing SDP stream: no known host IP\n");
957 media->conn->net_type = STR_IN;
959 pj_strdup2(pool, &media->conn->addr, hostip);
960 ast_udptl_get_us(session_media->
udptl, &addr);
962 media->desc.port_count = 1;
963 media->desc.fmt[media->desc.fmt_count++] = STR_T38;
966 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool,
"T38FaxVersion", pj_cstr(&stmp, tmp));
969 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool,
"T38MaxBitRate", pj_cstr(&stmp, tmp));
972 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool,
"T38FaxFillBitRemoval", NULL);
976 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool,
"T38FaxTranscodingMMR", NULL);
980 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool,
"T38FaxTranscodingJBIG", NULL);
984 case AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF:
985 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool,
"T38FaxRateManagement", &STR_TRANSFERREDTCF);
987 case AST_T38_RATE_MANAGEMENT_LOCAL_TCF:
988 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool,
"T38FaxRateManagement", &STR_LOCALTCF);
993 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool,
"T38FaxMaxDatagram", pj_cstr(&stmp, tmp));
995 switch (ast_udptl_get_error_correction_scheme(session_media->
udptl)) {
996 case UDPTL_ERROR_CORRECTION_NONE:
998 case UDPTL_ERROR_CORRECTION_FEC:
999 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool,
"T38FaxUdpEC", &STR_T38UDPFEC);
1001 case UDPTL_ERROR_CORRECTION_REDUNDANCY:
1002 media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool,
"T38FaxUdpEC", &STR_T38UDPREDUNDANCY);
1006 sdp->media[sdp->media_count++] = media;
1015 if (!session_media->
udptl) {
1019 frame = ast_udptl_read(session_media->
udptl);
1031 if (!session_media->
udptl) {
1035 return ast_udptl_write(session_media->
udptl, frame);
1041 const struct pjmedia_sdp_session *remote,
int index,
struct ast_stream *asterisk_stream)
1044 pjmedia_sdp_media *remote_stream = remote->media[index];
1045 char host[NI_MAXHOST];
1048 if (!session_media->
udptl) {
1049 ast_debug(3,
"Not applying negotiated SDP stream: no UDTPL session\n");
1057 ast_copy_pj_str(host, remote_stream->conn ? &remote_stream->conn->addr : &remote->conn->addr,
sizeof(host));
1062 ast_debug(3,
"Not applying negotiated SDP stream: failed to resolve remote stream host\n");
1067 ast_udptl_set_peer(session_media->
udptl, addrs);
1071 ast_sip_session_media_set_write_callback(session, session_media, media_session_udptl_write_callback);
1072 ast_sip_session_media_add_read_callback(session, session_media, ast_udptl_fd(session_media->
udptl),
1073 media_session_udptl_read_callback);
1082 char host[NI_MAXHOST];
1086 if (!stream->conn || !transport_state) {
1090 ast_copy_pj_str(host, &stream->conn->addr,
sizeof(host));
1097 if (ast_sip_transport_is_nonlocal(transport_state, &our_sdp_addr) && transport_state->localnet) {
1107 if (session_media->
udptl) {
1108 ast_udptl_destroy(session_media->
udptl);
1110 session_media->
udptl = NULL;
1127 ast_sip_session_unregister_sdp_handler(&image_sdp_handler,
"image");
1128 ast_sip_session_unregister_supplement(&t38_supplement);
1151 ast_sip_session_register_supplement(&t38_supplement);
1153 if (ast_sip_session_register_sdp_handler(&image_sdp_handler,
"image")) {
1154 ast_log(LOG_ERROR,
"Unable to register SDP handler for image stream type\n");
1165 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,
"PJSIP T.38 UDPTL Support",
1166 .support_level = AST_MODULE_SUPPORT_CORE,
1170 .requires =
"res_pjsip,res_pjsip_session,udptl",
enum ast_sip_session_t38state t38state
Main Channel structure associated with a channel.
struct ast_sip_endpoint * endpoint
static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_session *remote, struct ast_stream *stream)
Function which creates an outgoing stream.
#define ast_frdup(fr)
Copies a frame.
Asterisk main include file. File version handling, generic pbx functions.
static char * ast_sockaddr_stringify_addr_remote(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
struct ast_sip_session_media_state * pending_media_state
static int t38_reinvite_response_cb(struct ast_sip_session *session, pjsip_rx_data *rdata)
Callback for when a response is received for a T.38 re-invite.
static struct ast_sip_session_supplement t38_supplement
Supplement for adding framehook to session channel.
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, int index, struct ast_stream *asterisk_stream)
Function which negotiates an incoming media stream.
const ast_string_field transport
static void t38_change_state(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct t38_state *state, enum ast_sip_session_t38state new_state)
Helper function for changing the T.38 state.
enum ast_t38_ec_modes error_correction
#define T38_AUTOMATIC_REJECTION_SECONDS
The number of seconds after receiving a T.38 re-invite before automatically rejecting it...
ast_framehook_event
These are the types of events that the framehook's event callback can receive.
static int load_module(void)
Load the module.
A handler for SDPs in SIP sessions.
static enum ast_sip_session_sdp_stream_defer defer_incoming_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
Function which defers an incoming media stream.
static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_session *remote, int index, struct ast_stream *asterisk_stream)
Function which applies a negotiated stream.
const char * ast_codec_media_type2str(enum ast_media_type type)
Conversion function to take a media type and turn it into a string.
static pj_pool_t * pool
Global memory pool for configuration and timers.
static struct ast_sip_session_sdp_handler image_sdp_handler
SDP handler for 'image' media stream.
static struct ast_sockaddr address
Address for UDPTL.
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
unsigned int ast_udptl_get_local_max_datagram(struct ast_udptl *udptl)
retrieves local_max_datagram.
enum ast_control_t38 request_response
Structure for a data store type.
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
static struct ast_sip_session_media_state * t38_create_media_state(struct ast_sip_session *session)
Helper function which creates a media state for strictly T.38.
enum ast_sip_session_t38state state
Current state.
void ast_udptl_set_far_max_datagram(struct ast_udptl *udptl, unsigned int max_datagram)
sets far max datagram size. If max_datagram is = 0, the far max datagram size is set to a default val...
Structure for a data store object.
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
static int t38_automatic_reject(void *obj)
Task function which rejects a T.38 re-invite and resumes handling it.
struct ast_frame * frame
T.38 control frame.
struct pjsip_inv_session * inv_session
void ast_stream_set_formats(struct ast_stream *stream, struct ast_format_cap *caps)
Set the current negotiated formats of a stream.
Socket address structure.
int ast_stream_topology_set_stream(struct ast_stream_topology *topology, unsigned int position, struct ast_stream *stream)
Set a specific position in a topology.
A structure describing a SIP session.
struct ast_frame_subclass subclass
struct ast_sip_session_media_state * active_media_state
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
struct ast_sip_session * session
Session itself.
struct ast_sip_endpoint_media_configuration media
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
Attach an framehook onto a channel for frame interception.
unsigned int transcoding_mmr
static struct ast_frame * t38_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
Frame hook callback for T.38 related stuff.
Structure for SIP transport information.
static void t38_attach_framehook(struct ast_sip_session *session)
Function called to attach T.38 framehook to channel when appropriate.
General Asterisk PBX channel definitions.
int ast_check_ipv6(void)
Test that an OS supports IPv6 Networking.
static int t38_incoming_invite_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
Function called when an INVITE arrives.
struct ast_sip_session_media_state * media_state
Access Control of various sorts.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
static struct t38_state * t38_state_get_or_alloc(struct ast_sip_session *session)
Helper function which retrieves or allocates a T.38 state information datastore.
enum ast_control_t38_rate rate
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
struct ast_channel * channel
#define ast_debug(level,...)
Log a DEBUG message.
Structure to describe a channel "technology", ie a channel driver See for examples: ...
struct ast_taskprocessor * serializer
ast_frame_type
Frame types.
unsigned int ast_udptl_get_far_max_ifp(struct ast_udptl *udptl)
retrieves far max ifp
Set when the stream is sending and receiving media.
struct ast_stream_topology * ast_stream_topology_alloc(void)
Create a stream topology.
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
unsigned int fill_bit_removal
static void t38_interpret_sdp(struct t38_state *state, struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *stream)
Parse a T.38 image stream and store the attribute information.
userdata associated with baseline taskprocessor test
static void t38_outgoing_invite_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
Function called when an INVITE is sent.
union ast_frame::@224 data
#define ast_calloc(num, len)
A wrapper for calloc()
static int unload_module(void)
Unloads the SIP T.38 module from Asterisk.
struct ast_control_t38_parameters our_parms
Our T.38 parameters.
void ast_stream_set_state(struct ast_stream *stream, enum ast_stream_state state)
Set the state of a stream.
Module has failed to load, may be in an inconsistent state.
static int t38_reinvite_sdp_cb(struct ast_sip_session *session, pjmedia_sdp_session *sdp)
Callback for when T.38 reinvite SDP is created.
struct ast_control_t38_parameters their_parms
Their T.38 parameters.
pj_timer_entry timer
Timer entry for automatically rejecting an inbound re-invite.
A supplement to SIP message processing.
unsigned int transcoding_jbig
struct ast_frame ast_null_frame
void ast_stream_free(struct ast_stream *stream)
Destroy a media stream representation.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
static unsigned int t38_get_rate(enum ast_control_t38_rate rate)
Get Max T.38 Transmission rate from T38 capabilities.
struct ast_stream * ast_stream_alloc(const char *name, enum ast_media_type type)
Create a new media stream representation.
Structure for T.38 parameters task data.
static const struct ast_datastore_info t38_datastore
Datastore for attaching T.38 state information.
enum ast_control_t38_rate_management rate_management
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
void ast_udptl_set_tag(struct ast_udptl *udptl, const char *format,...)
Associates a character string 'tag' with a UDPTL session.
Data structure associated with a single frame of data.
unsigned int bind_udptl_to_media_address
static int t38_initialize_session(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
Initializes UDPTL support on a session, only done when actually needed.
enum ast_frame_type frametype
static pj_timer_heap_t * timer_heap
Global timer heap.
static void stream_destroy(struct ast_sip_session_media *session_media)
Function which destroys the UDPTL instance when session ends.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struct pjmedia_sdp_media *stream, struct ast_sip_transport *transport)
Function which updates the media stream with external media address, if applicable.
static struct t38_parameters_task_data * t38_parameters_task_data_alloc(struct ast_sip_session *session, struct ast_frame *frame)
Allocator for T.38 data.
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
static int t38_interpret_parameters(void *obj)
Task for reacting to T.38 control frame.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
static void t38_parameters_task_data_destroy(void *obj)
Destructor for T.38 data.
void(* stream_stop)(struct ast_sip_session_media *session_media)
Stop a session_media created by this handler but do not destroy resources.
static void t38_automatic_reject_timer_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)
Timer entry callback which queues a task to reject a T.38 re-invite and resume handling it...
void ast_channel_set_unbridged(struct ast_channel *chan, int value)
Sets the unbridged flag and queues a NULL frame on the channel to trigger a check by bridge_channel_w...
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family)
Parses a string with an IPv4 or IPv6 address and place results into an array.
static void t38_state_destroy(void *obj)
Destructor for T.38 state information.