예제 #1
0
파일: fetion.c 프로젝트: celiachen/hybrid
/**
 * Process the message sip message.
 */
static void
process_message_cb(fetion_account *ac, const gchar *sipmsg)
{
    gchar        *event;
    gchar        *sysmsg_text;
    gchar        *sysmsg_url;
    HybridNotify *notify;

    if ((event = sip_header_get_attr(sipmsg, "N")) &&
            g_strcmp0(event, "system-message") == 0) {
        if (fetion_message_parse_sysmsg(sipmsg, &sysmsg_text,
                    &sysmsg_url) != HYBRID_OK) {
            return;
        }

        notify = hybrid_notify_create(ac->account, _("System Message"));
        hybrid_notify_set_text(notify, sysmsg_text);

        g_free(sysmsg_text);
        g_free(sysmsg_url);
    }

    hybrid_debug_info("fetion", "received message:\n%s", sipmsg);

    fetion_process_message(ac, sipmsg);

    g_free(event);
}
예제 #2
0
파일: fx_login.c 프로젝트: GCrean/hybrid
static gint
parse_sipc_verification(fetion_account *ac, const gchar *resp)
{
    gchar *w;
    gchar *start;
    gchar *end;

    ac->verification = fetion_verification_create();

    w = sip_header_get_attr(resp, "W");

    for (start = w; *start != '\0' && *start != '\"'; start ++);

    if (!*start) {
        g_free(w);
        return HYBRID_ERROR;
    }

    start ++;

    for (end = start; *end != '\0' && *end != '\"'; end ++);

    if (!*end) {
        g_free(w);
        return HYBRID_ERROR;
    }

    ac->verification->algorithm = g_strndup(start, end - start);

    for (start = end + 1; *start != '\0' && *start != '\"'; start ++);

    if (!*start) {
        g_free(w);
        return HYBRID_ERROR;
    }

    start ++;

    for (end = start; *end != '\0' && *end != '\"'; end ++);

    if (!*end) {
        g_free(w);
        return HYBRID_ERROR;
    }

    ac->verification->type = g_strndup(start, end - start);


    return HYBRID_OK;
}
예제 #3
0
파일: fx_login.c 프로젝트: GCrean/hybrid
/**
 * Callback function to handle the sipc reg response.
 */
static gboolean
sipc_reg_cb(gint sk, gpointer user_data)
{
    gchar  buf[BUF_LENGTH];
    gchar *digest;
    gchar *nonce, *key, *aeskey;
    gchar *response;
    gint   n;

    fetion_account *ac = (fetion_account*)user_data;

    if ((n = recv(sk, buf, sizeof(buf), 0)) == -1) {
        hybrid_account_error_reason(ac->account, _("sipc reg error."));
        return FALSE;
    }

    buf[n] = '\0';

    hybrid_debug_info("fetion", "recv:\n%s", buf);

    /* parse response, we need the key and nouce */
    digest = sip_header_get_attr(buf, "W");

    if (parse_sipc_reg_response(digest, &nonce, &key) != HYBRID_OK) {
        g_free(digest);
        return FALSE;
    }

    aeskey = generate_aes_key();

    response = generate_response(nonce, ac->userid, ac->password, key, aeskey);

    /* fill verify_data for pic confirm */
    strncpy(verify_data.response, response, sizeof(verify_data.response));

    /* now we start to handle the pushed messages */
    ac->source = hybrid_event_add(sk, HYBRID_EVENT_READ, hybrid_push_cb, ac);

    /* start sipc authencation action. */
    sipc_aut_action(sk, ac, response);

    g_free(digest);
    g_free(nonce);
    g_free(key);
    g_free(aeskey);
    g_free(response);

    return FALSE;
}
예제 #4
0
파일: fx_msg.c 프로젝트: chenyukang/hybrid
/**
 * Callback function to handle the new_chat response message, if success
 * we would get the following message:
 *
 * SIP-C/4.0 200 OK
 * I: 4
 * Q: 2 S
 * A: CS address="221.176.31.128:8080;221.176.31.128:443",credential="439333922.916967705"
 *
 * Now we should start a new socket connect to 221.176.31.128:8080 with port 443 as
 * a back port if 8080 failed to connect.
 */
gint
new_chat_cb(fetion_account *account, const gchar *sipmsg,
				fetion_transaction *trans)
{
	gchar *auth;
	gchar *ip;
	gint port;
	gchar *credential;
	invite_data *data;
	fetion_transaction *new_trans;
	fetion_account *new_account;

	printf("%s\n", sipmsg);

	if (!(auth = sip_header_get_attr(sipmsg, "A"))) {

		hybrid_debug_error("fetion", "invalid invitation response.");

		return HYBRID_ERROR;
	}

	if (sip_header_get_auth(auth, &ip, &port, &credential) != HYBRID_OK) {

		hybrid_debug_error("fetion", "invalid invitation response.");

		return HYBRID_ERROR;
	}

	g_free(auth);

	new_trans = transaction_clone(trans);

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

	transaction_set_data(new_trans, new_account);

	data = g_new0(invite_data, 1);
	data->trans = new_trans;
	data->credential = credential;

	hybrid_proxy_connect(ip, port, invite_connect_cb, data);

	g_free(ip);

	return HYBRID_OK;
}
예제 #5
0
파일: fx_sip.c 프로젝트: CinsonChen/hybrid
gint
fetion_sip_get_length(const gchar *sipmsg)
{
    gint   length;
    gchar *temp;

    g_return_val_if_fail(sipmsg != NULL, 0);

    if(!(temp = sip_header_get_attr(sipmsg, "L"))) {
        return 0;
    }

    length = atoi(temp);
    g_free(temp);

    return length;
}
예제 #6
0
파일: fetion.c 프로젝트: celiachen/hybrid
/**
 * Process the sip response message.
 */
