Пример #1
0
/**
 * Parse the ssi authentication response string. then we can
 * get the following information: sipuri/mobileno/sid/ssic.
 */
static gint
parse_ssi_response(fetion_account *ac, const gchar *response)
{
    gchar   *prop;
    xmlnode *node;
    xmlnode *root = xmlnode_root(response, strlen(response));

    if (!root) {
        goto ssi_term;
    }

    prop = xmlnode_prop(root, "status-code");
    if (g_strcmp0(prop, "200") != 0) {
        g_free(prop);
        goto ssi_term;
    }

    g_free(prop);

    node = xmlnode_find(root, "user");

    prop = xmlnode_prop(node, "uri");
    fetion_account_set_sipuri(ac, prop);
    g_free(prop);

    if (!ac->sid || *(ac->sid) == '\0') {
        g_free(ac->sid);
        ac->sid = get_sid_from_sipuri(ac->sipuri);
        fetion_sip_set_from(ac->sip, ac->sid);
    }

    prop = xmlnode_prop(node, "mobile-no");
    fetion_account_set_mobileno(ac, prop);
    g_free(prop);

    prop = xmlnode_prop(node, "user-id");
    fetion_account_set_userid(ac, prop);
    g_free(prop);

#if 0
    node = xmlnode_find(root, "credential");
    prop = xmlnode_prop(node, "c");
    fetion_account_set_ssic(ac, prop);
    g_free(prop);
#endif

    return HYBRID_OK;
ssi_term:
    hybrid_account_error_reason(ac->account, _("ssi authencation"));
    xmlnode_free(root);
    return HYBRID_ERROR;
}
Пример #2
0
/**
 * Process the synchronization message, when the contact list or the personal info
 * changed, the server will push this message to tell the client to update its
 * local cache file, well, we will not update the local cache file, we keep the
 * old version numbers, and reload it after the next logining.
 */
static void
process_sync_info(fetion_account *ac, const gchar *sipmsg)
{
    GSList       *list;
    gchar        *sid;
    fetion_buddy *buddy;
    HybridBuddy  *hb;

    hybrid_debug_info("fetion", "sync info,recv:\n%s", sipmsg);

    if (!(list = sip_parse_sync(ac, sipmsg))) {
        return;
    }

    while (list) {
        buddy = (fetion_buddy*)list->data;

        list = g_slist_remove(list, buddy);

        if (buddy->status == 0) {
            continue;
        }

        if (!(hb = hybrid_blist_find_buddy(ac->account, buddy->userid))) {
            continue;
        }

        if (buddy->status == 1) {

            hybrid_blist_set_buddy_status(hb, TRUE);

        } else {
            hybrid_blist_set_buddy_status(hb, FALSE);
        }

        sid = get_sid_from_sipuri(buddy->sipuri);

        hybrid_message_box_show(HYBRID_MESSAGE_INFO,
                _("Buddy <b>%s</b> has %s your add-buddy request."),
                buddy->localname && *(buddy->localname) != '\0' ?
                buddy->localname : sid,
                buddy->status == 1 ? _("accepted") : _("declined"));
    }

}
Пример #3
0
gint
fetion_process_invite(fetion_account *account, const gchar *sipmsg)
{
	gchar *from;
	gchar *auth;
	gchar *ip;
	gchar *credential;
	gchar *sid;
	gint port;
	gchar *sip_text;
	fetion_account *new_account;
	fetion_buddy *buddy;
	invite_conn_data *data;

	g_return_val_if_fail(account != NULL, HYBRID_ERROR);
	g_return_val_if_fail(sipmsg != NULL, HYBRID_ERROR);

	from = sip_header_get_attr(sipmsg, "F");
	auth = sip_header_get_attr(sipmsg, "A");

	sip_header_get_auth(auth, &ip, &port, &credential);
	g_free(auth);

	sip_text = g_strdup_printf("SIP-C/4.0 200 OK\r\n"
								"F: %s\r\n"
								"I: 61\r\n"
								"Q: 200002 I\r\n\r\n", from);

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

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

		hybrid_debug_error("fetion", "process an invitation error.");

		g_free(from);
		g_free(ip);
		g_free(credential);
		g_free(sip_text);

		return HYBRID_ERROR;
	}
	
	g_free(sip_text);

	sid = get_sid_from_sipuri(from);

	if (!(buddy = fetion_buddy_find_by_sid(account, sid))) {

		hybrid_debug_error("fetion", "can't find buddy %s", from);

		g_free(from);
		g_free(ip);
		g_free(credential);
		g_free(sid);

		return HYBRID_ERROR;
	}

	g_free(sid);

	new_account = fetion_account_clone(account);
	fetion_account_set_who(new_account, buddy->userid);

	data = g_new0(invite_conn_data, 1);
	data->account = new_account;
	data->credential = credential;

	hybrid_proxy_connect(ip, port, process_invite_conn_cb, data);

	g_free(from);
	g_free(ip);

	return HYBRID_OK;
}
Пример #4
0
gint
fetion_process_message(fetion_account *account, const gchar *sipmsg)
{
	gchar *from;
	gchar *sid;
	gchar *callid;
	gchar *sequence;
	gchar *sendtime;
	gchar *text;
	gchar *sip_text;
	fetion_buddy *buddy;

	g_return_val_if_fail(account != NULL, HYBRID_ERROR);
	g_return_val_if_fail(sipmsg != NULL, HYBRID_ERROR);

	if (!(text = strstr(sipmsg, "\r\n\r\n"))) {
		hybrid_debug_error("fetion", "invalid message received\n");

		return HYBRID_ERROR;
	}

	text += 4;

	from     = sip_header_get_attr(sipmsg, "F");
	callid   = sip_header_get_attr(sipmsg, "I");
	sendtime = sip_header_get_attr(sipmsg, "D");
	sequence = sip_header_get_attr(sipmsg, "Q");

	sip_text = g_strdup_printf(
					"SIP-C/4.0 200 OK\r\n"
					"I: %s\r\n"
					"Q: %s\r\n"
					"F: %s\r\n\r\n", callid, sequence, from);
	g_free(callid);
	g_free(sendtime);
	g_free(sequence);

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

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

		return HYBRID_ERROR;
	}

	g_free(sip_text);

	sid = get_sid_from_sipuri(from);
	g_free(from);

	if (!(buddy = fetion_buddy_find_by_sid(account, sid))) {

		hybrid_debug_error("fetion", "invalid message received\n");
		g_free(sid);

		return HYBRID_ERROR;
	}

	hybrid_conv_got_message(account->account, buddy->userid, text, time(NULL));

	g_free(sid);


	return HYBRID_OK;
}
Пример #5
0
/**
 * Get the contact list from the xmlnode with name 'contact-list',
 * note that this node can either be a child node of the sipc
 * response xml message , or a child node of the local xml file.
 */
