2 This file is part of Telegram application for tizen
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 #include "tg_engine.h"
20 #include "server_response.h"
23 #include "tg_db_wrapper.h"
24 #include "tgl-fetch.h"
25 #include <mime_type.h>
26 #include "device_contacts_manager.h"
27 #include "tg-engine-service.h"
30 #define DC_SERIALIZED_MAGIC 0x868aa81d
31 #define STATE_FILE_MAGIC 0x28949a93
32 #define SECRET_CHAT_FILE_MAGIC 0x37a1988a
34 static struct _tg_engine {
37 char *default_username;
38 char *config_filename;
41 char *state_file_name;
42 char *secret_chat_file_name;
43 char *downloads_directory;
44 char *config_directory;
45 char *binlog_file_name;
50 int allow_weak_random;
52 int readline_disabled;
54 int reset_authorization;
60 char *config_full_path;
61 int need_dc_list_update;
62 struct tgl_state *TLS;
65 static void on_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info);
66 static void on_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U);
67 static void on_chat_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename);
68 static void on_document_download_completed(struct tgl_state *TLS, void *callback_extra, int success, char *filename);
69 static void on_buddy_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename);
70 static void on_new_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U);
71 extern void delete_all_messages_from_chat(int buddy_id, int type_of_chat);
73 void tgl_engine_var_init(void)
75 s_info.default_username = NULL;
76 s_info.config_filename = NULL;
77 s_info.auth_file_name = NULL;
78 s_info.state_file_name = NULL;
79 s_info.secret_chat_file_name = NULL;
80 s_info.downloads_directory = NULL;
81 s_info.config_directory = NULL;
82 s_info.binlog_file_name = NULL;
83 s_info.lua_file = NULL;
86 void tgl_engine_var_free(void)
88 if (s_info.default_username) {
89 free(s_info.default_username);
90 s_info.default_username = NULL;
92 if (s_info.config_filename) {
93 free(s_info.config_filename);
94 s_info.config_filename = NULL;
96 if (s_info.auth_file_name) {
97 free(s_info.auth_file_name);
98 s_info.auth_file_name = NULL;
100 if (s_info.state_file_name) {
101 free(s_info.state_file_name);
102 s_info.state_file_name = NULL;
104 if (s_info.secret_chat_file_name) {
105 free(s_info.secret_chat_file_name);
106 s_info.secret_chat_file_name = NULL;
108 if (s_info.downloads_directory) {
109 free(s_info.downloads_directory);
110 s_info.downloads_directory = NULL;
112 if (s_info.config_directory) {
113 free(s_info.config_directory);
114 s_info.config_directory = NULL;
116 if (s_info.binlog_file_name) {
117 free(s_info.binlog_file_name);
118 s_info.binlog_file_name = NULL;
120 if (s_info.lua_file) {
121 free(s_info.lua_file);
122 s_info.lua_file = NULL;
125 tgl_state_free(s_info.TLS);
126 tgl_free_all(s_info.TLS);
131 char *tgl_engine_get_auth_key_filename(void)
133 return s_info.auth_file_name;
136 char *tgl_engine_get_state_filename(void)
138 return s_info.state_file_name;
141 char *tgl_engine_get_secret_chat_filename(void)
143 return s_info.secret_chat_file_name;
146 char *tgl_engine_get_downloads_directory(void)
148 return s_info.downloads_directory;
151 void write_dc(struct tgl_dc *DC, void *extra)
153 int auth_file_fd = *(int *)extra;
159 assert(write(auth_file_fd, &x, 4) == 4);
163 assert(write(auth_file_fd, &x, 4) == 4);
164 assert(DC->has_auth);
165 assert(write(auth_file_fd, &DC->port, 4) == 4);
166 int l = strlen(DC->ip);
167 assert(write(auth_file_fd, &l, 4) == 4);
168 assert(write(auth_file_fd, DC->ip, l) == l);
169 assert(write(auth_file_fd, &DC->auth_key_id, 8) == 8);
170 assert(write(auth_file_fd, DC->auth_key, 256) == 256);
173 void write_secret_chat(tgl_peer_t *_P, void *extra)
175 struct tgl_secret_chat *P = (void *)_P;
177 if (tgl_get_peer_type(P->id) != TGL_PEER_ENCR_CHAT) {
181 if (P->state != sc_ok) {
189 int id = tgl_get_peer_id(P->id);
190 assert(write(fd, &id, 4) == 4);
191 //assert(write(fd, &P->flags, 4) == 4);
192 int l = strlen(P->print_name);
193 assert(write(fd, &l, 4) == 4);
194 assert(write(fd, P->print_name, l) == l);
195 assert(write(fd, &P->user_id, 4) == 4);
196 assert(write(fd, &P->admin_id, 4) == 4);
197 assert(write(fd, &P->date, 4) == 4);
198 assert(write(fd, &P->ttl, 4) == 4);
199 assert(write(fd, &P->layer, 4) == 4);
200 assert(write(fd, &P->access_hash, 8) == 8);
201 assert(write(fd, &P->state, 4) == 4);
202 assert(write(fd, &P->key_fingerprint, 8) == 8);
203 assert(write(fd, &P->key, 256) == 256);
204 assert(write(fd, &P->first_key_sha, 20) == 20);
205 assert(write(fd, &P->in_seq_no, 4) == 4);
206 assert(write(fd, &P->last_in_seq_no, 4) == 4);
207 assert(write(fd, &P->out_seq_no, 4) == 4);
210 void write_secret_chat_file(void)
212 if (s_info.binlog_enabled) {
215 int secret_chat_fd = open(tgl_engine_get_secret_chat_filename(), O_CREAT | O_RDWR, 0600);
216 assert(secret_chat_fd >= 0);
217 int x = SECRET_CHAT_FILE_MAGIC;
218 assert(write(secret_chat_fd, &x, 4) == 4);
220 assert(write(secret_chat_fd, &x, 4) == 4); // version
221 assert(write(secret_chat_fd, &x, 4) == 4); // num
224 y[0] = secret_chat_fd;
227 tgl_peer_iterator_ex(s_info.TLS, write_secret_chat, y);
229 lseek(secret_chat_fd, 8, SEEK_SET);
230 assert(write(secret_chat_fd, &y[1], 4) == 4);
231 close(secret_chat_fd);
234 void write_auth_file(void)
236 if (s_info.binlog_enabled) {
240 int auth_file_fd = open(tgl_engine_get_auth_key_filename(), O_CREAT | O_RDWR, 0600);
242 assert(auth_file_fd >= 0);
243 int x = DC_SERIALIZED_MAGIC;
244 assert(write(auth_file_fd, &x, 4) == 4);
245 assert(write(auth_file_fd, &s_info.TLS->max_dc_num, 4) == 4);
246 assert(write(auth_file_fd, &s_info.TLS->dc_working_num, 4) == 4);
247 tgl_dc_iterator_ex(s_info.TLS, write_dc, &auth_file_fd);
248 assert(write(auth_file_fd, &s_info.TLS->our_id, 4) == 4);
252 void read_dc(int auth_file_fd, int id, unsigned ver)
255 assert(read(auth_file_fd, &port, 4) == 4);
257 assert(read(auth_file_fd, &l, 4) == 4);
258 assert(l >= 0 && l < 100);
260 assert(read(auth_file_fd, ip, l) == l);
263 long long auth_key_id;
264 static unsigned char auth_key[256];
265 assert(read(auth_file_fd, &auth_key_id, 8) == 8);
266 assert(read(auth_file_fd, auth_key, 256) == 256);
268 //bl_do_add_dc(id, ip, l, port, auth_key_id, auth_key);
269 bl_do_dc_option(s_info.TLS, id, 2, "DC", l, ip, port);
270 bl_do_set_auth_key_id(s_info.TLS, id, auth_key);
271 bl_do_dc_signed(s_info.TLS, id);
274 void empty_auth_file(void)
276 if (s_info.TLS->test_mode) {
277 bl_do_dc_option(s_info.TLS, 1, 0, "", strlen(TG_SERVER_TEST_1), TG_SERVER_TEST_1, 443);
278 bl_do_dc_option(s_info.TLS, 2, 0, "", strlen(TG_SERVER_TEST_2), TG_SERVER_TEST_2, 443);
279 bl_do_dc_option(s_info.TLS, 3, 0, "", strlen(TG_SERVER_TEST_3), TG_SERVER_TEST_3, 443);
280 bl_do_set_working_dc(s_info.TLS, 2);
282 bl_do_dc_option(s_info.TLS, 1, 0, "", strlen(TG_SERVER_1), TG_SERVER_1, 443);
283 bl_do_dc_option(s_info.TLS, 2, 0, "", strlen(TG_SERVER_2), TG_SERVER_2, 443);
284 bl_do_dc_option(s_info.TLS, 3, 0, "", strlen(TG_SERVER_3), TG_SERVER_3, 443);
285 bl_do_dc_option(s_info.TLS, 4, 0, "", strlen(TG_SERVER_4), TG_SERVER_4, 443);
286 bl_do_dc_option(s_info.TLS, 5, 0, "", strlen(TG_SERVER_5), TG_SERVER_5, 443);
287 bl_do_set_working_dc(s_info.TLS, 4);
291 void read_secret_chat(int fd, int v)
293 int id, l, user_id, admin_id, date, ttl, layer, state;
294 long long access_hash, key_fingerprint;
296 static unsigned char key[256];
297 static unsigned char sha[20];
298 assert(read(fd, &id, 4) == 4);
299 //assert(read(fd, &flags, 4) == 4);
300 assert(read(fd, &l, 4) == 4);
301 assert(l > 0 && l < 1000);
302 assert(read(fd, s, l) == l);
303 assert(read(fd, &user_id, 4) == 4);
304 assert(read(fd, &admin_id, 4) == 4);
305 assert(read(fd, &date, 4) == 4);
306 assert(read(fd, &ttl, 4) == 4);
307 assert(read(fd, &layer, 4) == 4);
308 assert(read(fd, &access_hash, 8) == 8);
309 assert(read(fd, &state, 4) == 4);
310 assert(read(fd, &key_fingerprint, 8) == 8);
311 assert(read(fd, &key, 256) == 256);
313 assert(read(fd, sha, 20) == 20);
315 int in_seq_no = 0, out_seq_no = 0, last_in_seq_no = 0;
317 assert(read(fd, &in_seq_no, 4) == 4);
318 assert(read(fd, &last_in_seq_no, 4) == 4);
319 assert(read(fd, &out_seq_no, 4) == 4);
322 bl_do_encr_chat_create(s_info.TLS, id, user_id, admin_id, s, l);
323 struct tgl_secret_chat *P = (void *)tgl_peer_get(s_info.TLS, TGL_MK_ENCR_CHAT(id));
324 assert(P && (P->flags & FLAG_CREATED));
325 bl_do_encr_chat_set_date(s_info.TLS, P, date);
326 bl_do_encr_chat_set_ttl(s_info.TLS, P, ttl);
327 bl_do_encr_chat_set_layer(s_info.TLS , P, layer);
328 bl_do_encr_chat_set_access_hash(s_info.TLS, P, access_hash);
329 bl_do_encr_chat_set_state(s_info.TLS, P, state);
330 bl_do_encr_chat_set_key(s_info.TLS, P, key, key_fingerprint);
332 bl_do_encr_chat_set_sha(s_info.TLS, P, sha);
334 SHA1((void *)key, 256, sha);
335 bl_do_encr_chat_set_sha(s_info.TLS, P, sha);
338 bl_do_encr_chat_set_seq(s_info.TLS, P, in_seq_no, last_in_seq_no, out_seq_no);
342 void read_secret_chat_file(void)
344 if (s_info.binlog_enabled) {
348 int secret_chat_fd = open(tgl_engine_get_secret_chat_filename(), O_RDWR, 0600);
350 if (secret_chat_fd < 0) {
353 //assert(secret_chat_fd >= 0);
355 if (read(secret_chat_fd, &x, 4) < 4) { close(secret_chat_fd); return; }
356 if (x != SECRET_CHAT_FILE_MAGIC) { close(secret_chat_fd); return; }
358 assert(read(secret_chat_fd, &v, 4) == 4);
359 assert(v == 0 || v == 1 || v == 2); // version
360 assert(read(secret_chat_fd, &x, 4) == 4);
363 read_secret_chat(secret_chat_fd, v);
365 close(secret_chat_fd);
368 void read_state_file(void)
370 if (s_info.binlog_enabled) {
373 int state_file_fd = open(tgl_engine_get_state_filename(), O_CREAT | O_RDWR, 0600);
374 if (state_file_fd < 0)
379 if (read(state_file_fd, &magic, 4) < 4) {
380 close(state_file_fd);
384 if (magic != (int)STATE_FILE_MAGIC) {
385 close(state_file_fd);
389 if (read(state_file_fd, &version, 4) < 4) {
390 close(state_file_fd);
394 assert(version >= 0);
397 if (read(state_file_fd, x, 16) < 16) {
398 close(state_file_fd);
406 close(state_file_fd);
407 bl_do_set_seq(s_info.TLS, seq);
408 bl_do_set_pts(s_info.TLS, pts);
409 bl_do_set_qts(s_info.TLS, qts);
410 bl_do_set_date(s_info.TLS, date);
413 void read_auth_file(void)
415 if (s_info.binlog_enabled) {
420 auth_file_fd = open(tgl_engine_get_auth_key_filename(), O_CREAT | O_RDWR, 0600);
421 if (auth_file_fd < 0) {
423 * Logging this for handling exceptional cases.
429 assert(auth_file_fd >= 0);
433 if (read(auth_file_fd, &m, 4) < 4 || (m != DC_SERIALIZED_MAGIC)) {
439 assert(read(auth_file_fd, &x, 4) == 4);
442 assert(read(auth_file_fd, &dc_working_num, 4) == 4);
445 for (i = 0; i <= (int)x; i++) {
447 assert(read(auth_file_fd, &y, 4) == 4);
449 read_dc(auth_file_fd, i, m);
453 bl_do_set_working_dc(s_info.TLS, dc_working_num);
455 int l = read(auth_file_fd, &our_id, 4);
461 bl_do_set_our_id(s_info.TLS, our_id);
466 void tg_new_msg(struct tgl_state *TLS, struct tgl_message *M)
468 struct tgl_message *temp_msg = tgl_message_get(TLS, M->id);
470 LOGE("memory allocation failed!!! for tgl_message_get");
473 void tg_marked_read(struct tgl_state *TLS, int num, struct tgl_message *list[])
475 for (int i = 0; i < num; i++) {
477 struct tgl_message* message = list[i];
480 UC = tgl_peer_get(TLS, message->to_id);
481 struct tgl_user* buddy;
484 if (buddy && buddy->phone && strlen(buddy->phone) > 0) {
485 phone = buddy->phone;
488 message->msg_state = TG_MESSAGE_STATE_READ;
490 char *tb_name = get_table_name_from_number(message->to_id.id);
491 update_msg_into_db(message, tb_name, identifier);
492 if (message->media.type == tgl_message_media_photo) {
493 update_sent_media_info_in_db(message, (long long)message->media.photo.id);
495 send_message_read_by_buddy_response(TLS->callback_data, message->to_id.id, message->id, tb_name, phone, tgl_get_peer_type(message->to_id));
501 void on_code_via_phone_result(struct tgl_state *TLS, void *callback_extra, int success)
510 void request_for_code_via_call(struct tgl_state *TLS, char* phone_no, Eina_Bool trough_sms)
512 tg_engine_data_s *tg_data;
513 tg_data = TLS->callback_data;
514 if (tg_data && tg_data->phone_number && tg_data->mhash) {
515 tgl_do_phone_call(TLS, tg_data->phone_number, tg_data->mhash, on_code_via_phone_result, TLS);
519 void tg_get_string(struct tgl_state *TLS, const char *prompt, int flags, void(*callback)(struct tgl_state *TLS, char *string, void *arg), void *arg)
521 tg_engine_data_s *tg_data;
523 tg_data = TLS->callback_data;
525 tg_data->get_string = callback;
526 tg_data->callback_arg = arg;
527 if (strcmp(prompt, "phone number:") == 0) {
529 if (tg_data->tg_state == TG_ENGINE_STATE_REGISTRATION) {
530 send_request_phone_num_again(tg_data);
532 tg_data->tg_state = TG_ENGINE_STATE_REGISTRATION;
533 if (tg_data && tg_data->phone_number)
534 tg_data->get_string(TLS, tg_data->phone_number, tg_data->callback_arg);
536 send_request_phone_new_num(tg_data);
539 } else if (strcmp(prompt, "code('call' for phone call):") == 0) {
542 tg_data->mhash = strdup(T[1]);
544 if (tg_data->tg_state == TG_ENGINE_STATE_CODE_REQUEST) {
545 send_request_code_again(tg_data);
547 tg_data->tg_state = TG_ENGINE_STATE_CODE_REQUEST;
548 send_registration_response(tg_data, EINA_TRUE);
551 } else if (strcmp(prompt, "register [Y/n]:") == 0) {
553 tg_data->tg_state = TG_ENGINE_STATE_PROFILE_REGISTRATION;
554 tg_data->get_string(TLS, "Y", tg_data->callback_arg);
556 } else if (strcmp(prompt, "First name:") == 0) {
558 tg_data->tg_state = TG_ENGINE_STATE_PROFILE_FIRST_NAME_REGISTRATION;
559 tg_data->is_first_time_registration = EINA_TRUE;
561 if (tg_data->first_name) {
562 tg_data->get_string(TLS, tg_data->first_name, tg_data->callback_arg);
564 send_name_registration_response(tg_data);
567 } else if (strcmp(prompt, "Last name:") == 0) {
569 tg_data->tg_state = TG_ENGINE_STATE_PROFILE_LAST_NAME_REGISTRATION;
571 if (tg_data->last_name) {
572 tg_data->get_string(TLS, tg_data->last_name, tg_data->callback_arg);
582 void tg_logged_in(struct tgl_state *TLS)
584 tg_engine_data_s *tg_data;
585 tg_data = TLS->callback_data;
587 int offline_mode = 0;
589 t_id.id = TLS->our_id;
590 t_id.type = TGL_PEER_USER;
591 //tg_data->is_first_time_registration = EINA_TRUE;
592 create_data_base_tables();
593 tgl_do_get_user_info(TLS, t_id, offline_mode, &on_user_info_loaded, NULL);
596 static Eina_Bool on_send_media_message_requested(void *data)
598 sent_media_data_s *media_info = (sent_media_data_s*)data;
600 int buddy_id = atoi(media_info->buddy_id);
601 int message_id = atoi(media_info->message_id);
602 int media_id = atoi(media_info->media_id);
603 int msg_type = atoi(media_info->message_type);
604 int type_of_chat = atoi(media_info->type_of_chat);
606 process_send_media_command(buddy_id, message_id, media_id, msg_type, media_info->file_path, type_of_chat);
608 if (media_info->app_name) {
609 free(media_info->app_name);
610 media_info->app_name = NULL;
612 if (media_info->command) {
613 free(media_info->command);
614 media_info->command = NULL;
616 if (media_info->buddy_id) {
617 free(media_info->buddy_id);
618 media_info->buddy_id = NULL;
620 if (media_info->message_id) {
621 free(media_info->message_id);
622 media_info->message_id = NULL;
624 if (media_info->media_id) {
625 free(media_info->media_id);
626 media_info->media_id = NULL;
629 if (media_info->message_type) {
630 free(media_info->message_type);
631 media_info->message_type = NULL;
633 if (media_info->file_path) {
634 free(media_info->file_path);
635 media_info->file_path = NULL;
637 if (media_info->type_of_chat) {
638 free(media_info->type_of_chat);
639 media_info->type_of_chat = NULL;
643 return ECORE_CALLBACK_CANCEL;
645 static Eina_Bool on_load_offline_messages(void *data);
646 static Eina_Bool on_send_unsent_messages_requested(void *data)
648 struct tgl_state *TLS = data;
650 return ECORE_CALLBACK_CANCEL;
652 //tg_engine_data_s *tg_data = TLS->callback_data;
654 Eina_List *unset_text_msgs = get_all_unsent_text_messages();
655 sent_message_data_s* msg_info = NULL;
656 EINA_LIST_FREE(unset_text_msgs, msg_info) {
657 int buddy_id = atoi(msg_info->buddy_id);
658 int message_id = atoi(msg_info->message_id);
659 int msg_type = atoi(msg_info->message_type);
660 int type_of_chat = atoi(msg_info->type_of_chat);
661 process_send_message_command(buddy_id, message_id, msg_type, msg_info->message_data, type_of_chat);
663 if (msg_info->app_name) {
664 free(msg_info->app_name);
665 msg_info->app_name = NULL;
667 if (msg_info->command) {
668 free(msg_info->command);
669 msg_info->command = NULL;
671 if (msg_info->buddy_id) {
672 free(msg_info->buddy_id);
673 msg_info->buddy_id = NULL;
675 if (msg_info->message_id) {
676 free(msg_info->message_id);
677 msg_info->message_id = NULL;
680 if (msg_info->message_type) {
681 free(msg_info->message_type);
682 msg_info->message_type = NULL;
684 if (msg_info->message_data) {
685 free(msg_info->message_data);
686 msg_info->message_data = NULL;
688 if (msg_info->type_of_chat) {
689 free(msg_info->type_of_chat);
690 msg_info->type_of_chat = NULL;
695 Eina_List *unset_media_msgs = get_all_unsent_media_messages();
697 sent_media_data_s* media_info = NULL;
698 EINA_LIST_FREE(unset_media_msgs, media_info) {
699 sent_media_data_s* new_media_info = (sent_media_data_s*)malloc(sizeof(sent_media_data_s));
700 new_media_info->app_name = strdup(media_info->app_name);
701 new_media_info->command = strdup(media_info->command);
702 new_media_info->buddy_id = strdup(media_info->buddy_id);
703 new_media_info->message_id = strdup(media_info->message_id);
704 new_media_info->media_id = strdup(media_info->media_id);
705 new_media_info->message_type = strdup(media_info->message_type);
706 new_media_info->file_path = strdup(media_info->file_path);
707 new_media_info->type_of_chat = strdup(media_info->type_of_chat);
709 ecore_timer_add(init_time, on_send_media_message_requested, new_media_info);
711 if (media_info->app_name) {
712 free(media_info->app_name);
713 media_info->app_name = NULL;
715 if (media_info->command) {
716 free(media_info->command);
717 media_info->command = NULL;
719 if (media_info->buddy_id) {
720 free(media_info->buddy_id);
721 media_info->buddy_id = NULL;
723 if (media_info->message_id) {
724 free(media_info->message_id);
725 media_info->message_id = NULL;
727 if (media_info->media_id) {
728 free(media_info->media_id);
729 media_info->media_id = NULL;
732 if (media_info->message_type) {
733 free(media_info->message_type);
734 media_info->message_type = NULL;
736 if (media_info->file_path) {
737 free(media_info->file_path);
738 media_info->file_path = NULL;
740 if (media_info->type_of_chat) {
741 free(media_info->type_of_chat);
742 media_info->type_of_chat = NULL;
746 ecore_timer_add(1, on_load_offline_messages, TLS);
747 return ECORE_CALLBACK_CANCEL;
750 void tg_started(struct tgl_state *TLS)
752 tg_engine_data_s *tg_data = TLS->callback_data;
753 tg_data->is_login_activated = EINA_TRUE;
756 void tg_type_notification(struct tgl_state *TLS, struct tgl_user* buddy, enum tgl_typing_status status)
758 char *name_of_buddy = NULL;
760 if (buddy->first_name && buddy->last_name) {
761 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + strlen(buddy->last_name) + 1);
762 strcpy(name_of_buddy, buddy->first_name);
763 strcat(name_of_buddy, buddy->last_name);
764 } else if (buddy->first_name) {
765 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + 1);
766 strcpy(name_of_buddy, buddy->first_name);
768 name_of_buddy = (char *)malloc(strlen(" ") + 1);
769 strcpy(name_of_buddy, " ");
772 send_buddy_type_notification_response(TLS->callback_data, buddy->id.id, name_of_buddy, status);
776 name_of_buddy = NULL;
780 void tg_type_in_chat_notification(struct tgl_state *TLS, struct tgl_user *U, struct tgl_chat *C, enum tgl_typing_status status)
785 void tg_type_in_secret_chat_notification(struct tgl_state *TLS, struct tgl_secret_chat *E)
790 void tg_status_notification(struct tgl_state *TLS, struct tgl_user *buddy)
796 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
798 char *name_of_buddy = NULL;
799 if (buddy->first_name && buddy->last_name) {
800 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + strlen(buddy->last_name) + 1);
801 strcpy(name_of_buddy, buddy->first_name);
802 strcat(name_of_buddy, buddy->last_name);
803 } else if (buddy->first_name) {
804 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + 1);
805 strcpy(name_of_buddy, buddy->first_name);
807 name_of_buddy = (char *)malloc(strlen(" ") + 1);
808 strcpy(name_of_buddy, " ");
811 send_buddy_status_notification_response(TLS->callback_data, buddy->id.id, name_of_buddy, buddy->status.online);
815 name_of_buddy = NULL;
819 void tg_user_registered(struct tgl_state *TLS, struct tgl_user *U)
824 void tg_user_activated(struct tgl_state *TLS, struct tgl_user *U)
829 void tg_new_authorization(struct tgl_state *TLS, const char *device, const char *location)
834 void tg_chat_update(struct tgl_state *TLS, struct tgl_chat* chat_info, unsigned flags)
836 tg_engine_data_s *tg_data;
837 tg_data = TLS->callback_data;
839 if (chat_info && chat_info->flags == 144) {
843 if (flags == TGL_GROUP_CHAT_CREATED) {
845 insert_chat_info_to_db(chat_info, NULL);
846 tgl_peer_t* UC = tgl_peer_get(TLS, chat_info->id);
847 insert_peer_into_database(UC, 0, 0);
849 //if (tg_data->is_loading_completed) {
850 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_chat_info_received, NULL);
854 if (!(flags & TGL_UPDATE_CREATED)) {
856 if (!(flags & TGL_UPDATE_DELETED)) {
865 static inline void send_message(tg_engine_data_s *tg_data, struct tgl_user *buddy, const char *str, const char *name_of_buddy, int name_of_buddy_len)
871 * "%s phone number updated" will be changed to IDS_STRING for i18n.
873 len = name_of_buddy_len + strlen(str);
874 update_msg = (char *)malloc(len + 1);
879 snprintf(update_msg, len, str, name_of_buddy);
880 send_contact_updated_response(tg_data, buddy->id.id, update_msg);
884 void tg_user_update(struct tgl_state *TLS, struct tgl_user *buddy, unsigned flags)
887 int name_of_buddy_len;
888 static const char *NO_NAME = " ";
890 if (flags & TGL_UPDATE_CREATED) {
894 if (buddy->first_name && buddy->last_name) {
895 int first_len = strlen(buddy->first_name);
896 int last_len = strlen(buddy->last_name);
898 name_of_buddy_len = first_len + last_len;
900 name_of_buddy = (char *)malloc(name_of_buddy_len + 1);
902 strcpy(name_of_buddy, buddy->first_name);
903 strcpy(name_of_buddy + first_len, buddy->last_name);
904 } else if (buddy->first_name) {
905 name_of_buddy = strdup(buddy->first_name);
906 name_of_buddy_len = strlen(name_of_buddy);
908 name_of_buddy = (char *)NO_NAME;
909 name_of_buddy_len = strlen(NO_NAME);
912 if (!name_of_buddy) {
915 * Unable to allocate heap for buddy name
917 name_of_buddy = (char *)NO_NAME;
918 name_of_buddy_len = strlen(NO_NAME);
921 if (!(flags & TGL_UPDATE_DELETED)) {
922 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
924 if (flags & TGL_UPDATE_PHONE) {
925 send_message(TLS->callback_data, buddy, "%s phone number updated.", name_of_buddy, name_of_buddy_len);
927 if (flags & TGL_UPDATE_CONTACT) {
928 send_message(TLS->callback_data, buddy, "%s contact updated.", name_of_buddy, name_of_buddy_len);
930 if (flags & TGL_UPDATE_PHOTO) {
931 send_message(TLS->callback_data, buddy, "%s photo updated.", name_of_buddy, name_of_buddy_len);
932 //tgl_do_get_user_info(TLS, buddy->id, 0, &on_buddy_info_loaded, NULL);
934 if (flags & TGL_UPDATE_BLOCKED) {
935 send_message(TLS->callback_data, buddy, "%s contact blocked.", name_of_buddy, name_of_buddy_len);
937 if (flags & TGL_UPDATE_REAL_NAME) {
938 send_message(TLS->callback_data, buddy, "%s name updated.", name_of_buddy, name_of_buddy_len);
940 if (flags & TGL_UPDATE_NAME) {
941 send_message(TLS->callback_data, buddy, "%s contact name updated.", name_of_buddy, name_of_buddy_len);
943 if (flags & TGL_UPDATE_REQUESTED) {
944 send_message(TLS->callback_data, buddy, "%s status updated.", name_of_buddy, name_of_buddy_len);
946 if (flags & TGL_UPDATE_WORKING) {
947 send_message(TLS->callback_data, buddy, "%s status updated.", name_of_buddy, name_of_buddy_len);
949 if (flags & TGL_UPDATE_FLAGS) {
950 send_message(TLS->callback_data, buddy, "%s flags updated.", name_of_buddy, name_of_buddy_len);
952 if (flags & TGL_UPDATE_TITLE) {
953 send_message(TLS->callback_data, buddy, "%s title updated.", name_of_buddy, name_of_buddy_len);
955 if (flags & TGL_UPDATE_ADMIN) {
956 send_message(TLS->callback_data, buddy, "%s admin updated.", name_of_buddy, name_of_buddy_len);
958 if (flags & TGL_UPDATE_MEMBERS) {
959 send_message(TLS->callback_data, buddy, "%s memgers updated.", name_of_buddy, name_of_buddy_len);
961 if (flags & TGL_UPDATE_ACCESS_HASH) {
962 send_message(TLS->callback_data, buddy, "%s access hash updated.", name_of_buddy, name_of_buddy_len);
964 if (flags & TGL_UPDATE_USERNAME) {
965 send_message(TLS->callback_data, buddy, "%s username updated.", name_of_buddy, name_of_buddy_len);
968 send_message(TLS->callback_data, buddy, "%s contact deleted.", name_of_buddy, name_of_buddy_len);
971 if (name_of_buddy != NO_NAME) {
973 name_of_buddy = NULL;
977 void tg_secret_chat_update(struct tgl_state *TLS, struct tgl_secret_chat *C, unsigned flags)
982 void on_new_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
984 tg_engine_data_s *tg_data;
986 struct tgl_message *M = callback_extra;
992 if (chat_info->user_list) {
993 for (int i = 0; i < chat_info->user_list_size; i++) {
994 int user_id = chat_info->user_list[i].user_id;
995 Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
996 char* tb_name = get_table_name_from_number(user_id);
997 create_buddy_msg_table(tb_name);
998 if (!is_present_in_db) {
999 // add to buddy table
1000 tgl_peer_id_t from_id;
1001 from_id.id = user_id;
1002 from_id.type = TGL_PEER_USER;
1003 tgl_do_get_user_info(TLS, from_id, 0, on_new_buddy_info_loaded, NULL);
1009 tg_data = TLS->callback_data;
1011 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1012 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
1013 char* creator_name = (char*)malloc(msg_len);
1014 strcpy(creator_name, UC->user.first_name);
1015 strcat(creator_name, " created the group");
1017 int cur_time = time(NULL);
1018 M->id = chat_info->id.id;
1019 M->message = creator_name;
1020 M->message_len = msg_len;
1023 insert_buddy_msg_to_db(M);
1026 tgl_peer_t* chat_UC = tgl_peer_get(TLS, chat_info->id);
1027 insert_chat_info_to_db(chat_info, NULL);
1029 insert_peer_into_database(chat_UC, 0, 0, 0);
1031 send_new_group_added_response(tg_data, chat_info->id.id);
1035 void on_group_chat_info_updated(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1037 tg_engine_data_s *tg_data;
1043 tg_data = TLS->callback_data;
1044 char *type_of_change = callback_extra;
1046 if (!type_of_change) {
1047 type_of_change = strdup("");
1050 tgl_peer_t* chat_UC = tgl_peer_get(TLS, chat_info->id);
1051 insert_chat_info_to_db(chat_info, NULL);
1052 insert_peer_into_database(chat_UC, 0, 0, 0);
1053 send_group_chat_updated_response(tg_data, chat_info->id.id, type_of_change);
1054 free(type_of_change);
1057 void on_new_chat_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1059 struct tgl_message *M = callback_extra;
1064 tgl_peer_t* peer = tgl_peer_get(TLS, M->from_id);
1065 int msg_len = strlen(peer->user.first_name) + strlen(" changed group icon") + 1;
1066 char* creator_name = (char*)malloc(msg_len);
1067 strcpy(creator_name, peer->user.first_name);
1068 strcat(creator_name, " changed group icon");
1070 int cur_time = time(NULL);
1072 M->message = creator_name;
1073 M->message_len = msg_len;
1076 insert_buddy_msg_to_db(M);
1078 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1081 tgl_peer_t* UC = tgl_peer_get(TLS, M->to_id);
1082 struct tgl_chat *chat_info = &(UC->chat);
1083 update_chat_info_to_db(chat_info, filename);
1084 update_peer_info_database(UC, 0);
1085 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, chat_info->id.id);
1086 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, filename);
1090 void on_media_sticker_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1092 struct tgl_message *M = (struct tgl_message*)callback_extra;
1093 if (success && filename) {
1094 // update in db and send info to app...
1095 long long media_id = M->media.document.id;
1096 update_receive_media_info_in_db(media_id, filename);
1097 tg_engine_data_s *tg_data = TLS->callback_data;
1098 if (M->from_id.id == tg_data->id.id) {
1101 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1106 void on_video_thumb_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1108 struct tgl_message *M = (struct tgl_message*)callback_extra;
1109 if (success && filename) {
1110 // update in db and send info to app...
1111 long long media_id = M->media.document.id;
1112 update_video_thumb_in_db(media_id, filename);
1113 tg_engine_data_s *tg_data = TLS->callback_data;
1114 if (M->from_id.id == tg_data->id.id) {
1115 send_video_thumb_download_completed_response(tg_data, M->from_id.id, M->to_id.id, media_id, filename, NULL);
1117 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1122 struct tg_temp_msg_data {
1123 Ecore_Timer* send_timer;
1124 struct tgl_state *TLS;
1125 struct tgl_message *M;
1128 static Eina_Bool on_msg_received_cb(void *data)
1130 struct tg_temp_msg_data *msg_data = data;
1131 insert_buddy_msg_to_db(msg_data->M);
1132 if (msg_data->M->media.type != tgl_message_media_none) {
1133 insert_media_info_to_db(msg_data->M, NULL);
1134 if (msg_data->M->media.type != tgl_message_media_none && (msg_data->M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1135 tgl_do_load_document_thumb(msg_data->TLS, &(msg_data->M->media.document), on_video_thumb_loaded, msg_data->M);
1136 if (msg_data->send_timer) {
1137 ecore_timer_del(msg_data->send_timer);
1140 return ECORE_CALLBACK_CANCEL;
1143 // inform to application
1144 send_message_received_response(msg_data->TLS->callback_data, msg_data->M->from_id.id, msg_data->M->to_id.id, msg_data->M->id, tgl_get_peer_type(msg_data->M->to_id));
1145 if (msg_data->send_timer) {
1146 ecore_timer_del(msg_data->send_timer);
1149 return ECORE_CALLBACK_CANCEL;
1152 void on_requested_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1154 tg_engine_data_s *tg_data;
1156 struct tgl_message *M = callback_extra;
1164 if (!chat_info->user_list) {
1165 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_requested_chat_info_received, callback_extra);
1169 tg_data = TLS->callback_data;
1171 msg_table = get_table_name_from_number(chat_info->id.id);
1173 create_buddy_msg_table(msg_table);
1175 insert_chat_info_to_db(chat_info, NULL);
1176 struct tgl_photo *pic = &(chat_info->photo);
1178 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
1182 int msg_id = insert_current_date_to_table(msg_table);
1184 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, msg_id, tgl_get_peer_type(M->to_id));
1185 struct tg_temp_msg_data *msg_data = (struct tg_temp_msg_data*)malloc(sizeof(struct tg_temp_msg_data));
1187 msg_data->TLS = TLS;
1188 msg_data->send_timer = ecore_timer_add(1, on_msg_received_cb, msg_data);
1190 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1191 M->message = strdup("Audio");
1192 M->message_len = strlen("Audio");
1193 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1194 M->message = strdup("Video");
1195 M->message_len = strlen("Video");
1197 insert_buddy_msg_to_db(M);
1198 if (M->media.type != tgl_message_media_none) {
1199 insert_media_info_to_db(M, NULL);
1200 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1201 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1205 // inform to application
1206 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1213 void on_requested_update_chat_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1215 tg_engine_data_s *tg_data;
1217 msg_table = get_table_name_from_number(chat_info->id.id);
1218 create_buddy_msg_table(msg_table);
1224 if (chat_info->flags == 144) {
1227 int msg_count = get_number_of_messages(msg_table);
1228 if (msg_count <= 0) {
1229 if (chat_info->admin_id > 0) {
1230 set_date_item_to_table(msg_table, chat_info->date);
1231 tgl_peer_id_t admin_id;
1232 admin_id.id = chat_info->admin_id;
1233 admin_id.type = TGL_PEER_USER;
1235 tgl_peer_t* UC = tgl_peer_get(TLS, admin_id);
1236 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
1237 char* creator_name = (char*)malloc(msg_len);
1238 strcpy(creator_name, UC->user.first_name);
1239 strcat(creator_name, " created the group");
1240 struct tgl_message msg;
1241 int cur_time = chat_info->date;
1242 msg.to_id = chat_info->id;
1243 msg.from_id = admin_id;
1244 msg.id = chat_info->id.id;
1245 msg.message = creator_name;
1246 msg.message_len = msg_len;
1248 msg.date = cur_time;
1249 msg.media.type = tgl_message_media_none;
1253 insert_buddy_msg_to_db(&msg);
1255 //send_message_received_response(TLS->callback_data, msg.from_id.id, msg.to_id.id, msg.id, tgl_get_peer_type(msg.to_id));
1262 if (!chat_info->user_list) {
1263 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_chat_info_received, NULL);
1267 tg_data = TLS->callback_data;
1269 insert_chat_info_to_db(chat_info, NULL);
1270 struct tgl_photo *pic = &(chat_info->photo);
1272 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
1274 //char *type_of_change = strdup("add_user");
1275 tgl_peer_t* chat_UC = tgl_peer_get(TLS, chat_info->id);
1276 insert_chat_info_to_db(chat_info, NULL);
1277 insert_peer_into_database(chat_UC, 0, 0, 0);
1278 send_response_to_group_chat_updated_response(tg_data, chat_info->id.id);
1279 //free(type_of_change);
1282 void do_update_chat_info(int chat_id)
1284 tgl_peer_id_t to_id;
1286 to_id.type = TGL_PEER_CHAT;
1287 tgl_do_get_chat_info(s_info.TLS, to_id, 0, &on_requested_update_chat_received, NULL);
1290 void on_new_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U)
1295 tg_engine_data_s *tg_data = TLS->callback_data;
1296 struct tgl_message *M = callback_extra;
1297 if (U->id.id == tg_data->id.id) {
1300 tgl_peer_t* UC = tgl_peer_get(TLS, U->id);
1301 insert_peer_into_database(UC, 0, 0, 1);
1303 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, U);
1304 struct tgl_photo* pic = &(U->photo);
1306 tgl_do_load_photo(TLS, pic, &on_buddy_pic_loaded, U);
1309 send_new_buddy_added_response(tg_data, U->id.id);
1312 char* tb_name = get_table_name_from_number(U->id.id);
1313 int msg_id = insert_current_date_to_table(tb_name);
1316 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, msg_id, tgl_get_peer_type(M->to_id));
1318 struct tg_temp_msg_data *msg_data = (struct tg_temp_msg_data*)malloc(sizeof(struct tg_temp_msg_data));
1320 msg_data->TLS = TLS;
1321 msg_data->send_timer = ecore_timer_add(3, on_msg_received_cb, msg_data);
1323 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1324 M->message = strdup("Audio");
1325 M->message_len = strlen("Audio");
1326 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1327 M->message = strdup("Video");
1328 M->message_len = strlen("Video");
1330 insert_buddy_msg_to_db(M);
1331 if (M->media.type != tgl_message_media_none) {
1332 insert_media_info_to_db(M, NULL);
1333 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1334 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1336 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1340 // inform to application
1341 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1346 void tg_msg_receive(struct tgl_state *TLS, struct tgl_message *M)
1348 if (M && TLS->started) {
1350 if (M->flags & (FLAG_MESSAGE_EMPTY | FLAG_DELETED)) {
1353 if (!(M->flags & FLAG_CREATED)) {
1357 // this is service message. to be handled in telegram.
1358 if (tgl_get_peer_id(M->from_id) != TLS->our_id) {
1359 char *type_of_change = NULL;
1360 if (M->action.type == tgl_message_action_chat_create) {
1362 char* msg_table = get_table_name_from_number(M->to_id.id);
1363 create_buddy_msg_table(msg_table);
1366 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_new_chat_info_received, M);
1368 } else if (M->action.type == tgl_message_action_chat_edit_title) {
1369 type_of_change = strdup("edit_title");
1370 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1371 int msg_len = strlen(UC->user.first_name) + strlen(" changed the chat title") + 1;
1372 char* creator_name = (char*)malloc(msg_len);
1373 strcpy(creator_name, UC->user.first_name);
1374 strcat(creator_name, " changed the chat title");
1376 int cur_time = time(NULL);
1378 M->message = creator_name;
1379 M->message_len = msg_len;
1382 insert_buddy_msg_to_db(M);
1384 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1385 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
1386 } else if (M->action.type == tgl_message_action_chat_edit_photo) {
1388 char* msg_table = get_table_name_from_number(M->to_id.id);
1389 create_buddy_msg_table(msg_table);
1390 int msg_id = insert_current_date_to_table(msg_table);
1392 struct tgl_photo *pic = &(M->action.photo);
1394 tgl_do_load_photo(TLS, pic, &on_new_chat_pic_loaded, M);
1397 } else if (M->action.type == tgl_message_action_chat_delete_photo) {
1398 type_of_change = strdup("delete_photo");
1399 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1400 int msg_len = strlen(UC->user.first_name) + strlen(" deleted the profile photo") + 1;
1401 char* creator_name = (char*)malloc(msg_len);
1402 strcpy(creator_name, UC->user.first_name);
1403 strcat(creator_name, " deleted the profile photo");
1405 int cur_time = time(NULL);
1407 M->message = creator_name;
1408 M->message_len = msg_len;
1411 insert_buddy_msg_to_db(M);
1413 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1416 char *filename = "";
1417 tgl_peer_t* lUC = tgl_peer_get(TLS, M->to_id);
1418 struct tgl_chat *chat_info = &(lUC->chat);
1419 update_chat_info_to_db(chat_info, filename);
1420 update_peer_info_database(lUC, 0);
1421 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, chat_info->id.id);
1422 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, filename);
1425 } else if (M->action.type == tgl_message_action_chat_add_user) {
1426 type_of_change = strdup("add_user");
1427 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1428 int msg_len = strlen(UC->user.first_name) + strlen(" added to the group") + 1;
1429 char* creator_name = (char*)malloc(msg_len);
1430 strcpy(creator_name, UC->user.first_name);
1431 strcat(creator_name, " added to the group");
1433 int cur_time = time(NULL);
1435 M->message = creator_name;
1436 M->message_len = msg_len;
1439 insert_buddy_msg_to_db(M);
1441 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1442 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
1443 } else if (M->action.type == tgl_message_action_chat_delete_user) {
1444 type_of_change = strdup("delete_user");
1445 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1446 int msg_len = strlen(UC->user.first_name) + strlen(" left the group") + 1;
1447 char* creator_name = (char*)malloc(msg_len);
1448 strcpy(creator_name, UC->user.first_name);
1449 strcat(creator_name, " left the group");
1451 int cur_time = time(NULL);
1453 M->message = creator_name;
1454 M->message_len = msg_len;
1457 insert_buddy_msg_to_db(M);
1459 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1460 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
1466 if (!tgl_get_peer_type(M->to_id)) {
1471 if (tgl_get_peer_type(M->to_id) == TGL_PEER_USER) {
1479 if (M->media.type != tgl_message_media_none) {
1484 if (M->from_id.id == 333000 || M->from_id.id == 777000)
1487 char* tb_name = get_table_name_from_number(M->from_id.id);
1488 Eina_Bool is_present_in_db = is_user_present_buddy_table(M->from_id.id);
1489 create_buddy_msg_table(tb_name);
1490 if (!is_present_in_db) {
1491 tgl_do_get_user_info(TLS, M->from_id, 0, on_new_buddy_info_loaded, M);
1495 int msg_id = update_current_date_to_table(tb_name, M->date);
1499 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1500 M->message = strdup("Audio");
1501 M->message_len = strlen("Audio");
1502 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1503 M->message = strdup("Video");
1504 M->message_len = strlen("Video");
1505 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_STICKER)) {
1506 M->message = strdup("Sticker");
1507 M->message_len = strlen("Sticker");
1509 insert_buddy_msg_to_db(M);
1510 if (M->media.type != tgl_message_media_none) {
1511 insert_media_info_to_db(M, NULL);
1512 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1513 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1515 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_STICKER)) {
1516 tgl_do_load_document(TLS, &(M->media.document), on_media_sticker_loaded, M);
1520 // inform to application
1523 send_message_with_date_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, msg_id, tgl_get_peer_type(M->to_id));
1525 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1528 } else if (tgl_get_peer_type(M->to_id) == TGL_PEER_ENCR_CHAT) {
1532 if ((tgl_get_peer_type(M->from_id) == TGL_PEER_USER) && (tgl_get_peer_id(M->from_id) == TLS->our_id)) {
1535 if (M->media.type != tgl_message_media_none) {
1540 if (tgl_get_peer_type(M->to_id) == TGL_PEER_USER) {
1541 user_id = M->from_id.id;
1542 } else if (tgl_get_peer_type(M->to_id) == TGL_PEER_CHAT) {
1543 user_id = M->to_id.id;
1546 // check whether user is present or not
1548 Eina_Bool is_present_in_peer_db = is_user_present_buddy_table(user_id);
1549 if (!is_present_in_peer_db) {
1550 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_requested_chat_info_received, M);
1555 Eina_Bool is_present_in_chat_db = is_user_present_chat_table(user_id);
1556 if (!is_present_in_chat_db) {
1558 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_requested_chat_info_received, M);
1562 char* tb_name = get_table_name_from_number(user_id);
1563 int msg_id = update_current_date_to_table(tb_name, M->date);
1566 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1567 M->message = strdup("Audio");
1568 M->message_len = strlen("Audio");
1569 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1570 M->message = strdup("Video");
1571 M->message_len = strlen("Video");
1573 insert_buddy_msg_to_db(M);
1574 if (M->media.type != tgl_message_media_none) {
1575 insert_media_info_to_db(M, "");
1576 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1577 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1581 // inform to application
1584 send_message_with_date_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, msg_id, tgl_get_peer_type(M->to_id));
1586 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1593 void tg_our_id(struct tgl_state *TLS, int id)
1598 void tg_notification(struct tgl_state *TLS, char *type, char *message)
1603 void tg_user_status_update(struct tgl_state *TLS, struct tgl_user *U)
1606 if (tgl_get_peer_type(U->id) != TGL_PEER_USER) {
1613 if ((U->flags & FLAG_DELETED)) {
1615 } else if (!(U->flags & FLAG_CREATED)) {
1616 // newly created user
1622 if (U->flags & FLAG_USER_SELF) {
1623 update_buddy_into_db(USER_INFO_TABLE_NAME, U);
1624 } else if (U->flags & FLAG_USER_CONTACT) {
1625 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, U);
1627 struct tgl_user_status *S = &(U->status);
1629 if (S->online > 0) {
1632 if (S->online == 0) {
1634 } else if (S->online == -1) {
1635 //offline was online ");
1636 } else if (S->online == -2) {
1637 // offline (was online recently)
1638 } else if (S->online == -3) {
1639 //offline (was online last week)
1640 } else if (S->online == -4) {
1641 //offline (was online last month)
1645 // update status to application.
1646 send_buddy_status_updated_response(TLS->callback_data, U->id.id);
1655 char *tg_create_print_name(struct tgl_state *TLS, tgl_peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4)
1660 struct tgl_update_callback upd_cb = {
1661 .new_msg = tg_new_msg,
1662 .marked_read = tg_marked_read,
1663 .logprintf = tg_logprintf,
1664 .get_string = tg_get_string,
1665 .logged_in = tg_logged_in,
1666 .started = tg_started,
1667 .type_notification = tg_type_notification,
1668 .type_in_chat_notification = tg_type_in_chat_notification,
1669 .type_in_secret_chat_notification = tg_type_in_secret_chat_notification,
1670 //.status_notification = tg_status_notification,
1671 .status_notification = NULL,
1672 .user_registered = tg_user_registered,
1673 .user_activated = tg_user_activated,
1674 .new_authorization = tg_new_authorization,
1675 //.user_update = tg_user_update,
1676 .user_update = NULL,
1677 //.chat_update = tg_chat_update,
1678 .chat_update = NULL,
1679 .secret_chat_update = tg_secret_chat_update,
1680 .msg_receive = tg_msg_receive,
1681 .our_id = tg_our_id,
1682 .user_status_update = tg_user_status_update
1685 void on_chat_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1687 struct tgl_chat *chat_info = callback_extra;
1690 update_chat_info_to_db(chat_info, filename);
1691 tgl_peer_t* UC = tgl_peer_get(TLS, chat_info->id);
1692 update_peer_info_database(UC, 0);
1693 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, chat_info->id.id);
1694 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, filename);
1698 void on_buddy_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1700 struct tgl_user *buddy = callback_extra;
1701 tg_engine_data_s *tg_data = TLS->callback_data;
1703 if (buddy && buddy->id.id == tg_data->id.id) {
1705 update_buddy_pic_db(filename, USER_INFO_TABLE_NAME, buddy->id.id);
1706 update_buddy_pic_db(filename, BUDDY_INFO_TABLE_NAME, buddy->id.id);
1707 send_buddy_profile_pic_updated_response(TLS->callback_data, buddy->id.id, filename);
1713 update_buddy_pic_db(filename, BUDDY_INFO_TABLE_NAME, buddy->id.id);
1714 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, buddy->id.id);
1715 send_buddy_profile_pic_updated_response(TLS->callback_data, buddy->id.id, filename);
1720 void on_new_group_icon_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
1722 struct tgl_chat *chat_info = callback_extra;
1723 tg_engine_data_s *tg_data;
1725 tg_data = TLS->callback_data;
1727 if (tg_data->new_group_icon) {
1729 char *msg_table = get_table_name_from_number(chat_info->id.id);
1730 create_buddy_msg_table(msg_table);
1732 char *msg_data = "group icon changed.";
1733 struct tgl_message msg;
1735 msg.from_id.type = 0;
1739 msg.fwd_from_id.id = 0;
1740 msg.fwd_from_id.type = 0;
1742 msg.message = msg_data;
1743 msg.message_len = strlen(msg_data);
1747 msg.to_id.type = tg_data->id.type;
1749 msg.media.type = -1;
1750 msg.is_marked_for_delete = 0;
1752 insert_msg_into_db(&msg, msg_table, t);
1755 update_chat_info_to_db(chat_info, tg_data->new_group_icon);
1756 update_buddy_pic_db(tg_data->new_group_icon, PEER_INFO_TABLE_NAME, chat_info->id.id);
1757 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, tg_data->new_group_icon);
1759 free(tg_data->new_group_icon);
1760 tg_data->new_group_icon = NULL;
1765 void on_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1767 tg_engine_data_s *tg_data;
1773 if (chat_info->flags == 144) {
1776 msg_table = get_table_name_from_number(chat_info->id.id);
1777 create_buddy_msg_table(msg_table);
1779 int msg_count = get_number_of_messages(msg_table);
1780 if (msg_count <= 0) {
1781 if (chat_info->admin_id > 0) {
1782 set_date_item_to_table(msg_table, chat_info->date);
1783 tgl_peer_id_t admin_id;
1784 admin_id.id = chat_info->admin_id;
1785 admin_id.type = TGL_PEER_USER;
1787 tgl_peer_t* UC = tgl_peer_get(TLS, admin_id);
1788 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
1789 char* creator_name = (char*)malloc(msg_len);
1790 strcpy(creator_name, UC->user.first_name);
1791 strcat(creator_name, " created the group");
1792 struct tgl_message msg;
1793 int cur_time = chat_info->date;
1794 msg.to_id = chat_info->id;
1795 msg.from_id = admin_id;
1796 msg.id = chat_info->id.id;
1797 msg.message = creator_name;
1798 msg.message_len = msg_len;
1800 msg.date = cur_time;
1801 msg.media.type = tgl_message_media_none;
1805 insert_buddy_msg_to_db(&msg);
1807 send_message_received_response(TLS->callback_data, msg.from_id.id, msg.to_id.id, msg.id, tgl_get_peer_type(msg.to_id));
1813 if (!chat_info->user_list) {
1814 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_chat_info_received, NULL);
1817 for (int i = 0; i < chat_info->user_list_size; i++) {
1818 int user_id = chat_info->user_list[i].user_id;
1819 Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
1820 char* tb_name = get_table_name_from_number(user_id);
1821 create_buddy_msg_table(tb_name);
1822 if (!is_present_in_db) {
1823 // add to buddy table
1824 tgl_peer_id_t from_id;
1825 from_id.id = user_id;
1826 from_id.type = TGL_PEER_USER;
1827 tgl_do_get_user_info(TLS, from_id, 0, on_new_buddy_info_loaded, NULL);
1833 tg_data = TLS->callback_data;
1835 insert_chat_info_to_db(chat_info, NULL);
1836 struct tgl_photo *pic = &(chat_info->photo);
1838 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
1842 void on_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U)
1847 tg_engine_data_s *tg_data = TLS->callback_data;
1848 if (U->id.id == tg_data->id.id) {
1852 //update_buddy_into_db(BUDDY_INFO_TABLE_NAME, U);
1853 struct tgl_photo* pic = &(U->photo);
1855 tgl_do_load_photo(TLS, pic, &on_buddy_pic_loaded, U);
1859 void delete_pending_group_chats(tg_engine_data_s *tg_data)
1861 Eina_List* id_list = get_chat_ids_to_be_deleted();
1862 if (id_list && eina_list_count(id_list) > 0) {
1863 for (int i = 0; i < eina_list_count(id_list); i++) {
1864 int chat_id_val = (int)eina_list_nth(id_list, i);
1865 if (chat_id_val > 0) {
1866 tgl_peer_id_t chat_id;
1867 chat_id.id = chat_id_val;
1868 chat_id.type = TGL_PEER_CHAT;
1870 tgl_peer_id_t self_id = tg_data->id;
1872 tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, NULL, NULL);
1878 void on_offline_chat_received(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[])
1880 tg_engine_data_s *tg_data = TLS->callback_data;
1881 for (int i = size - 1; i >= 0; i--) {
1882 struct tgl_message* message = list[i];
1883 if (message->service || message->from_id.id == tg_data->id.id) {
1886 tg_msg_receive(s_info.TLS, message);
1888 Eina_Bool is_offline_msg_requested = EINA_FALSE;
1889 tg_data->current_offline_buddy_index = tg_data->current_offline_buddy_index + 1;
1890 if (tg_data->current_offline_buddy_index < eina_list_count(tg_data->peer_list)) {
1892 for (int i = tg_data->current_offline_buddy_index; i < eina_list_count(tg_data->peer_list); i++) {
1894 tg_data->current_offline_buddy_index = i;
1896 tgl_peer_t* UC = eina_list_nth(tg_data->peer_list, i);
1898 struct tgl_message *last_msg = UC->last;
1900 // check last message in message table
1901 char* msg_table = get_table_name_from_number(UC->id.id);
1902 struct tgl_message* org_last_msg = get_message_from_message_tableby_message_id(msg_table, last_msg->id);
1903 if (!org_last_msg) {
1904 tgl_do_get_history(s_info.TLS, UC->id, 10, 0, on_offline_chat_received, UC);
1905 is_offline_msg_requested = EINA_TRUE;
1908 if (org_last_msg->message) {
1909 free(org_last_msg->message);
1917 if (!is_offline_msg_requested) {
1918 delete_pending_group_chats(tg_data);
1919 send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
1923 static Eina_Bool on_load_offline_messages(void *data)
1925 struct tgl_state *TLS = data;
1927 return ECORE_CALLBACK_CANCEL;
1929 tg_engine_data_s *tg_data = TLS->callback_data;
1931 return ECORE_CALLBACK_CANCEL;
1934 if (tg_data->peer_list && eina_list_count(tg_data->peer_list) > 0) {
1935 for (int i = 0; i < eina_list_count(tg_data->peer_list); i++) {
1936 tgl_peer_t* UC = eina_list_nth(tg_data->peer_list, i);
1937 char* msg_table = get_table_name_from_number(UC->id.id);
1938 create_buddy_msg_table(msg_table);
1939 delete_all_messages_from_chat(UC->id.id, UC->id.type);
1944 Eina_Bool is_offline_msg_requested = EINA_FALSE;
1946 if (tg_data->peer_list && eina_list_count(tg_data->peer_list) > 0) {
1947 for (int i = 0; i < eina_list_count(tg_data->peer_list); i++) {
1949 tg_data->current_offline_buddy_index = i;
1951 tgl_peer_t* UC = eina_list_nth(tg_data->peer_list, i);
1953 struct tgl_message *last_msg = UC->last;
1955 // check last message in message table
1956 char* msg_table = get_table_name_from_number(UC->id.id);
1957 struct tgl_message* org_last_msg = get_message_from_message_tableby_message_id(msg_table, last_msg->id);
1958 if (!org_last_msg) {
1959 tgl_do_get_history(s_info.TLS, UC->id, 10, 0, on_offline_chat_received, UC);
1960 is_offline_msg_requested = EINA_TRUE;
1963 if (org_last_msg->message) {
1964 free(org_last_msg->message);
1973 if (!is_offline_msg_requested) {
1974 delete_pending_group_chats(tg_data);
1975 send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
1978 return ECORE_CALLBACK_CANCEL;
1982 extern void on_peer_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info);
1984 static Eina_Bool on_async_peer_info_requested(void *data)
1986 struct tgl_state *TLS = data;
1988 return ECORE_CALLBACK_CANCEL;
1990 tg_engine_data_s *tg_data = TLS->callback_data;
1992 return ECORE_CALLBACK_CANCEL;
1994 tg_data->current_chat_index = tg_data->current_chat_index + 1;
1995 if (tg_data->current_chat_index < eina_list_count(tg_data->chat_list)) {
1996 tgl_peer_t* UC = eina_list_nth(tg_data->chat_list, tg_data->current_chat_index);
1998 return ECORE_CALLBACK_CANCEL;
2000 tgl_do_get_chat_info(TLS, UC->id, 0, &on_peer_chat_info_received, NULL);
2002 //send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
2003 ecore_timer_add(1, on_send_unsent_messages_requested, TLS);
2006 return ECORE_CALLBACK_CANCEL;
2009 void on_peer_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
2017 if (chat_info->flags == 144) {
2021 msg_table = get_table_name_from_number(chat_info->id.id);
2022 create_buddy_msg_table(msg_table);
2024 if (chat_info->admin_id > 0) {
2025 set_date_item_to_table(msg_table, chat_info->date);
2026 tgl_peer_id_t admin_id;
2027 admin_id.id = chat_info->admin_id;
2028 admin_id.type = TGL_PEER_USER;
2030 tgl_peer_t* UC = tgl_peer_get(TLS, admin_id);
2031 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
2032 char* creator_name = (char*)malloc(msg_len);
2033 strcpy(creator_name, UC->user.first_name);
2034 strcat(creator_name, " created the group");
2035 struct tgl_message msg;
2037 msg.to_id = chat_info->id;
2038 msg.from_id = admin_id;
2039 msg.id = chat_info->id.id;
2040 msg.message = creator_name;
2041 msg.message_len = msg_len;
2043 msg.date = chat_info->date;
2044 msg.media.type = tgl_message_media_none;
2048 insert_buddy_msg_to_db(&msg);
2053 if (chat_info->user_list) {
2054 for (int i = 0; i < chat_info->user_list_size; i++) {
2055 int user_id = chat_info->user_list[i].user_id;
2056 Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
2057 char* tb_name = get_table_name_from_number(user_id);
2058 create_buddy_msg_table(tb_name);
2059 if (!is_present_in_db) {
2060 // add to buddy table
2061 tgl_peer_id_t from_id;
2062 from_id.id = user_id;
2063 from_id.type = TGL_PEER_USER;
2064 tgl_do_get_user_info(TLS, from_id, 0, on_new_buddy_info_loaded, NULL);
2072 insert_chat_info_to_db(chat_info, NULL);
2074 struct tgl_photo *pic = &(chat_info->photo);
2076 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
2080 ecore_timer_add(1, on_async_peer_info_requested, TLS);
2085 void on_contacts_and_chats_loaded(struct tgl_state *TLS, void *callback_extra, int success, int size, tgl_peer_id_t peers[], int last_msg_id[], int unread_count[])
2087 tg_engine_data_s *tg_data = TLS->callback_data;
2088 if (tg_data->chat_list) {
2089 eina_list_free(tg_data->chat_list);
2090 tg_data->chat_list = NULL;
2092 if (tg_data->buddy_list) {
2093 eina_list_free(tg_data->buddy_list);
2094 tg_data->buddy_list = NULL;
2096 if (tg_data->peer_list) {
2097 eina_list_free(tg_data->peer_list);
2098 tg_data->peer_list = NULL;
2100 for (int i = size - 1; i >= 0; i--) {
2101 tgl_peer_t* UC = tgl_peer_get(TLS, peers[i]);
2102 // user exited from chat
2103 if (UC->flags == 144) {
2106 tg_data->peer_list = eina_list_append(tg_data->peer_list, UC);
2107 // insert into peer table
2108 switch (tgl_get_peer_type(peers[i])) {
2110 tg_data->buddy_list = eina_list_append(tg_data->buddy_list, UC);
2112 // check peer exists in peer table / buddy table
2113 Eina_Bool is_buddy_present = is_user_present_buddy_table(UC->id.id);
2114 if (!is_buddy_present) {
2115 struct tgl_user* buddy = &(UC->user);
2117 char* msg_table = get_table_name_from_number(buddy->id.id);
2118 create_buddy_msg_table(msg_table);
2121 if (buddy->id.id == 333000 || buddy->id.id == 777000)
2122 buddy->is_unknown = 0;
2124 buddy->is_unknown = 1;
2126 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2127 insert_peer_into_database(UC, last_msg_id[i], unread_count[i], 1);
2128 tgl_do_get_user_info(TLS, buddy->id, 0, on_buddy_info_loaded, NULL);
2134 tg_data->chat_list = eina_list_append(tg_data->chat_list, UC);
2135 insert_peer_into_database(UC, last_msg_id[i], unread_count[i], 0);
2138 case TGL_PEER_ENCR_CHAT:
2146 if ((tg_data->chat_list == NULL) || (eina_list_count(tg_data->chat_list) <= 0)) {
2147 //send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
2148 ecore_timer_add(1, on_send_unsent_messages_requested, TLS);
2150 // load chat info one by one.
2151 tg_data->current_chat_index = 0;
2152 tgl_peer_t* UC = eina_list_nth(tg_data->chat_list, tg_data->current_chat_index);
2154 tgl_do_get_chat_info(TLS, UC->id, 0, &on_peer_chat_info_received, NULL);
2158 void on_contacts_received(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *contacts[])
2160 //tg_engine_data_s *tg_data = TLS->callback_data;
2161 for (int i = size - 1; i >= 0; i--) {
2162 struct tgl_user *buddy = contacts[i];
2163 char* msg_table = get_table_name_from_number(buddy->id.id);
2164 create_buddy_msg_table(msg_table);
2167 buddy->is_unknown = 0;
2168 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2169 tgl_peer_t* UC = tgl_peer_get(TLS, buddy->id);
2171 insert_peer_into_database(UC, 0, 0, 0);
2174 // inform client that contact loading is done.
2175 for (int i = size - 1; i >= 0; i--) {
2176 struct tgl_user *buddy = contacts[i];
2177 tgl_do_get_user_info(TLS, buddy->id, 0, on_buddy_info_loaded, NULL);
2180 tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2184 void add_contacts_to_account(struct tgl_state *TLS)
2186 tg_engine_data_s *tg_data = TLS->callback_data;
2187 if (sc_db_utils_connect()) {
2188 Eina_List* contact_list = get_contact_list_from_device_db();
2189 sc_db_utils_disconnect();
2191 if (!contact_list || eina_list_count(contact_list) <= 0) {
2192 // no contacts avilable. empty contact list.
2193 //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2195 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2197 eina_list_free(contact_list);
2201 int size = eina_list_count(contact_list);
2203 add_contacts_to_user(tg_data, size, contact_list);
2205 eina_list_free(contact_list);
2207 //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2208 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2213 void on_user_info_loaded(struct tgl_state *TLS, void *extra, int success, struct tgl_user *buddy)
2215 tg_engine_data_s *tg_data = TLS->callback_data;
2217 tg_data->id.id = buddy->id.id;
2218 tg_data->id.type = buddy->id.type;
2220 struct tgl_photo* pic = &(buddy->photo);
2222 tgl_do_load_photo(TLS, pic, &on_buddy_pic_loaded, buddy);
2225 buddy->is_unknown = 0;
2226 init_insert_buddy_into_db(USER_INFO_TABLE_NAME, buddy);
2229 if (tg_data->is_first_time_registration) {
2230 // send contact list to add friends.
2231 //send_add_contacts_request(tg_data);
2232 add_contacts_to_account(TLS);
2235 //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2236 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2239 add_contacts_to_account(TLS);
2243 void on_message_sent_to_buddy(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *message)
2245 tg_engine_data_s *tg_data;
2246 struct tgl_message* org_msg = (struct tgl_message*)callback_extra;
2247 tg_data = TLS->callback_data;
2249 if (success && message) {
2250 tgl_peer_t* UC = tgl_peer_get(TLS, message->to_id);
2252 message->msg_state = TG_MESSAGE_STATE_SENT;
2253 char* tb_name = get_table_name_from_number(message->to_id.id);
2254 update_msg_into_db(message, tb_name, org_msg->id);
2256 // delete message from unsent db
2257 delete_message_from_unsent_db(org_msg->id);
2258 delete_media_from_unsent_db(org_msg->id);
2260 if (message->media.type == tgl_message_media_photo || message->media.type == tgl_message_media_document || message->media.type == tgl_message_media_geo) {
2261 update_sent_media_info_in_db(message, (long long)org_msg->id);
2263 send_message_sent_to_buddy_response(tg_data, message->to_id.id, message->id, tb_name, EINA_TRUE, tgl_get_peer_type(message->to_id));
2266 if (message->media.type != tgl_message_media_none && (message->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
2267 //tgl_do_load_document_thumb(TLS, &(message->media.document), on_video_thumb_loaded, message);
2273 org_msg->msg_state = TG_MESSAGE_STATE_FAILED;
2274 char* tb_name = get_table_name_from_number(org_msg->to_id.id);
2275 update_msg_into_db(org_msg, tb_name, org_msg->id);
2276 if (org_msg->media.type == tgl_message_media_photo || org_msg->media.type == tgl_message_media_document || message->media.type == tgl_message_media_geo) {
2277 if (org_msg->media.type == tgl_message_media_photo) {
2278 org_msg->media.photo.sizes_num = 0;
2279 org_msg->media.photo.sizes = NULL;
2281 update_sent_media_info_in_db(org_msg, (long long)org_msg->id);
2283 send_message_sent_to_buddy_response(tg_data, org_msg->to_id.id, org_msg->id, tb_name, EINA_FALSE, tgl_get_peer_type(org_msg->to_id));
2288 if (org_msg->message) {
2289 free(org_msg->message);
2295 void on_image_download_completed(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
2297 tg_engine_data_s *tg_data = TLS->callback_data;
2298 struct tgl_photo* photo_prop = (struct tgl_photo*)callback_extra;
2299 long long media_id = photo_prop->id;
2300 int buddy_id = photo_prop->user_id;
2301 int to_id = photo_prop->to_peer_id;
2303 if (photo_prop && filename) {
2304 update_receive_media_info_in_db(media_id, filename);
2305 //send response to application
2306 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, filename, photo_prop->caption);
2310 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, NULL, NULL);
2314 void on_document_download_completed(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
2316 tg_engine_data_s *tg_data = TLS->callback_data;
2317 struct tgl_document* doc_prop = (struct tgl_document*)callback_extra;
2318 long long media_id = doc_prop->id;
2319 int buddy_id = doc_prop->user_id;
2320 int to_id = doc_prop->to_peer_id;
2322 if (doc_prop && filename) {
2323 update_receive_media_info_in_db(media_id, filename);
2324 //send response to application
2325 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, filename, doc_prop->caption);
2328 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, NULL, NULL);
2332 if (doc_prop->caption) {
2333 free(doc_prop->caption);
2340 void free_contact_data(Eina_List *contact_data)
2342 contact_data_s* contact = NULL;
2343 EINA_LIST_FREE(contact_data, contact) {
2344 if (contact->display_name) {
2345 free(contact->display_name);
2346 contact->display_name = NULL;
2348 if (contact->first_name) {
2349 free(contact->first_name);
2350 contact->first_name = NULL;
2352 if (contact->last_name) {
2353 free(contact->last_name);
2354 contact->last_name = NULL;
2356 if (contact->phone_number) {
2357 free(contact->phone_number);
2358 contact->phone_number = NULL;
2364 void on_contact_added(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *users[])
2366 tg_engine_data_s* data = callback_extra;
2368 data->current_index++;
2370 if (data->current_index < eina_list_count(data->contact_list_to_add)) {
2371 contact_data_s* contact = eina_list_nth(data->contact_list_to_add, data->current_index);
2376 char *first_name = contact->first_name;
2377 char *last_name = contact->last_name;
2378 char *phone_number = contact->phone_number;
2381 first_name = contact->display_name;
2390 if (first_name && last_name && phone_number)
2391 tgl_do_add_contact(tgl_engine_get_TLS(), phone_number, first_name, last_name, 0, on_contact_added, data);
2393 on_contact_added(tgl_engine_get_TLS(), data, 0, 0, NULL);
2396 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2397 free_contact_data(data->contact_list_to_add);
2398 data->contact_list_to_add = NULL;
2402 void on_new_group_icon_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2405 /* TODO send fail notification */
2409 // send success notofication
2411 if (M->action.type == tgl_message_action_chat_create) {
2413 } else if (M->action.type == tgl_message_action_chat_edit_title) {
2415 } else if (M->action.type == tgl_message_action_chat_edit_photo) {
2417 char* msg_table = get_table_name_from_number(M->to_id.id);
2418 create_buddy_msg_table(msg_table);
2419 int msg_id = insert_current_date_to_table(msg_table);
2421 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2422 int msg_len = strlen(UC->user.first_name) + strlen(" changed profile photo") + 1;
2423 char* creator_name = (char*)malloc(msg_len);
2424 strcpy(creator_name, UC->user.first_name);
2425 strcat(creator_name, " changed profile photo");
2428 //send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id,msg_id, tgl_get_peer_type(M->to_id));
2429 int cur_time = time(NULL);
2431 M->message = creator_name;
2432 M->message_len = msg_len;
2435 insert_buddy_msg_to_db(M);
2438 struct tgl_photo *pic = &(M->action.photo);
2440 tgl_peer_t* UC = tgl_peer_get(TLS, M->to_id);
2441 struct tgl_chat *chat_info = &(UC->chat);
2442 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
2446 } else if (M->action.type == tgl_message_action_chat_delete_photo) {
2448 } else if (M->action.type == tgl_message_action_chat_add_user) {
2450 } else if (M->action.type == tgl_message_action_chat_delete_user) {
2453 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2457 void on_new_group_created(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2459 tg_engine_data_s *tg_data = TLS->callback_data;
2461 // send fail notification
2463 // send success notofication
2465 if (M->action.type == tgl_message_action_chat_create) {
2466 char* msg_table = get_table_name_from_number(M->to_id.id);
2467 create_buddy_msg_table(msg_table);
2470 int msg_id = insert_current_date_to_table(msg_table);
2471 //send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id,msg_id, tgl_get_peer_type(M->to_id));
2474 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2475 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
2476 char* creator_name = (char*)malloc(msg_len);
2477 strcpy(creator_name, UC->user.first_name);
2478 strcat(creator_name, " created the group");
2482 int cur_time = time(NULL);
2483 M->id = M->to_id.id;
2484 M->message = creator_name;
2485 M->message_len = msg_len;
2489 insert_buddy_msg_to_db(M);
2492 tgl_peer_t* chat_UC = tgl_peer_get(TLS, M->to_id);
2493 chat_UC->chat.date = M->date;
2494 insert_chat_info_to_db(&(chat_UC->chat), NULL);
2496 insert_peer_into_database(chat_UC, 0, 0, 0);
2498 if (tg_data->new_group_icon) {
2499 tgl_peer_t* UC = tgl_peer_get(TLS, M->to_id);
2500 struct tgl_chat *chat_info = &(UC->chat);
2501 tgl_do_set_chat_photo(TLS, chat_info->id, tg_data->new_group_icon, on_new_group_icon_loaded, chat_info);
2505 } else if (M->action.type == tgl_message_action_chat_edit_title) {
2507 } else if (M->action.type == tgl_message_action_chat_edit_photo) {
2509 } else if (M->action.type == tgl_message_action_chat_delete_photo) {
2511 } else if (M->action.type == tgl_message_action_chat_add_user) {
2513 } else if (M->action.type == tgl_message_action_chat_delete_user) {
2516 send_new_group_added_response(tg_data, M->to_id.id);
2521 void on_set_profile_picture_response_received(struct tgl_state *TLS, void *callback_extra, int success)
2523 tg_engine_data_s *tg_data = TLS->callback_data;
2524 char *file_path = callback_extra;
2527 update_buddy_pic_db(file_path, USER_INFO_TABLE_NAME, tg_data->id.id);
2528 update_buddy_pic_db(file_path, BUDDY_INFO_TABLE_NAME, tg_data->id.id);
2529 send_self_profile_picture_updated_response(tg_data, file_path, EINA_TRUE);
2531 send_self_profile_picture_updated_response(tg_data, file_path, EINA_FALSE);
2537 void set_profile_picture(tg_engine_data_s *tg_data, int buddy_id, const char *file_path)
2540 char *org_path = strdup(file_path);
2541 tgl_do_set_profile_photo(tgl_engine_get_TLS(), (char*)file_path, on_set_profile_picture_response_received, org_path);
2545 void on_set_new_chat_title_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2548 char *type_of_change = NULL;
2549 if (M && M->action.type == tgl_message_action_chat_edit_title) {
2550 type_of_change = strdup("edit_title");
2551 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2552 int msg_len = strlen(UC->user.first_name) + strlen(" changed the chat title") + 1;
2553 char* creator_name = (char*)malloc(msg_len);
2554 strcpy(creator_name, UC->user.first_name);
2555 strcat(creator_name, " changed the chat title");
2557 int cur_time = time(NULL);
2559 M->message = creator_name;
2560 M->message_len = msg_len;
2563 insert_buddy_msg_to_db(M);
2565 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2566 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
2569 tg_engine_data_s *tg_data = TLS->callback_data;
2570 struct tgl_chat *chat_info = (struct tgl_chat*)callback_extra;
2571 send_group_chat_rename_response(tg_data, chat_info->id.id, EINA_FALSE);
2575 void set_group_chat_new_title(tg_engine_data_s *tg_data, int buddy_id, const char *new_title)
2578 tgl_peer_id_t peer_id;
2579 peer_id.id = buddy_id;
2580 peer_id.type = TGL_PEER_CHAT;
2582 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), peer_id);
2583 struct tgl_chat *chat_info = &(UC->chat);
2584 tgl_do_rename_chat(tgl_engine_get_TLS(), chat_info->id, (char*)new_title, on_set_new_chat_title_response_received, chat_info);
2588 void on_new_buddy_added_to_chat_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2591 char *type_of_change = NULL;
2592 if (M && M->action.type == tgl_message_action_chat_add_user) {
2593 type_of_change = strdup("add_user");
2594 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2596 tgl_peer_id_t added_id;
2597 added_id.id = M->action.user;
2598 added_id.type = TGL_PEER_USER;
2600 tgl_peer_t* added_UC = tgl_peer_get(TLS, added_id);
2601 char* new_user_name = replace(added_UC->print_name, '_', " ");
2602 int msg_len = strlen(UC->user.first_name) + strlen(" added ") + strlen(new_user_name) + 1;
2603 char* creator_name = (char*)malloc(msg_len);
2604 strcpy(creator_name, UC->user.first_name);
2605 strcat(creator_name, " added ");
2606 strcat(creator_name, new_user_name);
2607 free(new_user_name);
2609 int cur_time = time(NULL);
2611 M->message = creator_name;
2612 M->message_len = msg_len;
2615 insert_buddy_msg_to_db(M);
2617 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2618 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
2621 tg_engine_data_s *tg_data = TLS->callback_data;
2622 struct tgl_chat *chat_info = (struct tgl_chat*)callback_extra;
2623 send_group_chat_new_buddy_response(tg_data, chat_info->id.id, EINA_FALSE);
2627 void set_group_chat_add_new_buddy(tg_engine_data_s *tg_data, int s_buddy_id, int s_chat_id)
2629 tgl_peer_id_t chat_id;
2630 chat_id.id = s_chat_id;
2631 chat_id.type = TGL_PEER_CHAT;
2633 tgl_peer_id_t buddy_id;
2634 buddy_id.id = s_buddy_id;
2635 buddy_id.type = TGL_PEER_USER;
2637 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), chat_id);
2638 struct tgl_chat *chat_info = &(UC->chat);
2639 tgl_do_add_user_to_chat(tgl_engine_get_TLS(), chat_id, buddy_id, 100, on_new_buddy_added_to_chat_response_received, chat_info);
2643 void on_buddy_removed_from_chat_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2646 char *type_of_change = NULL;
2647 if (M && M->action.type == tgl_message_action_chat_delete_user) {
2648 type_of_change = strdup("delete_user");
2649 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2650 tgl_peer_id_t added_id;
2651 added_id.id = M->action.user;
2652 added_id.type = TGL_PEER_USER;
2654 tgl_peer_t* added_UC = tgl_peer_get(TLS, added_id);
2655 char* new_user_name = replace(added_UC->print_name, '_', " ");
2656 int msg_len = strlen(UC->user.first_name) + strlen(" removed ") + strlen(new_user_name) + 1;
2657 char* creator_name = (char*)malloc(msg_len);
2658 strcpy(creator_name, UC->user.first_name);
2659 strcat(creator_name, " removed ");
2660 strcat(creator_name, new_user_name);
2661 free(new_user_name);
2662 int cur_time = time(NULL);
2664 M->message = creator_name;
2665 M->message_len = msg_len;
2668 insert_buddy_msg_to_db(M);
2670 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2671 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
2674 tg_engine_data_s *tg_data = TLS->callback_data;
2675 struct tgl_chat *chat_info = (struct tgl_chat*)callback_extra;
2676 send_group_chat_delete_buddy_response(tg_data, chat_info->id.id, EINA_FALSE);
2680 void set_group_chat_remove_buddy(tg_engine_data_s *tg_data, int s_buddy_id, int s_chat_id)
2682 tgl_peer_id_t chat_id;
2683 chat_id.id = s_chat_id;
2684 chat_id.type = TGL_PEER_CHAT;
2686 tgl_peer_id_t buddy_id;
2687 buddy_id.id = s_buddy_id;
2688 buddy_id.type = TGL_PEER_USER;
2690 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), chat_id);
2691 struct tgl_chat *chat_info = &(UC->chat);
2692 tgl_do_del_user_from_chat(tgl_engine_get_TLS(), chat_id, buddy_id, on_buddy_removed_from_chat_response_received, chat_info);
2695 void set_group_chat_profile_picture(tg_engine_data_s *tg_data, int buddy_id, const char *file_path)
2698 tgl_peer_id_t peer_id;
2699 peer_id.id = buddy_id;
2700 peer_id.type = TGL_PEER_CHAT;
2702 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), peer_id);
2703 struct tgl_chat *chat_info = &(UC->chat);
2704 tgl_do_set_chat_photo(tgl_engine_get_TLS(), chat_info->id, (char*)file_path, on_new_group_icon_loaded, chat_info);
2708 void on_set_username_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *buddy)
2710 tg_engine_data_s *tg_data = TLS->callback_data;
2711 char *org_username = callback_extra;
2714 update_buddy_into_db(USER_INFO_TABLE_NAME, buddy);
2715 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2716 send_self_user_name_updated_response(tg_data, org_username, EINA_TRUE);
2718 send_self_user_name_updated_response(tg_data, org_username, EINA_FALSE);
2725 void set_user_name(tg_engine_data_s *tg_data, int buddy_id, const char *username)
2728 char *org_username = strdup(username);
2729 tgl_do_set_username(tgl_engine_get_TLS(), username, on_set_username_response_received, org_username);
2733 void on_profile_name_changed(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *buddy)
2735 tg_engine_data_s *tg_data = callback_extra;
2738 update_buddy_into_db(USER_INFO_TABLE_NAME, buddy);
2739 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2740 send_self_profile_name_updated_response(tg_data, buddy->first_name, buddy->last_name, EINA_TRUE);
2742 send_self_profile_name_updated_response(tg_data, "", "", EINA_FALSE);
2746 void update_user_display_name(tg_engine_data_s *tg_data, int buddy_id, const char *first_name, const char *last_name)
2748 if (first_name && last_name) {
2749 tgl_do_set_profile_name(tgl_engine_get_TLS(),
2750 first_name, last_name, on_profile_name_changed, tg_data);
2754 void create_new_group(tg_engine_data_s *tg_data, Eina_List* buddy_ids, const char *group_name, const char *group_icon)
2756 if (!buddy_ids || ! group_name) {
2759 int users_num = eina_list_count(buddy_ids);
2760 static tgl_peer_id_t ids[1024];
2761 static char _group_icon[1024];
2763 Eina_Bool is_added = EINA_FALSE;
2764 for (i = 0; i < users_num; i++) {
2765 char *buddy_id_str = (char *)eina_list_nth(buddy_ids, i);
2768 int buddy_id = atoi(buddy_id_str);
2769 ids[i].id = buddy_id;
2770 ids[i].type = TGL_PEER_USER;
2771 is_added = EINA_TRUE;
2777 strncpy(_group_icon, group_icon, sizeof(_group_icon));
2779 tgl_do_create_group_chat_ex(tgl_engine_get_TLS(), users_num, ids, group_name, on_new_group_created, (void *)_group_icon);
2780 tg_data->is_group_creation_requested = EINA_TRUE;
2782 if (tg_data->new_group_icon) {
2783 free(tg_data->new_group_icon);
2786 if (group_icon && strlen(group_icon) > 0) {
2787 tg_data->new_group_icon = strdup(group_icon);
2789 tg_data->new_group_icon = NULL;
2794 void add_contacts_to_user(tg_engine_data_s *tg_data, int size, Eina_List* contact_list)
2796 tg_data->contact_list_to_add = contact_list;
2797 contact_data_s* contact = eina_list_nth(contact_list, 0);
2799 char *first_name = contact->first_name;
2800 char *last_name = contact->last_name;
2801 char *phone_number = contact->phone_number;
2803 tg_data->current_index = 0;
2806 first_name = contact->display_name;
2816 if (first_name && last_name && phone_number) {
2817 tgl_do_add_contact(tgl_engine_get_TLS(), phone_number, first_name, last_name, 0, on_contact_added, tg_data);
2819 on_contact_added(tgl_engine_get_TLS(), tg_data, 0, 0, NULL);
2824 void media_download_request(tg_engine_data_s *tg_data, int buddy_id, long long media_id)
2826 // get media details by mediaid
2827 struct tgl_media* img_details = get_media_details_from_db(media_id);
2830 send_media_download_completed_response(tg_data, -1, buddy_id, media_id, NULL, NULL);
2834 if (img_details->media_type == tgl_message_media_none) {
2836 } else if (img_details->media_type == tgl_message_media_photo) {
2838 struct tgl_photo* photo_prop = (struct tgl_photo*)malloc(sizeof(struct tgl_photo));
2839 photo_prop->id = img_details->media_id;
2840 photo_prop->access_hash = img_details->access_hash;
2841 photo_prop->user_id = img_details->user_id;
2842 photo_prop->date = img_details->date;
2843 photo_prop->caption = img_details->caption;
2844 photo_prop->geo.latitude = atof(img_details->latitude);
2845 photo_prop->geo.longitude = atof(img_details->longitude);
2846 photo_prop->sizes_num = img_details->sizes;
2848 photo_prop->sizes = talloc(sizeof(struct tgl_photo_size) * photo_prop->sizes_num);
2850 for (i = 0; i < photo_prop->sizes_num; i++) {
2853 photo_prop->sizes[i].w = img_details->photo_width1;
2854 photo_prop->sizes[i].h = img_details->photo_height1;
2855 photo_prop->sizes[i].size = img_details->photo_size1;
2856 if (img_details->photo_data1) {
2857 photo_prop->sizes[i].data = strdup(img_details->photo_data1);
2859 if (img_details->photo_type1) {
2860 photo_prop->sizes[i].type = strdup(img_details->photo_type1);
2862 photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc1;
2863 photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id1;
2864 photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec1;
2865 photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol1;
2866 } else if (i == 1) {
2868 photo_prop->sizes[i].w = img_details->photo_width2;
2869 photo_prop->sizes[i].h = img_details->photo_height2;
2870 photo_prop->sizes[i].size = img_details->photo_size2;
2871 if (img_details->photo_data2) {
2872 photo_prop->sizes[i].data = strdup(img_details->photo_data2);
2874 if (img_details->photo_type2) {
2875 photo_prop->sizes[i].type = strdup(img_details->photo_type2);
2877 photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc2;
2878 photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id2;
2879 photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec2;
2880 photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol2;
2882 } else if (i == 2) {
2884 photo_prop->sizes[i].w = img_details->photo_width3;
2885 photo_prop->sizes[i].h = img_details->photo_height3;
2886 photo_prop->sizes[i].size = img_details->photo_size3;
2887 if (img_details->photo_data3) {
2888 photo_prop->sizes[i].data = strdup(img_details->photo_data3);
2890 if (img_details->photo_type3) {
2891 photo_prop->sizes[i].type = strdup(img_details->photo_type3);
2893 photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc3;
2894 photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id3;
2895 photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec3;
2896 photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol3;
2898 } else if (i == 3) {
2900 photo_prop->sizes[i].w = img_details->photo_width4;
2901 photo_prop->sizes[i].h = img_details->photo_height4;
2902 photo_prop->sizes[i].size = img_details->photo_size4;
2903 if (img_details->photo_data4) {
2904 photo_prop->sizes[i].data = strdup(img_details->photo_data4);
2906 if (img_details->photo_type4) {
2907 photo_prop->sizes[i].type = strdup(img_details->photo_type4);
2909 photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc4;
2910 photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id4;
2911 photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec4;
2912 photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol4;
2919 photo_prop->to_peer_id = buddy_id;
2920 tgl_do_load_photo(s_info.TLS, photo_prop, &on_image_download_completed, photo_prop);
2922 } else if (img_details->media_type == tgl_message_media_document) {
2923 struct tgl_document* doc_prop = (struct tgl_document*)malloc(sizeof(struct tgl_document));
2924 doc_prop->id = img_details->media_id;;
2925 doc_prop->access_hash = img_details->access_hash;
2926 doc_prop->user_id = img_details->user_id;
2927 doc_prop->date = img_details->date;
2928 doc_prop->size = img_details->sizes;
2929 doc_prop->mime_type = NULL;
2930 doc_prop->dc_id = img_details->doc_dc;
2931 doc_prop->to_peer_id = buddy_id;
2933 if (img_details->caption) {
2934 doc_prop->caption = strdup(img_details->caption);
2936 doc_prop->caption = NULL;
2940 if (!(img_details->mime_type) || strlen(img_details->mime_type) <= 0) {
2942 if (img_details->doc_type && strlen(img_details->doc_type) > 0) {
2943 if (img_details->doc_type && strstr(img_details->doc_type, "video") != NULL) {
2944 doc_prop->mime_type = strdup("video/mp4");
2945 } else if (img_details->doc_type && strstr(img_details->doc_type, "audio") != NULL) {
2946 doc_prop->mime_type = strdup("audio/wav");
2947 } else if (img_details->doc_type && strstr(img_details->doc_type, "image/gif") != NULL) {
2948 doc_prop->mime_type = strdup("image/gif");
2952 doc_prop->mime_type = img_details->mime_type;
2955 if (img_details->doc_type && strstr(img_details->doc_type, "video") != NULL) {
2956 doc_prop->flags = FLAG_DOCUMENT_VIDEO;
2957 } else if (img_details->doc_type && strstr(img_details->doc_type, "audio") != NULL) {
2958 doc_prop->flags = FLAG_DOCUMENT_AUDIO;
2959 } else if (img_details->doc_type && strstr(img_details->doc_type, "image") != NULL) {
2960 doc_prop->flags = FLAG_DOCUMENT_ANIMATED;
2963 tgl_do_load_document(s_info.TLS, doc_prop, on_document_download_completed, doc_prop);
2970 // delete image details
2972 if (img_details->caption) {
2973 free(img_details->caption);
2975 if (img_details->longitude) {
2976 free(img_details->longitude);
2978 if (img_details->latitude) {
2979 free(img_details->latitude);
2981 if (img_details->phone_no) {
2982 free(img_details->phone_no);
2984 if (img_details->first_name) {
2985 free(img_details->first_name);
2987 if (img_details->last_name) {
2988 free(img_details->last_name);
2990 if (img_details->file_path) {
2991 free(img_details->file_path);
2993 if (img_details->photo_type1) {
2994 free(img_details->photo_type1);
2996 if (img_details->photo_data1) {
2997 free(img_details->photo_data1);
2999 if (img_details->photo_type2) {
3000 free(img_details->photo_type2);
3002 if (img_details->photo_data2) {
3003 free(img_details->photo_data2);
3005 if (img_details->photo_type3) {
3006 free(img_details->photo_type3);
3008 if (img_details->photo_data3) {
3009 free(img_details->photo_data3);
3011 if (img_details->photo_type4) {
3012 free(img_details->photo_type4);
3014 if (img_details->photo_data4) {
3015 free(img_details->photo_data4);
3017 if (img_details->mime_type) {
3018 free(img_details->mime_type);
3020 if (img_details->doc_type) {
3021 free(img_details->doc_type);
3023 if (img_details->doc_thumb_path) {
3024 free(img_details->doc_thumb_path);
3030 void on_mark_read_callback(struct tgl_state *TLS, void *callback_extra, int success)
3032 // message read sent successfully. update to UI if needed.
3036 void on_message_deleted_from_message_list(struct tgl_state *TLS, void *callback_extra, int success)
3038 msg_list_container_s *msg_list_container = (msg_list_container_s*)callback_extra;
3039 /* tg_engine_data_s *tg_data = TLS->callback_data; */
3041 if (success && msg_list_container) {
3042 // delete message from message table
3043 char* tb_name = get_table_name_from_number(msg_list_container->buddy_id);
3044 delete_message_from_table(tb_name, msg_list_container->current_message_id);
3048 if (msg_list_container && msg_list_container->message_ids) {
3049 if (msg_list_container->current_index < eina_list_count(msg_list_container->message_ids)) {
3050 msg_list_container->current_index = msg_list_container->current_index + 1;
3051 msg_list_container->current_message_id = (int)eina_list_nth(msg_list_container->message_ids, msg_list_container->current_index);
3052 tgl_do_delete_msg(s_info.TLS, msg_list_container->current_message_id, &on_message_deleted_from_message_list , (void*)(msg_list_container));
3054 eina_list_free(msg_list_container->message_ids);
3055 free(msg_list_container);
3060 void delete_all_messages_from_chat(int buddy_id, int type_of_chat)
3062 tgl_peer_id_t chat_id;
3063 chat_id.id = buddy_id;
3064 chat_id.type = type_of_chat;
3066 char* tb_name = get_table_name_from_number(buddy_id);
3067 //get all message ids from table.
3068 Eina_List *msg_ids = get_all_message_ids_from_table(tb_name);
3071 if (msg_ids && eina_list_count(msg_ids) > 0) {
3072 msg_list_container_s *msg_list_container = (msg_list_container_s*)malloc(sizeof(msg_list_container_s));
3073 msg_list_container->message_ids = msg_ids;
3074 msg_list_container->buddy_id = buddy_id;
3075 msg_list_container->current_index = 0;
3076 msg_list_container->current_message_id = (int)eina_list_nth(msg_list_container->message_ids, msg_list_container->current_index);
3078 tgl_do_delete_msg(s_info.TLS, msg_list_container->current_message_id, &on_message_deleted_from_message_list , (void*)(msg_list_container));
3084 void send_do_mark_read_messages(int buddy_id, int type_of_chat)
3086 tgl_peer_id_t chat_id;
3087 chat_id.id = buddy_id;
3088 chat_id.type = type_of_chat;
3090 tgl_do_mark_read(s_info.TLS, chat_id, &on_mark_read_callback , (void*)(&chat_id));
3094 void on_user_block_response(struct tgl_state *TLS, void *callback_extra, int success)
3096 int buddy_id = (int)callback_extra;
3097 tg_engine_data_s *tg_data = TLS->callback_data;
3101 update_buddy_block_db(BUDDY_INFO_TABLE_NAME, buddy_id, blocked);
3102 send_buddy_blocked_response(tg_data, buddy_id, EINA_TRUE);
3104 send_buddy_blocked_response(tg_data, buddy_id, EINA_FALSE);
3108 void on_user_unblock_response(struct tgl_state *TLS, void *callback_extra, int success)
3110 int buddy_id = (int)callback_extra;
3111 tg_engine_data_s *tg_data = TLS->callback_data;
3114 update_buddy_block_db(BUDDY_INFO_TABLE_NAME, buddy_id, blocked);
3115 send_buddy_unblocked_response(tg_data, buddy_id, EINA_TRUE);
3117 send_buddy_unblocked_response(tg_data, buddy_id, EINA_FALSE);
3121 void on_user_delete_response(struct tgl_state *TLS, void *callback_extra, int success)
3123 int buddy_id = (int)callback_extra;
3124 tg_engine_data_s *tg_data = TLS->callback_data;
3127 // delete from peer table
3128 // delete from buddy table
3129 // delete chat items
3131 //delete_chat_from_db(buddy_id);
3132 //delete_buddy_from_db(buddy_id);
3133 //char* msg_table = get_table_name_from_number(buddy_id);
3134 //drop_table(msg_table);
3138 update_buddy_delete_db(BUDDY_INFO_TABLE_NAME, buddy_id, deleted);
3139 update_buddy_delete_db(PEER_INFO_TABLE_NAME, buddy_id, deleted);
3140 send_buddy_deleted_response(tg_data, buddy_id, EINA_TRUE);
3142 send_buddy_deleted_response(tg_data, buddy_id, EINA_FALSE);
3147 void on_buddy_readded(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *users[])
3149 int buddy_id = (int)callback_extra;
3150 tg_engine_data_s *tg_data = TLS->callback_data;
3153 update_buddy_delete_db(BUDDY_INFO_TABLE_NAME, buddy_id, deleted);
3154 send_buddy_readded_response(tg_data, buddy_id, EINA_TRUE);
3156 send_buddy_readded_response(tg_data, buddy_id, EINA_FALSE);
3160 void on_new_buddy_added(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *users[])
3162 tg_engine_data_s *tg_data = TLS->callback_data;
3163 if (success && size > 0) {
3164 struct tgl_user *buddy = users[0];
3166 char* msg_table = get_table_name_from_number(buddy->id.id);
3167 create_buddy_msg_table(msg_table);
3169 buddy->is_unknown = 0;
3170 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
3171 tgl_peer_t* UC = tgl_peer_get(TLS, buddy->id);
3173 insert_peer_into_database(UC, 0, 0, 0);
3175 tgl_do_get_user_info(TLS, buddy->id, 0, on_buddy_info_loaded, NULL);
3177 // send response to application
3178 send_new_contact_added_response(tg_data, buddy->id.id, EINA_TRUE);
3180 send_new_contact_added_response(tg_data, -1, EINA_FALSE);
3184 send_new_contact_added_response(tg_data, -1, EINA_FALSE);
3188 void do_add_buddy(int buddy_id, char *first_name, char *last_name, char *phone_num)
3200 if (first_name && last_name && phone_num) {
3201 if (buddy_id == -1) {
3202 tgl_do_add_contact(s_info.TLS, phone_num, first_name, last_name, 0, on_new_buddy_added, (void*)(buddy_id));
3204 tgl_do_add_contact(s_info.TLS, phone_num, first_name, last_name, 0, on_buddy_readded, (void*)(buddy_id));
3210 void logout_telegram(tg_engine_data_s *tg_data)
3215 void on_secret_chat_request_sent(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_secret_chat *E)
3218 int buddy_id = (int)callback_extra;
3219 tg_engine_data_s *tg_data = TLS->callback_data;
3228 void request_for_secret_chat(int buddy_id)
3230 tgl_peer_id_t peer_id;
3231 peer_id.id = buddy_id;
3232 peer_id.type = TGL_PEER_USER;
3233 tgl_do_create_secret_chat(s_info.TLS, peer_id, on_secret_chat_request_sent, (void*)(buddy_id));
3236 void do_delete_buddy(int buddy_id)
3238 tgl_peer_id_t peer_id;
3239 peer_id.id = buddy_id;
3240 peer_id.type = TGL_PEER_USER;
3241 tgl_do_del_contact(s_info.TLS, peer_id, &on_user_delete_response , (void*)(buddy_id));
3244 void on_message_deleted(struct tgl_state *TLS, void *callback_extra, int success)
3246 msg_container_s *msg_details = (msg_container_s*)callback_extra;
3247 tg_engine_data_s *tg_data = TLS->callback_data;
3250 send_message_deleted_response(tg_data, msg_details->buddy_id, msg_details->message_id, EINA_TRUE);
3252 send_message_deleted_response(tg_data, msg_details->buddy_id, msg_details->message_id, EINA_FALSE);
3256 void do_delete_message(int buddy_id, int message_id)
3258 msg_container_s *msg_details = (msg_container_s*)malloc(sizeof(msg_container_s));
3259 msg_details->buddy_id = buddy_id;
3260 msg_details->message_id = message_id;
3261 tgl_do_delete_msg(s_info.TLS, message_id, &on_message_deleted , (void*)(msg_details));
3265 void do_block_buddy(int buddy_id)
3267 tgl_peer_id_t peer_id;
3268 peer_id.id = buddy_id;
3269 peer_id.type = TGL_PEER_USER;
3270 tgl_do_block_user(s_info.TLS, peer_id, &on_user_block_response , (void*)(buddy_id));
3273 void do_unblock_buddy(int buddy_id)
3275 tgl_peer_id_t peer_id;
3276 peer_id.id = buddy_id;
3277 peer_id.type = TGL_PEER_USER;
3278 tgl_do_unblock_user(s_info.TLS, peer_id, &on_user_unblock_response , (void*)(buddy_id));
3281 extern void on_selected_group_chats_delete_reponse(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M);
3282 static Eina_Bool on_async_chat_deletion_requested(void *data)
3284 Eina_List *sel_grp_chats = data;
3285 if (sel_grp_chats) {
3286 tg_engine_data_s *tg_data = tgl_engine_get_TLS()->callback_data;
3287 tg_data->current_group_chat_index = tg_data->current_group_chat_index + 1;
3289 if (tg_data->current_group_chat_index < eina_list_count(sel_grp_chats)) {
3290 int group_chat_id = (int)eina_list_nth(sel_grp_chats, tg_data->current_group_chat_index);
3292 tgl_peer_id_t chat_id;
3293 chat_id.id = group_chat_id;
3294 chat_id.type = TGL_PEER_CHAT;
3296 tgl_peer_id_t self_id = tg_data->id;
3298 tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, on_selected_group_chats_delete_reponse, (void*)(sel_grp_chats));
3300 send_selected_group_chats_deleted_response(tg_data);
3303 return ECORE_CALLBACK_CANCEL;
3307 void on_selected_group_chats_delete_reponse(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
3309 Eina_List *sel_grp_chats = callback_extra;
3310 tg_engine_data_s *tg_data = TLS->callback_data;
3311 int chat_id = (int)eina_list_nth(sel_grp_chats, tg_data->current_group_chat_index);
3314 delete_chat_from_db(chat_id);
3315 char* msg_table = get_table_name_from_number(chat_id);
3316 drop_table(msg_table);
3319 ecore_timer_add(1, on_async_chat_deletion_requested, sel_grp_chats);
3322 void delete_selected_group_chat(tg_engine_data_s *tg_data, Eina_List *sel_grp_chats)
3324 if (sel_grp_chats && eina_list_count(sel_grp_chats) > 0) {
3326 tg_data->current_group_chat_index = 0;
3327 int group_chat_id = (int)eina_list_nth(sel_grp_chats, tg_data->current_group_chat_index);
3329 tgl_peer_id_t chat_id;
3330 chat_id.id = group_chat_id;
3331 chat_id.type = TGL_PEER_CHAT;
3333 tgl_peer_id_t self_id = tg_data->id;
3335 tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, on_selected_group_chats_delete_reponse, (void*)(sel_grp_chats));
3339 void on_group_chat_delete_reponse(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
3341 int chat_id = (int)callback_extra;
3342 tg_engine_data_s *tg_data = TLS->callback_data;
3345 // delete from peer table
3346 delete_chat_from_db(chat_id);
3347 char* msg_table = get_table_name_from_number(chat_id);
3348 drop_table(msg_table);
3350 send_group_chat_deleted_response(tg_data, chat_id, EINA_TRUE);
3352 send_group_chat_deleted_response(tg_data, chat_id, EINA_FALSE);
3356 void leave_group_chat(tg_engine_data_s *tg_data, int group_chat_id)
3358 tgl_peer_id_t chat_id;
3359 chat_id.id = group_chat_id;
3360 chat_id.type = TGL_PEER_CHAT;
3362 tgl_peer_id_t self_id = tg_data->id;
3364 tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, on_group_chat_delete_reponse, (void*)(group_chat_id));
3368 void on_new_msg_requested_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
3370 tg_engine_data_s *tg_data;
3372 struct tgl_message *msg = callback_extra;
3379 if (!chat_info->user_list) {
3380 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_requested_chat_info_received, callback_extra);
3384 tg_data = TLS->callback_data;
3386 msg_table = get_table_name_from_number(chat_info->id.id);
3388 create_buddy_msg_table(msg_table);
3390 insert_chat_info_to_db(chat_info, NULL);
3391 struct tgl_photo *pic = &(chat_info->photo);
3393 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
3396 tgl_do_send_message(s_info.TLS, msg->to_id, msg->message, strlen(msg->message), &on_message_sent_to_buddy, (void*)(msg));
3398 char *type_of_change = strdup("add_user");
3399 tgl_do_get_chat_info(s_info.TLS, msg->to_id, 0, &on_group_chat_info_updated, type_of_change);
3405 void forward_message_to_buddy(int to_id, int type_of_chat, int from_id, int message_id, int temp_message_id)
3407 char *msg_table = get_table_name_from_number(from_id);
3408 struct tgl_message* msg = get_message_from_message_table(temp_message_id, msg_table);
3411 tgl_peer_id_t id_to_send;
3412 id_to_send.id = type_of_chat;
3413 tgl_do_forward_message(s_info.TLS, id_to_send, message_id, &on_message_sent_to_buddy, (void*)(msg));
3418 void send_typing_status_to_buddy(int buddy_id, int type_of_chat, int typing_status)
3420 tgl_peer_id_t id_to_send;
3421 id_to_send.id = type_of_chat;
3422 tgl_do_send_typing(s_info.TLS, id_to_send, typing_status, NULL, NULL);
3425 void send_message_to_buddy(int buddy_id, int message_id, int msg_type, char *msg_data, int type_of_chat)
3427 // get type of chat from buddy_id.
3428 char *msg_table = get_table_name_from_number(buddy_id);
3429 struct tgl_message* msg = get_message_from_message_table(message_id, msg_table);
3432 if (type_of_chat == TGL_PEER_USER) {
3433 msg->from_id.type = TGL_PEER_USER;
3434 msg->to_id.type = TGL_PEER_USER;
3435 tgl_do_send_message(s_info.TLS, msg->to_id, msg->message, strlen(msg->message), &on_message_sent_to_buddy, (void*)(msg));
3436 } else if (type_of_chat == TGL_PEER_CHAT) {
3437 msg->from_id.type = TGL_PEER_CHAT;
3438 msg->to_id.type = TGL_PEER_CHAT;
3440 Eina_Bool is_present_in_chat_db = is_user_present_chat_table(msg->to_id.id);
3441 if (!is_present_in_chat_db) {
3443 tgl_do_get_chat_info(s_info.TLS, msg->to_id, 0, &on_new_msg_requested_chat_info_received, msg);
3447 tgl_do_send_message(s_info.TLS, msg->to_id, msg->message, strlen(msg->message), &on_message_sent_to_buddy, (void*)(msg));
3448 } else if (type_of_chat == TGL_PEER_ENCR_CHAT) {
3457 void send_media_to_buddy(int buddy_id, int message_id, int media_id, int msg_type, char *file_path, int type_of_chat)
3459 char *msg_table = get_table_name_from_number(buddy_id);
3460 struct tgl_message* msg = get_message_from_message_table(message_id, msg_table);
3463 if (type_of_chat == TGL_PEER_USER) {
3465 msg->from_id.type = TGL_PEER_USER;
3466 msg->to_id.type = TGL_PEER_USER;
3468 if (msg->media.type == tgl_message_media_photo) {
3469 tgl_do_send_document(s_info.TLS, -1, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3470 } else if (msg->media.type == tgl_message_media_document) {
3471 char *extn = strrchr(file_path, '.');
3473 extn = replace(extn, '.', "");
3475 char *mime_type = NULL;;
3477 mime_type_get_mime_type(extn, &mime_type);
3480 if (mime_type && strstr(mime_type, "video") != NULL) {
3482 char* thumb_path = get_video_thumb_path_from_db(media_id);
3483 tgl_do_send_video(s_info.TLS, -2, msg->to_id, file_path, thumb_path, &on_message_sent_to_buddy, (void*) (msg));
3488 } else if (mime_type && strstr(mime_type, "audio") != NULL) {
3489 tgl_do_send_audio(s_info.TLS, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3493 } else if (msg->media.type == tgl_message_media_geo) {
3494 char *latitude = NULL;
3495 char *longitude = NULL;
3496 get_geo_location_from_db(media_id, &latitude, &longitude);
3497 if (latitude && longitude) {
3498 tgl_do_send_location(s_info.TLS, msg->to_id, strtod(latitude, NULL), strtod(longitude, NULL), &on_message_sent_to_buddy, (void*) (msg));
3500 } else if (msg->media.type == tgl_message_media_contact) {
3501 char *first_name = NULL;
3502 char *last_name = NULL;
3503 char *phone_num = NULL;
3504 get_contact_details_from_db(media_id, &first_name, &last_name, &phone_num);
3505 if (first_name && last_name && phone_num) {
3506 tgl_do_send_contact(s_info.TLS, msg->to_id, first_name, strlen(first_name), last_name, strlen(last_name), phone_num, strlen(phone_num), &on_message_sent_to_buddy, (void*) (msg));
3510 } else if (type_of_chat == TGL_PEER_CHAT) {
3511 msg->from_id.type = TGL_PEER_CHAT;
3512 msg->to_id.type = TGL_PEER_CHAT;
3514 if (msg->media.type == tgl_message_media_photo) {
3515 tgl_do_send_document(s_info.TLS, -1, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3516 } else if (msg->media.type == tgl_message_media_document) {
3519 char *extn = strrchr(file_path, '.');
3521 extn = replace(extn, '.', "");
3523 char *mime_type = NULL;;
3525 mime_type_get_mime_type(extn, &mime_type);
3528 if (mime_type && strstr(mime_type, "video") != NULL) {
3530 char* thumb_path = get_video_thumb_path_from_db(media_id);
3531 tgl_do_send_video(s_info.TLS, -2, msg->to_id, file_path, thumb_path, &on_message_sent_to_buddy, (void*) (msg));
3536 } else if (mime_type && strstr(mime_type, "audio") != NULL) {
3537 tgl_do_send_audio(s_info.TLS, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3541 } else if (msg->media.type == tgl_message_media_geo) {
3542 char *latitude = NULL;
3543 char *longitude = NULL;
3544 get_geo_location_from_db(media_id, &latitude, &longitude);
3545 if (latitude && longitude) {
3546 tgl_do_send_location(s_info.TLS, msg->to_id, strtod(latitude, NULL), strtod(longitude, NULL), &on_message_sent_to_buddy, (void*) (msg));
3551 } else if (type_of_chat == TGL_PEER_ENCR_CHAT) {
3562 void check_type_sizes(void)
3564 if (sizeof(int) != 4u) {
3565 logprintf("sizeof(int) isn't equal 4.\n");
3568 if (sizeof(char) != 1u) {
3569 logprintf("sizeof(char) isn't equal 1.\n");
3574 int str_empty(char *str)
3576 return ((str == NULL) || (strlen(str) < 1));
3579 void parse_config(void)
3581 if (!s_info.disable_output) {
3582 //printf("libconfig not enabled\n");
3585 char *rsa_path = ui_utils_get_resource(DEFAULT_RSA_FILE_NAME);
3586 tasprintf(&s_info.rsa_file_name, "%s", rsa_path);
3587 tasprintf(&s_info.config_full_path, "%s%s", app_get_data_path(), CONFIG_DIRECTORY);
3588 struct stat st = { 0 };
3589 if (stat(s_info.config_full_path, &st) == -1) {
3590 mkdir(s_info.config_full_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
3593 if (remove(s_info.rsa_file_name) == 0) {
3594 //printf("File successfully deleted\n");
3597 //tasprintf(&s_info.downloads_directory, "%s%s/%s", app_get_data_path(), CONFIG_DIRECTORY, DOWNLOADS_DIRECTORY);
3598 tasprintf(&s_info.downloads_directory, "%s/%s", app_get_shared_data_path(), DOWNLOADS_DIRECTORY);
3600 if (s_info.binlog_enabled) {
3601 tasprintf(&s_info.binlog_file_name, "%s%s/%s", app_get_data_path(), CONFIG_DIRECTORY, BINLOG_FILE);
3602 tgl_set_binlog_mode(s_info.TLS, 1);
3603 tgl_set_binlog_path(s_info.TLS, s_info.binlog_file_name);
3605 tgl_set_binlog_mode(s_info.TLS, 0);
3606 //tgl_set_auth_file_path(auth_file_name;
3607 tasprintf(&s_info.auth_file_name, "%s%s/%s", app_get_data_path(), CONFIG_DIRECTORY, AUTH_KEY_FILE);
3608 tasprintf(&s_info.state_file_name, "%s%s/%s", app_get_data_path(), CONFIG_DIRECTORY, STATE_FILE);
3609 tasprintf(&s_info.secret_chat_file_name, "%s%s/%s", app_get_data_path(), CONFIG_DIRECTORY, SECRET_CHAT_FILE);
3611 tgl_set_download_directory(s_info.TLS, s_info.downloads_directory);
3612 if (!mkdir(s_info.downloads_directory, CONFIG_DIRECTORY_MODE)) {
3613 if (!s_info.disable_output) {
3614 //printf("[%s] created\n", downloads_directory);
3619 void running_for_first_time(void)
3622 if (!str_empty(s_info.config_filename)) {
3623 return; // Do not create custom config file
3626 if (str_empty(s_info.config_directory)) {
3627 s_info.config_directory = strdup(app_get_data_path()); // specific path for tizen application.
3630 struct stat st = {0};
3631 if (stat(s_info.config_directory, &st) == -1) {
3632 mkdir(s_info.config_directory, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
3635 tasprintf(&s_info.config_filename, "%s%s", s_info.config_directory, CONFIG_FILE);
3638 // see if config file is there
3639 if (access(s_info.config_filename, R_OK) != 0) {
3640 // config file missing, so touch it
3641 config_file_fd = open(s_info.config_filename, O_CREAT | O_RDWR, 0600);
3642 if (config_file_fd == -1) {
3643 perror("open[config_file]");
3644 //printf("I: config_file=[%s]\n", config_filename);
3647 if (write(config_file_fd, DEFAULT_CONFIG_CONTENTS, strlen(DEFAULT_CONFIG_CONTENTS)) <= 0) {
3648 perror("write[config_file]");
3651 close(config_file_fd);
3655 void init_tl_engine(void *cbdata)
3657 s_info.TLS = tgl_state_alloc();
3659 ERR("memory allocation failed!! for tgl_state_alloc");
3663 running_for_first_time();
3667 tgl_set_rsa_key(s_info.TLS, s_info.rsa_file_name);
3668 tgl_set_callback(s_info.TLS, &upd_cb, cbdata);
3669 tgl_set_verbosity(s_info.TLS, E_DEBUG);
3670 tgl_set_net_methods(s_info.TLS, &tgl_conn_methods);
3671 tgl_set_timer_methods(s_info.TLS, &tgl_libevent_timers);
3672 assert(s_info.TLS->timer_methods);
3673 tgl_set_download_directory(s_info.TLS, tgl_engine_get_downloads_directory());
3674 tgl_register_app_id(s_info.TLS, TELEGRAM_CLI_APP_ID, TELEGRAM_CLI_APP_HASH);
3675 tgl_set_app_version(s_info.TLS, "Telegram-cli " TELEGRAM_CLI_VERSION);
3676 if (s_info.ipv6_enabled) {
3677 tgl_enable_ipv6(s_info.TLS);
3679 tgl_init(s_info.TLS);
3681 if (s_info.binlog_enabled) {
3682 double t = tglt_get_double_time();
3683 if (s_info.verbosity >= E_DEBUG) {
3684 logprintf("replay log start\n");
3686 tgl_replay_log(s_info.TLS);
3687 if (s_info.verbosity >= E_DEBUG) {
3688 logprintf("replay log end in %lf seconds\n", tglt_get_double_time() - t);
3690 tgl_reopen_binlog_for_writing(s_info.TLS);
3694 read_secret_chat_file();
3698 void tgl_engine_destroy_TLS(void)
3704 tgl_state_free(tgl_engine_get_TLS());
3708 struct tgl_state *tgl_engine_get_TLS(void)