//struct lcr_gsm *gsm = NULL;
-#define RTP_PT_GSM_HALF 96
-#define RTP_PT_GSM_EFR 97
-#define RTP_PT_GSM_AMR 98
-
int new_callref = 1;
/* names of MNCC-SAP */
return ret;
}
+void Pgsm::send_mncc_rtp_connect(void)
+{
+ struct gsm_mncc_rtp *nrtp;
+
+ nrtp = (struct gsm_mncc_rtp *) create_mncc(MNCC_RTP_CONNECT, p_g_callref);
+ nrtp->ip = p_g_rtp_ip_remote;
+ nrtp->port = p_g_rtp_port_remote;
+ switch (p_g_media_type) {
+ case MEDIA_TYPE_GSM:
+ nrtp->payload_msg_type = GSM_TCHF_FRAME;
+ break;
+ case MEDIA_TYPE_GSM_EFR:
+ nrtp->payload_msg_type = GSM_TCHF_FRAME_EFR;
+ break;
+ case MEDIA_TYPE_AMR:
+ nrtp->payload_msg_type = GSM_TCHF_FRAME_AMR;
+ break;
+ case MEDIA_TYPE_GSM_HR:
+ nrtp->payload_msg_type = GSM_TCHF_FRAME_HR;
+ break;
+ }
+ nrtp->payload_type = p_g_payload_type;
+ PDEBUG(DEBUG_GSM, "sending MNCC RTP connect with payload_msg_type=%x, payload_type=%d\n", nrtp->payload_msg_type, nrtp->payload_type);
+ send_and_free_mncc(p_g_lcr_gsm, nrtp->msg_type, nrtp);
+}
+
static int delete_event(struct lcr_work *work, void *instance, int index);
/*
}
p_g_rxpos = 0;
p_g_tch_connected = 0;
- p_g_payload_type = -1;
+ p_g_media_type = 0;
PDEBUG(DEBUG_GSM, "Created new GSMPort(%s).\n", portname);
}
}
/* modify lchan to given payload type */
-void Pgsm::modify_lchan(unsigned char payload_type)
+void Pgsm::modify_lchan(int media_type)
{
struct gsm_mncc *mode;
/* already modified to that payload type */
- if (p_g_payload_type == payload_type)
+ if (p_g_media_type == media_type)
return;
- p_g_payload_type = payload_type;
+ p_g_media_type = media_type;
gsm_trace_header(p_g_interface_name, this, MNCC_LCHAN_MODIFY, DIRECTION_OUT);
mode = create_mncc(MNCC_LCHAN_MODIFY, p_g_callref);
- switch (payload_type) {
- case RTP_PT_GSM_EFR:
+ switch (media_type) {
+ case MEDIA_TYPE_GSM_EFR:
add_trace("speech", "version", "EFR given");
mode->lchan_mode = 0x21; /* GSM V2 */
break;
- case RTP_PT_GSM_AMR:
+ case MEDIA_TYPE_AMR:
add_trace("speech", "version", "AMR given");
mode->lchan_mode = 0x41; /* GSM V3 */
break;
- case RTP_PT_GSM_HALF:
+ case MEDIA_TYPE_GSM_HR:
add_trace("speech", "version", "Half Rate given");
- mode->lchan_mode = 0x05; /* GSM V1 */
+ mode->lchan_mode = 0x05; /* GSM V1 HR */
break;
default:
add_trace("speech", "version", "Full Rate given");
- mode->lchan_mode = 0x01; /* GSM V1 HR */
+ mode->lchan_mode = 0x01; /* GSM V1 */
}
mode->lchan_type = 0x02; /* FIXME: unused */
add_trace("mode", NULL, "0x%02x", mode->lchan_mode);
/* if we have a bridge, but not yet modified, the phone accepts out requested payload.
* we force the first in list */
if (p_g_rtp_bridge) {
- if (p_g_payload_type < 0) {
- /* modify to first given payload */
- modify_lchan(p_g_rtp_payload_types[0]);
+ if (!p_g_media_type) {
+ /* modify to first given type */
+ modify_lchan(p_g_rtp_media_types[0]);
+ /* also set payload type */
+ p_g_payload_type = p_g_rtp_payload_types[0];
}
+ message->param.connectinfo.rtpinfo.media_types[0] = p_g_media_type;
message->param.connectinfo.rtpinfo.payload_types[0] = p_g_payload_type;
message->param.connectinfo.rtpinfo.payloads = 1;
}
p_g_setup_pending = NULL;
}
if (p_g_connect_pending) {
- struct gsm_mncc_rtp *nrtp;
-
PDEBUG(DEBUG_GSM, "Got RTP peer info (%08x,%d) connecting RTP... \n", rtp->ip, rtp->port);
- nrtp = (struct gsm_mncc_rtp *) create_mncc(MNCC_RTP_CONNECT, p_g_callref);
- nrtp->ip = p_g_rtp_ip_remote;
- nrtp->port = p_g_rtp_port_remote;
- send_and_free_mncc(p_g_lcr_gsm, nrtp->msg_type, nrtp);
+ send_mncc_rtp_connect();
}
}
}
if (param->progressinfo.rtpinfo.port) {
- struct gsm_mncc_rtp *rtp;
+ PDEBUG(DEBUG_GSM, "PROGRESS with RTP peer info, sent to BSC (%08x,%d) with media %d, pt %d\n", param->progressinfo.rtpinfo.ip, param->progressinfo.rtpinfo.port, param->progressinfo.rtpinfo.media_types[0], param->progressinfo.rtpinfo.payload_types[0]);
- PDEBUG(DEBUG_GSM, "CONNECT with RTP peer info, sent to BSC (%08x,%d)\n", param->progressinfo.rtpinfo.ip, param->progressinfo.rtpinfo.port);
- rtp = (struct gsm_mncc_rtp *) create_mncc(MNCC_RTP_CONNECT, p_g_callref);
- rtp->ip = param->progressinfo.rtpinfo.ip;
- rtp->port = param->progressinfo.rtpinfo.port;
- send_and_free_mncc(p_g_lcr_gsm, rtp->msg_type, rtp);
+ /* modify channel to givne type, also sets media type */
+ modify_lchan(param->progressinfo.rtpinfo.media_types[0]);
- /* modify channel to accepted payload type */
- modify_lchan(param->progressinfo.rtpinfo.payload_types[0]);
+ /* connect RTP */
+ p_g_rtp_ip_remote = param->progressinfo.rtpinfo.ip;
+ p_g_rtp_port_remote = param->progressinfo.rtpinfo.port;
+ /* p_g_media_type is already set by modify_lchan() */
+ p_g_payload_type = param->progressinfo.rtpinfo.payload_types[0];
+ send_mncc_rtp_connect();
}
}
new_state(PORT_STATE_CONNECT_WAITING);
if (param->connectinfo.rtpinfo.port) {
- struct gsm_mncc_rtp *rtp;
-
PDEBUG(DEBUG_GSM, "CONNECT with RTP peer info, sent to BSC (%08x,%d)\n", param->connectinfo.rtpinfo.ip, param->connectinfo.rtpinfo.port);
- rtp = (struct gsm_mncc_rtp *) create_mncc(MNCC_RTP_CONNECT, p_g_callref);
- rtp->ip = param->connectinfo.rtpinfo.ip;
- rtp->port = param->connectinfo.rtpinfo.port;
- send_and_free_mncc(p_g_lcr_gsm, rtp->msg_type, rtp);
- /* modify channel to accepted payload type */
- modify_lchan(param->connectinfo.rtpinfo.payload_types[0]);
+ /* modify channel to givne type, also sets media type */
+ modify_lchan(param->connectinfo.rtpinfo.media_types[0]);
+
+ /* connect RTP */
+ p_g_rtp_ip_remote = param->connectinfo.rtpinfo.ip;
+ p_g_rtp_port_remote = param->connectinfo.rtpinfo.port;
+ /* p_g_media_type is already set by modify_lchan() */
+ p_g_payload_type = param->connectinfo.rtpinfo.payload_types[0];
+ send_mncc_rtp_connect();
}
}
signed short p_g_rxdata[160]; /* receive audio buffer */
int p_g_rxpos; /* position in audio buffer 0..159 */
int p_g_tch_connected; /* indicates if audio is connected */
- int p_g_payload_type; /* current payload type or -1 if not set */
+ int p_g_media_type; /* current payload type or 0 if not set */
+ int p_g_payload_type; /* current payload type */
int p_g_rtp_bridge; /* if we use a bridge */
unsigned int p_g_rtp_ip_remote; /* stores ip */
unsigned short p_g_rtp_port_remote; /* stores port */
int p_g_rtp_payloads;
- int p_g_rtp_payload_types[8];
+ int p_g_rtp_media_types[8];
+ unsigned char p_g_rtp_payload_types[8];
void frame_send(void *_frame);
void frame_receive(void *_frame);
int audio_send(unsigned char *data, int len);
int bridge_rx(unsigned char *data, int len);
+ void send_mncc_rtp_connect(void);
int hunt_bchannel(void);
- void modify_lchan(unsigned char payload_type);
+ void modify_lchan(int media_type);
void call_proc_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc);
void alert_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc);
void setup_cnf(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc);
struct lcr_gsm *gsm_bs = NULL;
-#define RTP_PT_GSM_FULL 3
-#define RTP_PT_GSM_HALF 96
-#define RTP_PT_GSM_EFR 97
-#define RTP_PT_GSM_AMR 98
+#define PAYLOAD_TYPE_GSM 3
/*
* DTMF stuff
/* PROCEEDING INDICATION (from MS) */
void Pgsm_bs::call_conf_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
{
+ int media_types[8];
unsigned char payload_types[8];
int payloads = 0;
/* get list of offered payload types
* if list ist empty, the FR V1 is selected */
- select_payload_type(mncc, payload_types, &payloads, sizeof(payload_types));
+ select_payload_type(mncc, payload_types, media_types, &payloads, sizeof(payload_types));
/* if no given payload type is supported, we assume */
if (!payloads) {
- payload_types[0] = RTP_PT_GSM_FULL;
+ media_types[0] = MEDIA_TYPE_GSM;
+ payload_types[0] = PAYLOAD_TYPE_GSM;
payloads = 1;
}
for (i = 0; i < p_g_rtp_payloads; i++) {
for (j = 0; j < payloads; j++) {
- if (p_g_rtp_payload_types[i] == payload_types[j])
+ if (p_g_rtp_media_types[i] == media_types[j])
break;
}
if (j < payloads)
send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
new_state(PORT_STATE_RELEASE);
trigger_work(&p_g_delete);
+
+ return;
}
- modify_lchan(p_g_rtp_payload_types[i]);
+ modify_lchan(p_g_rtp_media_types[i]);
+ /* use the payload type from received rtp list, not from locally generated payload types */
+ p_g_payload_type = p_g_rtp_payload_types[i];
} else {
/* modify to first given payload */
- modify_lchan(payload_types[0]);
+ modify_lchan(media_types[0]);
+ p_g_payload_type = payload_types[0];
}
}
* return the payload type or 0 if not given
*/
-void Pgsm_bs::select_payload_type(struct gsm_mncc *mncc, unsigned char *payload_types, int *payloads, int max_payloads)
+void Pgsm_bs::select_payload_type(struct gsm_mncc *mncc, unsigned char *payload_types, int *media_types, int *payloads, int max_payloads)
{
+ int media_type;
unsigned char payload_type;
*payloads = 0;
switch (mncc->bearer_cap.speech_ver[i]) {
case 0:
add_trace("speech", "version", "Full Rate given");
- payload_type = RTP_PT_GSM_FULL;
+ media_type = MEDIA_TYPE_GSM;
+ payload_type = PAYLOAD_TYPE_GSM;
break;
case 2:
add_trace("speech", "version", "EFR given");
- payload_type = RTP_PT_GSM_EFR;
+ media_type = MEDIA_TYPE_GSM_EFR;
+ payload_type = 100 + *payloads;
break;
case 4:
add_trace("speech", "version", "AMR given");
- payload_type = RTP_PT_GSM_AMR;
+ media_type = MEDIA_TYPE_AMR;
+ payload_type = 100 + *payloads;
break;
case 1:
add_trace("speech", "version", "Half Rate given");
- payload_type = RTP_PT_GSM_HALF;
+ media_type = MEDIA_TYPE_GSM_HR;
+ payload_type = 100 + *payloads;
break;
default:
add_trace("speech", "version", "%d given", mncc->bearer_cap.speech_ver[i]);
+ media_type = 0;
payload_type = 0;
}
/* wen don't support it, so we check the next */
- if (!payload_type) {
+ if (!media_type) {
add_trace("speech", "ignored", "Not supported by LCR");
continue;
}
if (!p_g_rtp_bridge) {
- if (payload_type != RTP_PT_GSM_FULL) {
+ if (media_type != MEDIA_TYPE_GSM) {
add_trace("speech", "ignored", "Not suitable for LCR");
continue;
}
}
if (*payloads <= max_payloads) {
+ media_types[*payloads] = media_type;
payload_types[*payloads] = payload_type;
(*payloads)++;
}
} else {
add_trace("bearer", "capa", "not given by MS");
add_trace("speech", "version", "Full Rate given");
- payload_types[0] = RTP_PT_GSM_FULL;
+ media_types[0] = MEDIA_TYPE_GSM;
+ payload_types[0] = PAYLOAD_TYPE_GSM;
*payloads = 1;
}
if (!(*payloads))
struct lcr_msg *message;
struct gsm_mncc *proceeding, *frame;
struct interface *interface;
+ int media_types[8];
unsigned char payload_types[8];
int payloads = 0;
/* get list of offered payload types
* if list ist empty, the FR V1 is selected */
- select_payload_type(mncc, payload_types, &payloads, sizeof(payload_types));
+ select_payload_type(mncc, payload_types, media_types, &payloads, sizeof(payload_types));
/* if no given payload type is supported, we assume */
if (!payloads) {
- payload_types[0] = RTP_PT_GSM_FULL;
+ media_types[0] = MEDIA_TYPE_GSM;
+ payload_types[0] = PAYLOAD_TYPE_GSM;
payloads = 1;
}
#if 0
/* modify lchan in case of no rtp bridge */
if (!p_g_rtp_bridge)
- modify_lchan(payload_types[0]);
+ modify_lchan(media_types[0]);
/* send call proceeding */
gsm_trace_header(p_g_interface_name, this, MNCC_CALL_PROC_REQ, DIRECTION_OUT);
send_and_free_mncc(p_g_lcr_gsm, rtp->msg_type, rtp);
for (i = 0; i < (int)sizeof(message->param.setup.rtpinfo.payload_types) && i < payloads; i++) {
+ message->param.setup.rtpinfo.media_types[i] = media_types[i];
message->param.setup.rtpinfo.payload_types[i] = payload_types[i];
message->param.setup.rtpinfo.payloads++;
}
p_g_rtp_payloads = 0;
gsm_trace_header(p_g_interface_name, this, 1 /* codec negotioation */, DIRECTION_NONE);
for (i = 0; i < param->setup.rtpinfo.payloads; i++) {
- switch (param->setup.rtpinfo.payload_types[i]) {
- case RTP_PT_GSM_FULL:
- case RTP_PT_GSM_EFR:
- case RTP_PT_GSM_AMR:
- case RTP_PT_GSM_HALF:
- add_trace("rtp", "payload", "%d supported", param->setup.rtpinfo.payload_types[i]);
+ switch (param->setup.rtpinfo.media_types[i]) {
+ case MEDIA_TYPE_GSM:
+ case MEDIA_TYPE_GSM_EFR:
+ case MEDIA_TYPE_AMR:
+ case MEDIA_TYPE_GSM_HR:
+ add_trace("rtp", "payload", "%s:%d supported", media_type2name(param->setup.rtpinfo.media_types[i]), param->setup.rtpinfo.payload_types[i]);
if (p_g_rtp_payloads < (int)sizeof(p_g_rtp_payload_types)) {
- p_g_rtp_payload_types[p_g_rtp_payloads++] = param->setup.rtpinfo.payload_types[i];
+ p_g_rtp_media_types[p_g_rtp_payloads] = param->setup.rtpinfo.media_types[i];
+ p_g_rtp_payload_types[p_g_rtp_payloads] = param->setup.rtpinfo.payload_types[i];
p_g_rtp_payloads++;
}
break;
default:
- add_trace("rtp", "payload", "%d unsupported", param->setup.rtpinfo.payload_types[i]);
+ add_trace("rtp", "payload", "%s:%d unsupported", media_type2name(param->setup.rtpinfo.media_types[i]), param->setup.rtpinfo.payload_types[i]);
}
}
end_trace();
unsigned char *p_g_dtmf; /* DTMF tone generation (MS only) */
int p_g_dtmf_index; /* DTMF tone generation index */
- void select_payload_type(struct gsm_mncc *mncc, unsigned char *payload_types, int *payloads, int max_payloads);
+ void select_payload_type(struct gsm_mncc *mncc, unsigned char *payload_types, int *media_types, int *payloads, int max_payloads);
void setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc);
void call_conf_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *gsm);
void start_dtmf_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc);
B_MODE_HDLC, /* hdlc data mode */
};
+enum {
+ MEDIA_TYPE_ALAW = 1,
+ MEDIA_TYPE_ULAW,
+ MEDIA_TYPE_GSM,
+ MEDIA_TYPE_GSM_EFR,
+ MEDIA_TYPE_AMR,
+ MEDIA_TYPE_GSM_HR,
+};
+
/* rtp-info structure */
struct rtp_info {
int payloads; /* number of payloads offered */
unsigned char payload_types[32];/* rtp payload types */
+ int media_types[32]; /* media type of given payload */
unsigned int ip; /* peer's IP */
unsigned short port; /* peer's port */
};
#define MNCC_RTP_CONNECT 0x0205
#define MNCC_RTP_FREE 0x0206
-#define GSM_TCHF_FRAME 0x0300
-#define GSM_TCHF_FRAME_EFR 0x0301
+#define GSM_TCHF_FRAME 0x0300
+#define GSM_TCHF_FRAME_EFR 0x0301
+#define GSM_TCHF_FRAME_HR 0x0302
+#define GSM_TCHF_FRAME_AMR 0x0303
#define GSM_TCHF_BAD_FRAME 0x03ff
#define GSM_MAX_FACILITY 128
uint32_t callref;
uint32_t ip;
uint16_t port;
+ uint32_t payload_type;
+ uint32_t payload_msg_type;
};
rtp_close();
}
-const char *payload_type2name(uint8_t payload_type) {
- switch (payload_type) {
- case 0:
+const char *media_type2name(uint8_t media_type) {
+ switch (media_type) {
+ case MEDIA_TYPE_ULAW:
return "PCMU";
- case 8:
+ case MEDIA_TYPE_ALAW:
return "PCMA";
- case 3:
- case 96:
- case 97:
- case 98:
+ case MEDIA_TYPE_GSM:
return "GSM";
+ case MEDIA_TYPE_GSM_HR:
+ return "GSM-HR";
+ case MEDIA_TYPE_GSM_EFR:
+ return "GSM-EFR";
+ case MEDIA_TYPE_AMR:
+ return "AMR";
}
return "UKN";
#define RTP_VERSION 2
-#define RTP_PT_ULAW 0
-#define RTP_PT_ALAW 8
-#define RTP_PT_GSM_FULL 3
-#define RTP_PT_GSM_HALF 96
-#define RTP_PT_GSM_EFR 97
-#define RTP_PT_GSM_AMR 98
+#define PAYLOAD_TYPE_ULAW 0
+#define PAYLOAD_TYPE_ALAW 8
+#define PAYLOAD_TYPE_GSM 3
/* decode an rtp frame */
static int rtp_decode(class Psip *psip, unsigned char *data, int len)
}
switch (rtph->payload_type) {
+#if 0
+we only support alaw and ulaw!
case RTP_PT_GSM_FULL:
if (payload_len != 33) {
PDEBUG(DEBUG_SIP, "received RTP full rate frame with "
return -EINVAL;
}
break;
- case RTP_PT_ALAW:
+#endif
+ case PAYLOAD_TYPE_ALAW:
if (options.law != 'a') {
PDEBUG(DEBUG_SIP, "received Alaw, but we don't do Alaw\n");
return -EINVAL;
}
break;
- case RTP_PT_ULAW:
+ case PAYLOAD_TYPE_ULAW:
if (options.law == 'a') {
PDEBUG(DEBUG_SIP, "received Ulaw, but we don't do Ulaw\n");
return -EINVAL;
}
switch (payload_type) {
+#if 0
+we only support alaw and ulaw!
case RTP_PT_GSM_FULL:
payload_len = 33;
duration = 160;
payload_len = 14;
duration = 160;
break;
- case RTP_PT_ALAW:
- case RTP_PT_ULAW:
+#endif
+ case PAYLOAD_TYPE_ALAW:
+ case PAYLOAD_TYPE_ULAW:
payload_len = len;
duration = len;
break;
p_s_rxpos = 0;
/* transmit data via rtp */
- rtp_send_frame(p_s_rxdata, 160, (options.law=='a')?RTP_PT_ALAW:RTP_PT_ULAW);
+ rtp_send_frame(p_s_rxdata, 160, (options.law=='a')?PAYLOAD_TYPE_ALAW:PAYLOAD_TYPE_ULAW);
}
}
char sdp_str[256];
struct in_addr ia;
struct lcr_msg *message;
+ int media_type;
unsigned char payload_type;
if (param->connectinfo.rtpinfo.port) {
PDEBUG(DEBUG_SIP, "RTP info given by remote, forward that\n");
p_s_rtp_bridge = 1;
+ media_type = param->connectinfo.rtpinfo.media_types[0];
payload_type = param->connectinfo.rtpinfo.payload_types[0];
p_s_rtp_ip_local = param->connectinfo.rtpinfo.ip;
p_s_rtp_port_local = param->connectinfo.rtpinfo.port;
PDEBUG(DEBUG_SIP, "remote ip %08x port %d\n", p_s_rtp_ip_remote, p_s_rtp_port_remote);
} else {
PDEBUG(DEBUG_SIP, "RTP info not given by remote, so we do our own RTP\n");
- payload_type = (options.law=='a') ? RTP_PT_ALAW : RTP_PT_ULAW;
+ media_type = (options.law=='a') ? MEDIA_TYPE_ALAW : MEDIA_TYPE_ULAW;
+ payload_type = (options.law=='a') ? PAYLOAD_TYPE_ALAW : PAYLOAD_TYPE_ULAW;
/* open local RTP peer (if not bridging) */
if (!p_s_rtp_is_connected && rtp_connect() < 0) {
nua_cancel(p_s_handle, TAG_END());
"t=0 0\n"
"m=audio %d RTP/AVP %d\n"
"a=rtpmap:%d %s/8000\n"
- , inet_ntoa(ia), inet_ntoa(ia), p_s_rtp_port_local, payload_type, payload_type, payload_type2name(payload_type));
+ , inet_ntoa(ia), inet_ntoa(ia), p_s_rtp_port_local, payload_type, payload_type, media_type2name(media_type));
PDEBUG(DEBUG_SIP, "Using SDP response: %s\n", sdp_str);
nua_respond(p_s_handle, SIP_200_OK,
add_trace("reason", NULL, "call connected");
add_trace("rtp", "ip", "%s", inet_ntoa(ia));
add_trace("rtp", "port", "%d,%d", p_s_rtp_port_local, p_s_rtp_port_local + 1);
- add_trace("rtp", "payload", "%d", payload_type);
+ add_trace("rtp", "payload", "%s:%d", media_type2name(media_type), payload_type);
end_trace();
return 0;
struct epoint_list *epointlist;
sip_cseq_t *cseq = NULL;
struct lcr_msg *message;
- unsigned char lcr_payload = { (options.law=='a') ? RTP_PT_ALAW : RTP_PT_ULAW };
+ int lcr_media = { (options.law=='a') ? MEDIA_TYPE_ALAW : MEDIA_TYPE_ULAW };
+ unsigned char lcr_payload = { (options.law=='a') ? PAYLOAD_TYPE_ALAW : PAYLOAD_TYPE_ULAW };
+ int *media_types;
unsigned char *payload_types;
int payloads = 0;
int i;
if (param->setup.rtpinfo.port) {
PDEBUG(DEBUG_SIP, "RTP info given by remote, forward that\n");
p_s_rtp_bridge = 1;
+ media_types = param->setup.rtpinfo.media_types;
payload_types = param->setup.rtpinfo.payload_types;
payloads = param->setup.rtpinfo.payloads;
p_s_rtp_ip_local = param->setup.rtpinfo.ip;
} else {
PDEBUG(DEBUG_SIP, "RTP info not given by remote, so we do our own RTP\n");
p_s_rtp_bridge = 0;
+ media_types = &lcr_media;
payload_types = &lcr_payload;
payloads = 1;
}
SCAT(sdp_str, "\n");
for (i = 0; i < payloads; i++) {
- SPRINT(pt_str, "a=rtpmap:%d %s/8000\n", payload_types[i], payload_type2name(payload_types[i]));
+ SPRINT(pt_str, "a=rtpmap:%d %s/8000\n", payload_types[i], media_type2name(media_types[i]));
SCAT(sdp_str, pt_str);
}
PDEBUG(DEBUG_SIP, "Using SDP for invite: %s\n", sdp_str);
add_trace("rtp", "ip", "%s", inet_ntoa(ia));
add_trace("rtp", "port", "%d,%d", p_s_rtp_port_local, p_s_rtp_port_local + 1);
for (i = 0; i < payloads; i++)
- add_trace("rtp", "payload", "%d", payload_types[i]);
+ add_trace("rtp", "payload", "%s:%d", media_type2name(media_types[i]), payload_types[i]);
end_trace();
// cseq = sip_cseq_create(sip_home, 123, SIP_METHOD_INVITE);
"t=0 0\n"
"m=audio %d RTP/AVP %d\n"
"a=rtpmap:%d %s/8000\n"
- , inet_ntoa(ia), inet_ntoa(ia), p_s_rtp_port_local, p_s_rtp_payload_type, p_s_rtp_payload_type, payload_type2name(p_s_rtp_payload_type));
+ , inet_ntoa(ia), inet_ntoa(ia), p_s_rtp_port_local, p_s_rtp_payload_type, p_s_rtp_payload_type, media_type2name(p_s_rtp_media_type));
PDEBUG(DEBUG_SIP, "Using SDP for rertieve: %s\n", sdp_str);
nua_info(p_s_handle,
// TAG_IF(from[0], SIPTAG_FROM_STR(from)),
return 0;
}
-int Psip::parse_sdp(sip_t const *sip, unsigned int *ip, unsigned short *port, uint8_t *payload_types, int *payloads, int max_payloads)
+int Psip::parse_sdp(sip_t const *sip, unsigned int *ip, unsigned short *port, uint8_t *payload_types, int *media_types, int *payloads, int max_payloads)
{
*payloads = 0;
*ip = ntohl(p_s_rtp_ip_remote);
}
for (map = m->m_rtpmaps; map; map = map->rm_next) {
+ int media_type = 0;
+
PDEBUG(DEBUG_SIP, "RTPMAP: coding:'%s' rate='%d' pt='%d'\n", map->rm_encoding, map->rm_rate, map->rm_pt);
/* append to payload list, if there is space */
- add_trace("rtp", "payload", "%d", map->rm_pt);
- if (*payloads <= max_payloads) {
+ add_trace("rtp", "payload", "%s:%d", map->rm_encoding, map->rm_pt);
+ if (map->rm_pt == PAYLOAD_TYPE_ALAW)
+ media_type = MEDIA_TYPE_ALAW;
+ else if (map->rm_pt == PAYLOAD_TYPE_ULAW)
+ media_type = MEDIA_TYPE_ULAW;
+ else if (map->rm_pt == PAYLOAD_TYPE_GSM)
+ media_type = MEDIA_TYPE_GSM;
+ else if (!strcmp(map->rm_encoding, "GSM-EFR"))
+ media_type = MEDIA_TYPE_GSM_EFR;
+ else if (!strcmp(map->rm_encoding, "AMR"))
+ media_type = MEDIA_TYPE_AMR;
+ else if (!strcmp(map->rm_encoding, "GSM-HR"))
+ media_type = MEDIA_TYPE_GSM_HR;
+ if (media_type && *payloads <= max_payloads) {
*payload_types++ = map->rm_pt;
+ *media_types++ = media_type;
(*payloads)++;
}
}
class Endpoint *epoint;
struct lcr_msg *message;
struct interface *interface;
+ int media_types[32];
uint8_t payload_types[32];
int payloads = 0;
PDEBUG(DEBUG_SIP, "invite received (%s->%s)\n", from, to);
sip_trace_header(this, "Payload received", DIRECTION_NONE);
- ret = parse_sdp(sip, &p_s_rtp_ip_remote, &p_s_rtp_port_remote, payload_types, &payloads, sizeof(payload_types));
+ ret = parse_sdp(sip, &p_s_rtp_ip_remote, &p_s_rtp_port_remote, payload_types, media_types, &payloads, sizeof(payload_types));
if (!ret) {
/* if no RTP bridge, we must support LAW codec, otherwise we forward what we have */
if (!p_s_rtp_bridge) {
/* check if supported payload type exists */
for (i = 0; i < payloads; i++) {
- if (payload_types[i] == ((options.law=='a') ? RTP_PT_ALAW : RTP_PT_ULAW))
+ if (media_types[i] == ((options.law=='a') ? MEDIA_TYPE_ALAW : MEDIA_TYPE_ULAW))
break;
}
if (i == payloads) {
end_trace();
sip_trace_header(this, "INVITE", DIRECTION_IN);
- add_trace("RTP", "port", "%d", p_s_rtp_port_remote);
+ add_trace("rtp", "port", "%d", p_s_rtp_port_remote);
/* caller information */
if (!from[0]) {
p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
message->param.setup.rtpinfo.port = p_s_rtp_port_remote;
/* add codecs to setup message */
for (i = 0; i < payloads; i++) {
- message->param.setup.rtpinfo.payload_types[message->param.setup.rtpinfo.payloads++] = payload_types[i];
- if (message->param.setup.rtpinfo.payloads == sizeof(message->param.setup.rtpinfo.payload_types))
+ message->param.setup.rtpinfo.media_types[i] = media_types[i];
+ message->param.setup.rtpinfo.payload_types[i] = payload_types[i];
+ if (i == sizeof(message->param.setup.rtpinfo.payload_types))
break;
}
+ message->param.setup.rtpinfo.payloads = i;
}
message_put(message);
{
struct lcr_msg *message;
int cause = 0, location = 0;
+ int media_types[32];
uint8_t payload_types[32];
int payloads = 0;
int ret;
sip_trace_header(this, "Payload received", DIRECTION_NONE);
- ret = parse_sdp(sip, &p_s_rtp_ip_remote, &p_s_rtp_port_remote, payload_types, &payloads, sizeof(payload_types));
+ ret = parse_sdp(sip, &p_s_rtp_ip_remote, &p_s_rtp_port_remote, payload_types, media_types, &payloads, sizeof(payload_types));
if (!ret) {
if (payloads != 1)
ret = 415;
else if (!p_s_rtp_bridge) {
- if (payload_types[0] != ((options.law=='a') ? RTP_PT_ALAW : RTP_PT_ULAW)) {
+ if (media_types[0] != ((options.law=='a') ? MEDIA_TYPE_ALAW : MEDIA_TYPE_ULAW)) {
add_trace("error", NULL, "Expected LAW payload type (not bridged)");
ret = 415;
}
if (p_s_rtp_bridge) {
message->param.progressinfo.rtpinfo.ip = p_s_rtp_ip_remote;
message->param.progressinfo.rtpinfo.port = p_s_rtp_port_remote;
+ message->param.progressinfo.rtpinfo.media_types[0] = media_types[0];
message->param.progressinfo.rtpinfo.payload_types[0] = payload_types[0];
message->param.progressinfo.rtpinfo.payloads = 1;
}
if (p_s_rtp_bridge) {
message->param.connectinfo.rtpinfo.ip = p_s_rtp_ip_remote;
message->param.connectinfo.rtpinfo.port = p_s_rtp_port_remote;
+ message->param.connectinfo.rtpinfo.media_types[0] = media_types[0];
message->param.connectinfo.rtpinfo.payload_types[0] = payload_types[0];
message->param.connectinfo.rtpinfo.payloads = 1;
}
unsigned char p_s_rxdata[160]; /* receive audio buffer */
int p_s_rxpos; /* position in audio buffer 0..159 */
int bridge_rx(unsigned char *data, int len);
- int parse_sdp(sip_t const *sip, unsigned int *ip, unsigned short *port, uint8_t *payload_types, int *payloads, int max_payloads);
+ int parse_sdp(sip_t const *sip, unsigned int *ip, unsigned short *port, uint8_t *payload_types, int *media_types, int *payloads, int max_payloads);
void rtp_shutdown(void);
};
+const char *media_type2name(uint8_t media_type);
int sip_init_inst(struct interface *interface);
void sip_exit_inst(struct interface *interface);
int sip_init(void);