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->is_first_time_registration = EINA_TRUE;
533 tg_data->tg_state = TG_ENGINE_STATE_REGISTRATION;
534 if (tg_data && tg_data->phone_number) {
535 tg_data->get_string(TLS, tg_data->phone_number, tg_data->callback_arg);
536 //tg_data->code_response_timer = ecore_timer_add(60, on_code_request_timer_expired, tg_data);
539 } else if (strcmp(prompt, "code('call' for phone call):") == 0) {
541 /* if (tg_data->code_response_timer) {
542 ecore_timer_del(tg_data->code_response_timer);
543 tg_data->code_response_timer = NULL;
547 tg_data->mhash = strdup(T[1]);
549 if (tg_data->tg_state == TG_ENGINE_STATE_CODE_REQUEST) {
550 send_request_code_again(tg_data);
552 tg_data->tg_state = TG_ENGINE_STATE_CODE_REQUEST;
553 send_registration_response(tg_data, EINA_TRUE);
556 } else if (strcmp(prompt, "register [Y/n]:") == 0) {
558 tg_data->tg_state = TG_ENGINE_STATE_PROFILE_REGISTRATION;
559 tg_data->get_string(TLS, "Y", tg_data->callback_arg);
561 } else if (strcmp(prompt, "First name:") == 0) {
563 tg_data->tg_state = TG_ENGINE_STATE_PROFILE_FIRST_NAME_REGISTRATION;
564 tg_data->is_first_time_registration = EINA_TRUE;
566 if (tg_data->first_name) {
567 tg_data->get_string(TLS, tg_data->first_name, tg_data->callback_arg);
569 send_name_registration_response(tg_data);
572 } else if (strcmp(prompt, "Last name:") == 0) {
574 tg_data->tg_state = TG_ENGINE_STATE_PROFILE_LAST_NAME_REGISTRATION;
576 if (tg_data->last_name) {
577 tg_data->get_string(TLS, tg_data->last_name, tg_data->callback_arg);
587 void tg_logged_in(struct tgl_state *TLS)
589 tg_engine_data_s *tg_data;
590 tg_data = TLS->callback_data;
592 int offline_mode = 0;
594 t_id.id = TLS->our_id;
595 t_id.type = TGL_PEER_USER;
596 //tg_data->is_first_time_registration = EINA_TRUE;
597 create_data_base_tables();
598 tgl_do_get_user_info(TLS, t_id, offline_mode, &on_user_info_loaded, NULL);
601 static Eina_Bool on_send_media_message_requested(void *data)
603 sent_media_data_s *media_info = (sent_media_data_s*)data;
605 int buddy_id = atoi(media_info->buddy_id);
606 int message_id = atoi(media_info->message_id);
607 int media_id = atoi(media_info->media_id);
608 int msg_type = atoi(media_info->message_type);
609 int type_of_chat = atoi(media_info->type_of_chat);
611 process_send_media_command(buddy_id, message_id, media_id, msg_type, media_info->file_path, type_of_chat);
613 if (media_info->app_name) {
614 free(media_info->app_name);
615 media_info->app_name = NULL;
617 if (media_info->command) {
618 free(media_info->command);
619 media_info->command = NULL;
621 if (media_info->buddy_id) {
622 free(media_info->buddy_id);
623 media_info->buddy_id = NULL;
625 if (media_info->message_id) {
626 free(media_info->message_id);
627 media_info->message_id = NULL;
629 if (media_info->media_id) {
630 free(media_info->media_id);
631 media_info->media_id = NULL;
634 if (media_info->message_type) {
635 free(media_info->message_type);
636 media_info->message_type = NULL;
638 if (media_info->file_path) {
639 free(media_info->file_path);
640 media_info->file_path = NULL;
642 if (media_info->type_of_chat) {
643 free(media_info->type_of_chat);
644 media_info->type_of_chat = NULL;
648 return ECORE_CALLBACK_CANCEL;
650 static Eina_Bool on_load_offline_messages(void *data);
651 static Eina_Bool on_send_unsent_messages_requested(void *data)
653 struct tgl_state *TLS = data;
655 return ECORE_CALLBACK_CANCEL;
657 //tg_engine_data_s *tg_data = TLS->callback_data;
659 Eina_List *unset_text_msgs = get_all_unsent_text_messages();
660 sent_message_data_s* msg_info = NULL;
661 EINA_LIST_FREE(unset_text_msgs, msg_info) {
662 int buddy_id = atoi(msg_info->buddy_id);
663 int message_id = atoi(msg_info->message_id);
664 int msg_type = atoi(msg_info->message_type);
665 int type_of_chat = atoi(msg_info->type_of_chat);
666 process_send_message_command(buddy_id, message_id, msg_type, msg_info->message_data, type_of_chat);
668 if (msg_info->app_name) {
669 free(msg_info->app_name);
670 msg_info->app_name = NULL;
672 if (msg_info->command) {
673 free(msg_info->command);
674 msg_info->command = NULL;
676 if (msg_info->buddy_id) {
677 free(msg_info->buddy_id);
678 msg_info->buddy_id = NULL;
680 if (msg_info->message_id) {
681 free(msg_info->message_id);
682 msg_info->message_id = NULL;
685 if (msg_info->message_type) {
686 free(msg_info->message_type);
687 msg_info->message_type = NULL;
689 if (msg_info->message_data) {
690 free(msg_info->message_data);
691 msg_info->message_data = NULL;
693 if (msg_info->type_of_chat) {
694 free(msg_info->type_of_chat);
695 msg_info->type_of_chat = NULL;
700 Eina_List *unset_media_msgs = get_all_unsent_media_messages();
702 sent_media_data_s* media_info = NULL;
703 EINA_LIST_FREE(unset_media_msgs, media_info) {
704 sent_media_data_s* new_media_info = (sent_media_data_s*)malloc(sizeof(sent_media_data_s));
705 new_media_info->app_name = strdup(media_info->app_name);
706 new_media_info->command = strdup(media_info->command);
707 new_media_info->buddy_id = strdup(media_info->buddy_id);
708 new_media_info->message_id = strdup(media_info->message_id);
709 new_media_info->media_id = strdup(media_info->media_id);
710 new_media_info->message_type = strdup(media_info->message_type);
711 new_media_info->file_path = strdup(media_info->file_path);
712 new_media_info->type_of_chat = strdup(media_info->type_of_chat);
714 ecore_timer_add(init_time, on_send_media_message_requested, new_media_info);
716 if (media_info->app_name) {
717 free(media_info->app_name);
718 media_info->app_name = NULL;
720 if (media_info->command) {
721 free(media_info->command);
722 media_info->command = NULL;
724 if (media_info->buddy_id) {
725 free(media_info->buddy_id);
726 media_info->buddy_id = NULL;
728 if (media_info->message_id) {
729 free(media_info->message_id);
730 media_info->message_id = NULL;
732 if (media_info->media_id) {
733 free(media_info->media_id);
734 media_info->media_id = NULL;
737 if (media_info->message_type) {
738 free(media_info->message_type);
739 media_info->message_type = NULL;
741 if (media_info->file_path) {
742 free(media_info->file_path);
743 media_info->file_path = NULL;
745 if (media_info->type_of_chat) {
746 free(media_info->type_of_chat);
747 media_info->type_of_chat = NULL;
751 ecore_timer_add(1, on_load_offline_messages, TLS);
752 return ECORE_CALLBACK_CANCEL;
755 void tg_started(struct tgl_state *TLS)
757 tg_engine_data_s *tg_data = TLS->callback_data;
758 tg_data->is_login_activated = EINA_TRUE;
761 void tg_type_notification(struct tgl_state *TLS, struct tgl_user* buddy, enum tgl_typing_status status)
763 char *name_of_buddy = NULL;
765 if (buddy->first_name && buddy->last_name) {
766 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + strlen(buddy->last_name) + 1);
767 strcpy(name_of_buddy, buddy->first_name);
768 strcat(name_of_buddy, buddy->last_name);
769 } else if (buddy->first_name) {
770 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + 1);
771 strcpy(name_of_buddy, buddy->first_name);
773 name_of_buddy = (char *)malloc(strlen(" ") + 1);
774 strcpy(name_of_buddy, " ");
777 send_buddy_type_notification_response(TLS->callback_data, buddy->id.id, name_of_buddy, status);
781 name_of_buddy = NULL;
785 void tg_type_in_chat_notification(struct tgl_state *TLS, struct tgl_user *U, struct tgl_chat *C, enum tgl_typing_status status)
790 void tg_type_in_secret_chat_notification(struct tgl_state *TLS, struct tgl_secret_chat *E)
795 void tg_status_notification(struct tgl_state *TLS, struct tgl_user *buddy)
801 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
803 char *name_of_buddy = NULL;
804 if (buddy->first_name && buddy->last_name) {
805 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + strlen(buddy->last_name) + 1);
806 strcpy(name_of_buddy, buddy->first_name);
807 strcat(name_of_buddy, buddy->last_name);
808 } else if (buddy->first_name) {
809 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + 1);
810 strcpy(name_of_buddy, buddy->first_name);
812 name_of_buddy = (char *)malloc(strlen(" ") + 1);
813 strcpy(name_of_buddy, " ");
816 send_buddy_status_notification_response(TLS->callback_data, buddy->id.id, name_of_buddy, buddy->status.online);
820 name_of_buddy = NULL;
824 void tg_user_registered(struct tgl_state *TLS, struct tgl_user *U)
829 void tg_user_activated(struct tgl_state *TLS, struct tgl_user *U)
834 void tg_new_authorization(struct tgl_state *TLS, const char *device, const char *location)
839 void tg_chat_update(struct tgl_state *TLS, struct tgl_chat* chat_info, unsigned flags)
841 tg_engine_data_s *tg_data;
842 tg_data = TLS->callback_data;
844 if (chat_info && chat_info->flags == 144) {
848 if (flags == TGL_GROUP_CHAT_CREATED) {
850 insert_chat_info_to_db(chat_info, NULL);
851 tgl_peer_t* UC = tgl_peer_get(TLS, chat_info->id);
852 insert_peer_into_database(UC, 0, 0);
854 //if (tg_data->is_loading_completed) {
855 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_chat_info_received, NULL);
859 if (!(flags & TGL_UPDATE_CREATED)) {
861 if (!(flags & TGL_UPDATE_DELETED)) {
870 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)
876 * "%s phone number updated" will be changed to IDS_STRING for i18n.
878 len = name_of_buddy_len + strlen(str);
879 update_msg = (char *)malloc(len + 1);
884 snprintf(update_msg, len, str, name_of_buddy);
885 send_contact_updated_response(tg_data, buddy->id.id, update_msg);
889 void tg_user_update(struct tgl_state *TLS, struct tgl_user *buddy, unsigned flags)
892 int name_of_buddy_len;
893 static const char *NO_NAME = " ";
895 if (flags & TGL_UPDATE_CREATED) {
899 if (buddy->first_name && buddy->last_name) {
900 int first_len = strlen(buddy->first_name);
901 int last_len = strlen(buddy->last_name);
903 name_of_buddy_len = first_len + last_len;
905 name_of_buddy = (char *)malloc(name_of_buddy_len + 1);
907 strcpy(name_of_buddy, buddy->first_name);
908 strcpy(name_of_buddy + first_len, buddy->last_name);
909 } else if (buddy->first_name) {
910 name_of_buddy = strdup(buddy->first_name);
911 name_of_buddy_len = strlen(name_of_buddy);
913 name_of_buddy = (char *)NO_NAME;
914 name_of_buddy_len = strlen(NO_NAME);
917 if (!name_of_buddy) {
920 * Unable to allocate heap for buddy name
922 name_of_buddy = (char *)NO_NAME;
923 name_of_buddy_len = strlen(NO_NAME);
926 if (!(flags & TGL_UPDATE_DELETED)) {
927 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
929 if (flags & TGL_UPDATE_PHONE) {
930 send_message(TLS->callback_data, buddy, "%s phone number updated.", name_of_buddy, name_of_buddy_len);
932 if (flags & TGL_UPDATE_CONTACT) {
933 send_message(TLS->callback_data, buddy, "%s contact updated.", name_of_buddy, name_of_buddy_len);
935 if (flags & TGL_UPDATE_PHOTO) {
936 send_message(TLS->callback_data, buddy, "%s photo updated.", name_of_buddy, name_of_buddy_len);
937 //tgl_do_get_user_info(TLS, buddy->id, 0, &on_buddy_info_loaded, NULL);
939 if (flags & TGL_UPDATE_BLOCKED) {
940 send_message(TLS->callback_data, buddy, "%s contact blocked.", name_of_buddy, name_of_buddy_len);
942 if (flags & TGL_UPDATE_REAL_NAME) {
943 send_message(TLS->callback_data, buddy, "%s name updated.", name_of_buddy, name_of_buddy_len);
945 if (flags & TGL_UPDATE_NAME) {
946 send_message(TLS->callback_data, buddy, "%s contact name updated.", name_of_buddy, name_of_buddy_len);
948 if (flags & TGL_UPDATE_REQUESTED) {
949 send_message(TLS->callback_data, buddy, "%s status updated.", name_of_buddy, name_of_buddy_len);
951 if (flags & TGL_UPDATE_WORKING) {
952 send_message(TLS->callback_data, buddy, "%s status updated.", name_of_buddy, name_of_buddy_len);
954 if (flags & TGL_UPDATE_FLAGS) {
955 send_message(TLS->callback_data, buddy, "%s flags updated.", name_of_buddy, name_of_buddy_len);
957 if (flags & TGL_UPDATE_TITLE) {
958 send_message(TLS->callback_data, buddy, "%s title updated.", name_of_buddy, name_of_buddy_len);
960 if (flags & TGL_UPDATE_ADMIN) {
961 send_message(TLS->callback_data, buddy, "%s admin updated.", name_of_buddy, name_of_buddy_len);
963 if (flags & TGL_UPDATE_MEMBERS) {
964 send_message(TLS->callback_data, buddy, "%s memgers updated.", name_of_buddy, name_of_buddy_len);
966 if (flags & TGL_UPDATE_ACCESS_HASH) {
967 send_message(TLS->callback_data, buddy, "%s access hash updated.", name_of_buddy, name_of_buddy_len);
969 if (flags & TGL_UPDATE_USERNAME) {
970 send_message(TLS->callback_data, buddy, "%s username updated.", name_of_buddy, name_of_buddy_len);
973 send_message(TLS->callback_data, buddy, "%s contact deleted.", name_of_buddy, name_of_buddy_len);
976 if (name_of_buddy != NO_NAME) {
978 name_of_buddy = NULL;
982 void tg_secret_chat_update(struct tgl_state *TLS, struct tgl_secret_chat *C, unsigned flags)
987 void on_new_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
989 tg_engine_data_s *tg_data;
991 struct tgl_message *M = callback_extra;
997 if (chat_info->user_list) {
998 for (int i = 0; i < chat_info->user_list_size; i++) {
999 int user_id = chat_info->user_list[i].user_id;
1000 Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
1001 char* tb_name = get_table_name_from_number(user_id);
1002 create_buddy_msg_table(tb_name);
1003 if (!is_present_in_db) {
1004 // add to buddy table
1005 tgl_peer_id_t from_id;
1006 from_id.id = user_id;
1007 from_id.type = TGL_PEER_USER;
1008 tgl_do_get_user_info(TLS, from_id, 0, on_new_buddy_info_loaded, NULL);
1014 tg_data = TLS->callback_data;
1016 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1017 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
1018 char* creator_name = (char*)malloc(msg_len);
1019 strcpy(creator_name, UC->user.first_name);
1020 strcat(creator_name, " created the group");
1022 int cur_time = time(NULL);
1023 M->id = chat_info->id.id;
1024 M->message = creator_name;
1025 M->message_len = msg_len;
1028 insert_buddy_msg_to_db(M);
1031 tgl_peer_t* chat_UC = tgl_peer_get(TLS, chat_info->id);
1032 insert_chat_info_to_db(chat_info, NULL);
1034 insert_peer_into_database(chat_UC, 0, 0, 0);
1036 send_new_group_added_response(tg_data, chat_info->id.id);
1040 void on_group_chat_info_updated(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1042 tg_engine_data_s *tg_data;
1048 tg_data = TLS->callback_data;
1049 char *type_of_change = callback_extra;
1051 if (!type_of_change) {
1052 type_of_change = strdup("");
1055 tgl_peer_t* chat_UC = tgl_peer_get(TLS, chat_info->id);
1056 insert_chat_info_to_db(chat_info, NULL);
1057 insert_peer_into_database(chat_UC, 0, 0, 0);
1058 send_group_chat_updated_response(tg_data, chat_info->id.id, type_of_change);
1059 free(type_of_change);
1062 void on_new_chat_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1064 struct tgl_message *M = callback_extra;
1069 tgl_peer_t* peer = tgl_peer_get(TLS, M->from_id);
1070 int msg_len = strlen(peer->user.first_name) + strlen(" changed group icon") + 1;
1071 char* creator_name = (char*)malloc(msg_len);
1072 strcpy(creator_name, peer->user.first_name);
1073 strcat(creator_name, " changed group icon");
1075 int cur_time = time(NULL);
1077 M->message = creator_name;
1078 M->message_len = msg_len;
1081 insert_buddy_msg_to_db(M);
1083 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1086 tgl_peer_t* UC = tgl_peer_get(TLS, M->to_id);
1087 struct tgl_chat *chat_info = &(UC->chat);
1088 update_chat_info_to_db(chat_info, filename);
1089 update_peer_info_database(UC, 0);
1090 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, chat_info->id.id);
1091 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, filename);
1095 void on_media_sticker_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1097 struct tgl_message *M = (struct tgl_message*)callback_extra;
1098 if (success && filename) {
1099 // update in db and send info to app...
1100 long long media_id = M->media.document.id;
1101 update_receive_media_info_in_db(media_id, filename);
1102 tg_engine_data_s *tg_data = TLS->callback_data;
1103 if (M->from_id.id == tg_data->id.id) {
1106 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1111 void on_video_thumb_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1113 struct tgl_message *M = (struct tgl_message*)callback_extra;
1114 if (success && filename) {
1115 // update in db and send info to app...
1116 long long media_id = M->media.document.id;
1117 update_video_thumb_in_db(media_id, filename);
1118 tg_engine_data_s *tg_data = TLS->callback_data;
1119 if (M->from_id.id == tg_data->id.id) {
1120 send_video_thumb_download_completed_response(tg_data, M->from_id.id, M->to_id.id, media_id, filename, NULL);
1122 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1127 struct tg_temp_msg_data {
1128 Ecore_Timer* send_timer;
1129 struct tgl_state *TLS;
1130 struct tgl_message *M;
1133 static Eina_Bool on_msg_received_cb(void *data)
1135 struct tg_temp_msg_data *msg_data = data;
1136 insert_buddy_msg_to_db(msg_data->M);
1137 if (msg_data->M->media.type != tgl_message_media_none) {
1138 insert_media_info_to_db(msg_data->M, NULL);
1139 if (msg_data->M->media.type != tgl_message_media_none && (msg_data->M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1140 tgl_do_load_document_thumb(msg_data->TLS, &(msg_data->M->media.document), on_video_thumb_loaded, msg_data->M);
1141 if (msg_data->send_timer) {
1142 ecore_timer_del(msg_data->send_timer);
1145 return ECORE_CALLBACK_CANCEL;
1148 // inform to application
1149 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));
1150 if (msg_data->send_timer) {
1151 ecore_timer_del(msg_data->send_timer);
1154 return ECORE_CALLBACK_CANCEL;
1157 void on_requested_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1159 tg_engine_data_s *tg_data;
1161 struct tgl_message *M = callback_extra;
1169 if (!chat_info->user_list) {
1170 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_requested_chat_info_received, callback_extra);
1174 tg_data = TLS->callback_data;
1176 msg_table = get_table_name_from_number(chat_info->id.id);
1178 create_buddy_msg_table(msg_table);
1180 insert_chat_info_to_db(chat_info, NULL);
1181 struct tgl_photo *pic = &(chat_info->photo);
1183 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
1187 int msg_id = insert_current_date_to_table(msg_table);
1189 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, msg_id, tgl_get_peer_type(M->to_id));
1190 struct tg_temp_msg_data *msg_data = (struct tg_temp_msg_data*)malloc(sizeof(struct tg_temp_msg_data));
1192 msg_data->TLS = TLS;
1193 msg_data->send_timer = ecore_timer_add(1, on_msg_received_cb, msg_data);
1195 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1196 M->message = strdup("Audio");
1197 M->message_len = strlen("Audio");
1198 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1199 M->message = strdup("Video");
1200 M->message_len = strlen("Video");
1202 insert_buddy_msg_to_db(M);
1203 if (M->media.type != tgl_message_media_none) {
1204 insert_media_info_to_db(M, NULL);
1205 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1206 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1210 // inform to application
1211 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1218 void on_requested_update_chat_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1220 tg_engine_data_s *tg_data;
1222 msg_table = get_table_name_from_number(chat_info->id.id);
1223 create_buddy_msg_table(msg_table);
1229 if (chat_info->flags == 144) {
1232 int msg_count = get_number_of_messages(msg_table);
1233 if (msg_count <= 0) {
1234 if (chat_info->admin_id > 0) {
1235 set_date_item_to_table(msg_table, chat_info->date);
1236 tgl_peer_id_t admin_id;
1237 admin_id.id = chat_info->admin_id;
1238 admin_id.type = TGL_PEER_USER;
1240 tgl_peer_t* UC = tgl_peer_get(TLS, admin_id);
1241 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
1242 char* creator_name = (char*)malloc(msg_len);
1243 strcpy(creator_name, UC->user.first_name);
1244 strcat(creator_name, " created the group");
1245 struct tgl_message msg;
1246 int cur_time = chat_info->date;
1247 msg.to_id = chat_info->id;
1248 msg.from_id = admin_id;
1249 msg.id = chat_info->id.id;
1250 msg.message = creator_name;
1251 msg.message_len = msg_len;
1253 msg.date = cur_time;
1254 msg.media.type = tgl_message_media_none;
1258 insert_buddy_msg_to_db(&msg);
1260 //send_message_received_response(TLS->callback_data, msg.from_id.id, msg.to_id.id, msg.id, tgl_get_peer_type(msg.to_id));
1267 if (!chat_info->user_list) {
1268 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_chat_info_received, NULL);
1272 tg_data = TLS->callback_data;
1274 insert_chat_info_to_db(chat_info, NULL);
1275 struct tgl_photo *pic = &(chat_info->photo);
1277 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
1279 //char *type_of_change = strdup("add_user");
1280 tgl_peer_t* chat_UC = tgl_peer_get(TLS, chat_info->id);
1281 insert_chat_info_to_db(chat_info, NULL);
1282 insert_peer_into_database(chat_UC, 0, 0, 0);
1283 send_response_to_group_chat_updated_response(tg_data, chat_info->id.id);
1284 //free(type_of_change);
1287 void do_update_chat_info(int chat_id)
1289 tgl_peer_id_t to_id;
1291 to_id.type = TGL_PEER_CHAT;
1292 tgl_do_get_chat_info(s_info.TLS, to_id, 0, &on_requested_update_chat_received, NULL);
1295 void on_new_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U)
1300 tg_engine_data_s *tg_data = TLS->callback_data;
1301 struct tgl_message *M = callback_extra;
1302 if (U->id.id == tg_data->id.id) {
1305 tgl_peer_t* UC = tgl_peer_get(TLS, U->id);
1306 insert_peer_into_database(UC, 0, 0, 1);
1308 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, U);
1309 struct tgl_photo* pic = &(U->photo);
1311 tgl_do_load_photo(TLS, pic, &on_buddy_pic_loaded, U);
1314 send_new_buddy_added_response(tg_data, U->id.id);
1317 char* tb_name = get_table_name_from_number(U->id.id);
1318 int msg_id = insert_current_date_to_table(tb_name);
1321 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, msg_id, tgl_get_peer_type(M->to_id));
1323 struct tg_temp_msg_data *msg_data = (struct tg_temp_msg_data*)malloc(sizeof(struct tg_temp_msg_data));
1325 msg_data->TLS = TLS;
1326 msg_data->send_timer = ecore_timer_add(3, on_msg_received_cb, msg_data);
1328 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1329 M->message = strdup("Audio");
1330 M->message_len = strlen("Audio");
1331 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1332 M->message = strdup("Video");
1333 M->message_len = strlen("Video");
1335 insert_buddy_msg_to_db(M);
1336 if (M->media.type != tgl_message_media_none) {
1337 insert_media_info_to_db(M, NULL);
1338 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1339 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1341 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1345 // inform to application
1346 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1351 void tg_msg_receive(struct tgl_state *TLS, struct tgl_message *M)
1353 if (M && TLS->started) {
1355 if (M->flags & (FLAG_MESSAGE_EMPTY | FLAG_DELETED)) {
1358 if (!(M->flags & FLAG_CREATED)) {
1362 // this is service message. to be handled in telegram.
1363 if (tgl_get_peer_id(M->from_id) != TLS->our_id) {
1364 char *type_of_change = NULL;
1365 if (M->action.type == tgl_message_action_chat_create) {
1367 char* msg_table = get_table_name_from_number(M->to_id.id);
1368 create_buddy_msg_table(msg_table);
1371 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_new_chat_info_received, M);
1373 } else if (M->action.type == tgl_message_action_chat_edit_title) {
1374 type_of_change = strdup("edit_title");
1375 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1376 int msg_len = strlen(UC->user.first_name) + strlen(" changed the chat title") + 1;
1377 char* creator_name = (char*)malloc(msg_len);
1378 strcpy(creator_name, UC->user.first_name);
1379 strcat(creator_name, " changed the chat title");
1381 int cur_time = time(NULL);
1383 M->message = creator_name;
1384 M->message_len = msg_len;
1387 insert_buddy_msg_to_db(M);
1389 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1390 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
1391 } else if (M->action.type == tgl_message_action_chat_edit_photo) {
1393 char* msg_table = get_table_name_from_number(M->to_id.id);
1394 create_buddy_msg_table(msg_table);
1395 int msg_id = insert_current_date_to_table(msg_table);
1397 struct tgl_photo *pic = &(M->action.photo);
1399 tgl_do_load_photo(TLS, pic, &on_new_chat_pic_loaded, M);
1402 } else if (M->action.type == tgl_message_action_chat_delete_photo) {
1403 type_of_change = strdup("delete_photo");
1404 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1405 int msg_len = strlen(UC->user.first_name) + strlen(" deleted the profile photo") + 1;
1406 char* creator_name = (char*)malloc(msg_len);
1407 strcpy(creator_name, UC->user.first_name);
1408 strcat(creator_name, " deleted the profile photo");
1410 int cur_time = time(NULL);
1412 M->message = creator_name;
1413 M->message_len = msg_len;
1416 insert_buddy_msg_to_db(M);
1418 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1421 char *filename = "";
1422 tgl_peer_t* lUC = tgl_peer_get(TLS, M->to_id);
1423 struct tgl_chat *chat_info = &(lUC->chat);
1424 update_chat_info_to_db(chat_info, filename);
1425 update_peer_info_database(lUC, 0);
1426 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, chat_info->id.id);
1427 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, filename);
1430 } else if (M->action.type == tgl_message_action_chat_add_user) {
1431 type_of_change = strdup("add_user");
1432 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1433 int msg_len = strlen(UC->user.first_name) + strlen(" added to the group") + 1;
1434 char* creator_name = (char*)malloc(msg_len);
1435 strcpy(creator_name, UC->user.first_name);
1436 strcat(creator_name, " added to the group");
1438 int cur_time = time(NULL);
1440 M->message = creator_name;
1441 M->message_len = msg_len;
1444 insert_buddy_msg_to_db(M);
1446 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1447 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
1448 } else if (M->action.type == tgl_message_action_chat_delete_user) {
1449 type_of_change = strdup("delete_user");
1450 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1451 int msg_len = strlen(UC->user.first_name) + strlen(" left the group") + 1;
1452 char* creator_name = (char*)malloc(msg_len);
1453 strcpy(creator_name, UC->user.first_name);
1454 strcat(creator_name, " left the group");
1456 int cur_time = time(NULL);
1458 M->message = creator_name;
1459 M->message_len = msg_len;
1462 insert_buddy_msg_to_db(M);
1464 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1465 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
1471 if (!tgl_get_peer_type(M->to_id)) {
1476 if (tgl_get_peer_type(M->to_id) == TGL_PEER_USER) {
1484 if (M->media.type != tgl_message_media_none) {
1489 if (M->from_id.id == 333000 || M->from_id.id == 777000)
1492 char* tb_name = get_table_name_from_number(M->from_id.id);
1493 Eina_Bool is_present_in_db = is_user_present_buddy_table(M->from_id.id);
1494 create_buddy_msg_table(tb_name);
1495 if (!is_present_in_db) {
1496 tgl_do_get_user_info(TLS, M->from_id, 0, on_new_buddy_info_loaded, M);
1500 int msg_id = update_current_date_to_table(tb_name, M->date);
1504 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1505 M->message = strdup("Audio");
1506 M->message_len = strlen("Audio");
1507 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1508 M->message = strdup("Video");
1509 M->message_len = strlen("Video");
1510 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_STICKER)) {
1511 M->message = strdup("Sticker");
1512 M->message_len = strlen("Sticker");
1514 insert_buddy_msg_to_db(M);
1515 if (M->media.type != tgl_message_media_none) {
1516 insert_media_info_to_db(M, NULL);
1517 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1518 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1520 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_STICKER)) {
1521 tgl_do_load_document(TLS, &(M->media.document), on_media_sticker_loaded, M);
1525 // inform to application
1528 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));
1530 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1533 } else if (tgl_get_peer_type(M->to_id) == TGL_PEER_ENCR_CHAT) {
1537 if ((tgl_get_peer_type(M->from_id) == TGL_PEER_USER) && (tgl_get_peer_id(M->from_id) == TLS->our_id)) {
1540 if (M->media.type != tgl_message_media_none) {
1545 if (tgl_get_peer_type(M->to_id) == TGL_PEER_USER) {
1546 user_id = M->from_id.id;
1547 } else if (tgl_get_peer_type(M->to_id) == TGL_PEER_CHAT) {
1548 user_id = M->to_id.id;
1551 // check whether user is present or not
1553 Eina_Bool is_present_in_peer_db = is_user_present_buddy_table(user_id);
1554 if (!is_present_in_peer_db) {
1555 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_requested_chat_info_received, M);
1560 Eina_Bool is_present_in_chat_db = is_user_present_chat_table(user_id);
1561 if (!is_present_in_chat_db) {
1563 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_requested_chat_info_received, M);
1567 char* tb_name = get_table_name_from_number(user_id);
1568 int msg_id = update_current_date_to_table(tb_name, M->date);
1571 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1572 M->message = strdup("Audio");
1573 M->message_len = strlen("Audio");
1574 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1575 M->message = strdup("Video");
1576 M->message_len = strlen("Video");
1578 insert_buddy_msg_to_db(M);
1579 if (M->media.type != tgl_message_media_none) {
1580 insert_media_info_to_db(M, "");
1581 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1582 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1586 // inform to application
1589 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));
1591 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1598 void tg_our_id(struct tgl_state *TLS, int id)
1603 void tg_notification(struct tgl_state *TLS, char *type, char *message)
1608 void tg_user_status_update(struct tgl_state *TLS, struct tgl_user *U)
1611 if (tgl_get_peer_type(U->id) != TGL_PEER_USER) {
1618 if ((U->flags & FLAG_DELETED)) {
1620 } else if (!(U->flags & FLAG_CREATED)) {
1621 // newly created user
1627 if (U->flags & FLAG_USER_SELF) {
1628 update_buddy_into_db(USER_INFO_TABLE_NAME, U);
1629 } else if (U->flags & FLAG_USER_CONTACT) {
1630 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, U);
1632 struct tgl_user_status *S = &(U->status);
1634 if (S->online > 0) {
1637 if (S->online == 0) {
1639 } else if (S->online == -1) {
1640 //offline was online ");
1641 } else if (S->online == -2) {
1642 // offline (was online recently)
1643 } else if (S->online == -3) {
1644 //offline (was online last week)
1645 } else if (S->online == -4) {
1646 //offline (was online last month)
1650 // update status to application.
1651 send_buddy_status_updated_response(TLS->callback_data, U->id.id);
1660 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)
1665 struct tgl_update_callback upd_cb = {
1666 .new_msg = tg_new_msg,
1667 .marked_read = tg_marked_read,
1668 .logprintf = tg_logprintf,
1669 .get_string = tg_get_string,
1670 .logged_in = tg_logged_in,
1671 .started = tg_started,
1672 .type_notification = tg_type_notification,
1673 .type_in_chat_notification = tg_type_in_chat_notification,
1674 .type_in_secret_chat_notification = tg_type_in_secret_chat_notification,
1675 //.status_notification = tg_status_notification,
1676 .status_notification = NULL,
1677 .user_registered = tg_user_registered,
1678 .user_activated = tg_user_activated,
1679 .new_authorization = tg_new_authorization,
1680 //.user_update = tg_user_update,
1681 .user_update = NULL,
1682 //.chat_update = tg_chat_update,
1683 .chat_update = NULL,
1684 .secret_chat_update = tg_secret_chat_update,
1685 .msg_receive = tg_msg_receive,
1686 .our_id = tg_our_id,
1687 .user_status_update = tg_user_status_update
1690 void on_chat_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1692 struct tgl_chat *chat_info = callback_extra;
1695 update_chat_info_to_db(chat_info, filename);
1696 tgl_peer_t* UC = tgl_peer_get(TLS, chat_info->id);
1697 update_peer_info_database(UC, 0);
1698 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, chat_info->id.id);
1699 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, filename);
1703 void on_buddy_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1705 struct tgl_user *buddy = callback_extra;
1706 tg_engine_data_s *tg_data = TLS->callback_data;
1708 if (buddy && buddy->id.id == tg_data->id.id) {
1710 update_buddy_pic_db(filename, USER_INFO_TABLE_NAME, buddy->id.id);
1711 update_buddy_pic_db(filename, BUDDY_INFO_TABLE_NAME, buddy->id.id);
1712 send_buddy_profile_pic_updated_response(TLS->callback_data, buddy->id.id, filename);
1718 update_buddy_pic_db(filename, BUDDY_INFO_TABLE_NAME, buddy->id.id);
1719 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, buddy->id.id);
1720 send_buddy_profile_pic_updated_response(TLS->callback_data, buddy->id.id, filename);
1725 void on_new_group_icon_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
1727 struct tgl_chat *chat_info = callback_extra;
1728 tg_engine_data_s *tg_data;
1730 tg_data = TLS->callback_data;
1732 if (tg_data->new_group_icon) {
1734 char *msg_table = get_table_name_from_number(chat_info->id.id);
1735 create_buddy_msg_table(msg_table);
1737 char *msg_data = "group icon changed.";
1738 struct tgl_message msg;
1740 msg.from_id.type = 0;
1744 msg.fwd_from_id.id = 0;
1745 msg.fwd_from_id.type = 0;
1747 msg.message = msg_data;
1748 msg.message_len = strlen(msg_data);
1752 msg.to_id.type = tg_data->id.type;
1754 msg.media.type = -1;
1755 msg.is_marked_for_delete = 0;
1757 insert_msg_into_db(&msg, msg_table, t);
1760 update_chat_info_to_db(chat_info, tg_data->new_group_icon);
1761 update_buddy_pic_db(tg_data->new_group_icon, PEER_INFO_TABLE_NAME, chat_info->id.id);
1762 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, tg_data->new_group_icon);
1764 free(tg_data->new_group_icon);
1765 tg_data->new_group_icon = NULL;
1770 void on_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1772 tg_engine_data_s *tg_data;
1778 if (chat_info->flags == 144) {
1781 msg_table = get_table_name_from_number(chat_info->id.id);
1782 create_buddy_msg_table(msg_table);
1784 int msg_count = get_number_of_messages(msg_table);
1785 if (msg_count <= 0) {
1786 if (chat_info->admin_id > 0) {
1787 set_date_item_to_table(msg_table, chat_info->date);
1788 tgl_peer_id_t admin_id;
1789 admin_id.id = chat_info->admin_id;
1790 admin_id.type = TGL_PEER_USER;
1792 tgl_peer_t* UC = tgl_peer_get(TLS, admin_id);
1793 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
1794 char* creator_name = (char*)malloc(msg_len);
1795 strcpy(creator_name, UC->user.first_name);
1796 strcat(creator_name, " created the group");
1797 struct tgl_message msg;
1798 int cur_time = chat_info->date;
1799 msg.to_id = chat_info->id;
1800 msg.from_id = admin_id;
1801 msg.id = chat_info->id.id;
1802 msg.message = creator_name;
1803 msg.message_len = msg_len;
1805 msg.date = cur_time;
1806 msg.media.type = tgl_message_media_none;
1810 insert_buddy_msg_to_db(&msg);
1812 send_message_received_response(TLS->callback_data, msg.from_id.id, msg.to_id.id, msg.id, tgl_get_peer_type(msg.to_id));
1818 if (!chat_info->user_list) {
1819 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_chat_info_received, NULL);
1822 for (int i = 0; i < chat_info->user_list_size; i++) {
1823 int user_id = chat_info->user_list[i].user_id;
1824 Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
1825 char* tb_name = get_table_name_from_number(user_id);
1826 create_buddy_msg_table(tb_name);
1827 if (!is_present_in_db) {
1828 // add to buddy table
1829 tgl_peer_id_t from_id;
1830 from_id.id = user_id;
1831 from_id.type = TGL_PEER_USER;
1832 tgl_do_get_user_info(TLS, from_id, 0, on_new_buddy_info_loaded, NULL);
1838 tg_data = TLS->callback_data;
1840 insert_chat_info_to_db(chat_info, NULL);
1841 struct tgl_photo *pic = &(chat_info->photo);
1843 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
1847 void on_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U)
1852 tg_engine_data_s *tg_data = TLS->callback_data;
1853 if (U->id.id == tg_data->id.id) {
1857 //update_buddy_into_db(BUDDY_INFO_TABLE_NAME, U);
1858 struct tgl_photo* pic = &(U->photo);
1860 tgl_do_load_photo(TLS, pic, &on_buddy_pic_loaded, U);
1864 void delete_pending_group_chats(tg_engine_data_s *tg_data)
1866 Eina_List* id_list = get_chat_ids_to_be_deleted();
1867 if (id_list && eina_list_count(id_list) > 0) {
1868 for (int i = 0; i < eina_list_count(id_list); i++) {
1869 int chat_id_val = (int)eina_list_nth(id_list, i);
1870 if (chat_id_val > 0) {
1871 tgl_peer_id_t chat_id;
1872 chat_id.id = chat_id_val;
1873 chat_id.type = TGL_PEER_CHAT;
1875 tgl_peer_id_t self_id = tg_data->id;
1877 tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, NULL, NULL);
1883 void on_offline_chat_received(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[])
1885 tg_engine_data_s *tg_data = TLS->callback_data;
1886 for (int i = size - 1; i >= 0; i--) {
1887 struct tgl_message* message = list[i];
1888 if (message->service || message->from_id.id == tg_data->id.id) {
1891 tg_msg_receive(s_info.TLS, message);
1893 Eina_Bool is_offline_msg_requested = EINA_FALSE;
1894 tg_data->current_offline_buddy_index = tg_data->current_offline_buddy_index + 1;
1895 if (tg_data->current_offline_buddy_index < eina_list_count(tg_data->peer_list)) {
1897 for (int i = tg_data->current_offline_buddy_index; i < eina_list_count(tg_data->peer_list); i++) {
1899 tg_data->current_offline_buddy_index = i;
1901 tgl_peer_t* UC = eina_list_nth(tg_data->peer_list, i);
1903 struct tgl_message *last_msg = UC->last;
1905 // check last message in message table
1906 char* msg_table = get_table_name_from_number(UC->id.id);
1907 struct tgl_message* org_last_msg = get_message_from_message_tableby_message_id(msg_table, last_msg->id);
1908 if (!org_last_msg) {
1909 tgl_do_get_history(s_info.TLS, UC->id, 10, 0, on_offline_chat_received, UC);
1910 is_offline_msg_requested = EINA_TRUE;
1913 if (org_last_msg->message) {
1914 free(org_last_msg->message);
1922 if (!is_offline_msg_requested) {
1923 delete_pending_group_chats(tg_data);
1924 send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
1928 static Eina_Bool on_load_offline_messages(void *data)
1930 struct tgl_state *TLS = data;
1932 return ECORE_CALLBACK_CANCEL;
1934 tg_engine_data_s *tg_data = TLS->callback_data;
1936 return ECORE_CALLBACK_CANCEL;
1939 if (tg_data->peer_list && eina_list_count(tg_data->peer_list) > 0) {
1940 for (int i = 0; i < eina_list_count(tg_data->peer_list); i++) {
1941 tgl_peer_t* UC = eina_list_nth(tg_data->peer_list, i);
1942 char* msg_table = get_table_name_from_number(UC->id.id);
1943 create_buddy_msg_table(msg_table);
1944 delete_all_messages_from_chat(UC->id.id, UC->id.type);
1949 Eina_Bool is_offline_msg_requested = EINA_FALSE;
1951 if (tg_data->peer_list && eina_list_count(tg_data->peer_list) > 0) {
1952 for (int i = 0; i < eina_list_count(tg_data->peer_list); i++) {
1954 tg_data->current_offline_buddy_index = i;
1956 tgl_peer_t* UC = eina_list_nth(tg_data->peer_list, i);
1958 struct tgl_message *last_msg = UC->last;
1960 // check last message in message table
1961 char* msg_table = get_table_name_from_number(UC->id.id);
1962 struct tgl_message* org_last_msg = get_message_from_message_tableby_message_id(msg_table, last_msg->id);
1963 if (!org_last_msg) {
1964 tgl_do_get_history(s_info.TLS, UC->id, 10, 0, on_offline_chat_received, UC);
1965 is_offline_msg_requested = EINA_TRUE;
1968 if (org_last_msg->message) {
1969 free(org_last_msg->message);
1978 if (!is_offline_msg_requested) {
1979 delete_pending_group_chats(tg_data);
1980 send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
1983 return ECORE_CALLBACK_CANCEL;
1987 extern void on_peer_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info);
1989 static Eina_Bool on_async_peer_info_requested(void *data)
1991 struct tgl_state *TLS = data;
1993 return ECORE_CALLBACK_CANCEL;
1995 tg_engine_data_s *tg_data = TLS->callback_data;
1997 return ECORE_CALLBACK_CANCEL;
1999 tg_data->current_chat_index = tg_data->current_chat_index + 1;
2000 if (tg_data->current_chat_index < eina_list_count(tg_data->chat_list)) {
2001 tgl_peer_t* UC = eina_list_nth(tg_data->chat_list, tg_data->current_chat_index);
2003 return ECORE_CALLBACK_CANCEL;
2005 tgl_do_get_chat_info(TLS, UC->id, 0, &on_peer_chat_info_received, NULL);
2007 //send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
2008 ecore_timer_add(1, on_send_unsent_messages_requested, TLS);
2011 return ECORE_CALLBACK_CANCEL;
2014 void on_peer_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
2022 if (chat_info->flags == 144) {
2026 msg_table = get_table_name_from_number(chat_info->id.id);
2027 create_buddy_msg_table(msg_table);
2029 if (chat_info->admin_id > 0) {
2030 set_date_item_to_table(msg_table, chat_info->date);
2031 tgl_peer_id_t admin_id;
2032 admin_id.id = chat_info->admin_id;
2033 admin_id.type = TGL_PEER_USER;
2035 tgl_peer_t* UC = tgl_peer_get(TLS, admin_id);
2036 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
2037 char* creator_name = (char*)malloc(msg_len);
2038 strcpy(creator_name, UC->user.first_name);
2039 strcat(creator_name, " created the group");
2040 struct tgl_message msg;
2042 msg.to_id = chat_info->id;
2043 msg.from_id = admin_id;
2044 msg.id = chat_info->id.id;
2045 msg.message = creator_name;
2046 msg.message_len = msg_len;
2048 msg.date = chat_info->date;
2049 msg.media.type = tgl_message_media_none;
2053 insert_buddy_msg_to_db(&msg);
2058 if (chat_info->user_list) {
2059 for (int i = 0; i < chat_info->user_list_size; i++) {
2060 int user_id = chat_info->user_list[i].user_id;
2061 Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
2062 char* tb_name = get_table_name_from_number(user_id);
2063 create_buddy_msg_table(tb_name);
2064 if (!is_present_in_db) {
2065 // add to buddy table
2066 tgl_peer_id_t from_id;
2067 from_id.id = user_id;
2068 from_id.type = TGL_PEER_USER;
2069 tgl_do_get_user_info(TLS, from_id, 0, on_new_buddy_info_loaded, NULL);
2077 insert_chat_info_to_db(chat_info, NULL);
2079 struct tgl_photo *pic = &(chat_info->photo);
2081 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
2085 ecore_timer_add(1, on_async_peer_info_requested, TLS);
2090 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[])
2092 tg_engine_data_s *tg_data = TLS->callback_data;
2093 if (tg_data->chat_list) {
2094 eina_list_free(tg_data->chat_list);
2095 tg_data->chat_list = NULL;
2097 if (tg_data->buddy_list) {
2098 eina_list_free(tg_data->buddy_list);
2099 tg_data->buddy_list = NULL;
2101 if (tg_data->peer_list) {
2102 eina_list_free(tg_data->peer_list);
2103 tg_data->peer_list = NULL;
2105 for (int i = size - 1; i >= 0; i--) {
2106 tgl_peer_t* UC = tgl_peer_get(TLS, peers[i]);
2107 // user exited from chat
2108 if (UC->flags == 144) {
2111 tg_data->peer_list = eina_list_append(tg_data->peer_list, UC);
2112 // insert into peer table
2113 switch (tgl_get_peer_type(peers[i])) {
2115 tg_data->buddy_list = eina_list_append(tg_data->buddy_list, UC);
2117 // check peer exists in peer table / buddy table
2118 Eina_Bool is_buddy_present = is_user_present_buddy_table(UC->id.id);
2119 if (!is_buddy_present) {
2120 struct tgl_user* buddy = &(UC->user);
2122 char* msg_table = get_table_name_from_number(buddy->id.id);
2123 create_buddy_msg_table(msg_table);
2126 if (buddy->id.id == 333000 || buddy->id.id == 777000)
2127 buddy->is_unknown = 0;
2129 buddy->is_unknown = 1;
2131 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2132 insert_peer_into_database(UC, last_msg_id[i], unread_count[i], 1);
2133 tgl_do_get_user_info(TLS, buddy->id, 0, on_buddy_info_loaded, NULL);
2139 tg_data->chat_list = eina_list_append(tg_data->chat_list, UC);
2140 insert_peer_into_database(UC, last_msg_id[i], unread_count[i], 0);
2143 case TGL_PEER_ENCR_CHAT:
2151 if ((tg_data->chat_list == NULL) || (eina_list_count(tg_data->chat_list) <= 0)) {
2152 //send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
2153 ecore_timer_add(1, on_send_unsent_messages_requested, TLS);
2155 // load chat info one by one.
2156 tg_data->current_chat_index = 0;
2157 tgl_peer_t* UC = eina_list_nth(tg_data->chat_list, tg_data->current_chat_index);
2159 tgl_do_get_chat_info(TLS, UC->id, 0, &on_peer_chat_info_received, NULL);
2163 void on_contacts_received(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *contacts[])
2165 //tg_engine_data_s *tg_data = TLS->callback_data;
2166 for (int i = size - 1; i >= 0; i--) {
2167 struct tgl_user *buddy = contacts[i];
2168 char* msg_table = get_table_name_from_number(buddy->id.id);
2169 create_buddy_msg_table(msg_table);
2172 buddy->is_unknown = 0;
2173 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2174 tgl_peer_t* UC = tgl_peer_get(TLS, buddy->id);
2176 insert_peer_into_database(UC, 0, 0, 0);
2179 // inform client that contact loading is done.
2180 for (int i = size - 1; i >= 0; i--) {
2181 struct tgl_user *buddy = contacts[i];
2182 tgl_do_get_user_info(TLS, buddy->id, 0, on_buddy_info_loaded, NULL);
2185 tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2189 void add_contacts_to_account(struct tgl_state *TLS)
2191 tg_engine_data_s *tg_data = TLS->callback_data;
2192 if (sc_db_utils_connect()) {
2193 Eina_List* contact_list = get_contact_list_from_device_db();
2194 sc_db_utils_disconnect();
2196 if (!contact_list || eina_list_count(contact_list) <= 0) {
2197 // no contacts avilable. empty contact list.
2198 //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2200 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2202 eina_list_free(contact_list);
2206 int size = eina_list_count(contact_list);
2208 add_contacts_to_user(tg_data, size, contact_list);
2210 eina_list_free(contact_list);
2212 //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2213 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2218 void on_user_info_loaded(struct tgl_state *TLS, void *extra, int success, struct tgl_user *buddy)
2220 tg_engine_data_s *tg_data = TLS->callback_data;
2222 tg_data->id.id = buddy->id.id;
2223 tg_data->id.type = buddy->id.type;
2225 struct tgl_photo* pic = &(buddy->photo);
2227 tgl_do_load_photo(TLS, pic, &on_buddy_pic_loaded, buddy);
2230 buddy->is_unknown = 0;
2231 init_insert_buddy_into_db(USER_INFO_TABLE_NAME, buddy);
2234 if (tg_data->is_first_time_registration) {
2235 // send contact list to add friends.
2236 //send_add_contacts_request(tg_data);
2237 add_contacts_to_account(TLS);
2240 //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2241 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2244 add_contacts_to_account(TLS);
2248 void on_message_sent_to_buddy(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *message)
2250 tg_engine_data_s *tg_data;
2251 struct tgl_message* org_msg = (struct tgl_message*)callback_extra;
2252 tg_data = TLS->callback_data;
2254 if (success && message) {
2255 tgl_peer_t* UC = tgl_peer_get(TLS, message->to_id);
2257 message->msg_state = TG_MESSAGE_STATE_SENT;
2258 char* tb_name = get_table_name_from_number(message->to_id.id);
2259 update_msg_into_db(message, tb_name, org_msg->id);
2261 // delete message from unsent db
2262 delete_message_from_unsent_db(org_msg->id);
2263 delete_media_from_unsent_db(org_msg->id);
2265 if (message->media.type == tgl_message_media_photo || message->media.type == tgl_message_media_document || message->media.type == tgl_message_media_geo) {
2266 update_sent_media_info_in_db(message, (long long)org_msg->id);
2268 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));
2271 if (message->media.type != tgl_message_media_none && (message->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
2272 //tgl_do_load_document_thumb(TLS, &(message->media.document), on_video_thumb_loaded, message);
2278 org_msg->msg_state = TG_MESSAGE_STATE_FAILED;
2279 char* tb_name = get_table_name_from_number(org_msg->to_id.id);
2280 update_msg_into_db(org_msg, tb_name, org_msg->id);
2281 if (org_msg->media.type == tgl_message_media_photo || org_msg->media.type == tgl_message_media_document || message->media.type == tgl_message_media_geo) {
2282 if (org_msg->media.type == tgl_message_media_photo) {
2283 org_msg->media.photo.sizes_num = 0;
2284 org_msg->media.photo.sizes = NULL;
2286 update_sent_media_info_in_db(org_msg, (long long)org_msg->id);
2288 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));
2293 if (org_msg->message) {
2294 free(org_msg->message);
2300 void on_image_download_completed(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
2302 tg_engine_data_s *tg_data = TLS->callback_data;
2303 struct tgl_photo* photo_prop = (struct tgl_photo*)callback_extra;
2304 long long media_id = photo_prop->id;
2305 int buddy_id = photo_prop->user_id;
2306 int to_id = photo_prop->to_peer_id;
2308 if (photo_prop && filename) {
2309 update_receive_media_info_in_db(media_id, filename);
2310 //send response to application
2311 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, filename, photo_prop->caption);
2315 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, NULL, NULL);
2319 void on_document_download_completed(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
2321 tg_engine_data_s *tg_data = TLS->callback_data;
2322 struct tgl_document* doc_prop = (struct tgl_document*)callback_extra;
2323 long long media_id = doc_prop->id;
2324 int buddy_id = doc_prop->user_id;
2325 int to_id = doc_prop->to_peer_id;
2327 if (doc_prop && filename) {
2328 update_receive_media_info_in_db(media_id, filename);
2329 //send response to application
2330 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, filename, doc_prop->caption);
2333 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, NULL, NULL);
2337 if (doc_prop->caption) {
2338 free(doc_prop->caption);
2345 void free_contact_data(Eina_List *contact_data)
2347 contact_data_s* contact = NULL;
2348 EINA_LIST_FREE(contact_data, contact) {
2349 if (contact->display_name) {
2350 free(contact->display_name);
2351 contact->display_name = NULL;
2353 if (contact->first_name) {
2354 free(contact->first_name);
2355 contact->first_name = NULL;
2357 if (contact->last_name) {
2358 free(contact->last_name);
2359 contact->last_name = NULL;
2361 if (contact->phone_number) {
2362 free(contact->phone_number);
2363 contact->phone_number = NULL;
2369 void on_contact_added(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *users[])
2371 tg_engine_data_s* data = callback_extra;
2373 data->current_index++;
2375 if (data->current_index < eina_list_count(data->contact_list_to_add)) {
2376 contact_data_s* contact = eina_list_nth(data->contact_list_to_add, data->current_index);
2381 char *first_name = contact->first_name;
2382 char *last_name = contact->last_name;
2383 char *phone_number = contact->phone_number;
2386 first_name = contact->display_name;
2395 if (first_name && last_name && phone_number)
2396 tgl_do_add_contact(tgl_engine_get_TLS(), phone_number, first_name, last_name, 0, on_contact_added, data);
2398 on_contact_added(tgl_engine_get_TLS(), data, 0, 0, NULL);
2401 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2402 free_contact_data(data->contact_list_to_add);
2403 data->contact_list_to_add = NULL;
2407 void on_new_group_icon_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2410 /* TODO send fail notification */
2414 // send success notofication
2416 if (M->action.type == tgl_message_action_chat_create) {
2418 } else if (M->action.type == tgl_message_action_chat_edit_title) {
2420 } else if (M->action.type == tgl_message_action_chat_edit_photo) {
2422 char* msg_table = get_table_name_from_number(M->to_id.id);
2423 create_buddy_msg_table(msg_table);
2424 int msg_id = insert_current_date_to_table(msg_table);
2426 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2427 int msg_len = strlen(UC->user.first_name) + strlen(" changed profile photo") + 1;
2428 char* creator_name = (char*)malloc(msg_len);
2429 strcpy(creator_name, UC->user.first_name);
2430 strcat(creator_name, " changed profile photo");
2433 //send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id,msg_id, tgl_get_peer_type(M->to_id));
2434 int cur_time = time(NULL);
2436 M->message = creator_name;
2437 M->message_len = msg_len;
2440 insert_buddy_msg_to_db(M);
2443 struct tgl_photo *pic = &(M->action.photo);
2445 tgl_peer_t* UC = tgl_peer_get(TLS, M->to_id);
2446 struct tgl_chat *chat_info = &(UC->chat);
2447 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
2451 } else if (M->action.type == tgl_message_action_chat_delete_photo) {
2453 } else if (M->action.type == tgl_message_action_chat_add_user) {
2455 } else if (M->action.type == tgl_message_action_chat_delete_user) {
2458 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2462 void on_new_group_created(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2464 tg_engine_data_s *tg_data = TLS->callback_data;
2466 // send fail notification
2468 // send success notofication
2470 if (M->action.type == tgl_message_action_chat_create) {
2471 char* msg_table = get_table_name_from_number(M->to_id.id);
2472 create_buddy_msg_table(msg_table);
2475 int msg_id = insert_current_date_to_table(msg_table);
2476 //send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id,msg_id, tgl_get_peer_type(M->to_id));
2479 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2480 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
2481 char* creator_name = (char*)malloc(msg_len);
2482 strcpy(creator_name, UC->user.first_name);
2483 strcat(creator_name, " created the group");
2487 int cur_time = time(NULL);
2488 M->id = M->to_id.id;
2489 M->message = creator_name;
2490 M->message_len = msg_len;
2494 insert_buddy_msg_to_db(M);
2497 tgl_peer_t* chat_UC = tgl_peer_get(TLS, M->to_id);
2498 chat_UC->chat.date = M->date;
2499 insert_chat_info_to_db(&(chat_UC->chat), NULL);
2501 insert_peer_into_database(chat_UC, 0, 0, 0);
2503 if (tg_data->new_group_icon) {
2504 tgl_peer_t* UC = tgl_peer_get(TLS, M->to_id);
2505 struct tgl_chat *chat_info = &(UC->chat);
2506 tgl_do_set_chat_photo(TLS, chat_info->id, tg_data->new_group_icon, on_new_group_icon_loaded, chat_info);
2510 } else if (M->action.type == tgl_message_action_chat_edit_title) {
2512 } else if (M->action.type == tgl_message_action_chat_edit_photo) {
2514 } else if (M->action.type == tgl_message_action_chat_delete_photo) {
2516 } else if (M->action.type == tgl_message_action_chat_add_user) {
2518 } else if (M->action.type == tgl_message_action_chat_delete_user) {
2521 send_new_group_added_response(tg_data, M->to_id.id);
2526 void on_set_profile_picture_response_received(struct tgl_state *TLS, void *callback_extra, int success)
2528 tg_engine_data_s *tg_data = TLS->callback_data;
2529 char *file_path = callback_extra;
2532 update_buddy_pic_db(file_path, USER_INFO_TABLE_NAME, tg_data->id.id);
2533 update_buddy_pic_db(file_path, BUDDY_INFO_TABLE_NAME, tg_data->id.id);
2534 send_self_profile_picture_updated_response(tg_data, file_path, EINA_TRUE);
2536 send_self_profile_picture_updated_response(tg_data, file_path, EINA_FALSE);
2542 void set_profile_picture(tg_engine_data_s *tg_data, int buddy_id, const char *file_path)
2545 char *org_path = strdup(file_path);
2546 tgl_do_set_profile_photo(tgl_engine_get_TLS(), (char*)file_path, on_set_profile_picture_response_received, org_path);
2550 void on_set_new_chat_title_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2553 char *type_of_change = NULL;
2554 if (M && M->action.type == tgl_message_action_chat_edit_title) {
2555 type_of_change = strdup("edit_title");
2556 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2557 int msg_len = strlen(UC->user.first_name) + strlen(" changed the chat title") + 1;
2558 char* creator_name = (char*)malloc(msg_len);
2559 strcpy(creator_name, UC->user.first_name);
2560 strcat(creator_name, " changed the chat title");
2562 int cur_time = time(NULL);
2564 M->message = creator_name;
2565 M->message_len = msg_len;
2568 insert_buddy_msg_to_db(M);
2570 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2571 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
2574 tg_engine_data_s *tg_data = TLS->callback_data;
2575 struct tgl_chat *chat_info = (struct tgl_chat*)callback_extra;
2576 send_group_chat_rename_response(tg_data, chat_info->id.id, EINA_FALSE);
2580 void set_group_chat_new_title(tg_engine_data_s *tg_data, int buddy_id, const char *new_title)
2583 tgl_peer_id_t peer_id;
2584 peer_id.id = buddy_id;
2585 peer_id.type = TGL_PEER_CHAT;
2587 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), peer_id);
2588 struct tgl_chat *chat_info = &(UC->chat);
2589 tgl_do_rename_chat(tgl_engine_get_TLS(), chat_info->id, (char*)new_title, on_set_new_chat_title_response_received, chat_info);
2593 void on_new_buddy_added_to_chat_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2596 char *type_of_change = NULL;
2597 if (M && M->action.type == tgl_message_action_chat_add_user) {
2598 type_of_change = strdup("add_user");
2599 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2601 tgl_peer_id_t added_id;
2602 added_id.id = M->action.user;
2603 added_id.type = TGL_PEER_USER;
2605 tgl_peer_t* added_UC = tgl_peer_get(TLS, added_id);
2606 char* new_user_name = replace(added_UC->print_name, '_', " ");
2607 int msg_len = strlen(UC->user.first_name) + strlen(" added ") + strlen(new_user_name) + 1;
2608 char* creator_name = (char*)malloc(msg_len);
2609 strcpy(creator_name, UC->user.first_name);
2610 strcat(creator_name, " added ");
2611 strcat(creator_name, new_user_name);
2612 free(new_user_name);
2614 int cur_time = time(NULL);
2616 M->message = creator_name;
2617 M->message_len = msg_len;
2620 insert_buddy_msg_to_db(M);
2622 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2623 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
2626 tg_engine_data_s *tg_data = TLS->callback_data;
2627 struct tgl_chat *chat_info = (struct tgl_chat*)callback_extra;
2628 send_group_chat_new_buddy_response(tg_data, chat_info->id.id, EINA_FALSE);
2632 void set_group_chat_add_new_buddy(tg_engine_data_s *tg_data, int s_buddy_id, int s_chat_id)
2634 tgl_peer_id_t chat_id;
2635 chat_id.id = s_chat_id;
2636 chat_id.type = TGL_PEER_CHAT;
2638 tgl_peer_id_t buddy_id;
2639 buddy_id.id = s_buddy_id;
2640 buddy_id.type = TGL_PEER_USER;
2642 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), chat_id);
2643 struct tgl_chat *chat_info = &(UC->chat);
2644 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);
2648 void on_buddy_removed_from_chat_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2651 char *type_of_change = NULL;
2652 if (M && M->action.type == tgl_message_action_chat_delete_user) {
2653 type_of_change = strdup("delete_user");
2654 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2655 tgl_peer_id_t added_id;
2656 added_id.id = M->action.user;
2657 added_id.type = TGL_PEER_USER;
2659 tgl_peer_t* added_UC = tgl_peer_get(TLS, added_id);
2660 char* new_user_name = replace(added_UC->print_name, '_', " ");
2661 int msg_len = strlen(UC->user.first_name) + strlen(" removed ") + strlen(new_user_name) + 1;
2662 char* creator_name = (char*)malloc(msg_len);
2663 strcpy(creator_name, UC->user.first_name);
2664 strcat(creator_name, " removed ");
2665 strcat(creator_name, new_user_name);
2666 free(new_user_name);
2667 int cur_time = time(NULL);
2669 M->message = creator_name;
2670 M->message_len = msg_len;
2673 insert_buddy_msg_to_db(M);
2675 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2676 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
2679 tg_engine_data_s *tg_data = TLS->callback_data;
2680 struct tgl_chat *chat_info = (struct tgl_chat*)callback_extra;
2681 send_group_chat_delete_buddy_response(tg_data, chat_info->id.id, EINA_FALSE);
2685 void set_group_chat_remove_buddy(tg_engine_data_s *tg_data, int s_buddy_id, int s_chat_id)
2687 tgl_peer_id_t chat_id;
2688 chat_id.id = s_chat_id;
2689 chat_id.type = TGL_PEER_CHAT;
2691 tgl_peer_id_t buddy_id;
2692 buddy_id.id = s_buddy_id;
2693 buddy_id.type = TGL_PEER_USER;
2695 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), chat_id);
2696 struct tgl_chat *chat_info = &(UC->chat);
2697 tgl_do_del_user_from_chat(tgl_engine_get_TLS(), chat_id, buddy_id, on_buddy_removed_from_chat_response_received, chat_info);
2700 void set_group_chat_profile_picture(tg_engine_data_s *tg_data, int buddy_id, const char *file_path)
2703 tgl_peer_id_t peer_id;
2704 peer_id.id = buddy_id;
2705 peer_id.type = TGL_PEER_CHAT;
2707 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), peer_id);
2708 struct tgl_chat *chat_info = &(UC->chat);
2709 tgl_do_set_chat_photo(tgl_engine_get_TLS(), chat_info->id, (char*)file_path, on_new_group_icon_loaded, chat_info);
2713 void on_set_username_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *buddy)
2715 tg_engine_data_s *tg_data = TLS->callback_data;
2716 char *org_username = callback_extra;
2719 update_buddy_into_db(USER_INFO_TABLE_NAME, buddy);
2720 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2721 send_self_user_name_updated_response(tg_data, org_username, EINA_TRUE);
2723 send_self_user_name_updated_response(tg_data, org_username, EINA_FALSE);
2730 void set_user_name(tg_engine_data_s *tg_data, int buddy_id, const char *username)
2733 char *org_username = strdup(username);
2734 tgl_do_set_username(tgl_engine_get_TLS(), username, on_set_username_response_received, org_username);
2738 void on_profile_name_changed(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *buddy)
2740 tg_engine_data_s *tg_data = callback_extra;
2743 update_buddy_into_db(USER_INFO_TABLE_NAME, buddy);
2744 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2745 send_self_profile_name_updated_response(tg_data, buddy->first_name, buddy->last_name, EINA_TRUE);
2747 send_self_profile_name_updated_response(tg_data, "", "", EINA_FALSE);
2751 void update_user_display_name(tg_engine_data_s *tg_data, int buddy_id, const char *first_name, const char *last_name)
2753 if (first_name && last_name) {
2754 tgl_do_set_profile_name(tgl_engine_get_TLS(),
2755 first_name, last_name, on_profile_name_changed, tg_data);
2759 void create_new_group(tg_engine_data_s *tg_data, Eina_List* buddy_ids, const char *group_name, const char *group_icon)
2761 if (!buddy_ids || ! group_name) {
2764 int users_num = eina_list_count(buddy_ids);
2765 static tgl_peer_id_t ids[1024];
2766 static char _group_icon[1024];
2768 Eina_Bool is_added = EINA_FALSE;
2769 for (i = 0; i < users_num; i++) {
2770 char *buddy_id_str = (char *)eina_list_nth(buddy_ids, i);
2773 int buddy_id = atoi(buddy_id_str);
2774 ids[i].id = buddy_id;
2775 ids[i].type = TGL_PEER_USER;
2776 is_added = EINA_TRUE;
2782 strncpy(_group_icon, group_icon, sizeof(_group_icon));
2784 tgl_do_create_group_chat_ex(tgl_engine_get_TLS(), users_num, ids, group_name, on_new_group_created, (void *)_group_icon);
2785 tg_data->is_group_creation_requested = EINA_TRUE;
2787 if (tg_data->new_group_icon) {
2788 free(tg_data->new_group_icon);
2791 if (group_icon && strlen(group_icon) > 0) {
2792 tg_data->new_group_icon = strdup(group_icon);
2794 tg_data->new_group_icon = NULL;
2799 void add_contacts_to_user(tg_engine_data_s *tg_data, int size, Eina_List* contact_list)
2801 tg_data->contact_list_to_add = contact_list;
2802 contact_data_s* contact = eina_list_nth(contact_list, 0);
2804 char *first_name = contact->first_name;
2805 char *last_name = contact->last_name;
2806 char *phone_number = contact->phone_number;
2808 tg_data->current_index = 0;
2811 first_name = contact->display_name;
2821 if (first_name && last_name && phone_number) {
2822 tgl_do_add_contact(tgl_engine_get_TLS(), phone_number, first_name, last_name, 0, on_contact_added, tg_data);
2824 on_contact_added(tgl_engine_get_TLS(), tg_data, 0, 0, NULL);
2829 void media_download_request(tg_engine_data_s *tg_data, int buddy_id, long long media_id)
2831 // get media details by mediaid
2832 struct tgl_media* img_details = get_media_details_from_db(media_id);
2835 send_media_download_completed_response(tg_data, -1, buddy_id, media_id, NULL, NULL);
2839 if (img_details->media_type == tgl_message_media_none) {
2841 } else if (img_details->media_type == tgl_message_media_photo) {
2843 struct tgl_photo* photo_prop = (struct tgl_photo*)malloc(sizeof(struct tgl_photo));
2844 photo_prop->id = img_details->media_id;
2845 photo_prop->access_hash = img_details->access_hash;
2846 photo_prop->user_id = img_details->user_id;
2847 photo_prop->date = img_details->date;
2848 photo_prop->caption = img_details->caption;
2849 photo_prop->geo.latitude = atof(img_details->latitude);
2850 photo_prop->geo.longitude = atof(img_details->longitude);
2851 photo_prop->sizes_num = img_details->sizes;
2853 photo_prop->sizes = talloc(sizeof(struct tgl_photo_size) * photo_prop->sizes_num);
2855 for (i = 0; i < photo_prop->sizes_num; i++) {
2858 photo_prop->sizes[i].w = img_details->photo_width1;
2859 photo_prop->sizes[i].h = img_details->photo_height1;
2860 photo_prop->sizes[i].size = img_details->photo_size1;
2861 if (img_details->photo_data1) {
2862 photo_prop->sizes[i].data = strdup(img_details->photo_data1);
2864 if (img_details->photo_type1) {
2865 photo_prop->sizes[i].type = strdup(img_details->photo_type1);
2867 photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc1;
2868 photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id1;
2869 photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec1;
2870 photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol1;
2871 } else if (i == 1) {
2873 photo_prop->sizes[i].w = img_details->photo_width2;
2874 photo_prop->sizes[i].h = img_details->photo_height2;
2875 photo_prop->sizes[i].size = img_details->photo_size2;
2876 if (img_details->photo_data2) {
2877 photo_prop->sizes[i].data = strdup(img_details->photo_data2);
2879 if (img_details->photo_type2) {
2880 photo_prop->sizes[i].type = strdup(img_details->photo_type2);
2882 photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc2;
2883 photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id2;
2884 photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec2;
2885 photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol2;
2887 } else if (i == 2) {
2889 photo_prop->sizes[i].w = img_details->photo_width3;
2890 photo_prop->sizes[i].h = img_details->photo_height3;
2891 photo_prop->sizes[i].size = img_details->photo_size3;
2892 if (img_details->photo_data3) {
2893 photo_prop->sizes[i].data = strdup(img_details->photo_data3);
2895 if (img_details->photo_type3) {
2896 photo_prop->sizes[i].type = strdup(img_details->photo_type3);
2898 photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc3;
2899 photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id3;
2900 photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec3;
2901 photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol3;
2903 } else if (i == 3) {
2905 photo_prop->sizes[i].w = img_details->photo_width4;
2906 photo_prop->sizes[i].h = img_details->photo_height4;
2907 photo_prop->sizes[i].size = img_details->photo_size4;
2908 if (img_details->photo_data4) {
2909 photo_prop->sizes[i].data = strdup(img_details->photo_data4);
2911 if (img_details->photo_type4) {
2912 photo_prop->sizes[i].type = strdup(img_details->photo_type4);
2914 photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc4;
2915 photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id4;
2916 photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec4;
2917 photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol4;
2924 photo_prop->to_peer_id = buddy_id;
2925 tgl_do_load_photo(s_info.TLS, photo_prop, &on_image_download_completed, photo_prop);
2927 } else if (img_details->media_type == tgl_message_media_document) {
2928 struct tgl_document* doc_prop = (struct tgl_document*)malloc(sizeof(struct tgl_document));
2929 doc_prop->id = img_details->media_id;;
2930 doc_prop->access_hash = img_details->access_hash;
2931 doc_prop->user_id = img_details->user_id;
2932 doc_prop->date = img_details->date;
2933 doc_prop->size = img_details->sizes;
2934 doc_prop->mime_type = NULL;
2935 doc_prop->dc_id = img_details->doc_dc;
2936 doc_prop->to_peer_id = buddy_id;
2938 if (img_details->caption) {
2939 doc_prop->caption = strdup(img_details->caption);
2941 doc_prop->caption = NULL;
2945 if (!(img_details->mime_type) || strlen(img_details->mime_type) <= 0) {
2947 if (img_details->doc_type && strlen(img_details->doc_type) > 0) {
2948 if (img_details->doc_type && strstr(img_details->doc_type, "video") != NULL) {
2949 doc_prop->mime_type = strdup("video/mp4");
2950 } else if (img_details->doc_type && strstr(img_details->doc_type, "audio") != NULL) {
2951 doc_prop->mime_type = strdup("audio/wav");
2952 } else if (img_details->doc_type && strstr(img_details->doc_type, "image/gif") != NULL) {
2953 doc_prop->mime_type = strdup("image/gif");
2957 doc_prop->mime_type = img_details->mime_type;
2960 if (img_details->doc_type && strstr(img_details->doc_type, "video") != NULL) {
2961 doc_prop->flags = FLAG_DOCUMENT_VIDEO;
2962 } else if (img_details->doc_type && strstr(img_details->doc_type, "audio") != NULL) {
2963 doc_prop->flags = FLAG_DOCUMENT_AUDIO;
2964 } else if (img_details->doc_type && strstr(img_details->doc_type, "image") != NULL) {
2965 doc_prop->flags = FLAG_DOCUMENT_ANIMATED;
2968 tgl_do_load_document(s_info.TLS, doc_prop, on_document_download_completed, doc_prop);
2975 // delete image details
2977 if (img_details->caption) {
2978 free(img_details->caption);
2980 if (img_details->longitude) {
2981 free(img_details->longitude);
2983 if (img_details->latitude) {
2984 free(img_details->latitude);
2986 if (img_details->phone_no) {
2987 free(img_details->phone_no);
2989 if (img_details->first_name) {
2990 free(img_details->first_name);
2992 if (img_details->last_name) {
2993 free(img_details->last_name);
2995 if (img_details->file_path) {
2996 free(img_details->file_path);
2998 if (img_details->photo_type1) {
2999 free(img_details->photo_type1);
3001 if (img_details->photo_data1) {
3002 free(img_details->photo_data1);
3004 if (img_details->photo_type2) {
3005 free(img_details->photo_type2);
3007 if (img_details->photo_data2) {
3008 free(img_details->photo_data2);
3010 if (img_details->photo_type3) {
3011 free(img_details->photo_type3);
3013 if (img_details->photo_data3) {
3014 free(img_details->photo_data3);
3016 if (img_details->photo_type4) {
3017 free(img_details->photo_type4);
3019 if (img_details->photo_data4) {
3020 free(img_details->photo_data4);
3022 if (img_details->mime_type) {
3023 free(img_details->mime_type);
3025 if (img_details->doc_type) {
3026 free(img_details->doc_type);
3028 if (img_details->doc_thumb_path) {
3029 free(img_details->doc_thumb_path);
3035 void on_mark_read_callback(struct tgl_state *TLS, void *callback_extra, int success)
3037 // message read sent successfully. update to UI if needed.
3041 void on_message_deleted_from_message_list(struct tgl_state *TLS, void *callback_extra, int success)
3043 msg_list_container_s *msg_list_container = (msg_list_container_s*)callback_extra;
3044 /* tg_engine_data_s *tg_data = TLS->callback_data; */
3046 if (success && msg_list_container) {
3047 // delete message from message table
3048 char* tb_name = get_table_name_from_number(msg_list_container->buddy_id);
3049 delete_message_from_table(tb_name, msg_list_container->current_message_id);
3053 if (msg_list_container && msg_list_container->message_ids) {
3054 if (msg_list_container->current_index < eina_list_count(msg_list_container->message_ids)) {
3055 msg_list_container->current_index = msg_list_container->current_index + 1;
3056 msg_list_container->current_message_id = (int)eina_list_nth(msg_list_container->message_ids, msg_list_container->current_index);
3057 tgl_do_delete_msg(s_info.TLS, msg_list_container->current_message_id, &on_message_deleted_from_message_list , (void*)(msg_list_container));
3059 eina_list_free(msg_list_container->message_ids);
3060 free(msg_list_container);
3065 void delete_all_messages_from_chat(int buddy_id, int type_of_chat)
3067 tgl_peer_id_t chat_id;
3068 chat_id.id = buddy_id;
3069 chat_id.type = type_of_chat;
3071 char* tb_name = get_table_name_from_number(buddy_id);
3072 //get all message ids from table.
3073 Eina_List *msg_ids = get_all_message_ids_from_table(tb_name);
3076 if (msg_ids && eina_list_count(msg_ids) > 0) {
3077 msg_list_container_s *msg_list_container = (msg_list_container_s*)malloc(sizeof(msg_list_container_s));
3078 msg_list_container->message_ids = msg_ids;
3079 msg_list_container->buddy_id = buddy_id;
3080 msg_list_container->current_index = 0;
3081 msg_list_container->current_message_id = (int)eina_list_nth(msg_list_container->message_ids, msg_list_container->current_index);
3083 tgl_do_delete_msg(s_info.TLS, msg_list_container->current_message_id, &on_message_deleted_from_message_list , (void*)(msg_list_container));
3089 void send_do_mark_read_messages(int buddy_id, int type_of_chat)
3091 tgl_peer_id_t chat_id;
3092 chat_id.id = buddy_id;
3093 chat_id.type = type_of_chat;
3095 tgl_do_mark_read(s_info.TLS, chat_id, &on_mark_read_callback , (void*)(&chat_id));
3099 void on_user_block_response(struct tgl_state *TLS, void *callback_extra, int success)
3101 int buddy_id = (int)callback_extra;
3102 tg_engine_data_s *tg_data = TLS->callback_data;
3106 update_buddy_block_db(BUDDY_INFO_TABLE_NAME, buddy_id, blocked);
3107 send_buddy_blocked_response(tg_data, buddy_id, EINA_TRUE);
3109 send_buddy_blocked_response(tg_data, buddy_id, EINA_FALSE);
3113 void on_user_unblock_response(struct tgl_state *TLS, void *callback_extra, int success)
3115 int buddy_id = (int)callback_extra;
3116 tg_engine_data_s *tg_data = TLS->callback_data;
3119 update_buddy_block_db(BUDDY_INFO_TABLE_NAME, buddy_id, blocked);
3120 send_buddy_unblocked_response(tg_data, buddy_id, EINA_TRUE);
3122 send_buddy_unblocked_response(tg_data, buddy_id, EINA_FALSE);
3126 void on_user_delete_response(struct tgl_state *TLS, void *callback_extra, int success)
3128 int buddy_id = (int)callback_extra;
3129 tg_engine_data_s *tg_data = TLS->callback_data;
3132 // delete from peer table
3133 // delete from buddy table
3134 // delete chat items
3136 //delete_chat_from_db(buddy_id);
3137 //delete_buddy_from_db(buddy_id);
3138 //char* msg_table = get_table_name_from_number(buddy_id);
3139 //drop_table(msg_table);
3143 update_buddy_delete_db(BUDDY_INFO_TABLE_NAME, buddy_id, deleted);
3144 update_buddy_delete_db(PEER_INFO_TABLE_NAME, buddy_id, deleted);
3145 send_buddy_deleted_response(tg_data, buddy_id, EINA_TRUE);
3147 send_buddy_deleted_response(tg_data, buddy_id, EINA_FALSE);
3152 void on_buddy_readded(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *users[])
3154 int buddy_id = (int)callback_extra;
3155 tg_engine_data_s *tg_data = TLS->callback_data;
3158 update_buddy_delete_db(BUDDY_INFO_TABLE_NAME, buddy_id, deleted);
3159 send_buddy_readded_response(tg_data, buddy_id, EINA_TRUE);
3161 send_buddy_readded_response(tg_data, buddy_id, EINA_FALSE);
3165 void on_new_buddy_added(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *users[])
3167 tg_engine_data_s *tg_data = TLS->callback_data;
3168 if (success && size > 0) {
3169 struct tgl_user *buddy = users[0];
3171 char* msg_table = get_table_name_from_number(buddy->id.id);
3172 create_buddy_msg_table(msg_table);
3174 buddy->is_unknown = 0;
3175 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
3176 tgl_peer_t* UC = tgl_peer_get(TLS, buddy->id);
3178 insert_peer_into_database(UC, 0, 0, 0);
3180 tgl_do_get_user_info(TLS, buddy->id, 0, on_buddy_info_loaded, NULL);
3182 // send response to application
3183 send_new_contact_added_response(tg_data, buddy->id.id, EINA_TRUE);
3185 send_new_contact_added_response(tg_data, -1, EINA_FALSE);
3189 send_new_contact_added_response(tg_data, -1, EINA_FALSE);
3193 void do_add_buddy(int buddy_id, char *first_name, char *last_name, char *phone_num)
3205 if (first_name && last_name && phone_num) {
3206 if (buddy_id == -1) {
3207 tgl_do_add_contact(s_info.TLS, phone_num, first_name, last_name, 0, on_new_buddy_added, (void*)(buddy_id));
3209 tgl_do_add_contact(s_info.TLS, phone_num, first_name, last_name, 0, on_buddy_readded, (void*)(buddy_id));
3215 void logout_telegram(tg_engine_data_s *tg_data)
3220 void on_secret_chat_request_sent(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_secret_chat *E)
3223 int buddy_id = (int)callback_extra;
3224 tg_engine_data_s *tg_data = TLS->callback_data;
3233 void request_for_secret_chat(int buddy_id)
3235 tgl_peer_id_t peer_id;
3236 peer_id.id = buddy_id;
3237 peer_id.type = TGL_PEER_USER;
3238 tgl_do_create_secret_chat(s_info.TLS, peer_id, on_secret_chat_request_sent, (void*)(buddy_id));
3241 void do_delete_buddy(int buddy_id)
3243 tgl_peer_id_t peer_id;
3244 peer_id.id = buddy_id;
3245 peer_id.type = TGL_PEER_USER;
3246 tgl_do_del_contact(s_info.TLS, peer_id, &on_user_delete_response , (void*)(buddy_id));
3249 void on_message_deleted(struct tgl_state *TLS, void *callback_extra, int success)
3251 msg_container_s *msg_details = (msg_container_s*)callback_extra;
3252 tg_engine_data_s *tg_data = TLS->callback_data;
3255 send_message_deleted_response(tg_data, msg_details->buddy_id, msg_details->message_id, EINA_TRUE);
3257 send_message_deleted_response(tg_data, msg_details->buddy_id, msg_details->message_id, EINA_FALSE);
3261 void do_delete_message(int buddy_id, int message_id)
3263 msg_container_s *msg_details = (msg_container_s*)malloc(sizeof(msg_container_s));
3264 msg_details->buddy_id = buddy_id;
3265 msg_details->message_id = message_id;
3266 tgl_do_delete_msg(s_info.TLS, message_id, &on_message_deleted , (void*)(msg_details));
3270 void do_block_buddy(int buddy_id)
3272 tgl_peer_id_t peer_id;
3273 peer_id.id = buddy_id;
3274 peer_id.type = TGL_PEER_USER;
3275 tgl_do_block_user(s_info.TLS, peer_id, &on_user_block_response , (void*)(buddy_id));
3278 void do_unblock_buddy(int buddy_id)
3280 tgl_peer_id_t peer_id;
3281 peer_id.id = buddy_id;
3282 peer_id.type = TGL_PEER_USER;
3283 tgl_do_unblock_user(s_info.TLS, peer_id, &on_user_unblock_response , (void*)(buddy_id));
3286 extern void on_selected_group_chats_delete_reponse(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M);
3287 static Eina_Bool on_async_chat_deletion_requested(void *data)
3289 Eina_List *sel_grp_chats = data;
3290 if (sel_grp_chats) {
3291 tg_engine_data_s *tg_data = tgl_engine_get_TLS()->callback_data;
3292 tg_data->current_group_chat_index = tg_data->current_group_chat_index + 1;
3294 if (tg_data->current_group_chat_index < eina_list_count(sel_grp_chats)) {
3295 int group_chat_id = (int)eina_list_nth(sel_grp_chats, tg_data->current_group_chat_index);
3297 tgl_peer_id_t chat_id;
3298 chat_id.id = group_chat_id;
3299 chat_id.type = TGL_PEER_CHAT;
3301 tgl_peer_id_t self_id = tg_data->id;
3303 tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, on_selected_group_chats_delete_reponse, (void*)(sel_grp_chats));
3305 send_selected_group_chats_deleted_response(tg_data);
3308 return ECORE_CALLBACK_CANCEL;
3312 void on_selected_group_chats_delete_reponse(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
3314 Eina_List *sel_grp_chats = callback_extra;
3315 tg_engine_data_s *tg_data = TLS->callback_data;
3316 int chat_id = (int)eina_list_nth(sel_grp_chats, tg_data->current_group_chat_index);
3319 delete_chat_from_db(chat_id);
3320 char* msg_table = get_table_name_from_number(chat_id);
3321 drop_table(msg_table);
3324 ecore_timer_add(1, on_async_chat_deletion_requested, sel_grp_chats);
3327 void delete_selected_group_chat(tg_engine_data_s *tg_data, Eina_List *sel_grp_chats)
3329 if (sel_grp_chats && eina_list_count(sel_grp_chats) > 0) {
3331 tg_data->current_group_chat_index = 0;
3332 int group_chat_id = (int)eina_list_nth(sel_grp_chats, tg_data->current_group_chat_index);
3334 tgl_peer_id_t chat_id;
3335 chat_id.id = group_chat_id;
3336 chat_id.type = TGL_PEER_CHAT;
3338 tgl_peer_id_t self_id = tg_data->id;
3340 tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, on_selected_group_chats_delete_reponse, (void*)(sel_grp_chats));
3344 void on_group_chat_delete_reponse(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
3346 int chat_id = (int)callback_extra;
3347 tg_engine_data_s *tg_data = TLS->callback_data;
3350 // delete from peer table
3351 delete_chat_from_db(chat_id);
3352 char* msg_table = get_table_name_from_number(chat_id);
3353 drop_table(msg_table);
3355 send_group_chat_deleted_response(tg_data, chat_id, EINA_TRUE);
3357 send_group_chat_deleted_response(tg_data, chat_id, EINA_FALSE);
3361 void leave_group_chat(tg_engine_data_s *tg_data, int group_chat_id)
3363 tgl_peer_id_t chat_id;
3364 chat_id.id = group_chat_id;
3365 chat_id.type = TGL_PEER_CHAT;
3367 tgl_peer_id_t self_id = tg_data->id;
3369 tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, on_group_chat_delete_reponse, (void*)(group_chat_id));
3373 void on_new_msg_requested_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
3375 tg_engine_data_s *tg_data;
3377 struct tgl_message *msg = callback_extra;
3384 if (!chat_info->user_list) {
3385 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_requested_chat_info_received, callback_extra);
3389 tg_data = TLS->callback_data;
3391 msg_table = get_table_name_from_number(chat_info->id.id);
3393 create_buddy_msg_table(msg_table);
3395 insert_chat_info_to_db(chat_info, NULL);
3396 struct tgl_photo *pic = &(chat_info->photo);
3398 tgl_do_load_photo(TLS, pic, &on_chat_pic_loaded, chat_info);
3401 tgl_do_send_message(s_info.TLS, msg->to_id, msg->message, strlen(msg->message), &on_message_sent_to_buddy, (void*)(msg));
3403 char *type_of_change = strdup("add_user");
3404 tgl_do_get_chat_info(s_info.TLS, msg->to_id, 0, &on_group_chat_info_updated, type_of_change);
3410 void forward_message_to_buddy(int to_id, int type_of_chat, int from_id, int message_id, int temp_message_id)
3412 char *msg_table = get_table_name_from_number(from_id);
3413 struct tgl_message* msg = get_message_from_message_table(temp_message_id, msg_table);
3416 tgl_peer_id_t id_to_send;
3417 id_to_send.id = type_of_chat;
3418 tgl_do_forward_message(s_info.TLS, id_to_send, message_id, &on_message_sent_to_buddy, (void*)(msg));
3423 void send_typing_status_to_buddy(int buddy_id, int type_of_chat, int typing_status)
3425 tgl_peer_id_t id_to_send;
3426 id_to_send.id = type_of_chat;
3427 tgl_do_send_typing(s_info.TLS, id_to_send, typing_status, NULL, NULL);
3430 void send_message_to_buddy(int buddy_id, int message_id, int msg_type, char *msg_data, int type_of_chat)
3432 // get type of chat from buddy_id.
3433 char *msg_table = get_table_name_from_number(buddy_id);
3434 struct tgl_message* msg = get_message_from_message_table(message_id, msg_table);
3437 if (type_of_chat == TGL_PEER_USER) {
3438 msg->from_id.type = TGL_PEER_USER;
3439 msg->to_id.type = TGL_PEER_USER;
3440 tgl_do_send_message(s_info.TLS, msg->to_id, msg->message, strlen(msg->message), &on_message_sent_to_buddy, (void*)(msg));
3441 } else if (type_of_chat == TGL_PEER_CHAT) {
3442 msg->from_id.type = TGL_PEER_CHAT;
3443 msg->to_id.type = TGL_PEER_CHAT;
3445 Eina_Bool is_present_in_chat_db = is_user_present_chat_table(msg->to_id.id);
3446 if (!is_present_in_chat_db) {
3448 tgl_do_get_chat_info(s_info.TLS, msg->to_id, 0, &on_new_msg_requested_chat_info_received, msg);
3452 tgl_do_send_message(s_info.TLS, msg->to_id, msg->message, strlen(msg->message), &on_message_sent_to_buddy, (void*)(msg));
3453 } else if (type_of_chat == TGL_PEER_ENCR_CHAT) {
3462 void send_media_to_buddy(int buddy_id, int message_id, int media_id, int msg_type, char *file_path, int type_of_chat)
3464 char *msg_table = get_table_name_from_number(buddy_id);
3465 struct tgl_message* msg = get_message_from_message_table(message_id, msg_table);
3468 if (type_of_chat == TGL_PEER_USER) {
3470 msg->from_id.type = TGL_PEER_USER;
3471 msg->to_id.type = TGL_PEER_USER;
3473 if (msg->media.type == tgl_message_media_photo) {
3474 tgl_do_send_document(s_info.TLS, -1, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3475 } else if (msg->media.type == tgl_message_media_document) {
3476 char *extn = strrchr(file_path, '.');
3478 extn = replace(extn, '.', "");
3480 char *mime_type = NULL;;
3482 mime_type_get_mime_type(extn, &mime_type);
3485 if (mime_type && strstr(mime_type, "video") != NULL) {
3487 char* thumb_path = get_video_thumb_path_from_db(media_id);
3488 tgl_do_send_video(s_info.TLS, -2, msg->to_id, file_path, thumb_path, &on_message_sent_to_buddy, (void*) (msg));
3493 } else if (mime_type && strstr(mime_type, "audio") != NULL) {
3494 tgl_do_send_audio(s_info.TLS, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3498 } else if (msg->media.type == tgl_message_media_geo) {
3499 char *latitude = NULL;
3500 char *longitude = NULL;
3501 get_geo_location_from_db(media_id, &latitude, &longitude);
3502 if (latitude && longitude) {
3503 tgl_do_send_location(s_info.TLS, msg->to_id, strtod(latitude, NULL), strtod(longitude, NULL), &on_message_sent_to_buddy, (void*) (msg));
3505 } else if (msg->media.type == tgl_message_media_contact) {
3506 char *first_name = NULL;
3507 char *last_name = NULL;
3508 char *phone_num = NULL;
3509 get_contact_details_from_db(media_id, &first_name, &last_name, &phone_num);
3510 if (first_name && last_name && phone_num) {
3511 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));
3515 } else if (type_of_chat == TGL_PEER_CHAT) {
3516 msg->from_id.type = TGL_PEER_CHAT;
3517 msg->to_id.type = TGL_PEER_CHAT;
3519 if (msg->media.type == tgl_message_media_photo) {
3520 tgl_do_send_document(s_info.TLS, -1, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3521 } else if (msg->media.type == tgl_message_media_document) {
3524 char *extn = strrchr(file_path, '.');
3526 extn = replace(extn, '.', "");
3528 char *mime_type = NULL;;
3530 mime_type_get_mime_type(extn, &mime_type);
3533 if (mime_type && strstr(mime_type, "video") != NULL) {
3535 char* thumb_path = get_video_thumb_path_from_db(media_id);
3536 tgl_do_send_video(s_info.TLS, -2, msg->to_id, file_path, thumb_path, &on_message_sent_to_buddy, (void*) (msg));
3541 } else if (mime_type && strstr(mime_type, "audio") != NULL) {
3542 tgl_do_send_audio(s_info.TLS, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3546 } else if (msg->media.type == tgl_message_media_geo) {
3547 char *latitude = NULL;
3548 char *longitude = NULL;
3549 get_geo_location_from_db(media_id, &latitude, &longitude);
3550 if (latitude && longitude) {
3551 tgl_do_send_location(s_info.TLS, msg->to_id, strtod(latitude, NULL), strtod(longitude, NULL), &on_message_sent_to_buddy, (void*) (msg));
3556 } else if (type_of_chat == TGL_PEER_ENCR_CHAT) {
3567 void check_type_sizes(void)
3569 if (sizeof(int) != 4u) {
3570 logprintf("sizeof(int) isn't equal 4.\n");
3573 if (sizeof(char) != 1u) {
3574 logprintf("sizeof(char) isn't equal 1.\n");
3579 int str_empty(char *str)
3581 return ((str == NULL) || (strlen(str) < 1));
3584 void parse_config(void)
3586 if (!s_info.disable_output) {
3587 //printf("libconfig not enabled\n");
3590 char *rsa_path = ui_utils_get_resource(DEFAULT_RSA_FILE_NAME);
3591 tasprintf(&s_info.rsa_file_name, "%s", rsa_path);
3592 tasprintf(&s_info.config_full_path, "%s%s", app_get_data_path(), CONFIG_DIRECTORY);
3593 struct stat st = { 0 };
3594 if (stat(s_info.config_full_path, &st) == -1) {
3595 mkdir(s_info.config_full_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
3598 if (remove(s_info.rsa_file_name) == 0) {
3599 //printf("File successfully deleted\n");
3602 //tasprintf(&s_info.downloads_directory, "%s%s/%s", app_get_data_path(), CONFIG_DIRECTORY, DOWNLOADS_DIRECTORY);
3603 tasprintf(&s_info.downloads_directory, "%s/%s", app_get_shared_data_path(), DOWNLOADS_DIRECTORY);
3605 if (s_info.binlog_enabled) {
3606 tasprintf(&s_info.binlog_file_name, "%s%s/%s", app_get_data_path(), CONFIG_DIRECTORY, BINLOG_FILE);
3607 tgl_set_binlog_mode(s_info.TLS, 1);
3608 tgl_set_binlog_path(s_info.TLS, s_info.binlog_file_name);
3610 tgl_set_binlog_mode(s_info.TLS, 0);
3611 //tgl_set_auth_file_path(auth_file_name;
3612 tasprintf(&s_info.auth_file_name, "%s%s/%s", app_get_data_path(), CONFIG_DIRECTORY, AUTH_KEY_FILE);
3613 tasprintf(&s_info.state_file_name, "%s%s/%s", app_get_data_path(), CONFIG_DIRECTORY, STATE_FILE);
3614 tasprintf(&s_info.secret_chat_file_name, "%s%s/%s", app_get_data_path(), CONFIG_DIRECTORY, SECRET_CHAT_FILE);
3616 tgl_set_download_directory(s_info.TLS, s_info.downloads_directory);
3617 if (!mkdir(s_info.downloads_directory, CONFIG_DIRECTORY_MODE)) {
3618 if (!s_info.disable_output) {
3619 //printf("[%s] created\n", downloads_directory);
3624 void running_for_first_time(void)
3627 if (!str_empty(s_info.config_filename)) {
3628 return; // Do not create custom config file
3631 if (str_empty(s_info.config_directory)) {
3632 s_info.config_directory = strdup(app_get_data_path()); // specific path for tizen application.
3635 struct stat st = {0};
3636 if (stat(s_info.config_directory, &st) == -1) {
3637 mkdir(s_info.config_directory, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
3640 tasprintf(&s_info.config_filename, "%s%s", s_info.config_directory, CONFIG_FILE);
3643 // see if config file is there
3644 if (access(s_info.config_filename, R_OK) != 0) {
3645 // config file missing, so touch it
3646 config_file_fd = open(s_info.config_filename, O_CREAT | O_RDWR, 0600);
3647 if (config_file_fd == -1) {
3648 perror("open[config_file]");
3649 //printf("I: config_file=[%s]\n", config_filename);
3652 if (write(config_file_fd, DEFAULT_CONFIG_CONTENTS, strlen(DEFAULT_CONFIG_CONTENTS)) <= 0) {
3653 perror("write[config_file]");
3656 close(config_file_fd);
3660 void init_tl_engine(void *cbdata)
3662 s_info.TLS = tgl_state_alloc();
3664 ERR("memory allocation failed!! for tgl_state_alloc");
3668 running_for_first_time();
3672 tgl_set_rsa_key(s_info.TLS, s_info.rsa_file_name);
3673 tgl_set_callback(s_info.TLS, &upd_cb, cbdata);
3674 tgl_set_verbosity(s_info.TLS, E_DEBUG);
3675 tgl_set_net_methods(s_info.TLS, &tgl_conn_methods);
3676 tgl_set_timer_methods(s_info.TLS, &tgl_libevent_timers);
3677 assert(s_info.TLS->timer_methods);
3678 tgl_set_download_directory(s_info.TLS, tgl_engine_get_downloads_directory());
3679 tgl_register_app_id(s_info.TLS, TELEGRAM_CLI_APP_ID, TELEGRAM_CLI_APP_HASH);
3680 tgl_set_app_version(s_info.TLS, "Telegram-cli " TELEGRAM_CLI_VERSION);
3681 if (s_info.ipv6_enabled) {
3682 tgl_enable_ipv6(s_info.TLS);
3684 tgl_init(s_info.TLS);
3686 if (s_info.binlog_enabled) {
3687 double t = tglt_get_double_time();
3688 if (s_info.verbosity >= E_DEBUG) {
3689 logprintf("replay log start\n");
3691 tgl_replay_log(s_info.TLS);
3692 if (s_info.verbosity >= E_DEBUG) {
3693 logprintf("replay log end in %lf seconds\n", tglt_get_double_time() - t);
3695 tgl_reopen_binlog_for_writing(s_info.TLS);
3699 read_secret_chat_file();
3703 void tgl_engine_destroy_TLS(void)
3709 tgl_state_free(tgl_engine_get_TLS());
3713 struct tgl_state *tgl_engine_get_TLS(void)