コード例 #1
0
ファイル: xjab_presence.c プロジェクト: 4N7HR4X/kamailio
/**
 * delete a user from presence list
 */
int xj_pres_list_del(xj_pres_list prl, str *uid)
{
	xj_pres_cell p;
	int lkey;
	if(!prl || !uid || !uid->s || uid->len<=0)
		return -1;
	if(prl->nr<=0 || prl->clist==NULL)
		return 0;
	
	lkey = xj_get_hash(uid, NULL);

	p = prl->clist;
	while(p && p->key <= lkey)
	{
		if(p->key == lkey && p->userid.len == uid->len
			&& !strncasecmp(p->userid.s, uid->s, uid->len))
		{
			prl->nr--;
			if(p->next)
				p->next->prev = p->prev;
			if(p->prev == NULL)
				prl->clist = p->next;
			else
				p->prev->next = p->next;
			xj_pres_cell_free(p);
			return 0;
		}
		p = p->next;
	}

	return 0;
}
コード例 #2
0
ファイル: xjab_presence.c プロジェクト: 4N7HR4X/kamailio
/**
 * add, if does not exist, an user in present list
 */
xj_pres_cell xj_pres_list_add(xj_pres_list prl, xj_pres_cell prc)
{
	xj_pres_cell p, p0;
	if(!prc)
		return NULL;
	if(!prl)
	{
		xj_pres_cell_free(prc);
		return NULL;
	}
	// presence list empty
	if(prl->clist==NULL)
	{
		prl->nr++;
		prl->clist = prc;
		return prc;
	}

	p0 = p = prl->clist;
	while(p && p->key <= prc->key)
	{
		if(p->key == prc->key && p->userid.len == prc->userid.len
			&& !strncasecmp(p->userid.s, prc->userid.s, p->userid.len))
		{ // cell already exist
			// update cbf and cbp
			p->cbf = prc->cbf;
			p->cbp = prc->cbp;
			xj_pres_cell_free(prc);
			return p;
		}
		p0 = p;
		p = p->next;
	}

	// add a the cell in list
	prc->next = p0->next;
	prc->prev = p0;
	if(p0->next)
		p0->next->prev = prc;
	p0->next = prc;
	prl->nr++;

	return prc;
}
コード例 #3
0
ファイル: xjab_presence.c プロジェクト: 4N7HR4X/kamailio
/**
 * free all presence cell linked to
 */
void xj_pres_cell_free_all(xj_pres_cell prc)
{
	xj_pres_cell p, p0;
	if(!prc)
		return;
	p = prc;
	while(p)
	{
		p0 = p->next;
		xj_pres_cell_free(p);
		p = p0;
	}
}
コード例 #4
0
ファイル: xjab_worker.c プロジェクト: x-talker/imscore
/**
 * parse incoming message from Jabber server
 */