static void
get_contact_list(fetion_account *ac, xmlnode *contact_node)
{
    gchar        *temp;
    gchar        *temp1;
    xmlnode      *node;
    fetion_group *group;
    fetion_buddy *buddy;
    gboolean      has_ungroup = FALSE;

    g_return_if_fail(ac != NULL);
    g_return_if_fail(contact_node != NULL);

    /* group list */
    node = xmlnode_find(contact_node, "buddy-lists");
    node = xmlnode_child(node);

    while (node) {
        temp  = xmlnode_prop(node, "name");
        temp1 = xmlnode_prop(node, "id");

        group      = fetion_group_create(atoi(temp1), temp);
        ac->groups = g_slist_append(ac->groups, group);

        g_free(temp);
        g_free(temp1);

        node = node->next;
    }

    /* contact list  */
    node = xmlnode_find(contact_node, "buddies");
    node = xmlnode_child(node);

    while (node) {
        buddy            = fetion_buddy_create();
        buddy->userid    = xmlnode_prop(node, "i");
        buddy->sipuri    = xmlnode_prop(node, "u");
        buddy->localname = xmlnode_prop(node, "n");
        buddy->groups    = xmlnode_prop(node, "l");
        buddy->sid       = get_sid_from_sipuri(buddy->sipuri);

        if (xmlnode_has_prop(node, "r")) {

            temp = xmlnode_prop(node, "r");
            buddy->status = atoi(temp);
            g_free(temp);

        } else {
            buddy->status = 0;
        }

        ac->buddies = g_slist_append(ac->buddies, buddy);

        /* ungrouped */
        if (*(buddy->groups) == '\0' || buddy->groups[0] == '0') {
            g_free(buddy->groups);
            buddy->groups = g_strdup("0");

            if (!has_ungroup) { /**< add an "ungroup" group */
                group      = fetion_group_create(0, _("Ungrouped"));
                ac->groups = g_slist_append(ac->groups, group);

                has_ungroup = TRUE;
            }
        }

        node = node->next;
    }
}
Пример #6
0
static gint
handle_request_cb(fetion_account *account, const gchar *sipmsg,
			fetion_transaction *trans)
{
	gchar *pos;
	gchar *value;
	fetion_buddy *buddy;
	xmlnode *root;
	xmlnode *node;
	HybridGroup *group;
	HybridBuddy *bd;
	gchar *name;

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

	pos += 4;

	if (!(root = xmlnode_root(pos, strlen(pos)))) {
		return HYBRID_ERROR;
	}

	if (!(node = xmlnode_find(root, "buddy"))) {
		return HYBRID_ERROR;
	}

	if (!xmlnode_has_prop(node, "uri") ||
		!xmlnode_has_prop(node, "user-id")) {
		return HYBRID_ERROR;
	}

	buddy = fetion_buddy_create();
	buddy->sipuri = xmlnode_prop(node, "uri");
	buddy->userid = xmlnode_prop(node, "user-id");
	buddy->sid = get_sid_from_sipuri(buddy->sipuri);

	account->buddies = g_slist_append(account->buddies, buddy);

	if (xmlnode_has_prop(node, "local-name")) {
		buddy->localname = xmlnode_prop(node, "localname");
	}

	if (xmlnode_has_prop(node, "buddy-lists")) {
		buddy->groups = xmlnode_prop(node, "buddy-lists");

	} else {
		buddy->groups = "0";
	}

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

	} else {
		buddy->status = 0;
	}

	if (!(group = hybrid_blist_find_group(account->account, buddy->groups))) {
		account->buddies = g_slist_remove(account->buddies, buddy);
		fetion_buddy_destroy(buddy);
		return HYBRID_ERROR;
	}

	if (buddy->localname && *(buddy->localname) == '\0') {
		name = get_sid_from_sipuri(buddy->sipuri);

	} else {
		name = g_strdup(buddy->localname);
	}

	bd = hybrid_blist_add_buddy(account->account, group, buddy->userid, name);
	hybrid_blist_set_buddy_status(bd, buddy->status == 1 ? TRUE: FALSE);

	g_free(name);

	return HYBRID_OK;
}
Пример #7
0
static gint
buddy_add_cb(fetion_account *account, const gchar *sipmsg,
			fetion_transaction *trans)
{
	gint code;
	gchar *pos;
	gchar *value;
	gchar *name;
	fetion_buddy *buddy;
	HybridGroup *group;
	HybridBuddy *bd;
	xmlnode *root;
	xmlnode *node;

	hybrid_debug_info("fetion", "add buddy, recv:\n%s", sipmsg);

	if ((code = fetion_sip_get_code(sipmsg)) != 200) {

		hybrid_message_box_show(HYBRID_MESSAGE_WARNING,
				"Add buddy error. Server response with %d", code);

		return HYBRID_ERROR;
	}

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

	pos += 4;

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

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

		xmlnode_free(root);

		goto add_buddy_unknown_err;
	}

	if (xmlnode_has_prop(node, "status-code")) {
		
		value = xmlnode_prop(node, "status-code");

		code = atoi(value);

		g_free(value);

		if (code == 200) {
			goto add_buddy_ok;
		}

		xmlnode_free(node);

		if (code == 521) {

			hybrid_message_box_show(HYBRID_MESSAGE_WARNING,
					"The buddy has already been in your buddy list,\n"
					"Please don't add it duplicately.");

			return HYBRID_ERROR;
		}

		if (code == 404) {

			hybrid_message_box_show(HYBRID_MESSAGE_WARNING,
					"The buddy you try to add doesn't exist.");

			return HYBRID_ERROR;
		}

		if (code == 486) {
			
			hybrid_message_box_show(HYBRID_MESSAGE_WARNING,
					"You have reached the daily limit of adding buddies,\n"
					"please try another day.");

			return HYBRID_ERROR;
		}

		goto add_buddy_unknown_err;
	}

