void sipe_process_imdn(struct sipe_core_private *sipe_private, struct sipmsg *msg) { gchar *with = parse_from(sipmsg_find_header(msg, "From")); const gchar *callid = sipmsg_find_header(msg, "Call-ID"); static struct sip_session *session; sipe_xml *xn_imdn; const sipe_xml *node; gchar *message_id; gchar *message; session = sipe_session_find_chat_or_im(sipe_private, callid, with); if (!session) { SIPE_DEBUG_INFO("sipe_process_imdn: unable to find conf session with callid=%s", callid); g_free(with); return; } xn_imdn = sipe_xml_parse(msg->body, msg->bodylen); message_id = sipe_xml_data(sipe_xml_child(xn_imdn, "message-id")); message = g_hash_table_lookup(session->conf_unconfirmed_messages, message_id); /* recipient */ for (node = sipe_xml_child(xn_imdn, "recipient"); node; node = sipe_xml_twin(node)) { gchar *tmp = parse_from(sipe_xml_attribute(node, "uri")); gchar *uri = parse_from(tmp); gchar *status = sipe_xml_data(sipe_xml_child(node, "status")); guint error = status ? g_ascii_strtoull(status, NULL, 10) : 0; /* default to error if missing or conversion failed */ if ((error == 0) || (error >= 300)) sipe_user_present_message_undelivered(sipe_private, session, error, -1, uri, message); g_free(status); g_free(tmp); g_free(uri); } sipe_xml_free(xn_imdn); g_hash_table_remove(session->conf_unconfirmed_messages, message_id); SIPE_DEBUG_INFO("sipe_process_imdn: removed message %s from conf_unconfirmed_messages(count=%d)", message_id, g_hash_table_size(session->conf_unconfirmed_messages)); g_free(message_id); g_free(with); }
void process_incoming_invite_conf(struct sipe_core_private *sipe_private, struct sipmsg *msg) { sipe_xml *xn_conferencing = sipe_xml_parse(msg->body, msg->bodylen); const sipe_xml *xn_focus_uri = sipe_xml_child(xn_conferencing, "focus-uri"); const sipe_xml *xn_audio = sipe_xml_child(xn_conferencing, "audio"); gchar *focus_uri = sipe_xml_data(xn_focus_uri); gboolean audio = sipe_strequal(sipe_xml_attribute(xn_audio, "available"), "true"); sipe_xml_free(xn_conferencing); SIPE_DEBUG_INFO("We have received invitation to Conference. Focus URI=%s", focus_uri); if (audio) { sip_transport_response(sipe_private, msg, 180, "Ringing", NULL); ask_accept_voice_conference(sipe_private, focus_uri, msg, (SipeUserAskCb) conf_accept_cb, (SipeUserAskCb) conf_decline_cb); } else { accept_incoming_invite_conf(sipe_private, focus_uri, FALSE, msg); } g_free(focus_uri); }
static void assert_data(const sipe_xml *xml, const gchar *s) { gchar *data = sipe_xml_data(xml); if (sipe_strequal(s, data)) { succeeded++; } else { printf("[%s]\nXML data FAILED: '%s' expected: '%s'\n", teststring, data ? data : "(nil)", s ? s : "(nil)"); failed++; } g_free(data); }
static gboolean process_add_group_response(struct sipe_core_private *sipe_private, struct sipmsg *msg, struct transaction *trans) { if (msg->response == 200) { struct sipe_group *group; struct group_user_context *ctx = trans->payload->data; sipe_xml *xml; const sipe_xml *node; char *group_id; xml = sipe_xml_parse(msg->body, msg->bodylen); if (!xml) { return FALSE; } node = sipe_xml_child(xml, "Body/addGroup/groupID"); if (!node) { sipe_xml_free(xml); return FALSE; } group_id = sipe_xml_data(node); if (!group_id) { sipe_xml_free(xml); return FALSE; } group = sipe_group_add(sipe_private, ctx->group_name, NULL, NULL, g_ascii_strtoull(group_id, NULL, 10)); g_free(group_id); if (group) { struct sipe_buddy *buddy = sipe_buddy_find_by_uri(sipe_private, ctx->user_name); if (buddy) { sipe_buddy_insert_group(buddy, group); sipe_group_update_buddy(sipe_private, buddy); } } sipe_xml_free(xml); return TRUE; } return FALSE; }
static void get_and_publish_cert(struct sipe_core_private *sipe_private, const gchar *uri, SIPE_UNUSED_PARAMETER const gchar *raw, sipe_xml *soap_body, gpointer callback_data) { struct certificate_callback_data *ccd = callback_data; gboolean success = (uri == NULL); /* abort case */ if (soap_body) { gchar *cert_base64 = sipe_xml_data(sipe_xml_child(soap_body, "Body/GetAndPublishCertResponse/RequestSecurityTokenResponse/RequestedSecurityToken/BinarySecurityToken")); SIPE_DEBUG_INFO("get_and_publish_cert: received valid SOAP message from service %s", uri); if (cert_base64) { gpointer opaque = sipe_cert_crypto_decode(sipe_private->certificate->backend, cert_base64); SIPE_DEBUG_INFO_NOFORMAT("get_and_publish_cert: found certificate"); if (opaque) { add_certificate(sipe_private, ccd->target, opaque); SIPE_DEBUG_INFO("get_and_publish_cert: certificate for target '%s' added", ccd->target); /* Let's try this again... */ sip_transport_authentication_completed(sipe_private); success = TRUE; } g_free(cert_base64); } } if (!success) { certificate_failure(sipe_private, _("Certificate request to %s failed"), uri, NULL); } callback_data_free(ccd); }
static void sipe_cal_parse_std_dst(const sipe_xml *xn_std_dst_time, struct sipe_cal_std_dst *std_dst) { const sipe_xml *node; gchar *tmp; if (!xn_std_dst_time) return; if (!std_dst) return; /* <StandardTime> <Bias>0</Bias> <Time>02:00:00</Time> <DayOrder>1</DayOrder> <Month>11</Month> <Year>2009</Year> <DayOfWeek>Sunday</DayOfWeek> </StandardTime> */ if ((node = sipe_xml_child(xn_std_dst_time, "Bias"))) { std_dst->bias = atoi(tmp = sipe_xml_data(node)); g_free(tmp); } if ((node = sipe_xml_child(xn_std_dst_time, "Time"))) { std_dst->time = sipe_xml_data(node); } if ((node = sipe_xml_child(xn_std_dst_time, "DayOrder"))) { std_dst->day_order = atoi(tmp = sipe_xml_data(node)); g_free(tmp); } if ((node = sipe_xml_child(xn_std_dst_time, "Month"))) { std_dst->month = atoi(tmp = sipe_xml_data(node)); g_free(tmp); } if ((node = sipe_xml_child(xn_std_dst_time, "DayOfWeek"))) { std_dst->day_of_week = sipe_xml_data(node); } if ((node = sipe_xml_child(xn_std_dst_time, "Year"))) { std_dst->year = sipe_xml_data(node); } }
void sipe_cal_parse_working_hours(const sipe_xml *xn_working_hours, struct sipe_buddy *buddy) { const sipe_xml *xn_bias; const sipe_xml *xn_timezone; const sipe_xml *xn_working_period; const sipe_xml *xn_standard_time; const sipe_xml *xn_daylight_time; gchar *tmp; time_t now = time(NULL); struct sipe_cal_std_dst* std; struct sipe_cal_std_dst* dst; if (!xn_working_hours) return; /* <WorkingHours xmlns="http://schemas.microsoft.com/exchange/services/2006/types"> <TimeZone> <Bias>480</Bias> ... </TimeZone> <WorkingPeriodArray> <WorkingPeriod> <DayOfWeek>Monday Tuesday Wednesday Thursday Friday</DayOfWeek> <StartTimeInMinutes>600</StartTimeInMinutes> <EndTimeInMinutes>1140</EndTimeInMinutes> </WorkingPeriod> </WorkingPeriodArray> </WorkingHours> */ sipe_cal_free_working_hours(buddy->cal_working_hours); buddy->cal_working_hours = g_new0(struct sipe_cal_working_hours, 1); xn_timezone = sipe_xml_child(xn_working_hours, "TimeZone"); xn_bias = sipe_xml_child(xn_timezone, "Bias"); if (xn_bias) { buddy->cal_working_hours->bias = atoi(tmp = sipe_xml_data(xn_bias)); g_free(tmp); } xn_standard_time = sipe_xml_child(xn_timezone, "StandardTime"); xn_daylight_time = sipe_xml_child(xn_timezone, "DaylightTime"); std = &((*buddy->cal_working_hours).std); dst = &((*buddy->cal_working_hours).dst); sipe_cal_parse_std_dst(xn_standard_time, std); sipe_cal_parse_std_dst(xn_daylight_time, dst); xn_working_period = sipe_xml_child(xn_working_hours, "WorkingPeriodArray/WorkingPeriod"); if (xn_working_period) { /* NOTE: this can be NULL! */ buddy->cal_working_hours->days_of_week = sipe_xml_data(sipe_xml_child(xn_working_period, "DayOfWeek")); buddy->cal_working_hours->start_time = atoi(tmp = sipe_xml_data(sipe_xml_child(xn_working_period, "StartTimeInMinutes"))); g_free(tmp); buddy->cal_working_hours->end_time = atoi(tmp = sipe_xml_data(sipe_xml_child(xn_working_period, "EndTimeInMinutes"))); g_free(tmp); } std->switch_time = sipe_cal_get_std_dst_time(now, buddy->cal_working_hours->bias, std, dst); dst->switch_time = sipe_cal_get_std_dst_time(now, buddy->cal_working_hours->bias, dst, std); /* TST8TDT7,M3.2.0/02:00:00,M11.1.0/02:00:00 */ buddy->cal_working_hours->tz = g_strdup_printf("TST%dTDT%d,M%d.%d.%d/%s,M%d.%d.%d/%s", (buddy->cal_working_hours->bias + buddy->cal_working_hours->std.bias) / 60, (buddy->cal_working_hours->bias + buddy->cal_working_hours->dst.bias) / 60, buddy->cal_working_hours->dst.month, buddy->cal_working_hours->dst.day_order, sipe_cal_get_wday(buddy->cal_working_hours->dst.day_of_week), buddy->cal_working_hours->dst.time, buddy->cal_working_hours->std.month, buddy->cal_working_hours->std.day_order, sipe_cal_get_wday(buddy->cal_working_hours->std.day_of_week), buddy->cal_working_hours->std.time ); /* TST8 */ buddy->cal_working_hours->tz_std = g_strdup_printf("TST%d", (buddy->cal_working_hours->bias + buddy->cal_working_hours->std.bias) / 60); /* TDT7 */ buddy->cal_working_hours->tz_dst = g_strdup_printf("TDT%d", (buddy->cal_working_hours->bias + buddy->cal_working_hours->dst.bias) / 60); }
void sipe_process_conference(struct sipe_core_private *sipe_private, struct sipmsg *msg) { sipe_xml *xn_conference_info; const sipe_xml *node; const sipe_xml *xn_subject; const gchar *focus_uri; struct sip_session *session; gboolean just_joined = FALSE; #ifdef HAVE_VV gboolean audio_was_added = FALSE; #endif if (msg->response != 0 && msg->response != 200) return; if (msg->bodylen == 0 || msg->body == NULL || !sipe_strequal(sipmsg_find_header(msg, "Event"), "conference")) return; xn_conference_info = sipe_xml_parse(msg->body, msg->bodylen); if (!xn_conference_info) return; focus_uri = sipe_xml_attribute(xn_conference_info, "entity"); session = sipe_session_find_conference(sipe_private, focus_uri); if (!session) { SIPE_DEBUG_INFO("sipe_process_conference: unable to find conf session with focus=%s", focus_uri); return; } if (!session->chat_session->backend) { gchar *self = sip_uri_self(sipe_private); /* create chat */ session->chat_session->backend = sipe_backend_chat_create(SIPE_CORE_PUBLIC, session->chat_session, session->chat_session->title, self); just_joined = TRUE; /* @TODO ask for full state (re-subscribe) if it was a partial one - * this is to obtain full list of conference participants. */ g_free(self); } /* subject */ if ((xn_subject = sipe_xml_child(xn_conference_info, "conference-description/subject"))) { g_free(session->subject); session->subject = sipe_xml_data(xn_subject); sipe_backend_chat_topic(session->chat_session->backend, session->subject); SIPE_DEBUG_INFO("sipe_process_conference: subject=%s", session->subject ? session->subject : ""); } /* IM MCU URI */ if (!session->im_mcu_uri) { for (node = sipe_xml_child(xn_conference_info, "conference-description/conf-uris/entry"); node; node = sipe_xml_twin(node)) { gchar *purpose = sipe_xml_data(sipe_xml_child(node, "purpose")); if (sipe_strequal("chat", purpose)) { g_free(purpose); session->im_mcu_uri = sipe_xml_data(sipe_xml_child(node, "uri")); SIPE_DEBUG_INFO("sipe_process_conference: im_mcu_uri=%s", session->im_mcu_uri); break; } g_free(purpose); } } /* users */ for (node = sipe_xml_child(xn_conference_info, "users/user"); node; node = sipe_xml_twin(node)) { const gchar *user_uri = sipe_xml_attribute(node, "entity"); const gchar *state = sipe_xml_attribute(node, "state"); gchar *role = sipe_xml_data(sipe_xml_child(node, "roles/entry")); gboolean is_operator = sipe_strequal(role, "presenter"); gboolean is_in_im_mcu = FALSE; gchar *self = sip_uri_self(sipe_private); if (sipe_strequal("deleted", state)) { if (sipe_backend_chat_find(session->chat_session->backend, user_uri)) { sipe_backend_chat_remove(session->chat_session->backend, user_uri); } } else { /* endpoints */ const sipe_xml *endpoint; for (endpoint = sipe_xml_child(node, "endpoint"); endpoint; endpoint = sipe_xml_twin(endpoint)) { const gchar *session_type; gchar *status = sipe_xml_data(sipe_xml_child(endpoint, "status")); gboolean connected = sipe_strequal("connected", status); g_free(status); if (!connected) continue; session_type = sipe_xml_attribute(endpoint, "session-type"); if (sipe_strequal("chat", session_type)) { is_in_im_mcu = TRUE; if (!sipe_backend_chat_find(session->chat_session->backend, user_uri)) { sipe_backend_chat_add(session->chat_session->backend, user_uri, !just_joined && g_ascii_strcasecmp(user_uri, self)); } if (is_operator) { sipe_backend_chat_operator(session->chat_session->backend, user_uri); } } else if (sipe_strequal("audio-video", session_type)) { #ifdef HAVE_VV if (!session->is_call) audio_was_added = TRUE; #endif } } if (!is_in_im_mcu) { if (sipe_backend_chat_find(session->chat_session->backend, user_uri)) { sipe_backend_chat_remove(session->chat_session->backend, user_uri); } } } g_free(role); g_free(self); } #ifdef HAVE_VV if (audio_was_added) { session->is_call = TRUE; ask_accept_voice_conference(sipe_private, focus_uri, NULL, (SipeUserAskCb) call_accept_cb, (SipeUserAskCb) call_decline_cb); } #endif /* entity-view, locked */ for (node = sipe_xml_child(xn_conference_info, "conference-view/entity-view"); node; node = sipe_xml_twin(node)) { const sipe_xml *xn_type = sipe_xml_child(node, "entity-state/media/entry/type"); gchar *tmp = NULL; if (xn_type && sipe_strequal("chat", (tmp = sipe_xml_data(xn_type)))) { const sipe_xml *xn_locked = sipe_xml_child(node, "entity-state/locked"); if (xn_locked) { gchar *locked = sipe_xml_data(xn_locked); gboolean prev_locked = session->locked; session->locked = sipe_strequal(locked, "true"); if (prev_locked && !session->locked) { sipe_user_present_info(sipe_private, session, _("This conference is no longer locked. Additional participants can now join.")); } if (!prev_locked && session->locked) { sipe_user_present_info(sipe_private, session, _("This conference is locked. Nobody else can join the conference while it is locked.")); } SIPE_DEBUG_INFO("sipe_process_conference: session->locked=%s", session->locked ? "TRUE" : "FALSE"); g_free(locked); } } g_free(tmp); } sipe_xml_free(xn_conference_info); if (session->im_mcu_uri) { struct sip_dialog *dialog = sipe_dialog_find(session, session->im_mcu_uri); if (!dialog) { dialog = sipe_dialog_add(session); dialog->callid = g_strdup(session->callid); dialog->with = g_strdup(session->im_mcu_uri); /* send INVITE to IM MCU */ sipe_im_invite(sipe_private, session, dialog->with, NULL, NULL, NULL, FALSE); } } sipe_process_pending_invite_queue(sipe_private, session); }
static void sipe_ews_process_avail_response(int return_code, const char *body, SIPE_UNUSED_PARAMETER const char *content_type, HttpConn *conn, void *data) { struct sipe_calendar *cal = data; SIPE_DEBUG_INFO_NOFORMAT("sipe_ews_process_avail_response: cb started."); if(!sipe_strequal(cal->as_url, cal->oof_url)) { /* whether reuse conn */ http_conn_set_close(conn); cal->http_conn = NULL; } if (return_code == 200 && body) { const sipe_xml *node; const sipe_xml *resp; /** ref: [MS-OXWAVLS] */ sipe_xml *xml = sipe_xml_parse(body, strlen(body)); /* Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/ResponseMessage@ResponseClass="Success" Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/FreeBusyView/MergedFreeBusy Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/FreeBusyView/CalendarEventArray/CalendarEvent Envelope/Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse/FreeBusyView/WorkingHours */ resp = sipe_xml_child(xml, "Body/GetUserAvailabilityResponse/FreeBusyResponseArray/FreeBusyResponse"); if (!resp) return; /* rather soap:Fault */ if (!sipe_strequal(sipe_xml_attribute(sipe_xml_child(resp, "ResponseMessage"), "ResponseClass"), "Success")) { return; /* Error response */ } /* MergedFreeBusy */ g_free(cal->free_busy); cal->free_busy = sipe_xml_data(sipe_xml_child(resp, "FreeBusyView/MergedFreeBusy")); /* WorkingHours */ node = sipe_xml_child(resp, "FreeBusyView/WorkingHours"); g_free(cal->working_hours_xml_str); cal->working_hours_xml_str = sipe_xml_stringify(node); SIPE_DEBUG_INFO("sipe_ews_process_avail_response: cal->working_hours_xml_str:\n%s", cal->working_hours_xml_str ? cal->working_hours_xml_str : ""); sipe_cal_events_free(cal->cal_events); cal->cal_events = NULL; /* CalendarEvents */ for (node = sipe_xml_child(resp, "FreeBusyView/CalendarEventArray/CalendarEvent"); node; node = sipe_xml_twin(node)) { char *tmp; /* <CalendarEvent> <StartTime>2009-12-07T13:30:00</StartTime> <EndTime>2009-12-07T14:30:00</EndTime> <BusyType>Busy</BusyType> <CalendarEventDetails> <ID>0000000...</ID> <Subject>Lunch</Subject> <Location>Cafe</Location> <IsMeeting>false</IsMeeting> <IsRecurring>true</IsRecurring> <IsException>false</IsException> <IsReminderSet>true</IsReminderSet> <IsPrivate>false</IsPrivate> </CalendarEventDetails> </CalendarEvent> */ struct sipe_cal_event *cal_event = g_new0(struct sipe_cal_event, 1); cal->cal_events = g_slist_append(cal->cal_events, cal_event); tmp = sipe_xml_data(sipe_xml_child(node, "StartTime")); cal_event->start_time = sipe_utils_str_to_time(tmp); g_free(tmp); tmp = sipe_xml_data(sipe_xml_child(node, "EndTime")); cal_event->end_time = sipe_utils_str_to_time(tmp); g_free(tmp); tmp = sipe_xml_data(sipe_xml_child(node, "BusyType")); if (sipe_strequal("Free", tmp)) { cal_event->cal_status = SIPE_CAL_FREE; } else if (sipe_strequal("Tentative", tmp)) { cal_event->cal_status = SIPE_CAL_TENTATIVE; } else if (sipe_strequal("Busy", tmp)) { cal_event->cal_status = SIPE_CAL_BUSY; } else if (sipe_strequal("OOF", tmp)) { cal_event->cal_status = SIPE_CAL_OOF; } else { cal_event->cal_status = SIPE_CAL_NO_DATA; } g_free(tmp); cal_event->subject = sipe_xml_data(sipe_xml_child(node, "CalendarEventDetails/Subject")); cal_event->location = sipe_xml_data(sipe_xml_child(node, "CalendarEventDetails/Location")); tmp = sipe_xml_data(sipe_xml_child(node, "CalendarEventDetails/IsMeeting")); cal_event->is_meeting = tmp ? sipe_strequal(tmp, "true") : TRUE; g_free(tmp); } sipe_xml_free(xml); cal->state = SIPE_EWS_STATE_AVAILABILITY_SUCCESS; sipe_ews_run_state_machine(cal); } else { if (return_code < 0) {
static void sipe_domino_process_calendar_response(int return_code, const char *body, const char *content_type, HttpConn *conn, void *data) { struct sipe_calendar *cal = data; SIPE_DEBUG_INFO_NOFORMAT("sipe_domino_process_calendar_response: cb started."); http_conn_set_close(conn); cal->http_conn = NULL; if (content_type && !g_str_has_prefix(content_type, "text/xml")) { cal->is_domino_disabled = TRUE; SIPE_DEBUG_INFO_NOFORMAT("sipe_domino_process_calendar_response: not XML, disabling."); return; } if (return_code == 200 && body) { const sipe_xml *node, *node2, *node3; sipe_xml *xml; SIPE_DEBUG_INFO("sipe_domino_process_calendar_response: SUCCESS, ret=%d", return_code); xml = sipe_xml_parse(body, strlen(body)); sipe_cal_events_free(cal->cal_events); cal->cal_events = NULL; /* viewentry */ for (node = sipe_xml_child(xml, "viewentry"); node; node = sipe_xml_twin(node)) { struct sipe_cal_event *cal_event = g_new0(struct sipe_cal_event, 1); cal->cal_events = g_slist_append(cal->cal_events, cal_event); cal_event->cal_status = SIPE_CAL_BUSY; cal_event->is_meeting = TRUE; /* SIPE_DEBUG_INFO("viewentry unid=%s", sipe_xml_attribute(node, "unid")); */ /* entrydata */ for (node2 = sipe_xml_child(node, "entrydata"); node2; node2 = sipe_xml_twin(node2)) { const char *name = sipe_xml_attribute(node2, "name"); SIPE_DEBUG_INFO("\tentrydata name=%s", name); if (sipe_strequal(name, VIEWENTITY_START0_TIME) || sipe_strequal(name, VIEWENTITY_START_TIME) || sipe_strequal(name, VIEWENTITY_END_TIME)) { char *tmp = sipe_xml_data(sipe_xml_child(node2, "datetime")); time_t time_val = sipe_utils_str_to_time(tmp); if (sipe_strequal(name, VIEWENTITY_START_TIME)) { cal_event->start_time = time_val; } else if (sipe_strequal(name, VIEWENTITY_END_TIME)) { cal_event->end_time = time_val; } SIPE_DEBUG_INFO("\t\tdatetime=%s", asctime(gmtime(&time_val))); g_free(tmp); } else if (sipe_strequal(name, VIEWENTITY_TEXT_LIST)) { int i = 0; /* test */ for (node3 = sipe_xml_child(node2, "textlist/text"); node3; node3 = sipe_xml_twin(node3)) { char *tmp = sipe_xml_data(node3); if (!tmp) continue; SIPE_DEBUG_INFO("\t\ttext=%s", tmp); if (i == 0) { cal_event->subject = g_strdup(tmp); SIPE_DEBUG_INFO("\t\t*Subj.=%s", tmp); } else { /* plain English, don't localize! */ if (!g_ascii_strncasecmp(tmp, "Location:", 9)) { if (strlen(tmp) > 9) { cal_event->location = g_strdup(g_strstrip(tmp+9)); SIPE_DEBUG_INFO("\t\t*Loc.=%s", cal_event->location); } /* Translators: (!) should be as in localized Lotus Notes to be able to extract meeting location */ } else if (g_str_has_prefix(tmp, _("Location:"))) { guint len = strlen(_("Location:")); if (strlen(tmp) > len) { cal_event->location = g_strdup(g_strstrip(tmp+len)); SIPE_DEBUG_INFO("\t\t*Loc.=%s", cal_event->location); } } } i++; g_free(tmp); } } } } sipe_xml_free(xml); /* creates FreeBusy from cal->cal_events */ g_free(cal->free_busy); cal->free_busy = sipe_domino_get_free_busy(cal->fb_start, cal->cal_events); /* update SIP server */ cal->is_updated = TRUE; if (cal->sip->ocs2007) { /* sipe.h */ publish_calendar_status_self(cal->sip->private, NULL); } else {
void process_incoming_message(struct sipe_core_private *sipe_private, struct sipmsg *msg) { gchar *from; const gchar *contenttype; gboolean found = FALSE; from = parse_from(sipmsg_find_header(msg, "From")); if (!from) return; SIPE_DEBUG_INFO("got message from %s: %s", from, msg->body); contenttype = sipmsg_find_header(msg, "Content-Type"); if (g_str_has_prefix(contenttype, "text/plain") || g_str_has_prefix(contenttype, "text/html") || g_str_has_prefix(contenttype, "multipart/related") || g_str_has_prefix(contenttype, "multipart/alternative")) { const gchar *callid = sipmsg_find_header(msg, "Call-ID"); gchar *html = get_html_message(contenttype, msg->body); struct sip_session *session = sipe_session_find_chat_or_im(sipe_private, callid, from); if (session && session->chat_session) { if (session->chat_session->type == SIPE_CHAT_TYPE_CONFERENCE) { /* a conference */ gchar *tmp = parse_from(sipmsg_find_header(msg, "Ms-Sender")); gchar *sender = parse_from(tmp); g_free(tmp); sipe_backend_chat_message(SIPE_CORE_PUBLIC, session->chat_session->backend, sender, 0, html); g_free(sender); } else { /* a multiparty chat */ sipe_backend_chat_message(SIPE_CORE_PUBLIC, session->chat_session->backend, from, 0, html); } } else { sipe_backend_im_message(SIPE_CORE_PUBLIC, from, html); } g_free(html); sip_transport_response(sipe_private, msg, 200, "OK", NULL); found = TRUE; } else if (g_str_has_prefix(contenttype, "application/im-iscomposing+xml")) { sipe_xml *isc = sipe_xml_parse(msg->body, msg->bodylen); const sipe_xml *state; gchar *statedata; if (!isc) { SIPE_DEBUG_INFO_NOFORMAT("process_incoming_message: can not parse iscomposing"); g_free(from); return; } state = sipe_xml_child(isc, "state"); if (!state) { SIPE_DEBUG_INFO_NOFORMAT("process_incoming_message: no state found"); sipe_xml_free(isc); g_free(from); return; } statedata = sipe_xml_data(state); if (statedata) { if (strstr(statedata, "active")) { sipe_backend_user_feedback_typing(SIPE_CORE_PUBLIC, from); } else { sipe_backend_user_feedback_typing_stop(SIPE_CORE_PUBLIC, from); } g_free(statedata); } sipe_xml_free(isc); sip_transport_response(sipe_private, msg, 200, "OK", NULL); found = TRUE; } else if (g_str_has_prefix(contenttype, "text/x-msmsgsinvite")) { const gchar *callid = sipmsg_find_header(msg, "Call-ID"); struct sip_session *session = sipe_session_find_chat_or_im(sipe_private, callid, from); if (session) { struct sip_dialog *dialog = sipe_dialog_find(session, from); GSList *body = sipe_ft_parse_msg_body(msg->body); found = sipe_process_incoming_x_msmsgsinvite(sipe_private, dialog, body); sipe_utils_nameval_free(body); if (found) { sip_transport_response(sipe_private, msg, 200, "OK", NULL); } } else { sip_transport_response(sipe_private, msg, 481, "Call Leg/Transaction Does Not Exist", NULL); found = TRUE; } } if (!found) { const gchar *callid = sipmsg_find_header(msg, "Call-ID"); struct sip_session *session = sipe_session_find_chat_or_im(sipe_private, callid, from); if (session) { gchar *errmsg = g_strdup_printf(_("Received a message with unrecognized contents from %s"), from); sipe_user_present_error(sipe_private, session, errmsg); g_free(errmsg); } SIPE_DEBUG_INFO("got unknown mime-type '%s'", contenttype); sip_transport_response(sipe_private, msg, 415, "Unsupported media type", NULL); } g_free(from); }