int xj_manage_jab(char *buf, int len, int *pos, xj_jalias als, xj_jcon jbc)
{
    int j, err=0;
    char *p, *to, *from, *msg, *type, *emsg, *ecode, lbuf[4096], fbuf[128];
    xj_jconf jcf = NULL;
    str ts, tf;
    xode x, y, z;
    str *sid;
    xj_pres_cell prc = NULL;

    if(!jbc)
        return -1;

    sid = jbc->jkey->id;
    x = xode_from_strx(buf, len, &err, &j);
#ifdef XJ_EXTRA_DEBUG
    DBG("XJAB:xj_parse_jab: XODE ret:%d pos:%d\n", err, j);
#endif
    if(err && pos != NULL)
        *pos= j;
    if(x == NULL)
        return -1;
    lbuf[0] = 0;
    ecode = NULL;

    /******************** XMPP 'MESSAGE' HANDLING **********************/

    if(!strncasecmp(xode_get_name(x), "message", 7))
    {
#ifdef XJ_EXTRA_DEBUG
        DBG("XJAB:xj_manage_jab: jabber [message] received\n");
#endif
        if((to = xode_get_attrib(x, "to")) == NULL)
        {
#ifdef XJ_EXTRA_DEBUG
            DBG("XJAB:xj_manage_jab: missing 'to' attribute\n");
#endif
            err = -1;
            goto ready;
        }
        if((from = xode_get_attrib(x, "from")) == NULL)
        {
#ifdef XJ_EXTRA_DEBUG
            DBG("XJAB:xj_manage_jab: missing 'from' attribute\n");
#endif
            err = -1;
            goto ready;
        }
        if((y = xode_get_tag(x, "body")) == NULL
                || (msg = xode_get_data(y)) == NULL)
        {
#ifdef XJ_EXTRA_DEBUG
            DBG("XJAB:xj_manage_jab: missing 'body' of message\n");
#endif
            err = -1;
            goto ready;
        }
        type = xode_get_attrib(x, "type");
        if(type != NULL && !strncasecmp(type, "error", 5))
        {
            if((y = xode_get_tag(x, "error")) == NULL
                    || (emsg = xode_get_data(y)) == NULL)
                strcpy(lbuf, "{Error sending following message} - ");
            else
            {
                ecode = xode_get_attrib(y, "code");
                strcpy(lbuf, "{Error (");
                if(ecode != NULL)
                {
                    strcat(lbuf, ecode);
                    strcat(lbuf, " - ");
                }
                strcat(lbuf, emsg);
                strcat(lbuf, ") when trying to send following message}");
            }

        }

        // is from a conference?!?!
        if((jcf=xj_jcon_check_jconf(jbc, from))!=NULL)
        {
            if(lbuf[0] == 0)
            {
                p = from + strlen(from);
                while(p>from && *p != '/')
                    p--;
                if(*p == '/')
                {
                    if(jcf->nick.len>0
                            && strlen(p+1) == jcf->nick.len
                            && !strncasecmp(p+1, jcf->nick.s, jcf->nick.len))
                    {
#ifdef XJ_EXTRA_DEBUG
                        DBG("XJAB:xj_manage_jab: message sent by myself\n");
#endif
                        goto ready;
                    }
                    lbuf[0] = '[';
                    lbuf[1] = 0;
                    strcat(lbuf, p+1);
                    strcat(lbuf, "] ");
                }
            }
            else
            {
                jcf->status = XJ_JCONF_NULL;
                xj_jcon_jconf_presence(jbc,jcf,NULL,"online");
            }
            strcat(lbuf, msg);
            ts.s = lbuf;
            ts.len = strlen(lbuf);

            if(xj_send_sip_msg(als->proxy, sid, &jcf->uri, &ts,
                               &jbc->jkey->flag)<0)
                DBG("XJAB:xj_manage_jab: ERROR SIP MESSAGE was not sent!\n");
#ifdef XJ_EXTRA_DEBUG
            else
                DBG("XJAB:xj_manage_jab: SIP MESSAGE was sent!\n");
#endif
            goto ready;
        }

        strcat(lbuf, msg);
        ts.s = from;
        ts.len = strlen(from);
        tf.s = fbuf;
        tf.len = 0;
        if(xj_address_translation(&ts, &tf, als, XJ_ADDRTR_J2S) == 0)
        {
            ts.s = lbuf;
            ts.len = strlen(lbuf);

            if(xj_send_sip_msg(als->proxy, sid, &tf, &ts, &jbc->jkey->flag)<0)
                DBG("XJAB:xj_manage_jab: ERROR SIP MESSAGE was not sent ...\n");
#ifdef XJ_EXTRA_DEBUG
            else
                DBG("XJAB:xj_manage_jab: SIP MESSAGE was sent.\n");
#endif
        }
        goto ready;
    }
    /*------------------- END 'MESSAGE' HANDLING ----------------------*/

    /******************** XMPP 'PRESENCE' HANDLING *********************/
    if(!strncasecmp(xode_get_name(x), "presence", 8))
    {
#ifdef XJ_EXTRA_DEBUG
        DBG("XJAB:xj_manage_jab: jabber [presence] received\n");
#endif
        type = xode_get_attrib(x, "type");
        from = xode_get_attrib(x, "from");
        if(from == NULL)
            goto ready;
        ts.s = from;
        p = from;
        while(p<from + strlen(from) && *p != '/')
            p++;
        if(*p == '/')
            ts.len = p - from;
        else
            ts.len = strlen(from);

        if(type == NULL || !strncasecmp(type, "online", 6)
                || !strncasecmp(type, "available", 9))
        {
            if(strchr(from, '@') == NULL)
            {
                if(!strncasecmp(from, XJ_AIM_NAME, XJ_AIM_LEN))
                {
                    jbc->ready |= XJ_NET_AIM;
#ifdef XJ_EXTRA_DEBUG
                    DBG("XJAB:xj_manage_jab: AIM network ready\n");
#endif
                }
                else if(!strncasecmp(from, XJ_ICQ_NAME, XJ_ICQ_LEN))
                {
                    jbc->ready |= XJ_NET_ICQ;
#ifdef XJ_EXTRA_DEBUG
                    DBG("XJAB:xj_manage_jab: ICQ network ready\n");
#endif
                }
                else if(!strncasecmp(from, XJ_MSN_NAME, XJ_MSN_LEN))
                {
                    jbc->ready |= XJ_NET_MSN;
#ifdef XJ_EXTRA_DEBUG
                    DBG("XJAB:xj_manage_jab: MSN network ready\n");
#endif
                }
                else if(!strncasecmp(from, XJ_YAH_NAME, XJ_YAH_LEN))
                {
                    jbc->ready |= XJ_NET_YAH;
#ifdef XJ_EXTRA_DEBUG
                    DBG("XJAB:xj_manage_jab: YAHOO network ready\n");
#endif
                }
            }
            else if((jcf=xj_jcon_check_jconf(jbc, from))!=NULL)
            {
                jcf->status = XJ_JCONF_READY;
#ifdef XJ_EXTRA_DEBUG
                DBG("XJAB:xj_manage_jab: %s conference ready\n", from);
#endif
            }
            else
            {
#ifdef XJ_EXTRA_DEBUG
                DBG("XJAB:xj_manage_jab: user <%.*s> is online\n",ts.len,ts.s);
#endif
                prc = xj_pres_list_check(jbc->plist, &ts);
                if(prc)
                {
                    if(prc->state != XJ_PS_ONLINE)
                    {
                        prc->state = XJ_PS_ONLINE;
                        goto call_pa_cbf;
                    }
                }
                else
                {
#ifdef XJ_EXTRA_DEBUG
                    DBG("XJAB:xj_manage_jab: user state received - creating"
                        " presence cell for [%.*s]\n", ts.len, ts.s);
#endif
                    prc = xj_pres_cell_new();
                    if(prc == NULL)
                    {
                        DBG("XJAB:xj_manage_jab: cannot create presence"
                            " cell for [%s]\n", from);
                        goto ready;
                    }
                    if(xj_pres_cell_init(prc, &ts, NULL, NULL)<0)
                    {
                        DBG("XJAB:xj_manage_jab: cannot init presence"
                            " cell for [%s]\n", from);
                        xj_pres_cell_free(prc);
                        goto ready;
                    }
                    prc = xj_pres_list_add(jbc->plist, prc);
                    if(prc)
                    {
                        prc->state = XJ_PS_ONLINE;
                        goto call_pa_cbf;
                    }
                }
            }
            goto ready;
        }

        if(strchr(from, '@') == NULL)
            goto ready;


        if(!strncasecmp(type, "error", 5))
        {
            if((jcf=xj_jcon_check_jconf(jbc, from))!=NULL)
            {
                tf.s = from;
                tf.len = strlen(from);
                if((y = xode_get_tag(x, "error")) == NULL)
                    goto ready;
                if ((p = xode_get_attrib(y, "code")) != NULL
                        && atoi(p) == 409)
                {
                    xj_send_sip_msgz(als->proxy, sid, &tf,
                                     XJ_DMSG_ERR_JCONFNICK, &jbc->jkey->flag);
                    goto ready;
                }
                xj_send_sip_msgz(als->proxy,sid,&tf,XJ_DMSG_ERR_JCONFREFUSED,
                                 &jbc->jkey->flag);
            }
            goto ready;
        }
        if(type!=NULL && !strncasecmp(type, "subscribe", 9))
        {
            xj_jcon_send_presence(jbc, from, "subscribed", NULL, NULL);
            goto ready;
        }

        prc = xj_pres_list_check(jbc->plist, &ts);
        if(!prc)
            goto ready;

        if(!strncasecmp(type, "unavailable", 11))
        {
#ifdef XJ_EXTRA_DEBUG
            DBG("XJAB:xj_manage_jab: user <%s> is offline\n", from);
#endif
            if(prc->state != XJ_PS_OFFLINE)
            {
                prc->state = XJ_PS_OFFLINE;
                goto call_pa_cbf;
            }
            goto ready;
        }

        if(!strncasecmp(type, "unsubscribed", 12))
        {
#ifdef XJ_EXTRA_DEBUG
            DBG("XJAB:xj_manage_jab: user <%s> does not allow to see his"
                " presence status\n", from);
#endif
            if(prc->state != XJ_PS_REFUSED)
            {
                prc->state = XJ_PS_REFUSED;
                goto call_pa_cbf;
            }
        }

        // ignoring unknown types
        goto ready;
    }
    /*------------------- END XMPP 'PRESENCE' HANDLING ----------------*/

    /******************** XMPP 'IQ' HANDLING ***************************/
    if(!strncasecmp(xode_get_name(x), "iq", 2))
    {
#ifdef XJ_EXTRA_DEBUG
        DBG("XJAB:xj_manage_jab: jabber [iq] received\n");
#endif
        if(!strncasecmp(xode_get_attrib(x, "type"), "result", 6))
        {
            if((y = xode_get_tag(x, "query?xmlns=jabber:iq:roster")) == NULL)
                goto ready;
            z = xode_get_firstchild(y);
            while(z)
            {
                if(!strncasecmp(xode_get_name(z), "item", 5)
                        && (from = xode_get_attrib(z, "jid")) != NULL)
                {
                    if(strchr(from, '@') == NULL)
                    {   // transports
                        if(!strncasecmp(from, XJ_AIM_NAME, XJ_AIM_LEN))
                        {
                            jbc->allowed |= XJ_NET_AIM;
#ifdef XJ_EXTRA_DEBUG
                            DBG("XJAB:xj_manage_jab:AIM network available\n");
#endif
                        }
                        else if(!strncasecmp(from, XJ_ICQ_NAME, XJ_ICQ_LEN))
                        {
                            jbc->allowed |= XJ_NET_ICQ;
#ifdef XJ_EXTRA_DEBUG
                            DBG("XJAB:xj_manage_jab:ICQ network available\n");
#endif
                        }
                        else if(!strncasecmp(from, XJ_MSN_NAME, XJ_MSN_LEN))
                        {
                            jbc->allowed |= XJ_NET_MSN;
#ifdef XJ_EXTRA_DEBUG
                            DBG("XJAB:xj_manage_jab:MSN network available\n");
#endif
                        }
                        else if(!strncasecmp(from, XJ_YAH_NAME, XJ_YAH_LEN))
                        {
                            jbc->allowed |= XJ_NET_YAH;
#ifdef XJ_EXTRA_DEBUG
                            DBG("XJAB:xj_manage_jab:YAHOO network available\n");
#endif
                        }
                        goto next_sibling;
                    }
                }
next_sibling:
                z = xode_get_nextsibling(z);
            }
        }

        goto ready;
    }
    /*------------------- END XMPP 'IQ' HANDLING ----------------------*/

call_pa_cbf:
    if(prc && prc->cbf)
    {
        // call the PA callback function
        tf.s = fbuf;
        tf.len = 0;
        if(xj_address_translation(&ts,&tf,als,XJ_ADDRTR_J2S)==0)
        {
#ifdef XJ_EXTRA_DEBUG
            DBG("XJAB:xj_manage_jab: calling CBF(%.*s,%d)\n",
                tf.len, tf.s, prc->state);
#endif
            (*(prc->cbf))(&tf, &tf, prc->state, prc->cbp);
        }
    }
ready:
    xode_free(x);
    return err;
}
コード例 #5
0
ファイル: xjab_worker.c プロジェクト: x-talker/imscore
/**
 * update or register a presence watcher
 */
