311 |
311 |
|
312 |
312 |
typedef struct janus_sip_media {
|
313 |
313 |
char *remote_ip;
|
|
314 |
gboolean earlymedia;
|
314 |
315 |
gboolean ready;
|
315 |
316 |
gboolean autoack;
|
316 |
317 |
gboolean require_srtp, has_srtp_local, has_srtp_remote;
|
... | ... | |
973 |
974 |
session->callid = NULL;
|
974 |
975 |
session->sdp = NULL;
|
975 |
976 |
session->media.remote_ip = NULL;
|
|
977 |
session->media.earlymedia = FALSE;
|
976 |
978 |
session->media.ready = FALSE;
|
977 |
979 |
session->media.autoack = TRUE;
|
978 |
980 |
session->media.require_srtp = FALSE;
|
... | ... | |
2026 |
2028 |
/* Also notify event handlers */
|
2027 |
2029 |
if(notify_events && gateway->events_is_enabled()) {
|
2028 |
2030 |
json_t *info = json_object();
|
2029 |
|
json_object_set_new(info, "event", json_string("accepted"));
|
|
2031 |
json_object_set_new(info, "event", json_string(answer ? "accepted" : "accepting"));
|
2030 |
2032 |
if(session->callid)
|
2031 |
2033 |
json_object_set_new(info, "call-id", json_string(session->callid));
|
2032 |
2034 |
gateway->notify_event(&janus_sip_plugin, session->handle, info);
|
... | ... | |
2050 |
2052 |
g_free(sdp);
|
2051 |
2053 |
/* Send an ack back */
|
2052 |
2054 |
result = json_object();
|
2053 |
|
json_object_set_new(result, "event", json_string("accepted"));
|
|
2055 |
json_object_set_new(result, "event", json_string(answer ? "accepted" : "accepting"));
|
2054 |
2056 |
if(answer) {
|
2055 |
2057 |
/* Start the media */
|
2056 |
2058 |
session->media.ready = TRUE; /* FIXME Maybe we need a better way to signal this */
|
... | ... | |
2078 |
2080 |
g_snprintf(error_cause, 512, "Wrong state (no callee?)");
|
2079 |
2081 |
goto error;
|
2080 |
2082 |
}
|
|
2083 |
session->media.earlymedia = FALSE;
|
2081 |
2084 |
session->media.ready = FALSE;
|
2082 |
2085 |
session->media.on_hold = FALSE;
|
2083 |
2086 |
session->status = janus_sip_call_status_closing;
|
... | ... | |
2200 |
2203 |
g_snprintf(error_cause, 512, "Wrong state (no callee?)");
|
2201 |
2204 |
goto error;
|
2202 |
2205 |
}
|
|
2206 |
session->media.earlymedia = FALSE;
|
2203 |
2207 |
session->media.ready = FALSE;
|
2204 |
2208 |
session->media.on_hold = FALSE;
|
2205 |
2209 |
session->status = janus_sip_call_status_closing;
|
... | ... | |
2615 |
2619 |
}
|
2616 |
2620 |
} else if(callstate == nua_callstate_terminated &&
|
2617 |
2621 |
(session->stack->s_nh_i == nh || session->stack->s_nh_i == NULL)) {
|
|
2622 |
session->media.earlymedia = FALSE;
|
2618 |
2623 |
session->media.ready = FALSE;
|
2619 |
2624 |
session->media.on_hold = FALSE;
|
2620 |
2625 |
session->status = janus_sip_call_status_idle;
|
... | ... | |
2909 |
2914 |
case nua_r_invite: {
|
2910 |
2915 |
JANUS_LOG(LOG_VERB, "[%s][%s]: %d %s\n", session->account.username, nua_event_name(event), status, phrase ? phrase : "??");
|
2911 |
2916 |
|
|
2917 |
gboolean in_progress = FALSE;
|
2912 |
2918 |
if(status < 200) {
|
2913 |
|
/* Not ready yet (FIXME May this be pranswer?? we don't handle it yet...) */
|
2914 |
|
break;
|
|
2919 |
/* Not ready yet, either notify the user (e.g., "ringing") or handle early media (if it's a 183) */
|
|
2920 |
if(status == 180) {
|
|
2921 |
/* Ringing, notify the application */
|
|
2922 |
json_t *ringing = json_object();
|
|
2923 |
json_object_set_new(ringing, "sip", json_string("event"));
|
|
2924 |
json_t *result = json_object();
|
|
2925 |
json_object_set_new(result, "event", json_string("ringing"));
|
|
2926 |
json_object_set_new(ringing, "result", result);
|
|
2927 |
int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, ringing, NULL);
|
|
2928 |
JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
|
|
2929 |
json_decref(ringing);
|
|
2930 |
break;
|
|
2931 |
} else if(status == 183) {
|
|
2932 |
/* If's a Session Progress: check if there's an SDP, and if so, treat it like a 200 */
|
|
2933 |
if(!sip->sip_payload->pl_data)
|
|
2934 |
break;
|
|
2935 |
in_progress = TRUE;
|
|
2936 |
} else {
|
|
2937 |
/* Nothing to do, let's wait for a 200 OK */
|
|
2938 |
break;
|
|
2939 |
}
|
2915 |
2940 |
} else if(status == 401 || status == 407) {
|
2916 |
2941 |
char auth[256];
|
2917 |
2942 |
const char* scheme;
|
... | ... | |
2959 |
2984 |
break;
|
2960 |
2985 |
}
|
2961 |
2986 |
/* Send an ACK, if needed */
|
2962 |
|
if(!session->media.autoack) {
|
|
2987 |
if(!in_progress && !session->media.autoack) {
|
2963 |
2988 |
char *route = sip->sip_record_route ? url_as_string(session->stack->s_home, sip->sip_record_route->r_url) : NULL;
|
2964 |
2989 |
JANUS_LOG(LOG_INFO, "Sending ACK (route=%s)\n", route ? route : "none");
|
2965 |
2990 |
nua_ack(nh,
|
... | ... | |
2978 |
3003 |
JANUS_LOG(LOG_ERR, "\tWe asked for mandatory SRTP but didn't get any in the reply!\n");
|
2979 |
3004 |
janus_sdp_free(sdp);
|
2980 |
3005 |
/* Hangup immediately */
|
|
3006 |
session->media.earlymedia = FALSE;
|
2981 |
3007 |
session->media.ready = FALSE;
|
2982 |
3008 |
session->media.on_hold = FALSE;
|
2983 |
3009 |
session->status = janus_sip_call_status_closing;
|
... | ... | |
2991 |
3017 |
JANUS_LOG(LOG_ERR, "\tNo remote IP address found for RTP, something's wrong with the SDP!\n");
|
2992 |
3018 |
janus_sdp_free(sdp);
|
2993 |
3019 |
/* Hangup immediately */
|
|
3020 |
session->media.earlymedia = FALSE;
|
2994 |
3021 |
session->media.ready = FALSE;
|
2995 |
3022 |
session->media.on_hold = FALSE;
|
2996 |
3023 |
session->status = janus_sip_call_status_closing;
|
... | ... | |
3008 |
3035 |
JANUS_LOG(LOG_VERB, "Detected video codec: %d (%s)\n", session->media.video_pt, session->media.video_pt_name);
|
3009 |
3036 |
}
|
3010 |
3037 |
session->media.ready = TRUE; /* FIXME Maybe we need a better way to signal this */
|
3011 |
|
if(update) {
|
|
3038 |
if(update && !session->media.earlymedia) {
|
3012 |
3039 |
/* Don't push to the browser if this is in response to a hold/unhold we sent ourselves */
|
3013 |
3040 |
JANUS_LOG(LOG_VERB, "This is an update to an existing call (possibly in response to hold/unhold)\n");
|
3014 |
3041 |
break;
|
3015 |
3042 |
}
|
3016 |
|
GError *error = NULL;
|
3017 |
|
char tname[16];
|
3018 |
|
g_snprintf(tname, sizeof(tname), "siprtp %s", session->account.username);
|
3019 |
|
g_thread_try_new(tname, janus_sip_relay_thread, session, &error);
|
3020 |
|
if(error != NULL) {
|
3021 |
|
JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the RTP/RTCP thread...\n", error->code, error->message ? error->message : "??");
|
|
3043 |
if(!session->media.earlymedia) {
|
|
3044 |
GError *error = NULL;
|
|
3045 |
char tname[16];
|
|
3046 |
g_snprintf(tname, sizeof(tname), "siprtp %s", session->account.username);
|
|
3047 |
g_thread_try_new(tname, janus_sip_relay_thread, session, &error);
|
|
3048 |
if(error != NULL) {
|
|
3049 |
JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the RTP/RTCP thread...\n", error->code, error->message ? error->message : "??");
|
|
3050 |
}
|
|
3051 |
}
|
|
3052 |
/* Send event back to the browser */
|
|
3053 |
json_t *jsep = NULL;
|
|
3054 |
if(!session->media.earlymedia) {
|
|
3055 |
jsep = json_pack("{ssss}", "type", "answer", "sdp", fixed_sdp);
|
|
3056 |
} else {
|
|
3057 |
/* We've received the 200 OK after the 183, we can remove the flag now */
|
|
3058 |
session->media.earlymedia = FALSE;
|
|
3059 |
}
|
|
3060 |
if(in_progress) {
|
|
3061 |
/* If we just received the 183, set the flag instead so that we can handle the 200 OK differently */
|
|
3062 |
session->media.earlymedia = TRUE;
|
3022 |
3063 |
}
|
3023 |
|
/* Send SDP to the browser */
|
3024 |
|
json_t *jsep = json_pack("{ssss}", "type", "answer", "sdp", fixed_sdp);
|
3025 |
3064 |
json_t *call = json_object();
|
3026 |
3065 |
json_object_set_new(call, "sip", json_string("event"));
|
3027 |
3066 |
json_t *calling = json_object();
|
3028 |
|
json_object_set_new(calling, "event", json_string("accepted"));
|
|
3067 |
json_object_set_new(calling, "event", json_string(in_progress ? "progress" : "accepted"));
|
3029 |
3068 |
json_object_set_new(calling, "username", json_string(session->callee));
|
3030 |
3069 |
json_object_set_new(call, "result", calling);
|
3031 |
3070 |
int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call, jsep);
|
... | ... | |
3036 |
3075 |
/* Also notify event handlers */
|
3037 |
3076 |
if(notify_events && gateway->events_is_enabled()) {
|
3038 |
3077 |
json_t *info = json_object();
|
3039 |
|
json_object_set_new(info, "event", json_string("accepted"));
|
|
3078 |
json_object_set_new(info, "event", json_string(in_progress ? "progress" : "accepted"));
|
3040 |
3079 |
if(session->callid)
|
3041 |
3080 |
json_object_set_new(info, "call-id", json_string(session->callid));
|
3042 |
3081 |
json_object_set_new(info, "username", json_string(session->callee));
|