www.pudn.com > exosip.rar > jsubscriptions.cpp
/* * josua - Jack's open sip User Agent * * Copyright (C) 2002,2003 Aymeric Moizard* * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with dpkg; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "stdafx.h" #include "jsubscriptions.h" jsubscription_t jsubscriptions[MAX_NUMBER_OF_SUBSCRIPTIONS]; static int ___jsubscription_init = 0; static int jsubscriptions_set_presence_status (jsubscription_t * ca, eXosip_event_t * je); static void __jsubscription_init () { int k; for (k = 0; k < MAX_NUMBER_OF_SUBSCRIPTIONS; k++) { memset (&(jsubscriptions[k]), 0, sizeof (jsubscription_t)); jsubscriptions[k].state = NOT_USED; } } int jsubscriptions_set_presence_status (jsubscription_t * ca, eXosip_event_t * je) { osip_content_type_t *ctype; osip_body_t *body = NULL; if (je->ss_status == EXOSIP_SUBCRSTATE_TERMINATED) { ca->online_status = EXOSIP_NOTIFY_UNKNOWN; /* isn't it unknown? */ return 0; } if (je->ss_status == EXOSIP_SUBCRSTATE_PENDING) { ca->online_status = EXOSIP_NOTIFY_PENDING; return 0; } ctype = osip_message_get_content_type (je->request); if (ctype == NULL || ctype->type == NULL || ctype->subtype == NULL) { return -1; /* missing body */ } osip_message_get_body (je->request, 0, &body); if (body == NULL) { return -1; } /* first test interop with MSN */ if (0 == osip_strcasecmp (ctype->type, "application") && 0 == osip_strcasecmp (ctype->subtype, "xpidf+xml")) { /* search for the open string */ char *tmp = body->body; while (tmp[0] != '\0') { if (tmp[0] == 'o' && 0 == strncmp (tmp, "online", 6)) { ca->online_status = EXOSIP_NOTIFY_ONLINE; /* search for the contact entry */ while (tmp[0] != '\0') { if (tmp[0] == 'c' && 0 == strncmp (tmp, "contact", 7)) { /* ... */ } tmp++; } break; } else if (tmp[0] == 'b' && 0 == strncmp (tmp, "busy", 4)) { ca->online_status = EXOSIP_NOTIFY_BUSY; break; } else if (tmp[0] == 'b' && 0 == strncmp (tmp, "berightback", 11)) { ca->online_status = EXOSIP_NOTIFY_BERIGHTBACK; break; } else if (tmp[0] == 'a' && 0 == strncmp (tmp, "away", 4)) { ca->online_status = EXOSIP_NOTIFY_AWAY; break; } else if (tmp[0] == 'o' && 0 == strncmp (tmp, "onthephone", 10)) { ca->online_status = EXOSIP_NOTIFY_ONTHEPHONE; break; } else if (tmp[0] == 'o' && 0 == strncmp (tmp, "outtolunch", 10)) { ca->online_status = EXOSIP_NOTIFY_OUTTOLUNCH; break; } tmp++; } } else if (0 == osip_strcasecmp (ctype->type, "application") && 0 == osip_strcasecmp (ctype->subtype, "pidf+xml")) { /* latest rfc! */ /* search for the open string */ char *tmp = body->body; while (tmp[0] != '\0') { if (tmp[0] == 'o' && 0 == osip_strncasecmp (tmp, "open", 4)) { ca->online_status = EXOSIP_NOTIFY_ONLINE; /* search for the contact entry */ while (tmp[0] != '\0') { if (tmp[0] == 'a' && 0 == osip_strncasecmp (tmp, "away", 4)) ca->online_status = EXOSIP_NOTIFY_AWAY; else if (tmp[0] == 'm' && 0 == osip_strncasecmp (tmp, "meal", 4)) ca->online_status = EXOSIP_NOTIFY_OUTTOLUNCH; else if (tmp[0] == 'i' && 0 == osip_strncasecmp (tmp, "in-transit", 10)) ca->online_status = EXOSIP_NOTIFY_BERIGHTBACK; else if (tmp[0] == 'b' && 0 == osip_strncasecmp (tmp, "busy", 4)) ca->online_status = EXOSIP_NOTIFY_BUSY; else if (tmp[0] == 'o' && 0 == osip_strncasecmp (tmp, "on-the-phone", 12)) ca->online_status = EXOSIP_NOTIFY_ONTHEPHONE; if (tmp[0] == '/' && 0 == osip_strncasecmp (tmp, "/status", 7)) break; if (ca->online_status != EXOSIP_NOTIFY_ONLINE) break; tmp++; } while (tmp[0] != '\0') { if (tmp[0] == 'c' && 0 == osip_strncasecmp (tmp, "contact", 7)) { /* ... */ } tmp++; } break; } else if (tmp[0] == 'c' && 0 == osip_strncasecmp (tmp, "closed", 6)) { ca->online_status = EXOSIP_NOTIFY_CLOSED; break; } tmp++; } } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Unknown body: %s/%s\n", ctype->type, ctype->subtype)); return -1; } return 0; } int jsubscription_get_number_of_pending_subscriptions () { int pos = 0; int k; for (k = 0; k < MAX_NUMBER_OF_SUBSCRIPTIONS; k++) { if (jsubscriptions[k].state != NOT_USED) { pos++; } } return pos; } jsubscription_t * jsubscription_find_subscription (int pos) { int k; for (k = 0; k < MAX_NUMBER_OF_SUBSCRIPTIONS; k++) { if (jsubscriptions[k].state != NOT_USED) { if (pos == 0) return &(jsubscriptions[k]); pos--; } } return NULL; } int jsubscription_new (eXosip_event_t * je) { jsubscription_t *ca; int k; if (___jsubscription_init == 0) { ___jsubscription_init = -1; __jsubscription_init (); } for (k = 0; k < MAX_NUMBER_OF_SUBSCRIPTIONS; k++) { if (jsubscriptions[k].state == NOT_USED) break; } if (k == MAX_NUMBER_OF_SUBSCRIPTIONS) return -1; ca = &(jsubscriptions[k]); memset (&(jsubscriptions[k]), 0, sizeof (jsubscription_t)); ca->sid = je->sid; ca->did = je->did; if (ca->did < 1 && ca->did < 1) { exit (0); return -1; /* not enough information for this event?? */ } ca->online_status = EXOSIP_NOTIFY_UNKNOWN; ca->ss_status = je->ss_status; ca->ss_reason = je->ss_reason; osip_strncpy (ca->textinfo, je->textinfo, 255); if (je->response != NULL) { ca->status_code = je->response->status_code; _snprintf (ca->reason_phrase, 50, je->response->reason_phrase); } if (je->request != NULL) { char *tmp = NULL; osip_from_to_str (je->request->to, &tmp); if (tmp != NULL) { _snprintf (ca->remote_uri, 256, "%s", tmp); osip_free (tmp); } } ca->state = je->type; return 0; } int jsubscription_remove (jsubscription_t * ca) { if (ca == NULL) return -1; ca->state = NOT_USED; return 0; } int jsubscription_proceeding (eXosip_event_t * je) { jsubscription_t *ca; int k; for (k = 0; k < MAX_NUMBER_OF_SUBSCRIPTIONS; k++) { if (jsubscriptions[k].state != NOT_USED && jsubscriptions[k].sid == je->sid && jsubscriptions[k].did == je->did) break; } if (k == MAX_NUMBER_OF_SUBSCRIPTIONS) { for (k = 0; k < MAX_NUMBER_OF_SUBSCRIPTIONS; k++) { if (jsubscriptions[k].state == NOT_USED) break; } if (k == MAX_NUMBER_OF_SUBSCRIPTIONS) return -1; ca = &(jsubscriptions[k]); memset (&(jsubscriptions[k]), 0, sizeof (jsubscription_t)); ca->sid = je->sid; ca->did = je->did; if (ca->did < 1 && ca->did < 1) { exit (0); return -1; /* not enough information for this event?? */ } } ca = &(jsubscriptions[k]); ca->online_status = EXOSIP_NOTIFY_UNKNOWN; ca->ss_status = je->ss_status; ca->ss_reason = je->ss_reason; osip_strncpy (ca->textinfo, je->textinfo, 255); if (je->response != NULL) { ca->status_code = je->response->status_code; _snprintf (ca->reason_phrase, 50, je->response->reason_phrase); } if (je->request != NULL) { char *tmp = NULL; osip_to_to_str (je->request->to, &tmp); if (tmp != NULL) { _snprintf (ca->remote_uri, 256, "%s", tmp); osip_free (tmp); } } ca->state = je->type; return 0; } int jsubscription_answered (eXosip_event_t * je) { jsubscription_t *ca; int k; for (k = 0; k < MAX_NUMBER_OF_SUBSCRIPTIONS; k++) { if (jsubscriptions[k].state != NOT_USED && jsubscriptions[k].sid == je->sid && jsubscriptions[k].did == je->did) break; } if (k == MAX_NUMBER_OF_SUBSCRIPTIONS) { for (k = 0; k < MAX_NUMBER_OF_SUBSCRIPTIONS; k++) { if (jsubscriptions[k].state == NOT_USED) break; } if (k == MAX_NUMBER_OF_SUBSCRIPTIONS) return -1; ca = &(jsubscriptions[k]); memset (&(jsubscriptions[k]), 0, sizeof (jsubscription_t)); ca->sid = je->sid; ca->did = je->did; if (ca->did < 1 && ca->did < 1) { exit (0); return -1; /* not enough information for this event?? */ } ca = &(jsubscriptions[k]); ca->online_status = EXOSIP_NOTIFY_UNKNOWN; } ca = &(jsubscriptions[k]); ca->ss_status = je->ss_status; ca->ss_reason = je->ss_reason; osip_strncpy (ca->textinfo, je->textinfo, 255); if (je->response != NULL) { ca->status_code = je->response->status_code; _snprintf (ca->reason_phrase, 50, je->response->reason_phrase); } if (je->request != NULL) { char *tmp = NULL; osip_to_to_str (je->request->to, &tmp); if (tmp != NULL) { _snprintf (ca->remote_uri, 256, "%s", tmp); osip_free (tmp); } } ca->state = je->type; return 0; } int jsubscription_redirected (eXosip_event_t * je) { jsubscription_t *ca; int k; for (k = 0; k < MAX_NUMBER_OF_SUBSCRIPTIONS; k++) { if (jsubscriptions[k].state != NOT_USED && jsubscriptions[k].sid == je->sid && jsubscriptions[k].did == je->did) break; } if (k == MAX_NUMBER_OF_SUBSCRIPTIONS) return -1; ca = &(jsubscriptions[k]); ca->ss_status = je->ss_status; ca->ss_reason = je->ss_reason; if (je->response != NULL) { ca->status_code = je->response->status_code; _snprintf (ca->reason_phrase, 50, je->response->reason_phrase); } if (je->request != NULL) { char *tmp = NULL; osip_to_to_str (je->request->to, &tmp); if (tmp != NULL) { _snprintf (ca->remote_uri, 256, "%s", tmp); osip_free (tmp); } } ca->state = NOT_USED; return 0; } int jsubscription_requestfailure (eXosip_event_t * je) { jsubscription_t *ca; int k; for (k = 0; k < MAX_NUMBER_OF_SUBSCRIPTIONS; k++) { if (jsubscriptions[k].state != NOT_USED && jsubscriptions[k].sid == je->sid && jsubscriptions[k].did == je->did) break; } if ((je->response != NULL && je->response->status_code == 407) || (je->response != NULL && je->response->status_code == 401)) { /* try authentication */ return 0; } if (k == MAX_NUMBER_OF_SUBSCRIPTIONS) return -1; ca = &(jsubscriptions[k]); ca->ss_status = je->ss_status; ca->ss_reason = je->ss_reason; if (je->response != NULL) { ca->status_code = je->response->status_code; _snprintf (ca->reason_phrase, 50, je->response->reason_phrase); } if (je->request != NULL) { char *tmp = NULL; osip_to_to_str (je->request->to, &tmp); if (tmp != NULL) { _snprintf (ca->remote_uri, 256, "%s", tmp); osip_free (tmp); } } ca->state = NOT_USED; return 0; } int jsubscription_serverfailure (eXosip_event_t * je) { jsubscription_t *ca; int k; for (k = 0; k < MAX_NUMBER_OF_SUBSCRIPTIONS; k++) { if (jsubscriptions[k].state != NOT_USED && jsubscriptions[k].sid == je->sid && jsubscriptions[k].did == je->did) break; } if (k == MAX_NUMBER_OF_SUBSCRIPTIONS) return -1; ca = &(jsubscriptions[k]); ca->ss_status = je->ss_status; ca->ss_reason = je->ss_reason; if (je->response != NULL) { ca->status_code = je->response->status_code; _snprintf (ca->reason_phrase, 50, je->response->reason_phrase); } if (je->request != NULL) { char *tmp = NULL; osip_to_to_str (je->request->to, &tmp); if (tmp != NULL) { _snprintf (ca->remote_uri, 256, "%s", tmp); osip_free (tmp); } } ca->state = NOT_USED; return 0; } int jsubscription_globalfailure (eXosip_event_t * je) { jsubscription_t *ca; int k; for (k = 0; k < MAX_NUMBER_OF_SUBSCRIPTIONS; k++) { if (jsubscriptions[k].state != NOT_USED && jsubscriptions[k].sid == je->sid && jsubscriptions[k].did == je->did) break; } if (k == MAX_NUMBER_OF_SUBSCRIPTIONS) return -1; ca = &(jsubscriptions[k]); ca->ss_status = je->ss_status; ca->ss_reason = je->ss_reason; if (je->response != NULL) { ca->status_code = je->response->status_code; _snprintf (ca->reason_phrase, 50, je->response->reason_phrase); } if (je->request != NULL) { char *tmp = NULL; osip_to_to_str (je->request->to, &tmp); if (tmp != NULL) { _snprintf (ca->remote_uri, 256, "%s", tmp); osip_free (tmp); } } ca->state = NOT_USED; return 0; } int jsubscription_notify (eXosip_event_t * je) { jsubscription_t *ca; int k; for (k = 0; k < MAX_NUMBER_OF_SUBSCRIPTIONS; k++) { if (jsubscriptions[k].state != NOT_USED && jsubscriptions[k].sid == je->sid && jsubscriptions[k].did == je->did) break; } if (k == MAX_NUMBER_OF_SUBSCRIPTIONS) { for (k = 0; k < MAX_NUMBER_OF_SUBSCRIPTIONS; k++) { if (jsubscriptions[k].state == NOT_USED) break; } if (k == MAX_NUMBER_OF_SUBSCRIPTIONS) return -1; ca = &(jsubscriptions[k]); memset (&(jsubscriptions[k]), 0, sizeof (jsubscription_t)); ca->sid = je->sid; ca->did = je->did; if (ca->did < 1 && ca->did < 1) { exit (0); return -1; /* not enough information for this event?? */ } } ca = &(jsubscriptions[k]); ca->online_status = EXOSIP_NOTIFY_UNKNOWN; ca->ss_status = je->ss_status; ca->ss_reason = je->ss_reason; osip_strncpy (ca->textinfo, je->textinfo, 255); ca->state = je->type; jsubscriptions_set_presence_status (ca, je); return 0; } int jsubscription_closed (eXosip_event_t * je) { jsubscription_t *ca; int k; for (k = 0; k < MAX_NUMBER_OF_SUBSCRIPTIONS; k++) { if (jsubscriptions[k].state != NOT_USED && jsubscriptions[k].sid == je->sid) break; } if (k == MAX_NUMBER_OF_SUBSCRIPTIONS) return -1; ca = &(jsubscriptions[k]); ca->ss_status = je->ss_status; ca->ss_reason = je->ss_reason; ca->state = NOT_USED; return 0; }