void xj_worker_check_watcher(xj_wlist jwl, xj_jcon_pool jcp,
                             xj_jcon jbc, xj_sipmsg jsmsg)
{
    str sto;
    char buff[1024];
    xj_pres_cell prc = NULL;

    if(!jwl || !jcp || !jbc || !jsmsg)
        return;

    if(!jsmsg->cbf)
    {
#ifdef XJ_EXTRA_DEBUG
        DBG("XJAB:xj_worker_check_watcher:%d: NULL PA callback"
            " function\n", _xj_pid);
#endif
        return;
    }

    if(!xj_jconf_check_addr(&jsmsg->to, jwl->aliases->dlm))
    {   // is for a conference - ignore?!?!
#ifdef XJ_EXTRA_DEBUG
        DBG("XJAB:xj_worker_check_watcher:%d: presence request for a"
            " conference.\n", _xj_pid);
#endif
        // set as offline
        (*(jsmsg->cbf))(&jsmsg->to, &jsmsg->to, XJ_PS_OFFLINE, jsmsg->p);
        return;
    }

    sto.s = buff;
    sto.len = 0;

    if(xj_address_translation(&jsmsg->to, &sto, jwl->aliases,
                              XJ_ADDRTR_S2J) == 0)
    {
        prc = xj_pres_list_check(jbc->plist, &sto);
        if(!prc)
        {
#ifdef XJ_EXTRA_DEBUG
            DBG("XJAB:xj_worker_check_watcher:%d: NEW presence"
                " cell for %.*s.\n", _xj_pid, sto.len, sto.s);
#endif
            prc = xj_pres_cell_new();
            if(!prc)
            {
                DBG("XJAB:xj_worker_check_watcher:%d: cannot create a presence"
                    " cell for %.*s.\n", _xj_pid, sto.len, sto.s);
                return;
            }
            if(xj_pres_cell_init(prc, &sto, jsmsg->cbf, jsmsg->p)<0)
            {
                DBG("XJAB:xj_worker_check_watcher:%d: cannot init the presence"
                    " cell for %.*s.\n", _xj_pid, sto.len, sto.s);
                xj_pres_cell_free(prc);
                return;
            }
            if((prc = xj_pres_list_add(jbc->plist, prc))==NULL)
            {
                DBG("XJAB:xj_worker_check_watcher:%d: cannot add the presence"
                    " cell for %.*s.\n", _xj_pid, sto.len, sto.s);
                return;
            }
            sto.s[sto.len] = 0;
            if(!xj_jcon_send_subscribe(jbc, sto.s, NULL, "subscribe"))
                prc->status = XJ_PRES_STATUS_WAIT;
        }
        else
        {
            xj_pres_cell_update(prc, jsmsg->cbf, jsmsg->p);
#ifdef XJ_EXTRA_DEBUG
            DBG("XJAB:xj_worker_check_watcher:%d: calling CBF(%.*s,%d)\n",
                _xj_pid, jsmsg->to.len, jsmsg->to.s, prc->state);
#endif
            // send presence info to SIP subscriber
            (*(prc->cbf))(&jsmsg->to, &jsmsg->to, prc->state, prc->cbp);
        }
    }
}