#include "asterisk.h"
#include <math.h>
#include "asterisk/channel.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/pbx.h"
#include "asterisk/acl.h"
#include "include/sip.h"
#include "include/globals.h"
#include "include/dialog.h"
#include "include/dialplan_functions.h"
#include "include/sip_utils.h"
Go to the source code of this file.
Functions | |
int | sip_acf_channel_read (struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen) |
void | sip_dialplan_function_register_tests (void) |
SIP test registration. | |
void | sip_dialplan_function_unregister_tests (void) |
SIP test registration. |
Definition in file dialplan_functions.c.
int sip_acf_channel_read | ( | struct ast_channel * | chan, | |
const char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) |
Definition at line 40 of file dialplan_functions.c.
References args, AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_MAX_USER_FIELD, ast_ouraddrfor(), ast_rtp_instance_get_local_address(), ast_rtp_instance_get_quality(), ast_rtp_instance_get_remote_address(), ast_rtp_instance_get_stats(), AST_RTP_INSTANCE_STAT_ALL, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_rtp_instance_stats::local_maxjitter, ast_rtp_instance_stats::local_maxrxploss, ast_rtp_instance_stats::local_minjitter, ast_rtp_instance_stats::local_minrxploss, ast_rtp_instance_stats::local_normdevjitter, ast_rtp_instance_stats::local_normdevrxploss, ast_rtp_instance_stats::local_ssrc, ast_rtp_instance_stats::local_stdevjitter, ast_rtp_instance_stats::local_stdevrxploss, LOG_ERROR, LOG_WARNING, ast_rtp_instance_stats::maxrtt, ast_rtp_instance_stats::minrtt, name, ast_rtp_instance_stats::normdevrtt, parse(), quality, ast_rtp_instance_stats::remote_maxjitter, ast_rtp_instance_stats::remote_maxrxploss, ast_rtp_instance_stats::remote_minjitter, ast_rtp_instance_stats::remote_minrxploss, ast_rtp_instance_stats::remote_normdevjitter, ast_rtp_instance_stats::remote_normdevrxploss, ast_rtp_instance_stats::remote_ssrc, ast_rtp_instance_stats::remote_stdevjitter, ast_rtp_instance_stats::remote_stdevrxploss, ast_rtp_instance_stats::rtt, ast_rtp_instance_stats::rxcount, ast_rtp_instance_stats::rxjitter, ast_rtp_instance_stats::rxploss, ast_rtp_instance_stats::stdevrtt, ast_channel::tech, ast_channel::tech_pvt, ast_rtp_instance_stats::txcount, ast_rtp_instance_stats::txjitter, ast_rtp_instance_stats::txploss, and type.
00041 { 00042 struct sip_pvt *p = chan->tech_pvt; 00043 char *parse = ast_strdupa(preparse); 00044 int res = 0; 00045 AST_DECLARE_APP_ARGS(args, 00046 AST_APP_ARG(param); 00047 AST_APP_ARG(type); 00048 AST_APP_ARG(field); 00049 ); 00050 00051 /* Check for zero arguments */ 00052 if (ast_strlen_zero(parse)) { 00053 ast_log(LOG_ERROR, "Cannot call %s without arguments\n", funcname); 00054 return -1; 00055 } 00056 00057 AST_STANDARD_APP_ARGS(args, parse); 00058 00059 /* Sanity check */ 00060 if (!IS_SIP_TECH(chan->tech)) { 00061 ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname); 00062 return 0; 00063 } 00064 00065 memset(buf, 0, buflen); 00066 00067 if (p == NULL) { 00068 return -1; 00069 } 00070 00071 if (!strcasecmp(args.param, "peerip")) { 00072 ast_copy_string(buf, ast_sockaddr_isnull(&p->sa) ? "" : ast_sockaddr_stringify_addr(&p->sa), buflen); 00073 } else if (!strcasecmp(args.param, "recvip")) { 00074 ast_copy_string(buf, ast_sockaddr_isnull(&p->recv) ? "" : ast_sockaddr_stringify_addr(&p->recv), buflen); 00075 } else if (!strcasecmp(args.param, "from")) { 00076 ast_copy_string(buf, p->from, buflen); 00077 } else if (!strcasecmp(args.param, "uri")) { 00078 ast_copy_string(buf, p->uri, buflen); 00079 } else if (!strcasecmp(args.param, "useragent")) { 00080 ast_copy_string(buf, p->useragent, buflen); 00081 } else if (!strcasecmp(args.param, "peername")) { 00082 ast_copy_string(buf, p->peername, buflen); 00083 } else if (!strcasecmp(args.param, "t38passthrough")) { 00084 ast_copy_string(buf, (p->t38.state == T38_DISABLED) ? "0" : "1", buflen); 00085 } else if (!strcasecmp(args.param, "rtpdest")) { 00086 struct ast_sockaddr addr; 00087 struct ast_rtp_instance *stream; 00088 00089 if (ast_strlen_zero(args.type)) 00090 args.type = "audio"; 00091 00092 if (!strcasecmp(args.type, "audio")) 00093 stream = p->rtp; 00094 else if (!strcasecmp(args.type, "video")) 00095 stream = p->vrtp; 00096 else if (!strcasecmp(args.type, "text")) 00097 stream = p->trtp; 00098 else 00099 return -1; 00100 00101 /* Return 0 to suppress a console warning message */ 00102 if (!stream) { 00103 return 0; 00104 } 00105 00106 ast_rtp_instance_get_remote_address(stream, &addr); 00107 snprintf(buf, buflen, "%s", ast_sockaddr_stringify(&addr)); 00108 } else if (!strcasecmp(args.param, "rtpsource")) { 00109 struct ast_sockaddr sa; 00110 struct ast_rtp_instance *stream; 00111 00112 if (ast_strlen_zero(args.type)) 00113 args.type = "audio"; 00114 00115 if (!strcasecmp(args.type, "audio")) 00116 stream = p->rtp; 00117 else if (!strcasecmp(args.type, "video")) 00118 stream = p->vrtp; 00119 else if (!strcasecmp(args.type, "text")) 00120 stream = p->trtp; 00121 else 00122 return -1; 00123 00124 /* Return 0 to suppress a console warning message */ 00125 if (!stream) { 00126 return 0; 00127 } 00128 00129 ast_rtp_instance_get_local_address(stream, &sa); 00130 00131 if (ast_sockaddr_isnull(&sa)) { 00132 struct ast_sockaddr dest_sa; 00133 ast_rtp_instance_get_remote_address(stream, &dest_sa); 00134 ast_ouraddrfor(&dest_sa, &sa); 00135 } 00136 00137 snprintf(buf, buflen, "%s", ast_sockaddr_stringify(&sa)); 00138 } else if (!strcasecmp(args.param, "rtpqos")) { 00139 struct ast_rtp_instance *rtp = NULL; 00140 00141 if (ast_strlen_zero(args.type)) { 00142 args.type = "audio"; 00143 } 00144 00145 if (!strcasecmp(args.type, "audio")) { 00146 rtp = p->rtp; 00147 } else if (!strcasecmp(args.type, "video")) { 00148 rtp = p->vrtp; 00149 } else if (!strcasecmp(args.type, "text")) { 00150 rtp = p->trtp; 00151 } else { 00152 return -1; 00153 } 00154 00155 if (ast_strlen_zero(args.field) || !strcasecmp(args.field, "all")) { 00156 char quality_buf[AST_MAX_USER_FIELD], *quality; 00157 00158 if (!(quality = ast_rtp_instance_get_quality(rtp, AST_RTP_INSTANCE_STAT_FIELD_QUALITY, quality_buf, sizeof(quality_buf)))) { 00159 return -1; 00160 } 00161 00162 ast_copy_string(buf, quality_buf, buflen); 00163 return res; 00164 } else { 00165 struct ast_rtp_instance_stats stats; 00166 int i; 00167 struct { 00168 const char *name; 00169 enum { INT, DBL } type; 00170 union { 00171 unsigned int *i4; 00172 double *d8; 00173 }; 00174 } lookup[] = { 00175 { "txcount", INT, { .i4 = &stats.txcount, }, }, 00176 { "rxcount", INT, { .i4 = &stats.rxcount, }, }, 00177 { "txjitter", DBL, { .d8 = &stats.txjitter, }, }, 00178 { "rxjitter", DBL, { .d8 = &stats.rxjitter, }, }, 00179 { "remote_maxjitter", DBL, { .d8 = &stats.remote_maxjitter, }, }, 00180 { "remote_minjitter", DBL, { .d8 = &stats.remote_minjitter, }, }, 00181 { "remote_normdevjitter", DBL, { .d8 = &stats.remote_normdevjitter, }, }, 00182 { "remote_stdevjitter", DBL, { .d8 = &stats.remote_stdevjitter, }, }, 00183 { "local_maxjitter", DBL, { .d8 = &stats.local_maxjitter, }, }, 00184 { "local_minjitter", DBL, { .d8 = &stats.local_minjitter, }, }, 00185 { "local_normdevjitter", DBL, { .d8 = &stats.local_normdevjitter, }, }, 00186 { "local_stdevjitter", DBL, { .d8 = &stats.local_stdevjitter, }, }, 00187 { "txploss", INT, { .i4 = &stats.txploss, }, }, 00188 { "rxploss", INT, { .i4 = &stats.rxploss, }, }, 00189 { "remote_maxrxploss", DBL, { .d8 = &stats.remote_maxrxploss, }, }, 00190 { "remote_minrxploss", DBL, { .d8 = &stats.remote_minrxploss, }, }, 00191 { "remote_normdevrxploss", DBL, { .d8 = &stats.remote_normdevrxploss, }, }, 00192 { "remote_stdevrxploss", DBL, { .d8 = &stats.remote_stdevrxploss, }, }, 00193 { "local_maxrxploss", DBL, { .d8 = &stats.local_maxrxploss, }, }, 00194 { "local_minrxploss", DBL, { .d8 = &stats.local_minrxploss, }, }, 00195 { "local_normdevrxploss", DBL, { .d8 = &stats.local_normdevrxploss, }, }, 00196 { "local_stdevrxploss", DBL, { .d8 = &stats.local_stdevrxploss, }, }, 00197 { "rtt", DBL, { .d8 = &stats.rtt, }, }, 00198 { "maxrtt", DBL, { .d8 = &stats.maxrtt, }, }, 00199 { "minrtt", DBL, { .d8 = &stats.minrtt, }, }, 00200 { "normdevrtt", DBL, { .d8 = &stats.normdevrtt, }, }, 00201 { "stdevrtt", DBL, { .d8 = &stats.stdevrtt, }, }, 00202 { "local_ssrc", INT, { .i4 = &stats.local_ssrc, }, }, 00203 { "remote_ssrc", INT, { .i4 = &stats.remote_ssrc, }, }, 00204 { NULL, }, 00205 }; 00206 00207 if (ast_rtp_instance_get_stats(rtp, &stats, AST_RTP_INSTANCE_STAT_ALL)) { 00208 return -1; 00209 } 00210 00211 for (i = 0; !ast_strlen_zero(lookup[i].name); i++) { 00212 if (!strcasecmp(args.field, lookup[i].name)) { 00213 if (lookup[i].type == INT) { 00214 snprintf(buf, buflen, "%u", *lookup[i].i4); 00215 } else { 00216 snprintf(buf, buflen, "%f", *lookup[i].d8); 00217 } 00218 return 0; 00219 } 00220 } 00221 ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname); 00222 return -1; 00223 } 00224 } else if (!strcasecmp(args.param, "secure_signaling")) { 00225 snprintf(buf, buflen, "%s", p->socket.type == SIP_TRANSPORT_TLS ? "1" : ""); 00226 } else if (!strcasecmp(args.param, "secure_media")) { 00227 snprintf(buf, buflen, "%s", p->srtp ? "1" : ""); 00228 } else { 00229 res = -1; 00230 } 00231 return res; 00232 }
void sip_dialplan_function_register_tests | ( | void | ) |
SIP test registration.
Definition at line 406 of file dialplan_functions.c.
References AST_TEST_REGISTER.
Referenced by sip_register_tests().
00407 { 00408 AST_TEST_REGISTER(test_sip_rtpqos_1); 00409 }
void sip_dialplan_function_unregister_tests | ( | void | ) |
SIP test registration.
Definition at line 412 of file dialplan_functions.c.
References AST_TEST_UNREGISTER.
Referenced by sip_unregister_tests().
00413 { 00414 AST_TEST_UNREGISTER(test_sip_rtpqos_1); 00415 }