/** * Callback function to handle the new-chat connecting event. * The message is: * * R fetion.com.cn SIP-C/4.0 * F: 547264589 * I: 5 * Q: 2 R * A: TICKS auth="2051600954.830102111" * K: text/html-fragment * K: multiparty * K: nudge */ static gint invite_connect_cb(gint sk, gpointer user_data) { fetion_transaction *trans; fetion_account *account; fetion_sip *sip; invite_data *data; gchar *credential; gchar *sip_text; sip_header *aheader; sip_header *theader; sip_header *mheader; sip_header *nheader; data = (invite_data*)user_data; trans = data->trans; credential = data->credential; account = trans->data; g_free(data); sip = account->sip; account->sk = sk; /* listen for this thread */ account->source = hybrid_event_add(sk, HYBRID_EVENT_READ, hybrid_push_cb, account); fetion_sip_set_type(sip, SIP_REGISTER); aheader = sip_credential_header_create(credential); theader = sip_header_create("K", "text/html-fragment"); mheader = sip_header_create("K", "multiparty"); nheader = sip_header_create("K", "nudge"); transaction_set_callid(trans, sip->callid); transaction_set_callback(trans, chat_reg_cb); transaction_add(account, trans); fetion_sip_add_header(sip, aheader); fetion_sip_add_header(sip, theader); fetion_sip_add_header(sip, mheader); fetion_sip_add_header(sip, nheader); sip_text = fetion_sip_to_string(sip, NULL); hybrid_debug_info("fetion", "register, send:\n%s", sip_text); if (send(sk, sip_text, strlen(sip_text), 0) == -1) { hybrid_debug_error("fetion", "register to the new chat channel failed"); return HYBRID_ERROR; } g_free(sip_text); g_free(credential); return HYBRID_OK; }
/** * Callback function to handle the cfg connect event. */ static gboolean cfg_connect_cb(gint sk, gpointer user_data) { gchar *http; gchar *body; fetion_account *ac = (fetion_account*)user_data; hybrid_account_set_connection_string(ac->account, _("Downloading configure file...")); body = generate_configuration_body(ac); http = g_strdup_printf("POST /nav/getsystemconfig.aspx HTTP/1.1\r\n" "User-Agent: IIC2.0/PC "PROTO_VERSION"\r\n" "Host: %s\r\n" "Connection: Close\r\n" "Content-Length: %lu\r\n\r\n%s", NAV_SERVER, strlen(body), body); g_free(body); hybrid_debug_info("fetion", "send:\n%s", http); if (send(sk, http, strlen(http), 0) == -1) { hybrid_account_error_reason(ac->account, _("downloading cfg error")); g_free(http); return FALSE; } g_free(http); ac->source = hybrid_event_add(sk, HYBRID_EVENT_READ, cfg_read_cb, ac); return FALSE; }
HybridConnection* hybrid_proxy_connect(const gchar *hostname, gint port, connect_callback func, gpointer user_data) { gint sk; struct sockaddr addr; HybridConnection *conn; g_return_val_if_fail(port != 0, NULL); g_return_val_if_fail(hostname != NULL, NULL); hybrid_debug_info("connect", "connecting to %s:%d", hostname, port); conn = g_new0(HybridConnection, 1); if ((sk = socket(AF_INET, SOCK_STREAM, 0)) == -1) { hybrid_debug_error("connect", "create socket: %s", strerror(errno)); hybrid_connection_destroy(conn); return NULL; } if (nonblock(sk) != HYBRID_OK) { hybrid_connection_destroy(conn); return NULL; } if (addr_init(hostname, port, &addr) != HYBRID_OK) { hybrid_connection_destroy(conn); return NULL; } if (connect(sk, &addr, sizeof(addr)) != 0) { if (errno != EINPROGRESS) { hybrid_debug_error("connect", "connect to \'%s:%d\':%s", hostname, port, strerror(errno)); hybrid_connection_destroy(conn); return NULL; } hybrid_debug_info("connect", "connect in progress"); hybrid_event_add(sk, HYBRID_EVENT_WRITE, func, user_data); } else { /* connection establish imediately */ func(sk, user_data); } conn->sk = sk; conn->host = g_strdup(hostname); conn->port = port; return conn; }
gboolean portrait_conn_cb(gint sk, gpointer user_data) { portrait_data *data = (portrait_data*)user_data; portrait_trans *trans; gchar *http_string; gchar *encoded_sipuri; gchar *encoded_ssic; gchar *uri; trans = g_new0(portrait_trans, 1); trans->buddy = data->buddy; trans->ac = data->ac; trans->portrait_type = data->portrait_type; g_free(data); if (trans->portrait_type == PORTRAIT_TYPE_BUDDY) { encoded_sipuri = g_uri_escape_string(trans->buddy->sipuri, NULL, TRUE); } else { encoded_sipuri = g_uri_escape_string(trans->ac->sipuri, NULL, TRUE); } encoded_ssic = g_uri_escape_string(trans->ac->ssic, NULL, TRUE); uri = g_strdup_printf("/%s/getportrait.aspx", trans->ac->portrait_host_path); http_string = g_strdup_printf("GET %s?Uri=%s" "&Size=120&c=%s HTTP/1.1\r\n" "User-Agent: IIC2.0/PC "PROTO_VERSION"\r\n" "Accept: image/pjpeg;image/jpeg;image/bmp;" "image/x-windows-bmp;image/png;image/gif\r\n" "Host: %s\r\nConnection: Close\r\n\r\n", uri, encoded_sipuri, encoded_ssic, trans->ac->portrait_host_name); g_free(encoded_sipuri); g_free(encoded_ssic); g_free(uri); if (send(sk, http_string, strlen(http_string), 0) == -1) { hybrid_debug_error("fetion", "download portrait for \'%s\':%s", trans->buddy->sid, strerror(errno)); g_free(http_string); return FALSE; } g_free(http_string); hybrid_event_add(sk, HYBRID_EVENT_READ, portrait_recv_cb, trans); return FALSE; }
/** * 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; }
/** * This function starts to register to the sipc server, since we have * got the ip address and port from the cfg string in the last step. */ static gboolean sipc_reg_action(gint sk, gpointer user_data) { gchar *sipmsg; gchar *cnouce = generate_cnouce(); fetion_account *ac = (fetion_account*)user_data; fetion_sip *sip = ac->sip; hybrid_debug_info("fetion", "sipc registeration action"); hybrid_account_set_connection_string(ac->account, _("start registering to the sipc server.")); /* Now we start to register to the sipc server. */ fetion_sip_set_type(sip, SIP_REGISTER); sip_header *cheader = sip_header_create("CN", cnouce); sip_header *client = sip_header_create("CL", "type=\"pc\"" " ,version=\""PROTO_VERSION"\""); fetion_sip_add_header(sip, cheader); fetion_sip_add_header(sip, client); g_free(cnouce); sipmsg = fetion_sip_to_string(sip, NULL); hybrid_debug_info("fetion", "start registering to sip server(%s:%d)", ac->sipc_proxy_ip, ac->sipc_proxy_port); hybrid_debug_info("fetion", "send:\n%s", sipmsg); if (send(sk, sipmsg, strlen(sipmsg), 0) == -1) { hybrid_account_error_reason(ac->account, _("sipc reg error")); g_free(sipmsg); return FALSE; } hybrid_event_add(sk, HYBRID_EVENT_READ, sipc_reg_cb, ac); g_free(sipmsg); return FALSE; }
gboolean xmpp_stream_init(gint sk, XmppStream *stream) { gchar *msg; stream->sk = sk; /* send version. */ msg = "<?xml version='1.0' ?>"; if (send(sk, msg, strlen(msg), 0) == -1) { hybrid_account_error_reason(stream->account->account, "send initial jabber request failed"); return FALSE; } /* send initiate stream request. */ msg = create_initiate_stream(stream); hybrid_debug_info("xmpp", "send initite jabber stream:\n%s", msg); if (send(sk, msg, strlen(msg), 0) == -1) { hybrid_account_error_reason(stream->account->account, "send initial jabber request failed"); g_free(msg); return FALSE; } g_free(msg); stream->source = hybrid_event_add(sk, HYBRID_EVENT_READ, (input_func)stream_recv_cb, stream); return FALSE; }
/** * Callback function to handle the pic-code download event. */ static gboolean pic_download_cb(gint sk, gpointer user_data) { gchar *cookie = NULL; gchar *http; fetion_account *ac = (fetion_account*)user_data; hybrid_debug_info("fetion", "start downloading pic-cocde."); if(ac->ssic) { cookie = g_strdup_printf("Cookie: ssic=%s\r\n", ac->ssic); } http = g_strdup_printf("GET /nav/GetPicCodeV4.aspx?algorithm=%s HTTP/1.1\r\n" "%sHost: %s\r\n" "User-Agent: IIC2.0/PC "PROTO_VERSION"\r\n" "Connection: close\r\n\r\n", ac->verification->algorithm == NULL ? "" : ac->verification->algorithm, ac->ssic == NULL ? "" : cookie, NAV_SERVER); hybrid_debug_info("fetion", "download pic request:\n%s", http); if (send(sk, http, strlen(http), 0) == -1) { g_free(cookie); g_free(http); return FALSE; } ac->buffer = (char*)0; ac->source = hybrid_event_add(sk, HYBRID_EVENT_READ, pic_read_cb, user_data); g_free(cookie); g_free(http); return FALSE; }
static gint process_invite_conn_cb(gint sk, gpointer user_data) { invite_conn_data *data; fetion_account *account; fetion_sip *sip; gchar *credential; gchar *sip_text; sip_header *aheader; sip_header *theader; sip_header *mheader; sip_header *nheader; data = (invite_conn_data*)user_data; account = data->account; credential = data->credential; g_free(data); account->sk = sk; sip = account->sip; account->source = hybrid_event_add(sk, HYBRID_EVENT_READ, hybrid_push_cb, account); if (account->source == 0) { hybrid_debug_error("fetion", "add read event error"); return HYBRID_ERROR; } fetion_sip_set_type(sip, SIP_REGISTER); aheader = sip_credential_header_create(credential); theader = sip_header_create("K", "text/html-fragment"); mheader = sip_header_create("K", "multiparty"); nheader = sip_header_create("K", "nudge"); g_free(credential); fetion_sip_add_header(sip, aheader); fetion_sip_add_header(sip, theader); fetion_sip_add_header(sip, mheader); fetion_sip_add_header(sip, nheader); sip_text = fetion_sip_to_string(sip, NULL); hybrid_debug_info("feiton", "register to a new channel:\n%s", sip_text); if (send(sk, sip_text, strlen(sip_text), 0) == -1) { hybrid_debug_error("fetion", "register to new channel error."); g_free(sip_text); return HYBRID_ERROR; } g_free(sip_text); return HYBRID_OK; }