/*! \brief Send frame to media channel (rtp) */ static int sip_write(struct ast_channel *ast, struct ast_frame *frame) { struct sip_pvt *p = ast_channel_tech_pvt(ast); int res = 0; switch (frame->frametype) { case AST_FRAME_VOICE: if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) { struct ast_str *codec_buf = ast_str_alloca(64); ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s read/write = %s/%s\n", ast_format_get_name(frame->subclass.format), ast_format_cap_get_names(ast_channel_nativeformats(ast), &codec_buf), ast_format_get_name(ast_channel_readformat(ast)), ast_format_get_name(ast_channel_writeformat(ast))); return 0; } if (p) { sip_pvt_lock(p); if (p->t38.state == T38_ENABLED) { /* drop frame, can't sent VOICE frames while in T.38 mode */ sip_pvt_unlock(p); break; } else if (p->rtp) { /* If channel is not up, activate early media session */ if ((ast_channel_state(ast) != AST_STATE_UP) && !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { ast_rtp_instance_update_source(p->rtp); if (!global_prematuremediafilter) { p->invitestate = INV_EARLY_MEDIA; transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); } } if (p->invitestate > INV_EARLY_MEDIA || (p->invitestate == INV_EARLY_MEDIA && ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT))) { p->lastrtptx = time(NULL); res = ast_rtp_instance_write(p->rtp, frame); } } sip_pvt_unlock(p); } break; case AST_FRAME_VIDEO: if (p) { sip_pvt_lock(p); if (p->vrtp) { /* Activate video early media */ if ((ast_channel_state(ast) != AST_STATE_UP) && !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { p->invitestate = INV_EARLY_MEDIA; transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); } if (p->invitestate > INV_EARLY_MEDIA || (p->invitestate == INV_EARLY_MEDIA && ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT))) { p->lastrtptx = time(NULL); res = ast_rtp_instance_write(p->vrtp, frame); } } sip_pvt_unlock(p); } break; case AST_FRAME_TEXT: if (p) { sip_pvt_lock(p); if (p->red) { ast_rtp_red_buffer(p->trtp, frame); } else { if (p->trtp) { /* Activate text early media */ if ((ast_channel_state(ast) != AST_STATE_UP) && !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { p->invitestate = INV_EARLY_MEDIA; transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE); ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT); } if (p->invitestate > INV_EARLY_MEDIA || (p->invitestate == INV_EARLY_MEDIA && ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT))) { p->lastrtptx = time(NULL); res = ast_rtp_instance_write(p->trtp, frame); } } } sip_pvt_unlock(p); } break; case AST_FRAME_IMAGE: return 0; break; case AST_FRAME_MODEM: if (p) { sip_pvt_lock(p); /* UDPTL requires two-way communication, so early media is not needed here. we simply forget the frames if we get modem frames before the bridge is up. Fax will re-transmit. */ if ((ast_channel_state(ast) == AST_STATE_UP) && p->udptl && (p->t38.state == T38_ENABLED)) { res = ast_udptl_write(p->udptl, frame); } sip_pvt_unlock(p); } break; default: //ast_log(LOG_WARNING, "Can't send %u type frames with SIP write\n", frame->frametype); // AURIS 2015/02/20 ast_log(LOG_WARNING, "Can't send %u type frames with SIP write: Channel Name (%s)\n", frame->frametype, ast_channel_name(ast)); // AURIS 2015/02/20 return 0; } return res; }