static void waprpl_chat_invite(PurpleConnection *gc, int id, const char *message, const char *name) { whatsapp_connection * wconn = purple_connection_get_protocol_data(gc); PurpleAccount *account = purple_connection_get_account(gc); PurpleConversation *convo = purple_find_chat(gc, id); PurpleBlistNode* node = purple_blist_get_root(); GHashTable* hasht = NULL; while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleChat * ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == account) { hasht = purple_chat_get_components(ch); if (chatid_to_convo(g_hash_table_lookup(hasht, "id")) == id) { break; } } } node = purple_blist_node_next(node,FALSE); } char * chat_id = g_hash_table_lookup(hasht, "id"); if (strstr(name,"@s.whatsapp.net") == 0) name = g_strdup_printf("*****@*****.**",name); waAPI_manageparticipant(wconn->waAPI, chat_id, name, "add"); purple_conv_chat_add_user (purple_conversation_get_chat_data(convo), name, "", PURPLE_CBFLAGS_NONE, FALSE); waprpl_check_output(gc); return 1; }
void waprpl_ssl_output_cb(gpointer data, gint source, PurpleInputCondition cond) { PurpleConnection *gc = data; whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); char tempbuff[16*1024]; int ret; do { int datatosend = waAPI_sslsendcb(wconn->waAPI, tempbuff, sizeof(tempbuff)); purple_debug_info(WHATSAPP_ID, "Output data to send %d\n", datatosend); if (datatosend == 0) break; ret = purple_ssl_write(wconn->gsc, tempbuff, datatosend); if (ret > 0) { waAPI_sslsenddone(wconn->waAPI, ret); } else if (ret == 0 || (ret < 0 && errno == EAGAIN)) { /* Check later */ } else { waprpl_ssl_cerr_cb(0, 0, gc); } } while (ret > 0); /* Check if we need to callback again or not */ waprpl_check_ssl_output(gc); waprpl_check_output(gc); }
// Try to read some data and push it to the WhatsApp API static void waprpl_input_cb(gpointer data, gint source, PurpleInputCondition cond) { PurpleConnection *gc = data; whatsapp_connection * wconn = purple_connection_get_protocol_data(gc); char tempbuff[1024]; int ret; do { ret = read(wconn->fd,tempbuff,sizeof(tempbuff)); if (ret > 0) waAPI_input(wconn->waAPI,tempbuff,ret); else if (ret < 0 && errno == EAGAIN) break; else if (ret < 0) { gchar *tmp = g_strdup_printf("Lost connection with server (in cb): %s",g_strerror(errno)); purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); break; } else { purple_connection_error_reason (gc,PURPLE_CONNECTION_ERROR_NETWORK_ERROR,"Server closed the connection"); } } while (ret > 0); waprpl_process_incoming_events(gc); waprpl_check_output(gc); // The input data may generate responses! }
static void waprpl_get_info(PurpleConnection * gc, const char *username) { PurpleNotifyUserInfo *info = purple_notify_user_info_new(); purple_debug_info(WHATSAPP_ID, "Fetching %s's user info for %s\n", username, gc->account->username); /* Get user status */ whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); const char *status_string = waAPI_getuserstatusstring(wconn->waAPI, username); /* Get user picture (big one) */ char *profile_image = ""; char *icon; int len; int res = waAPI_queryavatar(wconn->waAPI, username, &icon, &len); if (res) { int iid = purple_imgstore_add_with_id(g_memdup(icon, len), len, NULL); profile_image = g_strdup_printf("<img id=\"%u\">", iid); } purple_notify_user_info_add_pair(info, "Status", status_string); purple_notify_user_info_add_pair(info, "Profile image", profile_image); if (res) g_free(profile_image); purple_notify_userinfo(gc, username, info, NULL, NULL); waprpl_check_output(gc); }
static void waprpl_output_cb(gpointer data, gint source, PurpleInputCondition cond) { PurpleConnection *gc = data; whatsapp_connection * wconn = purple_connection_get_protocol_data(gc); char tempbuff[1024]; int ret; do { int datatosend = waAPI_sendcb(wconn->waAPI,tempbuff,sizeof(tempbuff)); if (datatosend == 0) break; ret = write(wconn->fd,tempbuff,datatosend); if (ret > 0) { waAPI_senddone(wconn->waAPI,ret); } else if (ret == 0 || (ret < 0 && errno == EAGAIN)) { // Check later } else { gchar *tmp = g_strdup_printf("Lost connection with server (out cb): %s",g_strerror(errno)); purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); purple_debug_info("waprpl", "Connection error (file desc: %d, ret val %d, errno %d)\n", wconn->fd,ret,errno); break; } } while (ret > 0); // Check if we need to callback again or not waprpl_check_output(gc); }
/* Try to read some data and push it to the WhatsApp API */ void waprpl_ssl_input_cb(gpointer data, gint source, PurpleInputCondition cond) { PurpleConnection *gc = data; whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); /* End point closed the connection */ if (!g_list_find(purple_connections_get_all(), gc)) { waprpl_ssl_cerr_cb(0, 0, gc); return; } char tempbuff[16*1024]; int ret; do { ret = purple_ssl_read(wconn->gsc, tempbuff, sizeof(tempbuff)); purple_debug_info(WHATSAPP_ID, "Input data read %d %d\n", ret, errno); if (ret > 0) { waAPI_sslinput(wconn->waAPI, tempbuff, ret); } else if (ret < 0 && errno == EAGAIN) break; else if (ret < 0) { waprpl_ssl_cerr_cb(0, 0, gc); break; } else { waprpl_ssl_cerr_cb(0, 0, gc); } } while (ret > 0); waprpl_check_ssl_output(gc); /* The input data may generate responses! */ waprpl_check_output(gc); }
static void waprpl_set_buddy_icon(PurpleConnection * gc, PurpleStoredImage * img) { /* Send the picture the user has selected! */ whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); size_t size = purple_imgstore_get_size(img); const void *data = purple_imgstore_get_data(img); if (data) { // First of all make the picture a square char * sqbuffer; int sqsize; imgProfile(data, size, (void**)&sqbuffer, &sqsize, 640); char * pbuffer; int osize; imgProfile(data, size, (void**)&pbuffer, &osize, 96); waAPI_setavatar(wconn->waAPI, sqbuffer, sqsize, pbuffer, osize); free(sqbuffer); free(pbuffer); } else { waAPI_setavatar(wconn->waAPI, 0,0,0,0); } waprpl_check_output(gc); }
static int waprpl_send_chat(PurpleConnection * gc, int id, const char *message, PurpleMessageFlags flags) { whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); PurpleAccount *account = purple_connection_get_account(gc); PurpleConversation *convo = purple_find_chat(gc, id); PurpleChat *ch = blist_find_chat_by_convo(gc, id); GHashTable *hasht = purple_chat_get_components(ch); char *chat_id = g_hash_table_lookup(hasht, "id"); char *plain; purple_markup_html_to_xhtml(message, NULL, &plain); char msgid[128]; waAPI_getmsgid(wconn->waAPI, msgid); purple_signal_emit(purple_connection_get_prpl(gc), "whatsapp-sending-message", gc, msgid, chat_id, message); waAPI_sendchat(wconn->waAPI, msgid, chat_id, plain); g_free(plain); waprpl_check_output(gc); const char *me = purple_account_get_string(account, "nick", ""); purple_conv_chat_write(PURPLE_CONV_CHAT(convo), me, message, PURPLE_MESSAGE_SEND, time(NULL)); return 1; }
static int waprpl_send_chat(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags) { whatsapp_connection * wconn = purple_connection_get_protocol_data(gc); PurpleAccount *account = purple_connection_get_account(gc); PurpleConversation *convo = purple_find_chat(gc, id); PurpleBlistNode* node = purple_blist_get_root(); GHashTable* hasht = NULL; while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleChat * ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == account) { hasht = purple_chat_get_components(ch); if (chatid_to_convo(g_hash_table_lookup(hasht, "id")) == id) { break; } } } node = purple_blist_node_next(node,FALSE); } char * chat_id = g_hash_table_lookup(hasht, "id"); waAPI_sendchat(wconn->waAPI,chat_id,message); waprpl_check_output(gc); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)), purple_connection_get_display_name(gc), PURPLE_MESSAGE_SEND, message, time(NULL)); purple_conv_im_write(PURPLE_CONV_CHAT(convo), purple_connection_get_display_name(gc), message, PURPLE_MESSAGE_SEND, time(NULL)); return 1; }
static int waprpl_send_im(PurpleConnection *gc, const char *who, const char *message, PurpleMessageFlags flags) { whatsapp_connection * wconn = purple_connection_get_protocol_data(gc); waAPI_sendim(wconn->waAPI,who,message); waprpl_check_output(gc); return 1; }
static void waprpl_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { whatsapp_connection * wconn = purple_connection_get_protocol_data(gc); const char * name = purple_buddy_get_name(buddy); waAPI_delcontact(wconn->waAPI,name); waprpl_check_output(gc); }
static void waprpl_set_buddy_icon(PurpleConnection *gc, PurpleStoredImage *img) { // Send the picture the user has selected! whatsapp_connection * wconn = purple_connection_get_protocol_data(gc); size_t size = purple_imgstore_get_size(img); const void * data = purple_imgstore_get_data(img); waAPI_setavatar(wconn->waAPI, data, size); waprpl_check_output(gc); }
static void waprpl_set_status(PurpleAccount *acct, PurpleStatus *status) { whatsapp_connection * wconn = purple_connection_get_protocol_data(purple_account_get_connection(acct)); const char * sid = purple_status_get_id(status); char * mid = purple_status_get_attr_string(status, "message"); if (mid == 0) mid = ""; waAPI_setmypresence(wconn->waAPI,sid,mid); waprpl_check_output(purple_account_get_connection(acct)); }
static void waprpl_blist_node_removed (PurpleBlistNode *node) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleChat * ch = PURPLE_CHAT(node); char * gid = g_hash_table_lookup(purple_chat_get_components(ch), "id"); if (gid == 0) return; // Group is not created yet... whatsapp_connection * wconn = purple_connection_get_protocol_data(purple_account_get_connection(purple_chat_get_account(ch))); waAPI_deletegroup(wconn->waAPI, gid); waprpl_check_output(purple_account_get_connection(purple_chat_get_account(ch))); } }
static unsigned int waprpl_send_typing(PurpleConnection *gc, const char *who, PurpleTypingState typing) { whatsapp_connection * wconn = purple_connection_get_protocol_data(gc); int status = 0; if (typing == PURPLE_TYPING) status = 1; waAPI_sendtyping(wconn->waAPI,who,status); waprpl_check_output(gc); return 1; }
static int waprpl_send_im(PurpleConnection * gc, const char *who, const char *message, PurpleMessageFlags flags) { whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); char *plain; purple_markup_html_to_xhtml(message, NULL, &plain); waAPI_sendim(wconn->waAPI, who, plain); g_free(plain); waprpl_check_output(gc); return 1; }
static void waprpl_connect_cb(gpointer data, gint source, const gchar *error_message) { PurpleConnection *gc = data; whatsapp_connection * wconn = purple_connection_get_protocol_data(gc); if (source < 0) { gchar *tmp = g_strdup_printf("Unable to connect: %s",error_message); purple_connection_error_reason (gc,PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); }else{ wconn->fd = source; waAPI_login(wconn->waAPI); wconn->rh = purple_input_add(wconn->fd, PURPLE_INPUT_READ, waprpl_input_cb, gc); waprpl_check_output(gc); } }
static void waprpl_chat_invite(PurpleConnection * gc, int id, const char *message, const char *name) { whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); PurpleConversation *convo = purple_find_chat(gc, id); PurpleChat *ch = blist_find_chat_by_convo(gc, id); GHashTable *hasht = purple_chat_get_components(ch); char *chat_id = g_hash_table_lookup(hasht, "id"); if (strstr(name, "@s.whatsapp.net") == 0) name = g_strdup_printf("*****@*****.**", name); waAPI_manageparticipant(wconn->waAPI, chat_id, name, "add"); purple_conv_chat_add_user(purple_conversation_get_chat_data(convo), name, "", PURPLE_CBFLAGS_NONE, FALSE); waprpl_check_output(gc); }
static void waprpl_update_privacy(PurpleConnection *gc, PurpleRequestFields *fields) { whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); int i,j; char priv[3][30]; for (i = 0; i < 3; i++) { PurpleRequestField * field = purple_request_fields_get_field(fields, priv_type[i]); GList *sel = purple_request_field_list_get_selected (field); for (j = 0; j < 3; j++) if (strcmp(sel->data, priv_opt_nice[j]) == 0) strcpy(priv[i], priv_opt[j]); } waAPI_setprivacy(wconn->waAPI, priv[0], priv[1], priv[2]); waprpl_check_output(gc); }
static void waprpl_insert_contacts(PurpleConnection *gc) { whatsapp_connection * wconn = purple_connection_get_protocol_data(gc); GSList *buddies = purple_find_buddies(purple_connection_get_account(gc), NULL); GSList * l; for (l = buddies; l; l = l->next) { PurpleBuddy * b = l->data; const char * name = purple_buddy_get_name(b); waAPI_addcontact(wconn->waAPI,name); } waprpl_check_output(gc); g_slist_free(buddies); }
static void waprpl_blist_node_added (PurpleBlistNode *node) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleChat * ch = PURPLE_CHAT(node); whatsapp_connection * wconn = purple_connection_get_protocol_data(purple_account_get_connection(purple_chat_get_account(ch))); GHashTable * hasht = purple_chat_get_components(ch); const char *groupname = g_hash_table_lookup(hasht, "subject"); const char *gid = g_hash_table_lookup(hasht, "id"); if (gid != 0) return; // Already created purple_debug_info(WHATSAPP_ID, "Creating group %s\n", groupname); waAPI_creategroup(wconn->waAPI, groupname); waprpl_check_output(purple_account_get_connection(purple_chat_get_account(ch))); // Remove it, it will get added at the moment the chat list gets refreshed purple_blist_remove_chat(node); } }
void waprpl_xfer_init(PurpleXfer * xfer) { purple_debug_info(WHATSAPP_ID, "File xfer init...\n"); wa_file_upload *xinfo = (wa_file_upload *) xfer->data; whatsapp_connection *wconn = xinfo->wconn; size_t fs = purple_xfer_get_size(xfer); const char *fn = purple_xfer_get_filename(xfer); const char *fp = purple_xfer_get_local_filename(xfer); wa_file_upload *xfer_info = (wa_file_upload *) xfer->data; purple_xfer_set_size(xfer, fs); xfer_info->ref_id = waAPI_sendimage(wconn->waAPI, xinfo->to, 100, 100, fs, fp); purple_debug_info(WHATSAPP_ID, "Transfer file %s at %s with size %zu (given ref %d)\n", fn, fp, fs, xfer_info->ref_id); waprpl_check_output(xinfo->gc); }
static int waprpl_send_im(PurpleConnection * gc, const char *who, const char *message, PurpleMessageFlags flags) { whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); char *plain; purple_markup_html_to_xhtml(message, NULL, &plain); char msgid[128]; waAPI_getmsgid(wconn->waAPI, msgid); purple_signal_emit(purple_connection_get_prpl(gc), "whatsapp-sending-message", gc, msgid, who, message); waAPI_sendim(wconn->waAPI, msgid, who, plain); g_free(plain); waprpl_check_output(gc); return 1; }
static void waprpl_connect_cb(gpointer data, gint source, const gchar * error_message) { PurpleConnection *gc = data; whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); PurpleAccount *acct = purple_connection_get_account(gc); const char *resource = purple_account_get_string(acct, "resource", default_resource); if (source < 0) { gchar *tmp = g_strdup_printf("Unable to connect: %s", error_message); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); } else { wconn->fd = source; waAPI_login(wconn->waAPI, resource); wconn->rh = purple_input_add(wconn->fd, PURPLE_INPUT_READ, waprpl_input_cb, gc); wconn->timer = purple_timeout_add_seconds(20, wa_timer_cb, gc); waprpl_check_output(gc); } }
static gboolean wa_timer_cb(gpointer data) { PurpleConnection * gc = (PurpleConnection*)data; waprpl_check_output(gc); return TRUE; }