/* 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[1024]; int ret; do { ret = purple_ssl_read(wconn->gsc, tempbuff, sizeof(tempbuff)); 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_process_ssl_events(gc); */ waprpl_check_ssl_output(gc); /* The input data may generate responses! */ }
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[1024]; int ret; do { int datatosend = waAPI_sslsendcb(wconn->waAPI, tempbuff, sizeof(tempbuff)); 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); }
void check_ssl_requests(PurpleAccount * acct) { PurpleConnection *gc = purple_account_get_connection(acct); whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); char *host; int port; if (wconn->gsc == 0 && waAPI_hassslconnection(wconn->waAPI, &host, &port) > 0) { purple_debug_info("waprpl", "Establishing SSL connection to %s:%d\n", host, port); PurpleSslConnection *sslc = purple_ssl_connect(acct, host, port, waprpl_ssl_connected_cb, waprpl_ssl_cerr_cb, gc); if (sslc == 0) { waprpl_ssl_cerr_cb(0, 0, gc); } else { /* The Fd are not available yet, wait for connected callback */ wconn->gsc = sslc; } } }
/* Checks if the WA protocol has data to output and schedules a write handler */ void waprpl_check_ssl_output(PurpleConnection * gc) { whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); if (wconn->sslfd >= 0) { int r = waAPI_sslhasoutdata(wconn->waAPI); if (r > 0) { /* Need to watch for output data (if we are not doing it already) */ if (wconn->sslwh == 0) wconn->sslwh = purple_input_add(wconn->sslfd, PURPLE_INPUT_WRITE, waprpl_ssl_output_cb, gc); } else if (r < 0) { waprpl_ssl_cerr_cb(0, 0, gc); /* Finished the connection! */ } else { if (wconn->sslwh != 0) purple_input_remove(wconn->sslwh); wconn->sslwh = 0; } purple_debug_info(WHATSAPP_ID, "Watch for output is %d %d\n", r, errno); /* Update transfer status */ int rid, bytes_sent; if (waAPI_fileuploadprogress(wconn->waAPI, &rid, &bytes_sent)) { GList *xfers = purple_xfers_get_all(); while (xfers) { PurpleXfer *xfer = xfers->data; wa_file_upload *xinfo = (wa_file_upload *) xfer->data; if (xinfo->ref_id == rid) { purple_debug_info(WHATSAPP_ID, "Upload progress %d bytes done\n", bytes_sent); purple_xfer_set_bytes_sent(xfer, bytes_sent); purple_xfer_update_progress(xfer); break; } xfers = g_list_next(xfers); } } } // Check uploads to mark them as done :) waprpl_check_complete_uploads(gc); }