/** * 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; }
/** * 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; }
sip_header* sip_ack_header_create(const gchar *code, const gchar *algorithm, const gchar *type, const gchar *guid) { gchar ack[BUF_LENGTH]; g_snprintf(ack, sizeof(ack) - 1, "Verify response=\"%s\",algorithm=\"%s\"," "type=\"%s\",chid=\"%s\"", code, algorithm, type, guid); return sip_header_create("A" , ack); }
sip_header* sip_credential_header_create(const gchar *credential) { gchar value[BUF_LENGTH]; g_return_val_if_fail(credential != NULL, NULL); g_snprintf(value, sizeof(value) - 1, "TICKS auth=\"%s\"", credential); return sip_header_create("A", value); }
sip_header* sip_authentication_header_create(const gchar *response) { gchar *value; gchar start[] = "Digest response=\""; gchar end[] = "\",algorithm=\"SHA1-sess-v4\""; sip_header *header; value = g_strjoin("", start, response, end, NULL); header = sip_header_create("A", value); g_free(value); return header; }
gint fetion_message_send_to_me(fetion_account *account, const gchar *text) { sip_header *toheader; sip_header *eheader; gchar *sip_text; fetion_sip *sip; fetion_transaction *trans; g_return_val_if_fail(account != NULL, HYBRID_ERROR); g_return_val_if_fail(text != NULL, HYBRID_ERROR); sip = account->sip; fetion_sip_set_type(sip, SIP_MESSAGE); toheader = sip_header_create("T", account->sipuri); eheader = sip_event_header_create(SIP_EVENT_SENDCATMESSAGE); fetion_sip_add_header(sip, toheader); fetion_sip_add_header(sip, eheader); trans = transaction_create(); transaction_set_callid(trans, sip->callid); transaction_set_callback(trans, sms_to_me_cb); transaction_add(account, trans); sip_text = fetion_sip_to_string(sip, text); hybrid_debug_info("fetion", "send sms to youself,send:\n%s", sip_text); if (send(account->sk, sip_text, strlen(sip_text), 0) == -1) { hybrid_debug_error("fetion", "send message to yourself error."); return HYBRID_ERROR; } g_free(sip_text); return HYBRID_OK; }
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; }
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; }
sip_header* sip_event_header_create(gint event_type) { gchar *event = NULL; sip_header *header; g_return_val_if_fail(event_type >= SIP_EVENT_PRESENCE, NULL); g_return_val_if_fail(event_type <= SIP_EVENT_PGPRESENCE, NULL); switch (event_type) { case SIP_EVENT_PRESENCE : event = g_strdup("PresenceV4"); break; case SIP_EVENT_SETPRESENCE : event = g_strdup("SetPresenceV4"); break; case SIP_EVENT_CATMESSAGE : event = g_strdup("CatMsg"); break; case SIP_EVENT_SENDCATMESSAGE : event = g_strdup("SendCatSMS"); break; case SIP_EVENT_STARTCHAT : event = g_strdup("StartChat"); break; case SIP_EVENT_GETCONTACTINFO : event = g_strdup("GetContactInfoV4"); break; case SIP_EVENT_CONVERSATION : event = g_strdup("Conversation"); break; case SIP_EVENT_INVITEBUDDY : event = g_strdup("InviteBuddy"); break; case SIP_EVENT_CREATEBUDDYLIST : event = g_strdup("CreateBuddyList"); break; case SIP_EVENT_DELETEBUDDYLIST : event = g_strdup("DeleteBuddyList"); break; case SIP_EVENT_SETCONTACTINFO : event = g_strdup("SetContactInfoV4"); break; case SIP_EVENT_SETUSERINFO : event = g_strdup("SetUserInfoV4"); break; case SIP_EVENT_SETBUDDYLISTINFO : event = g_strdup("SetBuddyListInfo"); break; case SIP_EVENT_DELETEBUDDY : event = g_strdup("DeleteBuddyV4"); break; case SIP_EVENT_ADDBUDDY : event = g_strdup("AddBuddyV4"); break; case SIP_EVENT_KEEPALIVE : event = g_strdup("KeepAlive"); break; case SIP_EVENT_DIRECTSMS : event = g_strdup("DirectSMS"); break; case SIP_EVENT_HANDLECONTACTREQUEST : event = g_strdup("HandleContactRequestV4"); break; case SIP_EVENT_SENDDIRECTCATSMS : event = g_strdup("SendDirectCatSMS"); break; case SIP_EVENT_PGGETGROUPLIST: event = g_strdup("PGGetGroupList"); break; case SIP_EVENT_PGGETGROUPINFO: event = g_strdup("PGGetGroupInfo"); break; case SIP_EVENT_PGPRESENCE: event = g_strdup("PGPresence"); break; case SIP_EVENT_PGGETGROUPMEMBERS: event = g_strdup("PGGetGroupMembers"); break; case SIP_EVENT_PGSENDCATSMS: event = g_strdup("PGSendCatSMS"); break; default: break; } header = sip_header_create("N", event); g_free(event); return header; }
/** * Start sipc authencation with the response string. * * @param response It is generated by generate_response(). */ static gint sipc_aut_action(gint sk, fetion_account *ac, const gchar *response) { gchar *sipmsg; gchar *body; sip_header *aheader; sip_header *akheader; sip_header *ackheader; fetion_transaction *trans; fetion_sip *sip = ac->sip; ac->sk = sk; hybrid_debug_info("fetion", "sipc authencation action"); hybrid_account_set_connection_string(ac->account, _("start sipc authentication...")); body = generate_auth_body(ac); fetion_sip_set_type(sip, SIP_REGISTER); aheader = sip_authentication_header_create(response); akheader = sip_header_create("AK", "ak-value"); trans = transaction_create(); transaction_set_callid(trans, sip->callid); transaction_set_callback(trans, sipc_auth_cb); transaction_add(ac, trans); fetion_sip_add_header(sip, aheader); fetion_sip_add_header(sip, akheader); if(ac->verification != NULL && ac->verification->algorithm != NULL) { ackheader = sip_ack_header_create(ac->verification->code, ac->verification->algorithm, ac->verification->type, ac->verification->guid); fetion_sip_add_header(sip , ackheader); } fetion_verification_destroy(ac->verification); ac->verification = NULL; sipmsg = fetion_sip_to_string(sip, body); g_free(body); hybrid_debug_info("fetion", "Start sipc authentication , with ak-value"); hybrid_debug_info("fetion", "send:\n%s", sipmsg); if(send(sk, sipmsg, strlen(sipmsg), 0) == -1) { hybrid_debug_error("fetion", "send sipc auth request:%s\n", strerror(errno)); g_free(sipmsg); return HYBRID_ERROR; } g_free(sipmsg); return 0; }