Пример #1
0
/**
 * Callback function to handle the invite-connect event, when we
 * get this acknowledge message, we should start to invite the buddy
 * to the conversation.
 *
 * The message received is:
 *
 * SIP-C/4.0 200 OK
 * I: 5
 * Q: 2 R
 * XI: 3d2ef745db9741a8946a57c40b0eb4d5
 * X: 1200
 * K: text/plain
 * K: text/html-fragment
 * K: multiparty
 * K: nudge
 *
 * then we send out invite-buddy request:
 */
static gint
chat_reg_cb(fetion_account *account, const gchar *sipmsg,
			fetion_transaction *trans)
{
	fetion_sip *sip;
	sip_header *eheader;
	gchar *body;
	gchar *sip_text;
	fetion_transaction *new_trans;
	fetion_buddy *buddy;

	sip = account->sip;

	fetion_sip_set_type(sip, SIP_SERVICE);

	if (!(buddy = fetion_buddy_find_by_userid(account, trans->userid))) {

		hybrid_debug_error("fetion", "invite new buddy failed");

		return HYBRID_ERROR;
	}

	eheader = sip_event_header_create(SIP_EVENT_INVITEBUDDY);
	fetion_sip_add_header(sip, eheader);

	body = generate_invite_buddy_body(buddy->sipuri);

	new_trans = transaction_clone(trans);
	transaction_set_callid(new_trans, sip->callid);
	transaction_set_callback(new_trans, invite_buddy_cb);
	transaction_add(account, new_trans);

	sip_text = fetion_sip_to_string(sip, body);
	g_free(body);

	hybrid_debug_info("fetion", "invite new buddy,send:\n%s", sip_text);

	if (send(account->sk, sip_text, strlen(sip_text), 0) == -1) {

		hybrid_debug_error("fetion", "invite new buddy failed");

		return HYBRID_ERROR;
	}

	g_free(sip_text);

	return HYBRID_OK;
}
Пример #2
0
static gboolean
fx_buddy_tooltip(HybridAccount *account, HybridBuddy *buddy, HybridTooltipData *tip_data)
{
    fetion_account *ac;
    fetion_buddy *bd;

    ac = hybrid_account_get_protocol_data(account);

    if (!(bd = fetion_buddy_find_by_userid(ac, buddy->id))) {
        return FALSE;
    }

    if (bd->mobileno && *bd->mobileno) {
        hybrid_tooltip_data_add_title(tip_data, bd->mobileno);

    } else {
        hybrid_tooltip_data_add_title(tip_data, bd->sid);
    }

    hybrid_tooltip_data_add_pair(tip_data, _("Name"), bd->nickname);

    if (bd->localname && *bd->localname) {
        hybrid_tooltip_data_add_pair(tip_data, _("Alias"), bd->localname);
    }
    hybrid_tooltip_data_add_pair(tip_data, _("Status"),
                                 hybrid_get_presence_name(buddy->state));

    if (bd->mobileno && *bd->mobileno) {
        hybrid_tooltip_data_add_pair(tip_data, _("Fetion Number"), bd->sid);
    } else {
        hybrid_tooltip_data_add_pair(tip_data, _("Mobile Number"),
                                     bd->mobileno);
    }

    if (bd->mood_phrase && *bd->mood_phrase) {
        hybrid_tooltip_data_add_pair(tip_data, _("Mood"), bd->mood_phrase);
    }

    return TRUE;
}
Пример #3
0
gint
fetion_message_send(fetion_account *account, const gchar *userid,
						const gchar *text)
{
	fetion_sip *sip;
	sip_header *toheader;
	sip_header *cheader;
	sip_header *kheader;
	sip_header *nheader;
	gchar *sip_text;
	fetion_buddy *buddy;

	g_return_val_if_fail(account != NULL, HYBRID_ERROR);
	g_return_val_if_fail(userid != NULL && *userid != '\0', HYBRID_ERROR);
	g_return_val_if_fail(text != NULL, HYBRID_ERROR);

	sip = account->sip;

	if (!(buddy = fetion_buddy_find_by_userid(account, userid))) {
		hybrid_debug_error("fetion", "FATAL, can't find specified buddy");

		return HYBRID_ERROR;
	}

	fetion_transaction *trans = transaction_create();

	transaction_set_userid(trans, userid);
	transaction_set_msg(trans, text);

	if (!account->channel_ready) {
		/* If the channel is not ready, make the transaction to wait
		 * until the transaction is ready */
		transaction_wait(account, trans);

		hybrid_debug_info("fetion", "channel not ready, transaction sleep.");

		return HYBRID_OK;
	}

	fetion_sip_set_type(sip, SIP_MESSAGE);

	nheader  = sip_event_header_create(SIP_EVENT_CATMESSAGE);
	toheader = sip_header_create("T", buddy->sipuri);
	cheader  = sip_header_create("C", "text/plain");
	kheader  = sip_header_create("K", "SaveHistory");
	fetion_sip_add_header(sip, toheader);
	fetion_sip_add_header(sip, cheader);
	fetion_sip_add_header(sip, kheader);
	fetion_sip_add_header(sip, nheader);

	transaction_set_callid(trans, sip->callid);
	transaction_set_callback(trans, sms_response_cb);

	transaction_set_data(trans, account);
	transaction_set_timeout(trans, (GSourceFunc)sms_timeout_cb, trans);
	transaction_add(account, trans);

	sip_text = fetion_sip_to_string(sip, text);

	hybrid_debug_info("fetion", "send message, send:\n%s", sip_text);

	if (send(account->sk, sip_text, strlen(sip_text), 0) == -1) {
		g_free(sip_text);

		return HYBRID_ERROR;
	}

	g_free(sip_text);

	return HYBRID_OK;
}
Пример #4
0
GSList*
sip_parse_presence(fetion_account *ac, const gchar *sipmsg)
{
    gchar        *pos;
    gchar        *temp;
    xmlnode      *root;
    xmlnode      *node;
    xmlnode      *pnode;
    GSList       *list = NULL;
    fetion_buddy *buddy;

    if (!(pos = strstr(sipmsg, "\r\n\r\n"))) {
        return list;
    }

    pos += 4;

    root = xmlnode_root(pos, strlen(pos));
    node = xmlnode_find(root, "contacts");
    node = xmlnode_child(node);

    while (node) {

        temp = xmlnode_prop(node, "id");

        if (!(buddy = fetion_buddy_find_by_userid(ac, temp))) {
            /* Maybe yourself's presence, we just ignore it. */
            g_free(temp);
            node = node->next;
            continue;
        }

        g_free(temp);

        list = g_slist_append(list, buddy);

        if ((pnode = xmlnode_find(node, "p"))) {

            if (xmlnode_has_prop(pnode, "m")) {
                temp = xmlnode_prop(pnode, "m");
                g_free(buddy->mobileno);
                buddy->mobileno = g_strdup(temp);
                g_free(temp);
            }

            if (xmlnode_has_prop(pnode, "n")) {
                temp = xmlnode_prop(pnode, "n");
                g_free(buddy->nickname);
                buddy->nickname = g_strdup(temp);
                g_free(temp);
            }

            if (xmlnode_has_prop(pnode, "i")) {
                temp = xmlnode_prop(pnode, "i");
                g_free(buddy->mood_phrase);
                buddy->mood_phrase = g_strdup(temp);
                g_free(temp);
            }

            if (xmlnode_has_prop(pnode, "c")) {
                temp = xmlnode_prop(pnode, "c");
                g_free(buddy->carrier);
                buddy->carrier = g_strdup(temp);
                g_free(temp);
            }

            if (xmlnode_has_prop(pnode, "p")) {
                temp = xmlnode_prop(pnode, "p");
                g_free(buddy->portrait_crc);

                if (*temp == '\0') {
                    g_free(temp);
                    temp = g_strdup("0");
                }
                buddy->portrait_crc = temp;
            } else {
                g_free(buddy->portrait_crc);
                buddy->portrait_crc = g_strdup("0");
            }

            if (xmlnode_has_prop(pnode, "cs")) {
                temp = xmlnode_prop(pnode, "cs");
                buddy->carrier_status = atoi(temp);
                g_free(temp);
            }
        }

        if ((pnode = xmlnode_find(node, "pr"))) {
            
            if (xmlnode_has_prop(pnode, "b")) {
                temp = xmlnode_prop(pnode, "b");
                buddy->state = atoi(temp);
                g_free(temp);
            }
        }

        node = node->next;
    }

    xmlnode_free(root);

    return list;
}
Пример #5
0
GSList*
sip_parse_sync(fetion_account *account, const gchar *sipmsg)
{
    gchar        *pos;
    gchar        *action;
    gchar        *userid;
    gchar        *status;
    xmlnode      *root;
    xmlnode      *node;
    fetion_buddy *buddy;
    GSList       *list = NULL;

    if (!(pos = strstr(sipmsg, "\r\n\r\n"))) {
        goto sync_info_err;
    }

    pos += 4;

    if (!(root = xmlnode_root(pos, strlen(pos)))) {
        goto sync_info_err;
    }

    if (!(node = xmlnode_find(root, "buddies"))) {

        xmlnode_free(root);

        return list;
    }

    node = xmlnode_child(node);

    while (node) {
        if (!xmlnode_has_prop(node, "action")) {
            goto next;
        }

        action = xmlnode_prop(node, "action");

        if (g_strcmp0(action, "update") == 0) {
            
            if (!xmlnode_has_prop(node, "user-id") ||
                !xmlnode_has_prop(node, "relation-status")) {

                g_free(action);

                goto next;
            }

            userid = xmlnode_prop(node, "user-id");
            status = xmlnode_prop(node, "relation-status");

            if (!(buddy = fetion_buddy_find_by_userid(account, userid))) {

                g_free(action);
                g_free(userid);
                g_free(status);

                goto next;
            }

            buddy->status = atoi(status);

            list = g_slist_append(list, buddy);

            g_free(status);
            g_free(userid);
        }

        g_free(action);
next:
        node = xmlnode_next(node);
    }

    return list;

sync_info_err:
    hybrid_debug_error("fetion", "invalid sync info");

    return list;
}
Пример #6
0
fetion_buddy*
fetion_buddy_parse_info(fetion_account *ac, 
		const gchar *userid, const gchar *sipmsg)
{
	xmlnode *root;
	xmlnode *node;
	gchar *pos;
	gchar *temp;
	gchar *value;
	fetion_buddy *buddy;
	gint code;

	code = fetion_sip_get_code(sipmsg);

	if (code != 200) {
		hybrid_debug_error("fetion", "get information with code:%d", code);
		return NULL;
	}

	if (!(pos = strstr(sipmsg, "\r\n\r\n"))) {
		goto get_info_error;
	}

	pos += 4;

	if (!(root = xmlnode_root(pos, strlen(pos)))) {
		goto get_info_error;
	}

	if (!(node = xmlnode_find(root, "contact"))) {
		xmlnode_free(root);
		goto get_info_error;
	}

	if (!(buddy = fetion_buddy_find_by_userid(ac, userid))) {
		xmlnode_free(root);
		goto get_info_error;
	}

	if (xmlnode_has_prop(node, "sid")) {
		value = xmlnode_prop(node, "sid");
		g_free(buddy->sid);
		buddy->sid = g_strdup(value);
		g_free(value);
	}

	if (xmlnode_has_prop(node, "mobile-no")) {
		value = xmlnode_prop(node, "mobile-no");
		g_free(buddy->mobileno);
		buddy->mobileno = g_strdup(value);
		g_free(value);
	}

	if (xmlnode_has_prop(node, "impresa")) {
		value = xmlnode_prop(node, "impresa");
		g_free(buddy->mood_phrase);
		buddy->mood_phrase = g_strdup(value);
		g_free(value);
	}

	if (xmlnode_has_prop(node, "nickname")) {
		value = xmlnode_prop(node, "nickname");
		g_free(buddy->nickname);
		buddy->nickname = g_strdup(value);
		g_free(value);
	}

	if (xmlnode_has_prop(node, "gender")) {
		value = xmlnode_prop(node, "gender");
		buddy->gender = atoi(value);
		g_free(value);
	}

	if (xmlnode_has_prop(node, "carrier-region")) {
		value = xmlnode_prop(node, "carrier-region");

		for (pos = value; *pos && *pos != '.'; pos ++);
		g_free(buddy->country);
		buddy->country = g_strndup(value, pos - value);

		for (pos ++, temp = pos; *pos && *pos != '.'; pos ++);
		g_free(buddy->province);
		buddy->province = g_strndup(temp, pos - temp);

		for (pos ++, temp = pos; *pos && *pos != '.'; pos ++);
		g_free(buddy->city);
		buddy->city = g_strndup(temp, pos - temp);

	}

	xmlnode_free(node);

	return buddy;

get_info_error:
	hybrid_debug_error("fetion", "invalid get-info response");
	return NULL;
}