/** * Construct an NLSML result for digit match * @param digits the matching digits * @return the NLSML <result> */ iks *nlsml_create_dtmf_match(const char *digits) { iks *result = iks_new("result"); iks_insert_attrib(result, "xmlns", NLSML_NS); iks_insert_attrib(result, "xmlns:xf", "http://www.w3.org/2000/xforms"); if (!zstr(digits)) { int first = 1; int i; int num_digits = strlen(digits); switch_stream_handle_t stream = { 0 }; iks *interpretation = iks_insert(result, "interpretation"); iks *input = iks_insert(interpretation, "input"); input = iks_insert(input, "input"); iks_insert_attrib(input, "mode", "dtmf"); iks_insert_attrib(input, "confidence", "100"); SWITCH_STANDARD_STREAM(stream); for (i = 0; i < num_digits; i++) { if (isdigit(digits[i])) { if (first) { stream.write_function(&stream, "%c", digits[i]); first = 0; } else { stream.write_function(&stream, " %c", digits[i]); } } } iks_insert_cdata(input, stream.data, strlen(stream.data)); switch_safe_free(stream.data); } return result; }
/** * Pass output component command */ static iks *forward_output_component_request(struct rayo_actor *prompt, struct rayo_message *msg, void *data) { iks *iq = msg->payload; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s) %s prompt\n", RAYO_JID(prompt), prompt_component_state_to_string(PROMPT_COMPONENT(prompt)->state), iks_name(iks_first_tag(iq))); switch (PROMPT_COMPONENT(prompt)->state) { case PCS_OUTPUT: case PCS_START_INPUT_OUTPUT: case PCS_INPUT_OUTPUT: { /* forward request to output component */ iks_insert_attrib(iq, "from", RAYO_JID(prompt)); iks_insert_attrib(iq, "to", PROMPT_COMPONENT(prompt)->output_jid); RAYO_SEND_MESSAGE_DUP(prompt, PROMPT_COMPONENT(prompt)->output_jid, iq); return NULL; } case PCS_START_INPUT_TIMERS: case PCS_START_OUTPUT: case PCS_START_OUTPUT_BARGE: /* ref hasn't been sent yet */ return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "too soon"); break; case PCS_START_INPUT: case PCS_STOP_OUTPUT: case PCS_DONE_STOP_OUTPUT: case PCS_INPUT: case PCS_DONE: return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "output is finished"); } return NULL; }
static int CFStouXmppGwConnStartAuth(CFStouXmppGwConn *gwConn) { iks *stz; const char *sid; stz = iks_new("STOU_XMPP"); if (!stz) { LCF_ERR_OUT(ERR_OUT, "out of memory !!\n"); } iks_insert_attrib(stz, "from", gwConn->xmppSvrJid->full); iks_insert_attrib(stz, "to", gwConn->xmppClientJid->full); if (!(sid = CFRandomStr("", 0, "", 0, 10))) { LCF_ERR_OUT(ERR_DEL_STZ, "\n"); } gwConn->sid = strdup(sid); LCF_DBG("sid=%s\n", gwConn->sid); iks_insert_attrib(stz, "sid", sid); if (CFStouSvrConnSendStanza(gwConn->stouConn, stz)) { LCF_ERR_OUT(ERR_FREE_SID, "\n"); } iks_delete(stz); return 0; ERR_FREE_SID: free(gwConn->sid); ERR_DEL_STZ: iks_delete(stz); ERR_OUT: return -1; }
static int CFStouXmppGwConnSendAuthResutl(CFStouXmppGwConn* gwConn, BOOL ok) { iks *stz; if (!(stz = iks_new("STOU_XMPP_AUTH"))) { LCF_ERR_OUT(ERR_OUT, "\n"); } if (ok) { iks_insert_attrib(stz, "auth", "proceed"); } else { iks_insert_attrib(stz, "auth", "failed"); } if (CFStouSvrConnSendStanza(gwConn->stouConn, stz)) { LCF_ERR_OUT(ERR_DEL_STZ, "\n"); } iks_delete(stz); return 0; ERR_DEL_STZ: iks_delete(stz); ERR_OUT: return -1; }
iks * iks_make_auth (iksid *id, const char *pass, const char *sid) { iks *x, *y; x = iks_new ("iq"); iks_insert_attrib (x, "type", "set"); y = iks_insert (x, "query"); iks_insert_attrib (y, "xmlns", IKS_NS_AUTH); iks_insert_cdata (iks_insert (y, "username"), id->user, 0); iks_insert_cdata (iks_insert (y, "resource"), id->resource, 0); if(sid) { char buf[41]; iksha *sha; sha = iks_sha_new (); iks_sha_hash (sha, sid, strlen (sid), 0); iks_sha_hash (sha, pass, strlen (pass), 1); iks_sha_print (sha, buf); iks_sha_delete (sha); iks_insert_cdata (iks_insert (y, "digest"), buf, 40); } else { iks_insert_cdata (iks_insert (y, "password"), pass, 0); } return x; }
/** * Handle input failure. */ static iks *prompt_component_handle_input_error(struct rayo_actor *prompt, struct rayo_message *msg, void *data) { iks *iq = msg->payload; iks *error = iks_find(iq, "error"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s) input error\n", RAYO_JID(prompt), prompt_component_state_to_string(PROMPT_COMPONENT(prompt)->state)); switch (PROMPT_COMPONENT(prompt)->state) { case PCS_START_INPUT_TIMERS: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, <input> error: %s\n", RAYO_JID(prompt), iks_string(iks_stack(iq), iq)); PROMPT_COMPONENT(prompt)->state = PCS_DONE; /* forward IQ error to client */ iq = PROMPT_COMPONENT(prompt)->iq; iks_insert_attrib(iq, "from", RAYO_JID(RAYO_COMPONENT(prompt)->parent)); iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid); iks_insert_node(iq, iks_copy_within(error, iks_stack(iq))); RAYO_SEND_REPLY(prompt, RAYO_COMPONENT(prompt)->client_jid, iq); /* done */ RAYO_UNLOCK(prompt); RAYO_DESTROY(prompt); break; case PCS_START_INPUT: /* send presence error to client */ PROMPT_COMPONENT(prompt)->state = PCS_DONE; iks_delete(PROMPT_COMPONENT(prompt)->iq); rayo_component_send_complete(RAYO_COMPONENT(prompt), COMPONENT_COMPLETE_ERROR); break; case PCS_START_INPUT_OUTPUT: PROMPT_COMPONENT(prompt)->state = PCS_DONE_STOP_OUTPUT; /* forward IQ error to client */ iq = PROMPT_COMPONENT(prompt)->iq; iks_insert_attrib(iq, "from", RAYO_JID(RAYO_COMPONENT(prompt)->parent)); iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid); iks_insert_node(iq, iks_copy_within(error, iks_stack(iq))); PROMPT_COMPONENT(prompt)->complete = iq; rayo_component_send_stop(prompt, PROMPT_COMPONENT(prompt)->output_jid); break; case PCS_START_OUTPUT: case PCS_START_OUTPUT_BARGE: case PCS_INPUT_OUTPUT: case PCS_STOP_OUTPUT: case PCS_INPUT: case PCS_OUTPUT: case PCS_DONE_STOP_OUTPUT: case PCS_DONE: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, unexpected start input error event\n", RAYO_JID(prompt)); break; } return NULL; }
/** * Send input-timers-started event */ void rayo_component_send_input_timers_started_event(struct rayo_component *component) { iks *event = iks_new("presence"); iks *x; iks_insert_attrib(event, "from", RAYO_JID(component)); iks_insert_attrib(event, "to", component->client_jid); x = iks_insert(event, "input-timers-started"); iks_insert_attrib(x, "xmlns", RAYO_PROMPT_NS); RAYO_SEND_REPLY(component, component->client_jid, event); }
iks * iks_make_session (void) { iks *x, *y; x = iks_new ("iq"); iks_insert_attrib (x, "type", "set"); y = iks_insert (x, "session"); iks_insert_attrib (y, "xmlns", IKS_NS_XMPP_SESSION); return x; }
/** * Send stop to component */ static void rayo_component_send_stop(struct rayo_actor *from, const char *to) { iks *stop = iks_new("iq"); iks *x; iks_insert_attrib(stop, "from", RAYO_JID(from)); iks_insert_attrib(stop, "to", to); iks_insert_attrib(stop, "type", "set"); iks_insert_attrib_printf(stop, "id", "mod_rayo-prompt-%d", RAYO_SEQ_NEXT(from)); x = iks_insert(stop, "stop"); iks_insert_attrib(x, "xmlns", RAYO_EXT_NS); RAYO_SEND_MESSAGE(from, to, stop); }
/** * Start input component timers */ static void start_input_timers(struct prompt_component *prompt) { iks *x; iks *iq = iks_new("iq"); iks_insert_attrib(iq, "from", RAYO_JID(prompt)); iks_insert_attrib(iq, "to", prompt->input_jid); iks_insert_attrib(iq, "type", "set"); iks_insert_attrib_printf(iq, "id", "mod_rayo-prompt-%d", RAYO_SEQ_NEXT(prompt)); x = iks_insert(iq, "start-timers"); iks_insert_attrib(x, "xmlns", RAYO_INPUT_NS); RAYO_SEND_MESSAGE(prompt, prompt->input_jid, iq); }
/** * Forward result */ static iks *prompt_component_handle_result(struct rayo_actor *prompt, struct rayo_message *msg, void *data) { iks *iq = msg->payload; /* forward all results, except for internal ones... */ if (strncmp("mod_rayo-prompt", iks_find_attrib_soft(iq, "id"), 15)) { iks_insert_attrib(iq, "from", RAYO_JID(prompt)); iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid); RAYO_SEND_REPLY_DUP(prompt, RAYO_COMPONENT(prompt)->client_jid, iq); } return NULL; }
/** * Start execution of prompt component */ static iks *start_call_prompt_component(struct rayo_actor *call, struct rayo_message *msg, void *session_data) { iks *iq = msg->payload; switch_core_session_t *session = (switch_core_session_t *)session_data; switch_memory_pool_t *pool; struct prompt_component *prompt_component = NULL; iks *prompt = iks_find(iq, "prompt"); iks *input; iks *output; iks *cmd; if (!VALIDATE_RAYO_PROMPT(prompt)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Bad <prompt> attrib\n"); return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Bad <prompt> attrib value"); } output = iks_find(prompt, "output"); if (!output) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Missing <output>\n"); return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Missing <output>"); } input = iks_find(prompt, "input"); if (!input) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Missing <input>\n"); return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Missing <input>"); } /* create prompt component, linked to call */ switch_core_new_memory_pool(&pool); prompt_component = switch_core_alloc(pool, sizeof(*prompt_component)); rayo_component_init(RAYO_COMPONENT(prompt_component), pool, RAT_CALL_COMPONENT, "prompt", NULL, call, iks_find_attrib(iq, "from")); prompt_component->iq = iks_copy(iq); /* start output */ if (iks_find_bool_attrib(prompt, "barge-in")) { prompt_component->state = PCS_START_OUTPUT_BARGE; } else { prompt_component->state = PCS_START_OUTPUT; } cmd = iks_new("iq"); iks_insert_attrib(cmd, "from", RAYO_JID(prompt_component)); iks_insert_attrib(cmd, "to", RAYO_JID(call)); iks_insert_attrib(cmd, "id", iks_find_attrib(iq, "id")); iks_insert_attrib(cmd, "type", "set"); output = iks_copy_within(output, iks_stack(cmd)); iks_insert_node(cmd, output); RAYO_SEND_MESSAGE(prompt_component, RAYO_JID(call), cmd); return NULL; }
/** * Add fax metadata to result * @param event source of metadata * @param name of metadata * @param result to add metadata to */ static void insert_fax_metadata(switch_event_t *event, const char *name, iks *result) { char actual_name[256]; const char *value; snprintf(actual_name, sizeof(actual_name), "variable_%s", name); actual_name[sizeof(actual_name) - 1] = '\0'; value = switch_event_get_header(event, actual_name); if (!zstr(value)) { iks *metadata = iks_insert(result, "metadata"); iks_insert_attrib(metadata, "xmlns", RAYO_FAX_COMPLETE_NS); iks_insert_attrib(metadata, "name", name); iks_insert_attrib(metadata, "value", value); } }
static void xmpp_process_msg( axis2_xmpp_session_data_t *session, iks *node) { iks *t = NULL; session->features = iks_stream_features(node); /* save features */ if(session->features & IKS_STREAM_BIND) { t = iks_make_resource_bind(session->jid); iks_send(session->parser, t); iks_delete(t); } /* Send a session if required */ if(session->features & IKS_STREAM_SESSION) { t = iks_make_session(); iks_insert_attrib(t, "id", "auth"); iks_send(session->parser, t); iks_delete(t); } /* Subscribe if the service is configured to do so */ if((session->subscribe) && (session->subscribe_to)) { /* Check whether the type of subscription is user or room * and send the subscription request accordingly */ if(!axutil_strcmp(session->subscribe_type, AXIS2_XMPP_SUB_TYPE_USER)) { iks_send(session->parser, iks_make_s10n(IKS_TYPE_SUBSCRIBE, session->subscribe_to, "")); } else if(!axutil_strcmp(session->subscribe_type, AXIS2_XMPP_SUB_TYPE_ROOM)) { axis2_char_t *id = axutil_uuid_gen(session->env); iks *x = iks_make_pres(IKS_SHOW_AVAILABLE, ""); iks_insert_attrib(x, "to", session->subscribe_to); iks_insert_attrib(x, "id", id); iks_send(session->parser, x); AXIS2_FREE(session->env->allocator, id); } else { AXIS2_LOG_ERROR(session->env->log, AXIS2_LOG_SI, "[xmpp]Unknown subscription type. No subscription done"); } } }
/** * Start input component */ static void start_input(struct prompt_component *prompt, int start_timers, int barge_event) { iks *iq = iks_new("iq"); iks *input = iks_find(PROMPT_COMPONENT(prompt)->iq, "prompt"); input = iks_find(input, "input"); iks_insert_attrib(iq, "from", RAYO_JID(prompt)); iks_insert_attrib(iq, "to", RAYO_JID(RAYO_COMPONENT(prompt)->parent)); iks_insert_attrib_printf(iq, "id", "mod_rayo-prompt-%d", RAYO_SEQ_NEXT(prompt)); iks_insert_attrib(iq, "type", "set"); input = iks_copy_within(input, iks_stack(iq)); iks_insert_attrib(input, "start-timers", start_timers ? "true" : "false"); iks_insert_attrib(input, "barge-event", barge_event ? "true" : "false"); iks_insert_node(iq, input); RAYO_SEND_MESSAGE(prompt, RAYO_JID(RAYO_COMPONENT(prompt)->parent), iq); }
iks * iks_make_resource_bind (iksid *id) { iks *x, *y, *z; x = iks_new("iq"); iks_insert_attrib(x, "type", "set"); y = iks_insert(x, "bind"); iks_insert_attrib(y, "xmlns", IKS_NS_XMPP_BIND); if (id->resource && iks_strcmp(id->resource, "")) { z = iks_insert(y, "resource"); iks_insert_cdata(z, id->resource, 0); } return x; }
/** * Forward result */ static iks *prompt_component_handle_result(struct rayo_actor *prompt, struct rayo_message *msg, void *data) { iks *iq = msg->payload; /* forward all results, except for internal ones... */ const char *id = iks_find_attrib_soft(iq, "id"); if (strncmp("mod_rayo-prompt", id, 15)) { iks_insert_attrib(iq, "from", RAYO_JID(prompt)); iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid); RAYO_SEND_REPLY_DUP(prompt, RAYO_COMPONENT(prompt)->client_jid, iq); } else if (!strcmp(PROMPT_COMPONENT(prompt)->start_timers_request_id, id)) { rayo_component_send_input_timers_started_event(RAYO_COMPONENT(prompt)); } return NULL; }
static void iks_sasl_challenge(struct stream_data *data, iks *challenge) { char *message; iks *x; char *tmp; tmp = iks_cdata(iks_child(challenge)); if(!tmp) return; /* decode received blob */ message = iks_base64_decode(tmp, NULL); if(!message) return; /* reply the challenge */ if(strstr(message, "rspauth")) { x = iks_new("response"); } else { x = make_sasl_response(data, message); } if(x) { iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_SASL); iks_send(data->prs, x); iks_delete(x); } iks_free(message); }
// xxx needs error return value static void send_sasl_challenge (ikss_Stream *self, iks *challenge) { char *message; iks *x; char *tmp; tmp = iks_cdata (iks_child (challenge)); if (!tmp) return; /* decode received blob */ message = iks_base64_decode (tmp); if (!message) return; /* reply the challenge */ if (strstr (message, "rspauth")) { x = iks_new ("response"); } else { x = make_sasl_response (self, message); } if (x) { iks_insert_attrib (x, "xmlns", IKS_NS_XMPP_SASL); ikss_Stream_send_node (self, x); // xxx check return value iks_delete (x); } iks_free (message); }
/** * Send component start reply * @param component the component * @param iq the start request */ void rayo_component_send_start(struct rayo_component *component, iks *iq) { iks *response = iks_new_iq_result(iq); iks *ref = iks_insert(response, "ref"); iks_insert_attrib(ref, "xmlns", RAYO_NS); iks_insert_attrib_printf(ref, "uri", "xmpp:%s", RAYO_JID(component)); RAYO_SEND_REPLY(component, iks_find_attrib(response, "to"), response); }
iks * iks_make_msg (enum iksubtype type, const char *to, const char *body) { iks *x; char *t = NULL; x = iks_new ("message"); switch (type) { case IKS_TYPE_CHAT: t = "chat"; break; case IKS_TYPE_GROUPCHAT: t = "groupchat"; break; case IKS_TYPE_HEADLINE: t = "headline"; break; default: break; } if (t) iks_insert_attrib (x, "type", t); if (to) iks_insert_attrib (x, "to", to); if (body) iks_insert_cdata (iks_insert (x, "body"), body, 0); return x; }
iks * iks_make_iq (enum iksubtype type, const char *xmlns) { iks *x; char *t = NULL; x = iks_new ("iq"); switch (type) { case IKS_TYPE_GET: t = "get"; break; case IKS_TYPE_SET: t = "set"; break; case IKS_TYPE_RESULT: t = "result"; break; case IKS_TYPE_ERROR: t = "error"; break; default: break; } if (t) iks_insert_attrib (x, "type", t); iks_insert_attrib (iks_insert (x, "query"), "xmlns", xmlns); return x; }
static void insert_attribs (iks *x, char **atts) { if (atts) { int i = 0; while (atts[i]) { iks_insert_attrib (x, atts[i], atts[i+1]); i += 2; } } }
iks * iks_make_s10n (enum iksubtype type, const char *to, const char *msg) { iks *x; char *t; x = iks_new ("presence"); switch (type) { case IKS_TYPE_SUBSCRIBE: t = "subscribe"; break; case IKS_TYPE_SUBSCRIBED: t = "subscribed"; break; case IKS_TYPE_UNSUBSCRIBE: t = "unsubscribe"; break; case IKS_TYPE_UNSUBSCRIBED: t = "unsubscribed"; break; case IKS_TYPE_PROBE: t = "probe"; break; default: t = NULL; break; } if (t) iks_insert_attrib (x, "type", t); if (to) iks_insert_attrib (x, "to", to); if (msg) iks_insert_cdata(iks_insert (x, "status"), msg, 0); return x; }
/// 客户端组装发给服务器端的协商包。 char* pkg_talk_make(const packet_parser_t *pkg) { char *r; iks *x, *tmp; x = iks_new ("connection"); if(NULL == x) return NULL; iks_insert_attrib(x, "xmlns", TALK_XMLNS); iks_insert_attrib(x, "type", "create"); tmp = iks_insert(x, "client-id"); if(NULL != tmp) { iks_insert_cdata(tmp, pkg->client_cert.client_id, 0); } tmp = iks_insert(x, "public-key"); if(NULL != tmp) { iks_insert_cdata(tmp, pkg->curr_ert.ert_keys[0], 0); iks_insert_attrib(tmp, "type", pkg->curr_ert.talk_ert_type); } if(0 != strlen(pkg->curr_ert.talk_ert_type)){ tmp = iks_insert(x, "encryption"); iks_insert_cdata(iks_insert(tmp,"allow"), pkg->curr_ert.transfer_ert_type, 0); } if(0 != strlen(pkg->cps_type)){ tmp = iks_insert(x, "compression"); iks_insert_cdata(iks_insert(tmp,"allow"), pkg->cps_type, 0); } if( pkg->client_cert.signature[0] != 0 ){ tmp = iks_insert(x, "certificate"); iks_insert_attrib(tmp, "id", pkg->client_cert.cert_id); iks_insert_cdata(iks_insert(tmp, "subject"), pkg->client_cert.subject, 0); iks_insert_cdata(iks_insert(tmp, "signature"), pkg->client_cert.signature, 0); } r = iks_string(NULL, x); iks_delete(x); return r; }
// 服务器端组装发给客户端的协商包 char* pkg_talk_rtn(const packet_parser_t *pkg) { char *r; unsigned char *encrypted_key;// 使用公钥加密过的临时密钥 char *output; iks *x, *tmp; int dest_len; x = iks_new ("connection"); if(NULL == x) return NULL; iks_insert_attrib(x, "xmlns", TALK_XMLNS); iks_insert_attrib(x, "type", "result"); tmp = iks_insert(x, "encryption"); iks_insert_attrib(tmp, "type", pkg->curr_ert.transfer_ert_type); // 使用公钥对临时密钥进行加密 if (pkg->asym_encrypt_hook == NULL) { encrypted_key = rsa_encrypt((unsigned char *)get_transfer_crt_key(pkg), strlen(get_transfer_crt_key(pkg)), &dest_len, (char *)(pkg->curr_ert.ert_keys[0]), CRYPT_TYPE_ENCRYPT); } else { encrypted_key = pkg->asym_encrypt_hook((unsigned char *)get_transfer_crt_key(pkg), strlen(get_transfer_crt_key(pkg)), &dest_len, (char *)(pkg->curr_ert.ert_keys[0]), CRYPT_TYPE_ENCRYPT); } output = (char *)calloc(dest_len*2+1, 1); byte2hex(encrypted_key, dest_len, output); iks_insert_cdata(tmp, output, 0); free(output); free(encrypted_key); iks_insert_cdata(iks_insert(x, "compression"), pkg->cps_type, 0); tmp = iks_insert(x, "heartbeat"); // TODO:在初始化服务器端包解析器的时候应该设置心跳参数 iks_insert_attrib(tmp, "sponsor", "server"); iks_insert_attrib(tmp, "seconds", "60"); r = iks_string(NULL, x); iks_delete(x); return r; }
/** * Notify completion of record component */ static void complete_record(struct rayo_component *component, const char *reason, const char *reason_namespace) { switch_core_session_t *session = NULL; const char *uuid = component->parent->id; char *uri = switch_mprintf("file://%s", RECORD_COMPONENT(component)->local_file_path); iks *recording; switch_size_t file_size = 0; /* TODO this doesn't work with HTTP */ #if 0 switch_file_t *file; if (switch_file_open(&file, RECORD_COMPONENT(component)->local_file_path, SWITCH_FOPEN_READ, SWITCH_FPROT_UREAD, RAYO_POOL(component)) == SWITCH_STATUS_SUCCESS) { file_size = switch_file_get_size(file); switch_file_close(file); } else { switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_INFO, "Failed to open %s.\n", RECORD_COMPONENT(component)->local_file_path); } #endif switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Recording %s done.\n", RECORD_COMPONENT(component)->local_file_path); if (RECORD_COMPONENT(component)->stop_beep && (session = switch_core_session_locate(uuid))) { switch_ivr_displace_session(session, RECORD_BEEP, 0, ""); switch_core_session_rwunlock(session); } /* send complete event to client */ recording = iks_new("recording"); iks_insert_attrib(recording, "xmlns", RAYO_RECORD_COMPLETE_NS); iks_insert_attrib(recording, "uri", uri); iks_insert_attrib_printf(recording, "duration", "%i", RECORD_COMPONENT(component)->duration_ms); iks_insert_attrib_printf(recording, "size", "%"SWITCH_SIZE_T_FMT, file_size); rayo_component_send_complete_with_metadata(component, reason, reason_namespace, recording, 1); iks_delete(recording); RAYO_UNLOCK(component); switch_safe_free(uri); }
/** * Create component complete event * @param component the component * @param reason_str the completion reason * @param reason_namespace the completion reason namespace * @param meta metadata to add as child * @param child_of_complete if true metadata is child of complete instead of reason * @return the event */ iks *rayo_component_create_complete_event_with_metadata(struct rayo_component *component, const char *reason_str, const char *reason_namespace, iks *meta, int child_of_complete) { iks *response = iks_new("presence"); iks *complete; iks *reason; iks_insert_attrib(response, "from", RAYO_JID(component)); iks_insert_attrib(response, "to", component->client_jid); iks_insert_attrib(response, "type", "unavailable"); complete = iks_insert(response, "complete"); iks_insert_attrib(complete, "xmlns", RAYO_EXT_NS); reason = iks_insert(complete, reason_str); iks_insert_attrib(reason, "xmlns", reason_namespace); if (meta) { meta = iks_copy_within(meta, iks_stack(response)); if (child_of_complete) { iks_insert_node(complete, meta); } else { iks_insert_node(reason, meta); } } return response; }
int iks_start_sasl (iksparser *prs, enum ikssasltype type, char *username, char *pass) { iks *x; x = iks_new ("auth"); iks_insert_attrib (x, "xmlns", IKS_NS_XMPP_SASL); switch (type) { case IKS_SASL_PLAIN: { int len = iks_strlen (username) + iks_strlen (pass) + 2; char *s = iks_malloc (80+len); char *base64; iks_insert_attrib (x, "mechanism", "PLAIN"); sprintf (s, "%c%s%c%s", 0, username, 0, pass); base64 = iks_base64_encode (s, len); iks_insert_cdata (x, base64, 0); iks_free (base64); iks_free (s); break; } case IKS_SASL_DIGEST_MD5: { struct stream_data *data = iks_user_data (prs); iks_insert_attrib (x, "mechanism", "DIGEST-MD5"); data->auth_username = username; data->auth_pass = pass; break; } default: iks_delete (x); return IKS_NET_NOTSUPP; } iks_send (prs, x); iks_delete (x); return IKS_OK; }
// if returns IKS_OK, do not send more before ikss_SENT callback int ikss_Stream_start_sasl (ikss_Stream *self, enum ikssasltype type, const char *username, const char *pass) { iks *x; x = iks_new ("auth"); // xxx check return? iks_insert_attrib (x, "xmlns", IKS_NS_XMPP_SASL); // xxx check return? switch (type) { case IKS_SASL_PLAIN: { int len = iks_strlen (username) + iks_strlen (pass) + 2; char *s = iks_malloc (80+len); // xxx check for oom, on error free x and return error code char *base64; iks_insert_attrib (x, "mechanism", "PLAIN"); // xxx check return? sprintf (s, "%c%s%c%s", 0, username, 0, pass); base64 = iks_base64_encode (s, len); // xxx check return? iks_insert_cdata (x, base64, 0); iks_free (base64); iks_free (s); break; } case IKS_SASL_DIGEST_MD5: { iks_insert_attrib (x, "mechanism", "DIGEST-MD5"); // xxx check return? self->auth_username = username; self->auth_pass = pass; break; } default: iks_delete (x); return IKS_NET_NOTSUPP; } int ret = ikss_Stream_send_node (self, x); iks_delete (x); // delete ok since above makes a copy if (ret) return ret; return IKS_OK; }