void bl_do_set_msg_id (struct tgl_state *TLS, tgl_message_id_t *old_id, tgl_message_id_t *new_id) /* {{{ */ { if (!memcmp (old_id, new_id, sizeof (tgl_message_id_t))) { return; } struct tgl_message *M = tgl_message_get (TLS, old_id); assert (M); if (M->flags & TGLMF_PENDING) { tglm_message_remove_unsent (TLS, M); M->flags &= ~TGLMF_PENDING; } tglm_message_remove_tree (TLS, M); tglm_message_del_peer (TLS, M); M->permanent_id = *new_id; if (tgl_message_get (TLS, new_id)) { tglm_message_del_use (TLS, M); tglm_message_del_temp_id (TLS, M); tglm_message_del_random_id (TLS, M); tgls_free_message (TLS, M); } else { tglm_message_insert_tree (TLS, M); tglm_message_add_peer (TLS, M); } M->server_id = new_id->id; }
void tgl_do_send_encr_action (struct tgl_state *TLS, struct tgl_secret_chat *E, struct tl_ds_decrypted_message_action *A) { long long t; tglt_secure_random (&t, 8); int peer_id = tgl_get_peer_id (E->id); int peer_type = TGL_PEER_ENCR_CHAT; int date = time (0); bl_do_create_message_encr_new (TLS, t, &TLS->our_id, &peer_type, &peer_id, &date, NULL, 0, NULL, A, NULL, TGLMF_PENDING | TGLMF_OUT | TGLMF_UNREAD | TGLMF_CREATE | TGLMF_CREATED | TGLMF_ENCRYPTED); struct tgl_message *M = tgl_message_get (TLS, t); assert (M); tgl_do_send_msg (TLS, M, 0, 0); }
void bl_do_msg_update (struct tgl_state *TLS, tgl_message_id_t *id) /* {{{ */ { struct tgl_message *M = tgl_message_get (TLS, id); if (!M) { return; } assert (M); if (!(M->flags & TGLMF_ENCRYPTED)) { if (TLS->max_msg_id < M->server_id) { TLS->max_msg_id = M->server_id; } } if (TLS->callback.msg_receive) { TLS->callback.msg_receive (TLS, M); } }
void bl_do_message_delete (struct tgl_state *TLS, tgl_message_id_t *id) /* {{{ */ { struct tgl_message *M = tgl_message_get (TLS, id); if (!M) { return; } assert (M); if (M->flags & TGLMF_PENDING) { tglm_message_remove_unsent (TLS, M); M->flags &= ~TGLMF_PENDING; } tglm_message_remove_tree (TLS, M); tglm_message_del_peer (TLS, M); tglm_message_del_use (TLS, M); tglm_message_del_temp_id (TLS, M); tglm_message_del_random_id (TLS, M); tgls_free_message (TLS, M); }
void py_dialog_list_cb (struct tgl_state *TLSR, void *cb_extra, int success, int num, tgl_peer_id_t peers[], int msgs[], int unread[]) { assert (TLSR == TLS); PyObject *callable = cb_extra; PyObject *arglist = NULL; PyObject *dialog_list = NULL; PyObject *dialog = NULL; PyObject *result = NULL; if(PyCallable_Check(callable)) { dialog_list = PyList_New(0); if (success) { int i; for (i = 0; i < num; i++) { dialog = PyDict_New(); PyDict_SetItemString(dialog, "peer", get_peer(peers[i], tgl_peer_get (TLS, peers[i]))); struct tgl_message *M = tgl_message_get (TLS, msgs[i]); if (M && (M->flags & TGLMF_CREATED)) { PyDict_SetItemString(dialog, "message", get_message(M)); } PyDict_SetItemString(dialog, "unread", unread[i] ? Py_True : Py_False); PyList_Append(dialog_list, dialog); } } arglist = Py_BuildValue("(OO)", success ? Py_True : Py_False, dialog_list); result = PyEval_CallObject(callable, arglist); Py_DECREF(arglist); if(result == NULL) PyErr_Print(); Py_XDECREF(result); } Py_XDECREF(callable); }
void tgl_do_send_location_encr (struct tgl_state *TLS, tgl_peer_id_t id, double latitude, double longitude, unsigned long long flags, void (*callback)(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M), void *callback_extra) { struct tl_ds_decrypted_message_media TDSM; TDSM.magic = CODE_decrypted_message_media_geo_point; TDSM.latitude = talloc (sizeof (double)); *TDSM.latitude = latitude; TDSM.longitude = talloc (sizeof (double)); *TDSM.longitude = longitude; int peer_type = tgl_get_peer_type (id); int peer_id = tgl_get_peer_id (id); int date = time (0); long long t; tglt_secure_random (&t, 8); bl_do_create_message_encr_new (TLS, t, &TLS->our_id, &peer_type, &peer_id, &date, NULL, 0, &TDSM, NULL, NULL, TGLMF_UNREAD | TGLMF_OUT | TGLMF_PENDING | TGLMF_CREATE | TGLMF_CREATED | TGLMF_ENCRYPTED); tfree (TDSM.latitude, sizeof (double)); tfree (TDSM.longitude, sizeof (double)); struct tgl_message *M = tgl_message_get (TLS, t); tgl_do_send_encr_msg (TLS, M, callback, callback_extra); }
static void send_file_encrypted_end (struct tgl_state *TLS, struct send_file *f, void *callback, void *callback_extra) { out_int (CODE_messages_send_encrypted_file); out_int (CODE_input_encrypted_chat); out_int (tgl_get_peer_id (f->to_id)); tgl_peer_t *P = tgl_peer_get (TLS, f->to_id); assert (P); out_long (P->encr_chat.access_hash); long long r; tglt_secure_random (&r, 8); out_long (r); encr_start (); out_int (CODE_decrypted_message_layer); out_random (15 + 4 * (lrand48 () % 3)); out_int (TGL_ENCRYPTED_LAYER); out_int (2 * P->encr_chat.in_seq_no + (P->encr_chat.admin_id != TLS->our_id)); out_int (2 * P->encr_chat.out_seq_no + (P->encr_chat.admin_id == TLS->our_id)); out_int (CODE_decrypted_message); out_long (r); out_int (P->encr_chat.ttl); out_string (""); int *save_ptr = packet_ptr; if (f->flags == -1) { out_int (CODE_decrypted_message_media_photo); } else if ((f->flags & TGLDF_VIDEO)) { out_int (CODE_decrypted_message_media_video); } else if ((f->flags & TGLDF_AUDIO)) { out_int (CODE_decrypted_message_media_audio); } else { out_int (CODE_decrypted_message_media_document); } if (f->flags == -1 || !(f->flags & TGLDF_AUDIO)) { out_cstring ("", 0); out_int (90); out_int (90); } if (f->flags == -1) { out_int (f->w); out_int (f->h); } else if (f->flags & TGLDF_VIDEO) { out_int (f->duration); out_string (tg_mime_by_filename (f->file_name)); out_int (f->w); out_int (f->h); } else if (f->flags & TGLDF_AUDIO) { out_int (f->duration); out_string (tg_mime_by_filename (f->file_name)); } else { out_string (""); out_string (tg_mime_by_filename (f->file_name)); // document } out_int (f->size); out_cstring ((void *)f->key, 32); out_cstring ((void *)f->init_iv, 32); int *save_in_ptr = in_ptr; int *save_in_end = in_end; in_ptr = save_ptr; in_end = packet_ptr; assert (skip_type_any (TYPE_TO_PARAM(decrypted_message_media)) >= 0); assert (in_ptr == in_end); in_ptr = save_ptr; in_end = packet_ptr; struct tl_ds_decrypted_message_media *DS_DMM = fetch_ds_type_decrypted_message_media (TYPE_TO_PARAM (decrypted_message_media)); in_end = save_in_ptr; in_ptr = save_in_end; int peer_type = tgl_get_peer_type (f->to_id); int peer_id = tgl_get_peer_id (f->to_id); int date = time (NULL); encr_finish (&P->encr_chat); if (f->size < (16 << 20)) { out_int (CODE_input_encrypted_file_uploaded); } else { out_int (CODE_input_encrypted_file_big_uploaded); } out_long (f->id); out_int (f->part_num); if (f->size < (16 << 20)) { out_string (""); } unsigned char md5[16]; unsigned char str[64]; memcpy (str, f->key, 32); memcpy (str + 32, f->init_iv, 32); MD5 (str, 64, md5); out_int ((*(int *)md5) ^ (*(int *)(md5 + 4))); tfree_secure (f->iv, 32); bl_do_create_message_encr_new (TLS, r, &TLS->our_id, &peer_type, &peer_id, &date, NULL, 0, DS_DMM, NULL, NULL, TGLMF_OUT | TGLMF_UNREAD | TGLMF_ENCRYPTED | TGLMF_CREATE | TGLMF_CREATED); free_ds_type_decrypted_message_media (DS_DMM, TYPE_TO_PARAM (decrypted_message_media)); struct tgl_message *M = tgl_message_get (TLS, r); assert (M); tglq_send_query (TLS, TLS->DC_working, packet_ptr - packet_buffer, packet_buffer, &send_encr_file_methods, M, callback, callback_extra); tfree_str (f->file_name); tfree (f, sizeof (*f)); }
void bl_do_edit_message_encr (struct tgl_state *TLS, tgl_message_id_t *id, tgl_peer_id_t *from_id, tgl_peer_id_t *to_id, int *date, const char *message, int message_len, struct tl_ds_decrypted_message_media *media, struct tl_ds_decrypted_message_action *action, struct tl_ds_encrypted_file *file, int flags) /* {{{ */ { clear_packet (); assert (!(flags & 0xfffe0000)); struct tgl_message *M = tgl_message_get (TLS, id); if (flags & (1 << 16)) { if (!M) { M = tglm_message_alloc (TLS, id); } else { assert (!(M->flags & TGLMF_CREATED)); } assert (!(M->flags & TGLMF_CREATED)); } else { assert (M->flags & TGLMF_CREATED); } assert (flags & TGLMF_CREATED); assert (flags & TGLMF_ENCRYPTED); if ((M->flags & TGLMF_PENDING) && !(flags & TGLMF_PENDING)){ tglm_message_remove_unsent (TLS, M); } if (!(M->flags & TGLMF_PENDING) && (flags & TGLMF_PENDING)){ tglm_message_insert_unsent (TLS, M); } M->flags = flags & 0xffff; if (from_id) { M->from_id = *from_id; } if (to_id) { assert (flags & 0x10000); M->to_id = *to_id; } if (date) { M->date = *date; } struct tgl_secret_chat *E = (void *)tgl_peer_get (TLS, M->to_id); assert (E); if (action) { tglf_fetch_message_action_encrypted (TLS, &M->action, action); M->flags |= TGLMF_SERVICE; } if (message) { M->message_len = message_len; M->message = tstrndup (message, message_len); assert (!(M->flags & TGLMF_SERVICE)); } if (media) { tglf_fetch_message_media_encrypted (TLS, &M->media, media); assert (!(M->flags & TGLMF_SERVICE)); } if (file) { tglf_fetch_encrypted_message_file (TLS, &M->media, file); assert (!(M->flags & TGLMF_SERVICE)); } if (action && !(M->flags & TGLMF_OUT) && M->action.type == tgl_message_action_notify_layer) { E->layer = M->action.layer; } if ((flags & TGLMF_CREATE) && (flags & TGLMF_OUT)) { E->out_seq_no ++; } if (flags & 0x10000) { tglm_message_insert (TLS, M); } }
void bl_do_edit_message (struct tgl_state *TLS, tgl_message_id_t *id, tgl_peer_id_t *from_id, tgl_peer_id_t *to_id, tgl_peer_id_t *fwd_from_id, int *fwd_date, int *date, const char *message, int message_len, struct tl_ds_message_media *media, struct tl_ds_message_action *action, int *reply_id, struct tl_ds_reply_markup *reply_markup, int *views, struct tl_ds_vector *entities, int flags) /* {{{ */ { assert (!(flags & 0xfffe0000)); struct tgl_message *M = tgl_message_get (TLS, id); assert (flags & TGLMF_CREATED); assert (!(flags & TGLMF_ENCRYPTED)); if (flags & (1 << 16)) { if (!M) { M = tglm_message_alloc (TLS, id); } M->server_id = id->id; assert (!(M->flags & TGLMF_CREATED)); } else { assert (M->flags & TGLMF_CREATED); } assert (M); assert (!(M->flags & TGLMF_ENCRYPTED)); if ((M->flags & TGLMF_PENDING) && !(flags & TGLMF_PENDING)){ tglm_message_remove_unsent (TLS, M); } if (!(M->flags & TGLMF_PENDING) && (flags & TGLMF_PENDING)){ tglm_message_insert_unsent (TLS, M); } if ((M->flags & TGLMF_UNREAD) && !(flags & TGLMF_UNREAD)) { M->flags = (flags & 0xffff) | TGLMF_UNREAD; } else { M->flags = (flags & 0xffff); } if (from_id) { M->from_id = *from_id; } else { if (!M->from_id.peer_type) { assert (to_id); M->from_id = *to_id; } } if (to_id) { assert (flags & 0x10000); M->to_id = *to_id; } if (date) { M->date = *date; } if (fwd_from_id) { assert (fwd_date); M->fwd_from_id = *fwd_from_id; M->fwd_date = *fwd_date;; } if (action) { tglf_fetch_message_action (TLS, &M->action, action); M->flags |= TGLMF_SERVICE; } if (message) { M->message_len = message_len; M->message = tstrndup (message, message_len); assert (!(M->flags & TGLMF_SERVICE)); } if (media) { tglf_fetch_message_media (TLS, &M->media, media); assert (!(M->flags & TGLMF_SERVICE)); } if (entities) { tglf_fetch_message_entities (TLS, M, entities); } if (reply_id) { M->reply_id = *reply_id; } if (flags & 0x10000) { tglm_message_insert (TLS, M); } if (!(flags & TGLMF_UNREAD) && (M->flags & TGLMF_UNREAD)) { tgls_messages_mark_read (TLS, M, M->flags & TGLMF_OUT, M->permanent_id.id); } if (reply_markup) { M->reply_markup = tglf_fetch_alloc_reply_markup (TLS, M->next, reply_markup); } if (views) { M->views = *views; } if (M->flags & TGLMF_PENDING) { tgls_message_change_random_id (TLS, M, M->permanent_id.id); } if (!M->temp_id) { tgls_message_change_temp_id (TLS, M, ++TLS->last_temp_id); } }