add_buddy_ok:

	if (!xmlnode_has_prop(node, "user-id") ||
		!xmlnode_has_prop(node, "local-name") ||
		!xmlnode_has_prop(node, "uri") ||
		!xmlnode_has_prop(node, "buddy-lists")) {

		xmlnode_free(root);

		goto add_buddy_unknown_err;
	}

	buddy = fetion_buddy_create();

	buddy->userid    = xmlnode_prop(node, "user-id");
	buddy->localname = xmlnode_prop(node, "local-name");
	buddy->sipuri    = xmlnode_prop(node, "uri");
	buddy->groups    = xmlnode_prop(node, "buddy-lists");

	xmlnode_free(root);

	account->buddies = g_slist_append(account->buddies, buddy);

	if (!(group = hybrid_blist_find_group(account->account, buddy->groups))) {
		fetion_buddy_destroy(buddy);
		account->buddies = g_slist_remove(account->buddies, buddy);

		goto add_buddy_unknown_err;
	}

	if (buddy->localname && *(buddy->localname) == '\0') {
		name = get_sid_from_sipuri(buddy->sipuri);

	} else {
		name = g_strdup(buddy->localname);
	}

	bd = hybrid_blist_add_buddy(account->account, group, buddy->userid, name);
	hybrid_blist_set_buddy_status(bd, FALSE);

	g_free(name);

	return HYBRID_OK;

add_buddy_unknown_err:
	hybrid_message_box_show(HYBRID_MESSAGE_WARNING,
			"Add buddy error. Unknown reason.");
	
	return HYBRID_ERROR;
}