static void
process_sipc_cb(fetion_account *ac, const gchar *sipmsg)
{
    gchar              *callid;
    gint                callid0;
    fetion_transaction *trans;
    GSList             *trans_cur;

    if (!(callid = sip_header_get_attr(sipmsg, "I"))) {
        hybrid_debug_error("fetion", "invalid sipc message received\n%s",
                sipmsg);
        g_free(callid);
        return;
    }

    callid0 = atoi(callid);

    trans_cur = ac->trans_list;

    while(trans_cur) {
        trans = (fetion_transaction*)(trans_cur->data);

        if (trans->callid == callid0) {

            if (trans->callback) {
                (trans->callback)(ac, sipmsg, trans);
            }

            transaction_remove(ac, trans);

            break;
        }

        trans_cur = g_slist_next(trans_cur);
    }
}
예제 #7
0
파일: fx_msg.c 프로젝트: chenyukang/hybrid
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;
}
예제 #8
0
파일: fx_msg.c 프로젝트: chenyukang/hybrid
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;
}
예제 #9
0
파일: fx_sip.c 프로젝트: CinsonChen/hybrid
void
sip_parse_notify(const gchar *sipmsg, gint *notify_type, gint *event_type)
{
    gchar   *attr;
    gchar   *pos;
    gchar   *event;
    xmlnode *root = NULL;
    xmlnode *node;

    g_return_if_fail(sipmsg != NULL);

    if (!(attr = sip_header_get_attr(sipmsg, "N"))) {
        *notify_type = NOTIFICATION_TYPE_UNKNOWN;
        *event_type = NOTIFICATION_EVENT_UNKNOWN;
        return;
    }

    if (g_strcmp0(attr, "PresenceV4") == 0) {
        *notify_type = NOTIFICATION_TYPE_PRESENCE;

    } else if (g_strcmp0(attr, "Conversation") == 0) {
        *notify_type = NOTIFICATION_TYPE_CONVERSATION;

    } else if (g_strcmp0(attr, "contact") == 0) {
        *notify_type = NOTIFICATION_TYPE_CONTACT;

    } else if (g_strcmp0(attr, "registration") == 0) {
        *notify_type = NOTIFICATION_TYPE_REGISTRATION;

    } else if (g_strcmp0(attr, "SyncUserInfoV4") == 0) {
        *notify_type = NOTIFICATION_TYPE_SYNCUSERINFO;

    } else if (g_strcmp0(attr, "PGGroup") == 0) {
        *notify_type = NOTIFICATION_TYPE_PGGROUP;

    } else {
        *notify_type = NOTIFICATION_TYPE_UNKNOWN;
    }

    g_free(attr);

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

    pos += 4;

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

    if (!(node = xmlnode_find(root, "event"))) {
        goto notify_err;
    }

    if (!(event = xmlnode_prop(node, "type"))) {
        goto notify_err;
    }

    if (g_strcmp0(event, "Support") == 0) {
        if (!(node = xmlnode_next(node))) {
            goto notify_err;
        }

        if (g_strcmp0(node->name, "event") != 0) {
            goto notify_err;
        }

        if (!(event = xmlnode_prop(node, "type"))) {
            goto notify_err;
        }

    }

    if (g_strcmp0(event, "PresenceChanged") == 0) {
        *event_type = NOTIFICATION_EVENT_PRESENCECHANGED;

    } else if (g_strcmp0(event, "UserEntered") == 0) {
        *event_type = NOTIFICATION_EVENT_USERENTER;

    } else if (g_strcmp0(event, "UserLeft") == 0) {
        *event_type = NOTIFICATION_EVENT_USERLEFT;

    } else if (g_strcmp0(event, "deregistered") == 0) {
        *event_type = NOTIFICATION_EVENT_DEREGISTRATION;

    } else if (g_strcmp0(event, "SyncUserInfo") == 0) {
        *event_type = NOTIFICATION_EVENT_SYNCUSERINFO;

    } else if (g_strcmp0(event, "AddBuddyApplication") == 0) {
        *event_type = NOTIFICATION_EVENT_ADDBUDDYAPPLICATION;

    } else if (g_strcmp0(event, "PGGetGroupInfo") == 0) {
        *event_type = NOTIFICATION_EVENT_PGGETGROUPINFO;

    } else {
        *event_type = NOTIFICATION_EVENT_UNKNOWN;
    }

    xmlnode_free(root);
    return;

notify_err:
    xmlnode_free(root);
    *event_type = NOTIFICATION_EVENT_UNKNOWN;
    return;
}