8 #include "server_response.h"
11 #include "tg_db_wrapper.h"
12 #include "tgl-fetch.h"
13 #include <mime_type.h>
14 #include "device_contacts_manager.h"
15 #include "tg-engine-service.h"
17 #define DC_SERIALIZED_MAGIC 0x868aa81d
18 #define STATE_FILE_MAGIC 0x28949a93
19 #define SECRET_CHAT_FILE_MAGIC 0x37a1988a
21 static struct _tg_engine {
24 char *default_username;
25 char *config_filename;
28 char *state_file_name;
29 char *secret_chat_file_name;
30 char *downloads_directory;
31 char *config_directory;
32 char *binlog_file_name;
37 int allow_weak_random;
39 int readline_disabled;
41 int reset_authorization;
47 char *config_full_path;
48 int need_dc_list_update;
49 struct tgl_state *TLS;
52 static void on_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info);
53 static void on_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U);
54 static void on_chat_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename);
55 static void on_document_download_completed(struct tgl_state *TLS, void *callback_extra, int success, char *filename);
56 static void on_buddy_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename);
57 static void on_new_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U);
58 extern void delete_all_messages_from_chat(int buddy_id, int type_of_chat);
59 void tgl_engine_var_init(void)
61 s_info.default_username = NULL;
62 s_info.config_filename = NULL;
63 s_info.auth_file_name = NULL;
64 s_info.state_file_name = NULL;
65 s_info.secret_chat_file_name = NULL;
66 s_info.downloads_directory = NULL;
67 s_info.config_directory = NULL;
68 s_info.binlog_file_name = NULL;
69 s_info.lua_file = NULL;
72 void tgl_engine_var_free(void)
74 if (s_info.default_username) {
75 free(s_info.default_username);
76 s_info.default_username = NULL;
78 if (s_info.config_filename) {
79 free(s_info.config_filename);
80 s_info.config_filename = NULL;
82 if (s_info.auth_file_name) {
83 free(s_info.auth_file_name);
84 s_info.auth_file_name = NULL;
86 if (s_info.state_file_name) {
87 free(s_info.state_file_name);
88 s_info.state_file_name = NULL;
90 if (s_info.secret_chat_file_name) {
91 free(s_info.secret_chat_file_name);
92 s_info.secret_chat_file_name = NULL;
94 if (s_info.downloads_directory) {
95 free(s_info.downloads_directory);
96 s_info.downloads_directory = NULL;
98 if (s_info.config_directory) {
99 free(s_info.config_directory);
100 s_info.config_directory = NULL;
102 if (s_info.binlog_file_name) {
103 free(s_info.binlog_file_name);
104 s_info.binlog_file_name = NULL;
106 if (s_info.lua_file) {
107 free(s_info.lua_file);
108 s_info.lua_file = NULL;
111 tgl_state_free(s_info.TLS);
112 tgl_free_all(s_info.TLS);
117 char *tgl_engine_get_auth_key_filename(void)
119 return s_info.auth_file_name;
122 char *tgl_engine_get_state_filename(void)
124 return s_info.state_file_name;
127 char *tgl_engine_get_secret_chat_filename (void)
129 return s_info.secret_chat_file_name;
132 char *tgl_engine_get_downloads_directory (void)
134 return s_info.downloads_directory;
137 void write_dc(struct tgl_dc *DC, void *extra)
139 int auth_file_fd = *(int *)extra;
145 assert(write(auth_file_fd, &x, 4) == 4);
149 assert(write(auth_file_fd, &x, 4) == 4);
150 assert(DC->has_auth);
151 assert(write(auth_file_fd, &DC->port, 4) == 4);
152 int l = strlen(DC->ip);
153 assert(write(auth_file_fd, &l, 4) == 4);
154 assert(write(auth_file_fd, DC->ip, l) == l);
155 assert(write(auth_file_fd, &DC->auth_key_id, 8) == 8);
156 assert(write(auth_file_fd, DC->auth_key, 256) == 256);
159 void write_secret_chat(tgl_peer_t *_P, void *extra)
161 struct tgl_secret_chat *P = (void *)_P;
163 if (tgl_get_peer_type (P->id) != TGL_PEER_ENCR_CHAT) {
167 if (P->state != sc_ok) {
175 int id = tgl_get_peer_id (P->id);
176 assert (write (fd, &id, 4) == 4);
177 //assert (write (fd, &P->flags, 4) == 4);
178 int l = strlen(P->print_name);
179 assert(write (fd, &l, 4) == 4);
180 assert(write (fd, P->print_name, l) == l);
181 assert(write (fd, &P->user_id, 4) == 4);
182 assert(write (fd, &P->admin_id, 4) == 4);
183 assert(write (fd, &P->date, 4) == 4);
184 assert(write (fd, &P->ttl, 4) == 4);
185 assert(write (fd, &P->layer, 4) == 4);
186 assert(write (fd, &P->access_hash, 8) == 8);
187 assert(write (fd, &P->state, 4) == 4);
188 assert(write (fd, &P->key_fingerprint, 8) == 8);
189 assert(write (fd, &P->key, 256) == 256);
190 assert(write (fd, &P->first_key_sha, 20) == 20);
191 assert(write (fd, &P->in_seq_no, 4) == 4);
192 assert(write (fd, &P->last_in_seq_no, 4) == 4);
193 assert(write (fd, &P->out_seq_no, 4) == 4);
196 void write_secret_chat_file(void)
198 if (s_info.binlog_enabled) {
201 int secret_chat_fd = open (tgl_engine_get_secret_chat_filename(), O_CREAT | O_RDWR, 0600);
202 assert (secret_chat_fd >= 0);
203 int x = SECRET_CHAT_FILE_MAGIC;
204 assert (write (secret_chat_fd, &x, 4) == 4);
206 assert (write (secret_chat_fd, &x, 4) == 4); // version
207 assert (write (secret_chat_fd, &x, 4) == 4); // num
210 y[0] = secret_chat_fd;
213 tgl_peer_iterator_ex(s_info.TLS, write_secret_chat, y);
215 lseek(secret_chat_fd, 8, SEEK_SET);
216 assert(write (secret_chat_fd, &y[1], 4) == 4);
217 close(secret_chat_fd);
220 void write_auth_file(void)
222 if (s_info.binlog_enabled) {
226 int auth_file_fd = open(tgl_engine_get_auth_key_filename(), O_CREAT | O_RDWR, 0600);
228 assert(auth_file_fd >= 0);
229 int x = DC_SERIALIZED_MAGIC;
230 assert(write(auth_file_fd, &x, 4) == 4);
231 assert(write(auth_file_fd, &s_info.TLS->max_dc_num, 4) == 4);
232 assert(write(auth_file_fd, &s_info.TLS->dc_working_num, 4) == 4);
233 tgl_dc_iterator_ex(s_info.TLS, write_dc, &auth_file_fd);
234 assert(write(auth_file_fd, &s_info.TLS->our_id, 4) == 4);
238 void read_dc(int auth_file_fd, int id, unsigned ver)
241 assert(read(auth_file_fd, &port, 4) == 4);
243 assert(read(auth_file_fd, &l, 4) == 4);
244 assert(l >= 0 && l < 100);
246 assert(read(auth_file_fd, ip, l) == l);
249 long long auth_key_id;
250 static unsigned char auth_key[256];
251 assert(read(auth_file_fd, &auth_key_id, 8) == 8);
252 assert(read(auth_file_fd, auth_key, 256) == 256);
254 //bl_do_add_dc(id, ip, l, port, auth_key_id, auth_key);
255 bl_do_dc_option(s_info.TLS, id, 2, "DC", l, ip, port);
256 bl_do_set_auth_key_id(s_info.TLS, id, auth_key);
257 bl_do_dc_signed(s_info.TLS, id);
260 void empty_auth_file(void)
262 if (s_info.TLS->test_mode) {
263 bl_do_dc_option(s_info.TLS, 1, 0, "", strlen(TG_SERVER_TEST_1), TG_SERVER_TEST_1, 443);
264 bl_do_dc_option(s_info.TLS, 2, 0, "", strlen(TG_SERVER_TEST_2), TG_SERVER_TEST_2, 443);
265 bl_do_dc_option(s_info.TLS, 3, 0, "", strlen(TG_SERVER_TEST_3), TG_SERVER_TEST_3, 443);
266 bl_do_set_working_dc(s_info.TLS, 2);
268 bl_do_dc_option(s_info.TLS, 1, 0, "", strlen(TG_SERVER_1), TG_SERVER_1, 443);
269 bl_do_dc_option(s_info.TLS, 2, 0, "", strlen(TG_SERVER_2), TG_SERVER_2, 443);
270 bl_do_dc_option(s_info.TLS, 3, 0, "", strlen(TG_SERVER_3), TG_SERVER_3, 443);
271 bl_do_dc_option(s_info.TLS, 4, 0, "", strlen(TG_SERVER_4), TG_SERVER_4, 443);
272 bl_do_dc_option(s_info.TLS, 5, 0, "", strlen(TG_SERVER_5), TG_SERVER_5, 443);
273 bl_do_set_working_dc(s_info.TLS, 4);
277 void read_secret_chat(int fd, int v)
279 int id, l, user_id, admin_id, date, ttl, layer, state;
280 long long access_hash, key_fingerprint;
282 static unsigned char key[256];
283 static unsigned char sha[20];
284 assert(read(fd, &id, 4) == 4);
285 //assert(read(fd, &flags, 4) == 4);
286 assert(read(fd, &l, 4) == 4);
287 assert(l > 0 && l < 1000);
288 assert(read(fd, s, l) == l);
289 assert(read(fd, &user_id, 4) == 4);
290 assert(read(fd, &admin_id, 4) == 4);
291 assert(read(fd, &date, 4) == 4);
292 assert(read(fd, &ttl, 4) == 4);
293 assert(read(fd, &layer, 4) == 4);
294 assert(read(fd, &access_hash, 8) == 8);
295 assert(read(fd, &state, 4) == 4);
296 assert(read(fd, &key_fingerprint, 8) == 8);
297 assert(read(fd, &key, 256) == 256);
299 assert(read(fd, sha, 20) == 20);
301 int in_seq_no = 0, out_seq_no = 0, last_in_seq_no = 0;
303 assert(read(fd, &in_seq_no, 4) == 4);
304 assert(read(fd, &last_in_seq_no, 4) == 4);
305 assert(read(fd, &out_seq_no, 4) == 4);
308 bl_do_encr_chat_create(s_info.TLS, id, user_id, admin_id, s, l);
309 struct tgl_secret_chat *P =(void *)tgl_peer_get(s_info.TLS, TGL_MK_ENCR_CHAT(id));
310 assert(P &&(P->flags & FLAG_CREATED));
311 bl_do_encr_chat_set_date(s_info.TLS, P, date);
312 bl_do_encr_chat_set_ttl(s_info.TLS, P, ttl);
313 bl_do_encr_chat_set_layer(s_info.TLS ,P, layer);
314 bl_do_encr_chat_set_access_hash(s_info.TLS, P, access_hash);
315 bl_do_encr_chat_set_state(s_info.TLS, P, state);
316 bl_do_encr_chat_set_key(s_info.TLS, P, key, key_fingerprint);
318 bl_do_encr_chat_set_sha(s_info.TLS, P, sha);
320 SHA1((void *)key, 256, sha);
321 bl_do_encr_chat_set_sha(s_info.TLS, P, sha);
324 bl_do_encr_chat_set_seq(s_info.TLS, P, in_seq_no, last_in_seq_no, out_seq_no);
328 void read_secret_chat_file(void)
330 if (s_info.binlog_enabled) {
334 int secret_chat_fd = open(tgl_engine_get_secret_chat_filename(), O_RDWR, 0600);
336 if (secret_chat_fd < 0) {
339 //assert(secret_chat_fd >= 0);
341 if (read(secret_chat_fd, &x, 4) < 4) { close(secret_chat_fd); return; }
342 if (x != SECRET_CHAT_FILE_MAGIC) { close(secret_chat_fd); return; }
344 assert(read(secret_chat_fd, &v, 4) == 4);
345 assert(v == 0 || v == 1 || v == 2); // version
346 assert(read(secret_chat_fd, &x, 4) == 4);
349 read_secret_chat(secret_chat_fd, v);
351 close(secret_chat_fd);
354 void read_state_file(void)
356 if (s_info.binlog_enabled) {
359 int state_file_fd = open(tgl_engine_get_state_filename(), O_CREAT | O_RDWR, 0600);
360 if (state_file_fd < 0)
365 if (read(state_file_fd, &magic, 4) < 4) {
366 close(state_file_fd);
370 if (magic !=(int)STATE_FILE_MAGIC) {
371 close(state_file_fd);
375 if (read(state_file_fd, &version, 4) < 4) {
376 close(state_file_fd);
380 assert(version >= 0);
383 if (read(state_file_fd, x, 16) < 16) {
384 close(state_file_fd);
392 close(state_file_fd);
393 bl_do_set_seq(s_info.TLS, seq);
394 bl_do_set_pts(s_info.TLS, pts);
395 bl_do_set_qts(s_info.TLS, qts);
396 bl_do_set_date(s_info.TLS, date);
399 void read_auth_file(void)
401 if (s_info.binlog_enabled) {
406 auth_file_fd = open(tgl_engine_get_auth_key_filename(), O_CREAT | O_RDWR, 0600);
407 if (auth_file_fd < 0) {
409 * Logging this for handling exceptional cases.
415 assert(auth_file_fd >= 0);
419 if (read(auth_file_fd, &m, 4) < 4 ||(m != DC_SERIALIZED_MAGIC)) {
425 assert(read(auth_file_fd, &x, 4) == 4);
428 assert(read(auth_file_fd, &dc_working_num, 4) == 4);
431 for(i = 0; i <=(int)x; i++) {
433 assert(read(auth_file_fd, &y, 4) == 4);
435 read_dc(auth_file_fd, i, m);
439 bl_do_set_working_dc(s_info.TLS, dc_working_num);
441 int l = read(auth_file_fd, &our_id, 4);
447 bl_do_set_our_id(s_info.TLS, our_id);
452 void tg_new_msg(struct tgl_state *TLS, struct tgl_message *M)
454 struct tgl_message *temp_msg = tgl_message_get(TLS, M->id);
460 void tg_marked_read(struct tgl_state *TLS, int num, struct tgl_message *list[])
462 for (int i = 0; i < num; i++) {
464 struct tgl_message* message = list[i];
467 UC = tgl_peer_get(TLS, message->to_id);
468 struct tgl_user* buddy;
471 if (buddy && buddy->phone && strlen(buddy->phone) > 0) {
472 phone = buddy->phone;
475 message->msg_state = TG_MESSAGE_STATE_READ;
477 char *tb_name = get_table_name_from_number(message->to_id.id);
478 update_msg_into_db(message, tb_name, identifier);
479 if (message->media.type == tgl_message_media_photo) {
480 update_sent_media_info_in_db(message, (long long)message->media.photo.id);
482 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));
488 void tg_logprintf(const char *format, ...)
493 void on_code_via_phone_result(struct tgl_state *TLS, void *callback_extra, int success)
500 void request_for_code_via_call(struct tgl_state *TLS, char* phone_no, Eina_Bool trough_sms)
502 tg_engine_data_s *tg_data;
503 tg_data = TLS->callback_data;
504 if (tg_data && tg_data->phone_number && tg_data->mhash) {
505 tgl_do_phone_call(TLS, tg_data->phone_number, tg_data->mhash, on_code_via_phone_result, TLS);
509 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)
511 tg_engine_data_s *tg_data;
513 tg_data = TLS->callback_data;
515 tg_data->get_string = callback;
516 tg_data->callback_arg = arg;
517 if (strcmp (prompt, "phone number:") == 0) {
519 if (tg_data->tg_state == TG_ENGINE_STATE_REGISTRATION) {
520 send_request_phone_num_again(tg_data);
522 //tg_data->is_first_time_registration = EINA_TRUE;
523 tg_data->tg_state = TG_ENGINE_STATE_REGISTRATION;
524 if (tg_data && tg_data->phone_number) {
525 tg_data->get_string(TLS, tg_data->phone_number, tg_data->callback_arg);
526 tg_data->code_response_timer = ecore_timer_add(60, on_code_request_timer_expired, tg_data);
529 } else if (strcmp (prompt, "code('call' for phone call):") == 0) {
531 if (tg_data->code_response_timer) {
532 ecore_timer_del(tg_data->code_response_timer);
533 tg_data->code_response_timer = NULL;
537 tg_data->mhash = strdup(T[1]);
539 if (tg_data->tg_state == TG_ENGINE_STATE_CODE_REQUEST) {
540 send_request_code_again(tg_data);
542 tg_data->tg_state = TG_ENGINE_STATE_CODE_REQUEST;
543 send_registration_response(tg_data, EINA_TRUE);
546 } else if (strcmp (prompt, "register [Y/n]:") == 0) {
548 tg_data->tg_state = TG_ENGINE_STATE_PROFILE_REGISTRATION;
549 tg_data->get_string(TLS, "Y", tg_data->callback_arg);
551 } else if (strcmp (prompt, "First name:") == 0) {
552 // request for first name
554 tg_data->tg_state = TG_ENGINE_STATE_PROFILE_FIRST_NAME_REGISTRATION;
555 tg_data->is_first_time_registration = EINA_TRUE;
557 if (tg_data->first_name) {
558 tg_data->get_string(TLS, tg_data->first_name, tg_data->callback_arg);
560 send_name_registration_response(tg_data);
563 } else if (strcmp (prompt, "Last name:") == 0) {
564 // request for last name
565 tg_data->tg_state = TG_ENGINE_STATE_PROFILE_LAST_NAME_REGISTRATION;
567 if (tg_data->last_name) {
568 tg_data->get_string(TLS, tg_data->last_name, tg_data->callback_arg);
578 void tg_logged_in(struct tgl_state *TLS)
580 tg_engine_data_s *tg_data;
581 tg_data = TLS->callback_data;
583 int offline_mode = 0;
585 t_id.id = TLS->our_id;
586 t_id.type = TGL_PEER_USER;
587 //tg_data->is_first_time_registration = EINA_TRUE;
588 create_data_base_tables();
589 tgl_do_get_user_info(TLS, t_id, offline_mode, &on_user_info_loaded, NULL);
592 static Eina_Bool on_send_media_message_requested(void *data)
594 sent_media_data_s *media_info = (sent_media_data_s*)data;
596 int buddy_id = atoi(media_info->buddy_id);
597 int message_id = atoi(media_info->message_id);
598 int media_id = atoi(media_info->media_id);
599 int msg_type = atoi(media_info->message_type);
600 int type_of_chat = atoi(media_info->type_of_chat);
602 process_send_media_command(buddy_id, message_id, media_id, msg_type, media_info->file_path, type_of_chat);
604 if (media_info->app_name) {
605 free(media_info->app_name);
606 media_info->app_name = NULL;
608 if (media_info->command) {
609 free(media_info->command);
610 media_info->command = NULL;
612 if (media_info->buddy_id) {
613 free(media_info->buddy_id);
614 media_info->buddy_id = NULL;
616 if (media_info->message_id) {
617 free(media_info->message_id);
618 media_info->message_id = NULL;
620 if (media_info->media_id) {
621 free(media_info->media_id);
622 media_info->media_id = NULL;
625 if (media_info->message_type) {
626 free(media_info->message_type);
627 media_info->message_type = NULL;
629 if (media_info->file_path) {
630 free(media_info->file_path);
631 media_info->file_path = NULL;
633 if (media_info->type_of_chat) {
634 free(media_info->type_of_chat);
635 media_info->type_of_chat = NULL;
639 return ECORE_CALLBACK_CANCEL;
641 static Eina_Bool on_load_offline_messages(void *data);
642 static Eina_Bool on_send_unsent_messages_requested(void *data)
644 struct tgl_state *TLS = data;
646 //tg_engine_data_s *tg_data = TLS->callback_data;
648 Eina_List *unset_text_msgs = get_all_unsent_text_messages();
649 if (unset_text_msgs && eina_list_count(unset_text_msgs) > 0 ) {
650 for (int i = 0 ; i < eina_list_count(unset_text_msgs) ; i++) {
651 sent_message_data_s* msg_info = eina_list_nth(unset_text_msgs, i);
653 int buddy_id = atoi(msg_info->buddy_id);
654 int message_id = atoi(msg_info->message_id);
655 int msg_type = atoi(msg_info->message_type);
656 int type_of_chat = atoi(msg_info->type_of_chat);
657 process_send_message_command(buddy_id, message_id, msg_type, msg_info->message_data, type_of_chat);
659 if (msg_info->app_name) {
660 free(msg_info->app_name);
661 msg_info->app_name = NULL;
663 if (msg_info->command) {
664 free(msg_info->command);
665 msg_info->command = NULL;
667 if (msg_info->buddy_id) {
668 free(msg_info->buddy_id);
669 msg_info->buddy_id = NULL;
671 if (msg_info->message_id) {
672 free(msg_info->message_id);
673 msg_info->message_id = NULL;
676 if (msg_info->message_type) {
677 free(msg_info->message_type);
678 msg_info->message_type = NULL;
680 if (msg_info->message_data) {
681 free(msg_info->message_data);
682 msg_info->message_data = NULL;
684 if (msg_info->type_of_chat) {
685 free(msg_info->type_of_chat);
686 msg_info->type_of_chat = NULL;
692 eina_list_free(unset_text_msgs);
695 Eina_List *unset_media_msgs = get_all_unsent_media_messages();
697 if (unset_media_msgs && eina_list_count(unset_media_msgs) > 0 ) {
698 for (int i = 0 ; i < eina_list_count(unset_media_msgs) ; i++) {
699 sent_media_data_s* media_info = eina_list_nth(unset_media_msgs, i);
701 /* int buddy_id = atoi(media_info->buddy_id);
702 int message_id = atoi(media_info->message_id);
703 int media_id = atoi(media_info->media_id);
704 int msg_type = atoi(media_info->message_type);
705 int type_of_chat = atoi(media_info->type_of_chat);*/
707 sent_media_data_s* new_media_info = (sent_media_data_s*)malloc(sizeof(sent_media_data_s));
708 new_media_info->app_name = strdup(media_info->app_name);
709 new_media_info->command = strdup(media_info->command);
710 new_media_info->buddy_id = strdup(media_info->buddy_id);
711 new_media_info->message_id = strdup(media_info->message_id);
712 new_media_info->media_id = strdup(media_info->media_id);
713 new_media_info->message_type = strdup(media_info->message_type);
714 new_media_info->file_path = strdup(media_info->file_path);
715 new_media_info->type_of_chat = strdup(media_info->type_of_chat);
717 ecore_timer_add(init_time, on_send_media_message_requested, new_media_info);
719 //process_send_media_command(buddy_id, message_id, media_id, msg_type, media_info->file_path, type_of_chat);
721 if (media_info->app_name) {
722 free(media_info->app_name);
723 media_info->app_name = NULL;
725 if (media_info->command) {
726 free(media_info->command);
727 media_info->command = NULL;
729 if (media_info->buddy_id) {
730 free(media_info->buddy_id);
731 media_info->buddy_id = NULL;
733 if (media_info->message_id) {
734 free(media_info->message_id);
735 media_info->message_id = NULL;
737 if (media_info->media_id) {
738 free(media_info->media_id);
739 media_info->media_id = NULL;
742 if (media_info->message_type) {
743 free(media_info->message_type);
744 media_info->message_type = NULL;
746 if (media_info->file_path) {
747 free(media_info->file_path);
748 media_info->file_path = NULL;
750 if (media_info->type_of_chat) {
751 free(media_info->type_of_chat);
752 media_info->type_of_chat = NULL;
758 eina_list_free(unset_media_msgs);
760 ecore_timer_add(5, on_load_offline_messages, TLS);
762 return ECORE_CALLBACK_CANCEL;
765 void tg_started(struct tgl_state *TLS)
767 tg_engine_data_s *tg_data = TLS->callback_data;
768 tg_data->is_login_activated = EINA_TRUE;
771 void tg_type_notification(struct tgl_state *TLS, struct tgl_user* buddy, enum tgl_typing_status status)
773 char *name_of_buddy = NULL;
775 if (buddy->first_name && buddy->last_name) {
776 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + strlen(buddy->last_name) + 1);
777 strcpy(name_of_buddy, buddy->first_name);
778 strcat(name_of_buddy, buddy->last_name);
779 } else if(buddy->first_name) {
780 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + 1);
781 strcpy(name_of_buddy, buddy->first_name);
783 name_of_buddy = (char *)malloc(strlen(" ") + 1);
784 strcpy(name_of_buddy, " ");
787 send_buddy_type_notification_response(TLS->callback_data, buddy->id.id, name_of_buddy, status);
791 name_of_buddy = NULL;
795 void tg_type_in_chat_notification(struct tgl_state *TLS, struct tgl_user *U, struct tgl_chat *C, enum tgl_typing_status status)
800 void tg_type_in_secret_chat_notification(struct tgl_state *TLS, struct tgl_secret_chat *E)
805 void tg_status_notification(struct tgl_state *TLS, struct tgl_user *buddy)
808 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
810 char *name_of_buddy = NULL;
812 if (buddy->first_name && buddy->last_name) {
813 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + strlen(buddy->last_name) + 1);
814 strcpy(name_of_buddy, buddy->first_name);
815 strcat(name_of_buddy, buddy->last_name);
816 } else if(buddy->first_name) {
817 name_of_buddy = (char *)malloc(strlen(buddy->first_name) + 1);
818 strcpy(name_of_buddy, buddy->first_name);
820 name_of_buddy = (char *)malloc(strlen(" ") + 1);
821 strcpy(name_of_buddy, " ");
824 send_buddy_status_notification_response(TLS->callback_data, buddy->id.id, name_of_buddy, buddy->status.online);
828 name_of_buddy = NULL;
834 void tg_user_registered(struct tgl_state *TLS, struct tgl_user *U)
839 void tg_user_activated(struct tgl_state *TLS, struct tgl_user *U)
844 void tg_new_authorization(struct tgl_state *TLS, const char *device, const char *location)
849 void tg_chat_update(struct tgl_state *TLS, struct tgl_chat* chat_info, unsigned flags)
851 tg_engine_data_s *tg_data;
852 tg_data = TLS->callback_data;
854 if (chat_info && chat_info->flags == 144) {
858 if (flags == TGL_GROUP_CHAT_CREATED) {
860 insert_chat_info_to_db(chat_info, NULL);
861 tgl_peer_t* UC = tgl_peer_get(TLS, chat_info->id);
862 insert_peer_into_database(UC, 0, 0);
864 //if (tg_data->is_loading_completed) {
865 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_chat_info_received, NULL);
869 if (!(flags & TGL_UPDATE_CREATED)) {
871 if (!(flags & TGL_UPDATE_DELETED)) {
880 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)
886 * "%s phone number updated" will be changed to IDS_STRING for i18n.
888 len = name_of_buddy_len + strlen(str);
889 update_msg = (char *)malloc(len + 1);
894 snprintf(update_msg, len, str, name_of_buddy);
895 send_contact_updated_response(tg_data, buddy->id.id, update_msg);
899 void tg_user_update(struct tgl_state *TLS, struct tgl_user *buddy, unsigned flags)
902 int name_of_buddy_len;
903 static const char *NO_NAME = " ";
905 if (flags & TGL_UPDATE_CREATED) {
909 if (buddy->first_name && buddy->last_name) {
910 int first_len = strlen(buddy->first_name);
911 int last_len = strlen(buddy->last_name);
913 name_of_buddy_len = first_len + last_len;
915 name_of_buddy = (char *)malloc(name_of_buddy_len + 1);
917 strcpy(name_of_buddy, buddy->first_name);
918 strcpy(name_of_buddy + first_len, buddy->last_name);
919 } else if(buddy->first_name) {
920 name_of_buddy = strdup(buddy->first_name);
921 name_of_buddy_len = strlen(name_of_buddy);
923 name_of_buddy = (char *)NO_NAME;
924 name_of_buddy_len = strlen(NO_NAME);
927 if (!name_of_buddy) {
930 * Unable to allocate heap for buddy name
932 name_of_buddy = (char *)NO_NAME;
933 name_of_buddy_len = strlen(NO_NAME);
936 if (!(flags & TGL_UPDATE_DELETED)) {
937 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
939 if (flags & TGL_UPDATE_PHONE) {
940 send_message(TLS->callback_data, buddy, "%s phone number updated.", name_of_buddy, name_of_buddy_len);
942 if (flags & TGL_UPDATE_CONTACT) {
943 send_message(TLS->callback_data, buddy, "%s contact updated.", name_of_buddy, name_of_buddy_len);
945 if (flags & TGL_UPDATE_PHOTO) {
946 send_message(TLS->callback_data, buddy, "%s photo updated.", name_of_buddy, name_of_buddy_len);
947 //tgl_do_get_user_info(TLS, buddy->id, 0, &on_buddy_info_loaded, NULL);
949 if (flags & TGL_UPDATE_BLOCKED) {
950 send_message(TLS->callback_data, buddy, "%s contact blocked.", name_of_buddy, name_of_buddy_len);
952 if (flags & TGL_UPDATE_REAL_NAME) {
953 send_message(TLS->callback_data, buddy, "%s name updated.", name_of_buddy, name_of_buddy_len);
955 if (flags & TGL_UPDATE_NAME) {
956 send_message(TLS->callback_data, buddy, "%s contact name updated.", name_of_buddy, name_of_buddy_len);
958 if (flags & TGL_UPDATE_REQUESTED) {
959 send_message(TLS->callback_data, buddy, "%s status updated.", name_of_buddy, name_of_buddy_len);
961 if (flags & TGL_UPDATE_WORKING) {
962 send_message(TLS->callback_data, buddy, "%s status updated.", name_of_buddy, name_of_buddy_len);
964 if (flags & TGL_UPDATE_FLAGS) {
965 send_message(TLS->callback_data, buddy, "%s flags updated.", name_of_buddy, name_of_buddy_len);
967 if (flags & TGL_UPDATE_TITLE) {
968 send_message(TLS->callback_data, buddy, "%s title updated.", name_of_buddy, name_of_buddy_len);
970 if (flags & TGL_UPDATE_ADMIN) {
971 send_message(TLS->callback_data, buddy, "%s admin updated.", name_of_buddy, name_of_buddy_len);
973 if (flags & TGL_UPDATE_MEMBERS) {
974 send_message(TLS->callback_data, buddy, "%s memgers updated.", name_of_buddy, name_of_buddy_len);
976 if (flags & TGL_UPDATE_ACCESS_HASH) {
977 send_message(TLS->callback_data, buddy, "%s access hash updated.", name_of_buddy, name_of_buddy_len);
979 if (flags & TGL_UPDATE_USERNAME) {
980 send_message(TLS->callback_data, buddy, "%s username updated.", name_of_buddy, name_of_buddy_len);
983 send_message(TLS->callback_data, buddy, "%s contact deleted.", name_of_buddy, name_of_buddy_len);
986 if (name_of_buddy != NO_NAME) {
988 name_of_buddy = NULL;
992 void tg_secret_chat_update(struct tgl_state *TLS, struct tgl_secret_chat *C, unsigned flags)
997 void on_new_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
999 tg_engine_data_s *tg_data;
1001 struct tgl_message *M = callback_extra;
1007 if (chat_info->user_list) {
1008 for (int i = 0; i < chat_info->user_list_size; i++) {
1009 int user_id = chat_info->user_list[i].user_id;
1010 Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
1011 char* tb_name = get_table_name_from_number(user_id);
1012 create_buddy_msg_table(tb_name);
1013 if (!is_present_in_db) {
1014 // add to buddy table
1015 tgl_peer_id_t from_id;
1016 from_id.id = user_id;
1017 from_id.type = TGL_PEER_USER;
1018 tgl_do_get_user_info(TLS, from_id, 0, on_new_buddy_info_loaded, NULL);
1024 tg_data = TLS->callback_data;
1026 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1027 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
1028 char* creator_name = (char*)malloc(msg_len);
1029 strcpy(creator_name, UC->user.first_name);
1030 strcat(creator_name, " created the group");
1032 int cur_time = time(NULL);
1033 M->id = chat_info->id.id;
1034 M->message = creator_name;
1035 M->message_len = msg_len;
1038 insert_buddy_msg_to_db(M);
1041 tgl_peer_t* chat_UC = tgl_peer_get(TLS, chat_info->id);
1042 insert_chat_info_to_db(chat_info, NULL);
1044 insert_peer_into_database(chat_UC, 0, 0, 0);
1046 send_new_group_added_response(tg_data, chat_info->id.id);
1050 void on_group_chat_info_updated(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1052 tg_engine_data_s *tg_data;
1059 tg_data = TLS->callback_data;
1060 char *type_of_change = callback_extra;
1062 if (!type_of_change) {
1063 type_of_change = strdup("");
1066 tgl_peer_t* chat_UC = tgl_peer_get(TLS, chat_info->id);
1067 insert_chat_info_to_db(chat_info, NULL);
1068 insert_peer_into_database(chat_UC, 0, 0, 0);
1069 send_group_chat_updated_response(tg_data, chat_info->id.id, type_of_change);
1070 free(type_of_change);
1073 void on_new_chat_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1075 struct tgl_message *M = callback_extra;
1080 tgl_peer_t* peer = tgl_peer_get(TLS, M->from_id);
1081 int msg_len = strlen(peer->user.first_name) + strlen(" changed group icon") + 1;
1082 char* creator_name = (char*)malloc(msg_len);
1083 strcpy(creator_name, peer->user.first_name);
1084 strcat(creator_name, " changed group icon");
1086 int cur_time = time(NULL);
1088 M->message = creator_name;
1089 M->message_len = msg_len;
1092 insert_buddy_msg_to_db(M);
1094 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1097 tgl_peer_t* UC = tgl_peer_get(TLS, M->to_id);
1098 struct tgl_chat *chat_info = &(UC->chat);
1099 update_chat_info_to_db(chat_info, filename);
1100 update_peer_info_database(UC, 0);
1101 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, chat_info->id.id);
1102 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, filename);
1106 void on_media_sticker_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1108 struct tgl_message *M = (struct tgl_message*)callback_extra;
1109 if (success && filename) {
1110 // update in db and send info to app...
1111 long long media_id = M->media.document.id;
1112 update_receive_media_info_in_db(media_id, filename);
1113 tg_engine_data_s *tg_data = TLS->callback_data;
1114 if (M->from_id.id == tg_data->id.id) {
1117 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1122 void on_video_thumb_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1124 struct tgl_message *M = (struct tgl_message*)callback_extra;
1125 if (success && filename) {
1126 // update in db and send info to app...
1127 long long media_id = M->media.document.id;
1128 update_video_thumb_in_db(media_id, filename);
1129 tg_engine_data_s *tg_data = TLS->callback_data;
1130 if (M->from_id.id == tg_data->id.id) {
1131 send_video_thumb_download_completed_response(tg_data, M->from_id.id, M->to_id.id, media_id, filename, NULL);
1133 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1138 struct tg_temp_msg_data {
1139 Ecore_Timer* send_timer;
1140 struct tgl_state *TLS;
1141 struct tgl_message *M;
1144 static Eina_Bool on_msg_received_cb(void *data)
1146 struct tg_temp_msg_data *msg_data = data;
1147 insert_buddy_msg_to_db(msg_data->M);
1148 if(msg_data->M->media.type != tgl_message_media_none) {
1149 insert_media_info_to_db(msg_data->M, "");
1150 if (msg_data->M->media.type != tgl_message_media_none && (msg_data->M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1151 tgl_do_load_document_thumb(msg_data->TLS, &(msg_data->M->media.document), on_video_thumb_loaded, msg_data->M);
1152 if (msg_data->send_timer) {
1153 ecore_timer_del(msg_data->send_timer);
1156 return ECORE_CALLBACK_CANCEL;
1159 // inform to application
1160 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));
1161 if (msg_data->send_timer) {
1162 ecore_timer_del(msg_data->send_timer);
1165 return ECORE_CALLBACK_CANCEL;
1168 void on_requested_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1170 tg_engine_data_s *tg_data;
1172 struct tgl_message *M = callback_extra;
1180 if (!chat_info->user_list) {
1181 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_requested_chat_info_received, callback_extra);
1185 tg_data = TLS->callback_data;
1187 msg_table = get_table_name_from_number(chat_info->id.id);
1189 create_buddy_msg_table(msg_table);
1191 insert_chat_info_to_db(chat_info, NULL);
1192 struct tgl_photo *pic = &(chat_info->photo);
1194 tgl_do_load_photo(TLS, pic ,&on_chat_pic_loaded,chat_info);
1198 int msg_id = insert_current_date_to_table(msg_table);
1200 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, msg_id, tgl_get_peer_type(M->to_id));
1201 struct tg_temp_msg_data *msg_data = (struct tg_temp_msg_data*)malloc(sizeof(struct tg_temp_msg_data));
1203 msg_data->TLS = TLS;
1204 msg_data->send_timer = ecore_timer_add(3, on_msg_received_cb, msg_data);
1206 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1207 M->message = strdup("Audio");
1208 M->message_len = strlen("Audio");
1209 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1210 M->message = strdup("Video");
1211 M->message_len = strlen("Video");
1213 insert_buddy_msg_to_db(M);
1214 if(M->media.type != tgl_message_media_none) {
1215 insert_media_info_to_db(M, "");
1216 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1217 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1221 // inform to application
1222 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1229 void on_requested_update_chat_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1231 tg_engine_data_s *tg_data;
1233 msg_table = get_table_name_from_number(chat_info->id.id);
1234 create_buddy_msg_table(msg_table);
1240 if (chat_info->flags == 144) {
1243 int msg_count = get_number_of_messages(msg_table);
1244 if (msg_count <= 0) {
1245 if (chat_info->admin_id > 0) {
1246 set_date_item_to_table(msg_table, chat_info->date);
1247 tgl_peer_id_t admin_id;
1248 admin_id.id = chat_info->admin_id;
1249 admin_id.type = TGL_PEER_USER;
1251 tgl_peer_t* UC = tgl_peer_get(TLS, admin_id);
1252 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
1253 char* creator_name = (char*)malloc(msg_len);
1254 strcpy(creator_name, UC->user.first_name);
1255 strcat(creator_name, " created the group");
1256 struct tgl_message msg;
1257 int cur_time = chat_info->date;
1258 msg.to_id = chat_info->id;
1259 msg.from_id = admin_id;
1260 msg.id = chat_info->id.id;
1261 msg.message = creator_name;
1262 msg.message_len = msg_len;
1264 msg.date = cur_time;
1265 msg.media.type = tgl_message_media_none;
1269 insert_buddy_msg_to_db(&msg);
1271 //send_message_received_response(TLS->callback_data, msg.from_id.id, msg.to_id.id, msg.id, tgl_get_peer_type(msg.to_id));
1278 if (!chat_info->user_list) {
1279 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_chat_info_received, NULL);
1283 tg_data = TLS->callback_data;
1285 insert_chat_info_to_db(chat_info, NULL);
1286 struct tgl_photo *pic = &(chat_info->photo);
1288 tgl_do_load_photo(TLS, pic ,&on_chat_pic_loaded,chat_info);
1290 //char *type_of_change = strdup("add_user");
1291 tgl_peer_t* chat_UC = tgl_peer_get(TLS, chat_info->id);
1292 insert_chat_info_to_db(chat_info, NULL);
1293 insert_peer_into_database(chat_UC, 0, 0, 0);
1294 send_response_to_group_chat_updated_response(tg_data, chat_info->id.id);
1295 //free(type_of_change);
1298 void do_update_chat_info(int chat_id)
1300 tgl_peer_id_t to_id;
1302 to_id.type = TGL_PEER_CHAT;
1303 tgl_do_get_chat_info(s_info.TLS, to_id, 0, &on_requested_update_chat_received, NULL);
1306 void on_new_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U)
1311 tg_engine_data_s *tg_data = TLS->callback_data;
1312 struct tgl_message *M = callback_extra;
1313 if (U->id.id == tg_data->id.id) {
1316 tgl_peer_t* UC = tgl_peer_get(TLS, U->id);
1317 insert_peer_into_database(UC, 0, 0, 1);
1319 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, U);
1320 struct tgl_photo* pic = &(U->photo);
1322 tgl_do_load_photo(TLS, pic ,&on_buddy_pic_loaded,U);
1325 send_new_buddy_added_response(tg_data, U->id.id);
1328 char* tb_name = get_table_name_from_number(U->id.id);
1329 int msg_id = insert_current_date_to_table(tb_name);
1332 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, msg_id, tgl_get_peer_type(M->to_id));
1334 struct tg_temp_msg_data *msg_data = (struct tg_temp_msg_data*)malloc(sizeof(struct tg_temp_msg_data));
1336 msg_data->TLS = TLS;
1337 msg_data->send_timer = ecore_timer_add(3, on_msg_received_cb, msg_data);
1339 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1340 M->message = strdup("Audio");
1341 M->message_len = strlen("Audio");
1342 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1343 M->message = strdup("Video");
1344 M->message_len = strlen("Video");
1346 insert_buddy_msg_to_db(M);
1347 if(M->media.type != tgl_message_media_none) {
1348 insert_media_info_to_db(M, "");
1349 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1350 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1352 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1356 // inform to application
1357 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1362 void tg_msg_receive(struct tgl_state *TLS, struct tgl_message *M)
1364 if (M && TLS->started) {
1366 if (M->flags & (FLAG_MESSAGE_EMPTY | FLAG_DELETED)) {
1369 if (!(M->flags & FLAG_CREATED)) {
1373 // this is service message. to be handled in telegram.
1374 if (tgl_get_peer_id (M->from_id) != TLS->our_id) {
1375 char *type_of_change = NULL;
1376 if (M->action.type == tgl_message_action_chat_create) {
1378 char* msg_table = get_table_name_from_number(M->to_id.id);
1379 create_buddy_msg_table(msg_table);
1380 int msg_id = insert_current_date_to_table(msg_table);
1383 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_new_chat_info_received, M);
1385 } else if (M->action.type == tgl_message_action_chat_edit_title) {
1386 type_of_change = strdup("edit_title");
1387 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1388 int msg_len = strlen(UC->user.first_name) + strlen(" changed the chat title") + 1;
1389 char* creator_name = (char*)malloc(msg_len);
1390 strcpy(creator_name, UC->user.first_name);
1391 strcat(creator_name, " changed the chat title");
1393 int cur_time = time(NULL);
1395 M->message = creator_name;
1396 M->message_len = msg_len;
1399 insert_buddy_msg_to_db(M);
1401 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1402 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
1403 } else if (M->action.type == tgl_message_action_chat_edit_photo) {
1405 char* msg_table = get_table_name_from_number(M->to_id.id);
1406 create_buddy_msg_table(msg_table);
1407 int msg_id = insert_current_date_to_table(msg_table);
1409 struct tgl_photo *pic = &(M->action.photo);
1411 tgl_do_load_photo(TLS, pic ,&on_new_chat_pic_loaded, M);
1414 } else if (M->action.type == tgl_message_action_chat_delete_photo) {
1415 type_of_change = strdup("delete_photo");
1416 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1417 int msg_len = strlen(UC->user.first_name) + strlen(" deleted the profile photo") + 1;
1418 char* creator_name = (char*)malloc(msg_len);
1419 strcpy(creator_name, UC->user.first_name);
1420 strcat(creator_name, " deleted the profile photo");
1422 int cur_time = time(NULL);
1424 M->message = creator_name;
1425 M->message_len = msg_len;
1428 insert_buddy_msg_to_db(M);
1430 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1433 char *filename = "";
1434 tgl_peer_t* lUC = tgl_peer_get(TLS, M->to_id);
1435 struct tgl_chat *chat_info = &(lUC->chat);
1436 update_chat_info_to_db(chat_info, filename);
1437 update_peer_info_database(lUC, 0);
1438 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, chat_info->id.id);
1439 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, filename);
1442 } else if (M->action.type == tgl_message_action_chat_add_user) {
1443 type_of_change = strdup("add_user");
1444 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1445 int msg_len = strlen(UC->user.first_name) + strlen(" added to the group") + 1;
1446 char* creator_name = (char*)malloc(msg_len);
1447 strcpy(creator_name, UC->user.first_name);
1448 strcat(creator_name, " added to the group");
1450 int cur_time = time(NULL);
1452 M->message = creator_name;
1453 M->message_len = msg_len;
1456 insert_buddy_msg_to_db(M);
1458 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1459 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
1460 } else if (M->action.type == tgl_message_action_chat_delete_user) {
1461 type_of_change = strdup("delete_user");
1462 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
1463 int msg_len = strlen(UC->user.first_name) + strlen(" left the group") + 1;
1464 char* creator_name = (char*)malloc(msg_len);
1465 strcpy(creator_name, UC->user.first_name);
1466 strcat(creator_name, " left the group");
1468 int cur_time = time(NULL);
1470 M->message = creator_name;
1471 M->message_len = msg_len;
1474 insert_buddy_msg_to_db(M);
1476 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1477 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
1483 if (!tgl_get_peer_type(M->to_id)) {
1488 if (tgl_get_peer_type(M->to_id) == TGL_PEER_USER) {
1496 if (M->media.type != tgl_message_media_none) {
1501 int user_id = M->from_id.id;
1503 Eina_Bool is_present_in_db = is_user_present_peer_table(user_id);
1504 char* tb_name = get_table_name_from_number(user_id);
1505 create_buddy_msg_table(tb_name);
1506 if (!is_present_in_db) {
1507 // add to buddy table
1508 tgl_do_get_user_info(TLS, M->from_id, 0, on_new_buddy_info_loaded, NULL);
1511 char* tb_name = get_table_name_from_number(user_id);
1512 Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
1513 create_buddy_msg_table(tb_name);
1514 if (!is_present_in_db) {
1515 tgl_do_get_user_info(TLS, M->from_id, 0, on_new_buddy_info_loaded, M);
1520 int msg_id = update_current_date_to_table(tb_name, M->date);
1524 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1525 M->message = strdup("Audio");
1526 M->message_len = strlen("Audio");
1527 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1528 M->message = strdup("Video");
1529 M->message_len = strlen("Video");
1530 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_STICKER)) {
1531 M->message = strdup("Sticker");
1532 M->message_len = strlen("Sticker");
1534 insert_buddy_msg_to_db(M);
1535 if(M->media.type != tgl_message_media_none) {
1536 insert_media_info_to_db(M, "");
1537 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1538 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1540 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1542 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_STICKER)) {
1543 tgl_do_load_document(TLS, &(M->media.document), on_media_sticker_loaded, M);
1547 // inform to application
1550 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));
1552 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1557 } else if (tgl_get_peer_type(M->to_id) == TGL_PEER_ENCR_CHAT) {
1561 if ((tgl_get_peer_type (M->from_id) == TGL_PEER_USER) && (tgl_get_peer_id (M->from_id) == TLS->our_id)) {
1564 if (M->media.type != tgl_message_media_none) {
1569 if (tgl_get_peer_type(M->to_id) == TGL_PEER_USER) {
1570 user_id = M->from_id.id;
1571 } else if (tgl_get_peer_type(M->to_id) == TGL_PEER_CHAT) {
1572 user_id = M->to_id.id;
1575 // check whether user is present or not
1577 Eina_Bool is_present_in_peer_db = is_user_present_buddy_table(user_id);
1578 if (!is_present_in_peer_db) {
1579 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_requested_chat_info_received, M);
1584 Eina_Bool is_present_in_chat_db = is_user_present_chat_table(user_id);
1585 if (!is_present_in_chat_db) {
1587 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_requested_chat_info_received, M);
1591 char* tb_name = get_table_name_from_number(user_id);
1592 int msg_id = update_current_date_to_table(tb_name, M->date);
1595 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_AUDIO)) {
1596 M->message = strdup("Audio");
1597 M->message_len = strlen("Audio");
1598 } else if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1599 M->message = strdup("Video");
1600 M->message_len = strlen("Video");
1602 insert_buddy_msg_to_db(M);
1603 if(M->media.type != tgl_message_media_none) {
1604 insert_media_info_to_db(M, "");
1605 if (M->media.type != tgl_message_media_none && (M->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
1606 tgl_do_load_document_thumb(TLS, &(M->media.document), on_video_thumb_loaded, M);
1610 // inform to application
1613 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));
1615 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
1622 void tg_our_id(struct tgl_state *TLS, int id)
1627 void tg_notification(struct tgl_state *TLS, char *type, char *message)
1632 void tg_user_status_update(struct tgl_state *TLS, struct tgl_user *U)
1635 if (tgl_get_peer_type (U->id) != TGL_PEER_USER) {
1642 if ((U->flags & FLAG_DELETED)) {
1644 } else if (!(U->flags & FLAG_CREATED)) {
1645 // newly created user
1651 if (U->flags & FLAG_USER_SELF) {
1652 update_buddy_into_db(USER_INFO_TABLE_NAME, U);
1653 } else if (U->flags & FLAG_USER_CONTACT) {
1654 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, U);
1656 struct tgl_user_status *S = &(U->status);
1658 if (S->online > 0) {
1661 if (S->online == 0) {
1663 } else if (S->online == -1) {
1664 //offline was online ");
1665 } else if (S->online == -2) {
1666 // offline (was online recently)
1667 } else if (S->online == -3) {
1668 //offline (was online last week)
1669 } else if (S->online == -4) {
1670 //offline (was online last month)
1674 // update status to application.
1675 send_buddy_status_updated_response(TLS->callback_data, U->id.id);
1684 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)
1689 struct tgl_update_callback upd_cb = {
1690 .new_msg = tg_new_msg,
1691 .marked_read = tg_marked_read,
1692 .logprintf = tg_logprintf,
1693 .get_string = tg_get_string,
1694 .logged_in = tg_logged_in,
1695 .started = tg_started,
1696 .type_notification = tg_type_notification,
1697 .type_in_chat_notification = tg_type_in_chat_notification,
1698 .type_in_secret_chat_notification = tg_type_in_secret_chat_notification,
1699 //.status_notification = tg_status_notification,
1700 .status_notification = NULL,
1701 .user_registered = tg_user_registered,
1702 .user_activated = tg_user_activated,
1703 .new_authorization = tg_new_authorization,
1704 //.user_update = tg_user_update,
1705 .user_update = NULL,
1706 //.chat_update = tg_chat_update,
1707 .chat_update = NULL,
1708 .secret_chat_update = tg_secret_chat_update,
1709 .msg_receive = tg_msg_receive,
1710 .our_id = tg_our_id,
1711 .user_status_update = tg_user_status_update
1714 void on_chat_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1716 struct tgl_chat *chat_info = callback_extra;
1719 update_chat_info_to_db(chat_info, filename);
1720 tgl_peer_t* UC = tgl_peer_get(TLS, chat_info->id);
1721 update_peer_info_database(UC, 0);
1722 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, chat_info->id.id);
1723 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, filename);
1727 void on_buddy_pic_loaded(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
1729 struct tgl_user *buddy = callback_extra;
1730 tg_engine_data_s *tg_data = TLS->callback_data;
1732 if (buddy && buddy->id.id == tg_data->id.id) {
1734 update_buddy_pic_db(filename, USER_INFO_TABLE_NAME, buddy->id.id);
1735 update_buddy_pic_db(filename, BUDDY_INFO_TABLE_NAME, buddy->id.id);
1736 send_buddy_profile_pic_updated_response(TLS->callback_data, buddy->id.id, filename);
1742 update_buddy_pic_db(filename, BUDDY_INFO_TABLE_NAME, buddy->id.id);
1743 update_buddy_pic_db(filename, PEER_INFO_TABLE_NAME, buddy->id.id);
1744 send_buddy_profile_pic_updated_response(TLS->callback_data, buddy->id.id, filename);
1749 void on_new_group_icon_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
1751 struct tgl_chat *chat_info = callback_extra;
1752 tg_engine_data_s *tg_data;
1754 tg_data = TLS->callback_data;
1756 if(tg_data->new_group_icon) {
1758 char *msg_table = get_table_name_from_number(chat_info->id.id);
1759 create_buddy_msg_table(msg_table);
1761 char *msg_data = "group icon changed.";
1762 struct tgl_message msg;
1764 msg.from_id.type = 0;
1768 msg.fwd_from_id.id = 0;
1769 msg.fwd_from_id.type = 0;
1771 msg.message = msg_data;
1772 msg.message_len = strlen (msg_data);
1776 msg.to_id.type = tg_data->id.type;
1778 msg.media.type = -1;
1779 msg.is_marked_for_delete = 0;
1781 insert_msg_into_db(&msg, msg_table, t);
1784 update_chat_info_to_db(chat_info, tg_data->new_group_icon);
1785 update_buddy_pic_db(tg_data->new_group_icon, PEER_INFO_TABLE_NAME, chat_info->id.id);
1786 send_buddy_profile_pic_updated_response(TLS->callback_data, chat_info->id.id, tg_data->new_group_icon);
1788 free(tg_data->new_group_icon);
1789 tg_data->new_group_icon = NULL;
1794 void on_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
1796 tg_engine_data_s *tg_data;
1802 if (chat_info->flags == 144) {
1805 msg_table = get_table_name_from_number(chat_info->id.id);
1806 create_buddy_msg_table(msg_table);
1808 int msg_count = get_number_of_messages(msg_table);
1809 if (msg_count <= 0) {
1810 if (chat_info->admin_id > 0) {
1811 set_date_item_to_table(msg_table, chat_info->date);
1812 tgl_peer_id_t admin_id;
1813 admin_id.id = chat_info->admin_id;
1814 admin_id.type = TGL_PEER_USER;
1816 tgl_peer_t* UC = tgl_peer_get(TLS, admin_id);
1817 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
1818 char* creator_name = (char*)malloc(msg_len);
1819 strcpy(creator_name, UC->user.first_name);
1820 strcat(creator_name, " created the group");
1821 struct tgl_message msg;
1822 int cur_time = chat_info->date;
1823 msg.to_id = chat_info->id;
1824 msg.from_id = admin_id;
1825 msg.id = chat_info->id.id;
1826 msg.message = creator_name;
1827 msg.message_len = msg_len;
1829 msg.date = cur_time;
1830 msg.media.type = tgl_message_media_none;
1834 insert_buddy_msg_to_db(&msg);
1836 send_message_received_response(TLS->callback_data, msg.from_id.id, msg.to_id.id, msg.id, tgl_get_peer_type(msg.to_id));
1842 if (!chat_info->user_list) {
1843 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_chat_info_received, NULL);
1846 for (int i = 0; i < chat_info->user_list_size; i++) {
1847 int user_id = chat_info->user_list[i].user_id;
1848 Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
1849 char* tb_name = get_table_name_from_number(user_id);
1850 create_buddy_msg_table(tb_name);
1851 if (!is_present_in_db) {
1852 // add to buddy table
1853 tgl_peer_id_t from_id;
1854 from_id.id = user_id;
1855 from_id.type = TGL_PEER_USER;
1856 tgl_do_get_user_info(TLS, from_id, 0, on_new_buddy_info_loaded, NULL);
1862 tg_data = TLS->callback_data;
1864 insert_chat_info_to_db(chat_info, NULL);
1865 struct tgl_photo *pic = &(chat_info->photo);
1867 tgl_do_load_photo(TLS, pic ,&on_chat_pic_loaded,chat_info);
1871 void on_buddy_info_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *U)
1876 tg_engine_data_s *tg_data = TLS->callback_data;
1877 if (U->id.id == tg_data->id.id) {
1881 //update_buddy_into_db(BUDDY_INFO_TABLE_NAME, U);
1882 struct tgl_photo* pic = &(U->photo);
1884 tgl_do_load_photo(TLS, pic ,&on_buddy_pic_loaded,U);
1889 void on_chat_history_received(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[])
1891 tg_engine_data_s *tg_data = TLS->callback_data;
1895 for (int i = 0; i < size; i++) {
1896 struct tgl_message* message = list[i];
1897 if (message->service || message->from_id.id == tg_data->id.id) {
1900 Eina_Bool ret = insert_buddy_msg_to_db(message);
1902 tg_msg_receive(s_info.TLS, message);
1905 tg_data->current_chat_index = tg_data->current_chat_index + 1;
1906 if (tg_data->chat_list && (tg_data->current_chat_index < eina_list_count(tg_data->chat_list))) {
1907 tgl_peer_t* UC = eina_list_nth(tg_data->chat_list, tg_data->current_chat_index);
1908 tgl_do_get_history(s_info.TLS, UC->id, 20, 0, on_chat_history_received, UC);
1910 tg_data->current_chat_index = 0;
1914 static Eina_Bool on_load_chat_history_requested(void *data)
1916 struct tgl_state *TLS = data;
1917 tg_engine_data_s *tg_data = TLS->callback_data;
1918 if (TLS && tg_data && tg_data->chat_list && eina_list_count(tg_data->chat_list) > 0) {
1919 tg_data->current_chat_index = 0;
1920 tgl_peer_t* UC = eina_list_nth(tg_data->chat_list, tg_data->current_chat_index);
1922 tgl_do_get_history(s_info.TLS, UC->id, 20, 0, on_chat_history_received, UC);
1925 return ECORE_CALLBACK_CANCEL;
1928 void on_buddy_history_received(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[])
1930 tg_engine_data_s *tg_data = TLS->callback_data;
1931 for (int i = 0; i < size; i++) {
1932 struct tgl_message* message = list[i];
1933 if (message->service || message->from_id.id == tg_data->id.id) {
1936 Eina_Bool ret = insert_buddy_msg_to_db(message);
1938 tg_msg_receive(s_info.TLS, message);
1941 tg_data->current_buddy_index = tg_data->current_buddy_index + 1;
1942 if (tg_data->buddy_list && (tg_data->current_buddy_index < eina_list_count(tg_data->buddy_list))) {
1943 tgl_peer_t* UC = eina_list_nth(tg_data->buddy_list, tg_data->current_buddy_index);
1944 tgl_do_get_history(s_info.TLS, UC->id, 20, 0, on_buddy_history_received, UC);
1946 tg_data->current_buddy_index = 0;
1947 ecore_timer_add(5, on_load_chat_history_requested, TLS);
1951 static Eina_Bool on_load_buddy_history_requested(void *data)
1953 struct tgl_state *TLS = data;
1954 tg_engine_data_s *tg_data = TLS->callback_data;
1955 if (TLS && tg_data && tg_data->buddy_list && eina_list_count(tg_data->buddy_list) > 0) {
1956 tg_data->current_buddy_index = 0;
1957 tgl_peer_t* UC = eina_list_nth(tg_data->buddy_list, tg_data->current_buddy_index);
1958 tgl_do_get_history(s_info.TLS, UC->id, 20, 0, on_buddy_history_received, UC);
1960 return ECORE_CALLBACK_CANCEL;
1965 static Eina_Bool send_login_activated_response(void *data)
1967 struct tgl_state *TLS = data;
1969 tg_engine_data_s *tg_data = TLS->callback_data;
1970 send_response_for_server_connection_status(tg_data, tg_data->is_login_activated);
1972 return ECORE_CALLBACK_CANCEL;
1976 static Eina_Bool send_chat_loading_is_done_response(void *data)
1978 struct tgl_state *TLS = data;
1980 send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
1981 ecore_timer_add(3, send_login_activated_response, TLS);
1983 return ECORE_CALLBACK_CANCEL;
1987 void on_offline_chat_received(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_message *list[])
1989 tg_engine_data_s *tg_data = TLS->callback_data;
1990 for (int i = size - 1; i >= 0; i--) {
1991 struct tgl_message* message = list[i];
1992 if (message->service || message->from_id.id == tg_data->id.id) {
1996 Eina_Bool ret = insert_buddy_msg_to_db(message);
1998 tg_msg_receive(s_info.TLS, message);
2001 tg_msg_receive(s_info.TLS, message);
2005 static Eina_Bool on_load_offline_messages(void *data)
2007 struct tgl_state *TLS = data;
2009 tg_engine_data_s *tg_data = TLS->callback_data;
2010 if (!tg_data->is_first_time_registration) {
2011 if (tg_data->peer_list && eina_list_count(tg_data->peer_list) > 0) {
2012 for (int i = 0; i < eina_list_count(tg_data->peer_list); i++) {
2013 tgl_peer_t* UC = eina_list_nth(tg_data->peer_list, i);
2014 struct tgl_message *last_msg = UC->last;
2016 // check last message in message table
2017 char* msg_table = get_table_name_from_number(UC->id.id);
2018 struct tgl_message* org_last_msg = get_message_from_message_tableby_message_id(msg_table, last_msg->id);
2019 if (!org_last_msg) {
2020 tgl_do_get_history(s_info.TLS, UC->id, 10, 0, on_offline_chat_received, UC);
2022 if (org_last_msg->message) {
2023 free(org_last_msg->message);
2032 if (tg_data->peer_list && eina_list_count(tg_data->peer_list) > 0) {
2033 for (int i = 0; i < eina_list_count(tg_data->peer_list); i++) {
2034 tgl_peer_t* UC = eina_list_nth(tg_data->peer_list, i);
2035 char* msg_table = get_table_name_from_number(UC->id.id);
2036 create_buddy_msg_table(msg_table);
2037 delete_all_messages_from_chat(UC->id.id, UC->id.type);
2042 return ECORE_CALLBACK_CANCEL;
2046 extern void on_peer_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info);
2048 static Eina_Bool on_async_peer_info_requested(void *data)
2050 struct tgl_state *TLS = data;
2052 tg_engine_data_s *tg_data = TLS->callback_data;
2053 tg_data->current_chat_index = tg_data->current_chat_index + 1;
2054 if (tg_data->current_chat_index < eina_list_count(tg_data->chat_list)) {
2055 tgl_peer_t* UC = eina_list_nth(tg_data->chat_list, tg_data->current_chat_index);
2057 tgl_do_get_chat_info(TLS, UC->id, 0, &on_peer_chat_info_received, NULL);
2060 send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
2061 ecore_timer_add(5, on_send_unsent_messages_requested, TLS);
2064 return ECORE_CALLBACK_CANCEL;
2067 void on_peer_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
2075 if (chat_info->flags == 144) {
2079 msg_table = get_table_name_from_number(chat_info->id.id);
2080 create_buddy_msg_table(msg_table);
2082 if (chat_info->admin_id > 0) {
2083 set_date_item_to_table(msg_table, chat_info->date);
2084 tgl_peer_id_t admin_id;
2085 admin_id.id = chat_info->admin_id;
2086 admin_id.type = TGL_PEER_USER;
2088 tgl_peer_t* UC = tgl_peer_get(TLS, admin_id);
2089 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
2090 char* creator_name = (char*)malloc(msg_len);
2091 strcpy(creator_name, UC->user.first_name);
2092 strcat(creator_name, " created the group");
2093 struct tgl_message msg;
2095 msg.to_id = chat_info->id;
2096 msg.from_id = admin_id;
2097 msg.id = chat_info->id.id;
2098 msg.message = creator_name;
2099 msg.message_len = msg_len;
2101 msg.date = chat_info->date;
2102 msg.media.type = tgl_message_media_none;
2106 insert_buddy_msg_to_db(&msg);
2111 if (chat_info->user_list) {
2112 for (int i = 0; i < chat_info->user_list_size; i++) {
2113 int user_id = chat_info->user_list[i].user_id;
2114 Eina_Bool is_present_in_db = is_user_present_buddy_table(user_id);
2115 char* tb_name = get_table_name_from_number(user_id);
2116 create_buddy_msg_table(tb_name);
2117 if (!is_present_in_db) {
2118 // add to buddy table
2119 tgl_peer_id_t from_id;
2120 from_id.id = user_id;
2121 from_id.type = TGL_PEER_USER;
2122 tgl_do_get_user_info(TLS, from_id, 0, on_new_buddy_info_loaded, NULL);
2130 insert_chat_info_to_db(chat_info, NULL);
2132 struct tgl_photo *pic = &(chat_info->photo);
2134 tgl_do_load_photo(TLS, pic ,&on_chat_pic_loaded,chat_info);
2138 ecore_timer_add(1, on_async_peer_info_requested, TLS);
2143 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[])
2145 tg_engine_data_s *tg_data = TLS->callback_data;
2146 if (tg_data->chat_list) {
2147 eina_list_free(tg_data->chat_list);
2148 tg_data->chat_list = NULL;
2150 if (tg_data->buddy_list) {
2151 eina_list_free(tg_data->buddy_list);
2152 tg_data->buddy_list = NULL;
2154 if (tg_data->peer_list) {
2155 eina_list_free(tg_data->peer_list);
2156 tg_data->peer_list = NULL;
2158 for (int i = size - 1; i >= 0; i--) {
2159 tgl_peer_t* UC = tgl_peer_get(TLS, peers[i]);
2160 // user exited from chat
2161 if(UC->flags == 144) {
2164 tg_data->peer_list = eina_list_append(tg_data->peer_list, UC);
2165 // insert into peer table
2166 switch (tgl_get_peer_type(peers[i])) {
2168 tg_data->buddy_list = eina_list_append(tg_data->buddy_list, UC);
2170 // check peer exists in peer table / buddy table
2171 Eina_Bool is_buddy_present = is_user_present_buddy_table(UC->id.id);
2172 if (!is_buddy_present) {
2173 struct tgl_user* buddy = &(UC->user);
2175 char* msg_table = get_table_name_from_number(buddy->id.id);
2176 create_buddy_msg_table(msg_table);
2179 buddy->is_unknown = 1;
2180 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2181 insert_peer_into_database(UC, last_msg_id[i], unread_count[i], 1);
2187 tg_data->chat_list = eina_list_append(tg_data->chat_list, UC);
2188 insert_peer_into_database(UC, last_msg_id[i], unread_count[i], 0);
2191 case TGL_PEER_ENCR_CHAT:
2199 if (!tg_data->is_first_time_registration) {
2200 struct tgl_message *last_msg = UC->last;
2202 // check last message in message table
2203 char* msg_table = get_table_name_from_number(UC->id.id);
2205 struct tgl_message* org_last_msg = get_message_from_message_tableby_message_id(msg_table, last_msg->id);
2207 if (!org_last_msg) {
2208 tgl_do_get_history(s_info.TLS, UC->id, 10, 0, on_offline_chat_received, UC);
2210 if (org_last_msg->message) {
2211 free(org_last_msg->message);
2220 char* msg_table = get_table_name_from_number(UC->id.id);
2221 create_buddy_msg_table(msg_table);
2222 delete_all_messages_from_chat(UC->id.id, UC->id.type);
2227 ecore_timer_add(3, on_send_unsent_messages_requested, TLS);
2228 send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
2231 if ((tg_data->chat_list == NULL) || (eina_list_count(tg_data->chat_list) <= 0)) {
2232 send_contacts_and_chats_load_done_response(TLS->callback_data, EINA_TRUE);
2233 ecore_timer_add(5, on_send_unsent_messages_requested, TLS);
2235 // load chat info one by one.
2236 tg_data->current_chat_index = 0;
2237 tgl_peer_t* UC = eina_list_nth(tg_data->chat_list, tg_data->current_chat_index);
2239 tgl_do_get_chat_info(TLS, UC->id, 0, &on_peer_chat_info_received, NULL);
2244 void on_contacts_received(struct tgl_state *TLS, void *callback_extra, int success, int size, struct tgl_user *contacts[])
2246 //tg_engine_data_s *tg_data = TLS->callback_data;
2247 for (int i = size - 1; i >= 0; i--) {
2248 struct tgl_user *buddy = contacts[i];
2249 char* msg_table = get_table_name_from_number(buddy->id.id);
2250 create_buddy_msg_table(msg_table);
2253 if (buddy->id.id == 333000 || buddy->id.id == 777000) {
2254 buddy->is_unknown = 1;
2256 buddy->is_unknown = 0;
2258 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2259 tgl_peer_t* UC = tgl_peer_get(TLS, buddy->id);
2261 insert_peer_into_database(UC, 0, 0, 0);
2265 // inform client that contact loading is done.
2266 for (int i = size - 1; i >= 0; i--) {
2267 struct tgl_user *buddy = contacts[i];
2268 tgl_do_get_user_info(TLS, buddy->id, 0, on_buddy_info_loaded, NULL);
2271 tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2275 void add_contacts_to_account(struct tgl_state *TLS)
2277 tg_engine_data_s *tg_data = TLS->callback_data;
2278 if(sc_db_utils_connect())
2280 Eina_List* contact_list = get_contact_list_from_device_db();
2281 sc_db_utils_disconnect();
2283 if (!contact_list || eina_list_count(contact_list) <= 0) {
2284 // no contacts avilable. empty contact list.
2285 //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2287 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2289 eina_list_free(contact_list);
2293 int size = eina_list_count(contact_list);
2295 add_contacts_to_user(tg_data, size, contact_list);
2297 eina_list_free(contact_list);
2299 //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2300 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2305 void on_user_info_loaded(struct tgl_state *TLS, void *extra, int success, struct tgl_user *buddy)
2307 tg_engine_data_s *tg_data = TLS->callback_data;
2309 tg_data->id.id = buddy->id.id;
2310 tg_data->id.type = buddy->id.type;
2312 struct tgl_photo* pic = &(buddy->photo);
2314 tgl_do_load_photo(TLS, pic ,&on_buddy_pic_loaded, buddy);
2317 buddy->is_unknown = 0;
2318 init_insert_buddy_into_db(USER_INFO_TABLE_NAME, buddy);
2321 if (tg_data->is_first_time_registration) {
2322 // send contact list to add friends.
2323 //send_add_contacts_request(tg_data);
2324 add_contacts_to_account(TLS);
2327 //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2328 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2331 add_contacts_to_account(TLS);
2335 void on_message_sent_to_buddy(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *message)
2337 tg_engine_data_s *tg_data;
2338 struct tgl_message* org_msg = (struct tgl_message*)callback_extra;
2339 tg_data = TLS->callback_data;
2341 if (success && message) {
2342 tgl_peer_t* UC = tgl_peer_get(TLS, message->to_id);
2344 message->msg_state = TG_MESSAGE_STATE_SENT;
2345 char* tb_name = get_table_name_from_number(message->to_id.id);
2346 update_msg_into_db(message, tb_name, org_msg->id);
2348 // delete message from unsent db
2349 delete_message_from_unsent_db(org_msg->id);
2350 delete_media_from_unsent_db(org_msg->id);
2352 if (message->media.type == tgl_message_media_photo || message->media.type == tgl_message_media_document || message->media.type == tgl_message_media_geo) {
2353 update_sent_media_info_in_db(message, (long long)org_msg->id);
2355 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));
2358 if (message->media.type != tgl_message_media_none && (message->media.document.flags & FLAG_DOCUMENT_VIDEO)) {
2359 //tgl_do_load_document_thumb(TLS, &(message->media.document), on_video_thumb_loaded, message);
2365 org_msg->msg_state = TG_MESSAGE_STATE_FAILED;
2366 char* tb_name = get_table_name_from_number(org_msg->to_id.id);
2367 update_msg_into_db(org_msg, tb_name, org_msg->id);
2368 if (org_msg->media.type == tgl_message_media_photo || org_msg->media.type == tgl_message_media_document || message->media.type == tgl_message_media_geo) {
2369 if (org_msg->media.type == tgl_message_media_photo) {
2370 org_msg->media.photo.sizes_num = 0;
2371 org_msg->media.photo.sizes = NULL;
2373 update_sent_media_info_in_db(org_msg, (long long)org_msg->id);
2375 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));
2380 if (org_msg->message) {
2381 free(org_msg->message);
2387 void on_image_download_completed(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
2389 tg_engine_data_s *tg_data = TLS->callback_data;
2390 struct tgl_photo* photo_prop = (struct tgl_photo*)callback_extra;
2391 long long media_id = photo_prop->id;
2392 int buddy_id = photo_prop->user_id;
2393 int to_id = photo_prop->to_peer_id;
2395 if(photo_prop && filename) {
2396 update_receive_media_info_in_db(media_id, filename);
2397 //send response to application
2398 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, filename, photo_prop->caption);
2402 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, NULL, NULL);
2406 void on_document_download_completed(struct tgl_state *TLS, void *callback_extra, int success, char *filename)
2408 tg_engine_data_s *tg_data = TLS->callback_data;
2409 struct tgl_document* doc_prop = (struct tgl_document*)callback_extra;
2410 long long media_id = doc_prop->id;
2411 int buddy_id = doc_prop->user_id;
2412 int to_id = doc_prop->to_peer_id;
2414 if(doc_prop && filename) {
2415 update_receive_media_info_in_db(media_id, filename);
2416 //send response to application
2417 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, filename, doc_prop->caption);
2420 send_media_download_completed_response(tg_data, buddy_id, to_id, media_id, NULL, NULL);
2424 if (doc_prop->caption) {
2425 free(doc_prop->caption);
2432 void free_contact_data(Eina_List *contact_data)
2435 for (int i = 0; i < eina_list_count(contact_data); i++) {
2436 contact_data_s* contact = eina_list_nth(contact_data, i);
2438 if (contact->display_name) {
2439 free(contact->display_name);
2440 contact->display_name = NULL;
2442 if (contact->first_name) {
2443 free(contact->first_name);
2444 contact->first_name = NULL;
2446 if (contact->last_name) {
2447 free(contact->last_name);
2448 contact->last_name = NULL;
2450 if (contact->phone_number) {
2451 free(contact->phone_number);
2452 contact->phone_number = NULL;
2457 eina_list_free(contact_data);
2461 void on_contact_added(struct tgl_state *TLS,void *callback_extra, int success, int size, struct tgl_user *users[])
2463 tg_engine_data_s* data = callback_extra;
2465 data->current_index++;
2467 if (data->current_index < eina_list_count(data->contact_list_to_add)) {
2468 contact_data_s* contact = eina_list_nth(data->contact_list_to_add, data->current_index);
2471 char *first_name = contact->first_name;
2472 char *last_name = contact->last_name;
2473 char *phone_number = contact->phone_number;
2476 first_name = contact->display_name;
2486 if (first_name && last_name && phone_number) {
2487 tgl_do_add_contact(tgl_engine_get_TLS(), phone_number, first_name, last_name, 0, on_contact_added, data);
2489 on_contact_added(tgl_engine_get_TLS(), data, 0, 0, NULL);
2494 //tgl_do_get_dialog_list(TLS, on_contacts_and_chats_loaded, NULL);
2495 tgl_do_update_contact_list(TLS, on_contacts_received, NULL);
2496 free_contact_data(data->contact_list_to_add);
2497 data->contact_list_to_add = NULL;
2501 void on_new_group_icon_loaded(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2503 tg_engine_data_s *tg_data = TLS->callback_data;
2505 // send fail notification
2507 // send success notofication
2509 if (M->action.type == tgl_message_action_chat_create) {
2511 } else if (M->action.type == tgl_message_action_chat_edit_title) {
2513 } else if (M->action.type == tgl_message_action_chat_edit_photo) {
2515 char* msg_table = get_table_name_from_number(M->to_id.id);
2516 create_buddy_msg_table(msg_table);
2517 int msg_id = insert_current_date_to_table(msg_table);
2519 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2520 int msg_len = strlen(UC->user.first_name) + strlen(" changed profile photo") + 1;
2521 char* creator_name = (char*)malloc(msg_len);
2522 strcpy(creator_name, UC->user.first_name);
2523 strcat(creator_name, " changed profile photo");
2526 //send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id,msg_id, tgl_get_peer_type(M->to_id));
2527 int cur_time = time(NULL);
2529 M->message = creator_name;
2530 M->message_len = msg_len;
2533 insert_buddy_msg_to_db(M);
2536 struct tgl_photo *pic = &(M->action.photo);
2538 tgl_peer_t* UC = tgl_peer_get(TLS, M->to_id);
2539 struct tgl_chat *chat_info = &(UC->chat);
2540 tgl_do_load_photo(TLS, pic ,&on_chat_pic_loaded, chat_info);
2544 } else if (M->action.type == tgl_message_action_chat_delete_photo) {
2546 } else if (M->action.type == tgl_message_action_chat_add_user) {
2548 } else if (M->action.type == tgl_message_action_chat_delete_user) {
2551 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2559 void on_new_group_created(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2561 tg_engine_data_s *tg_data = TLS->callback_data;
2563 // send fail notification
2565 // send success notofication
2567 if (M->action.type == tgl_message_action_chat_create) {
2568 char* msg_table = get_table_name_from_number(M->to_id.id);
2569 create_buddy_msg_table(msg_table);
2572 int msg_id = insert_current_date_to_table(msg_table);
2573 //send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id,msg_id, tgl_get_peer_type(M->to_id));
2576 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2577 int msg_len = strlen(UC->user.first_name) + strlen(" created the group") + 1;
2578 char* creator_name = (char*)malloc(msg_len);
2579 strcpy(creator_name, UC->user.first_name);
2580 strcat(creator_name, " created the group");
2584 int cur_time = time(NULL);
2585 M->id = M->to_id.id;
2586 M->message = creator_name;
2587 M->message_len = msg_len;
2591 insert_buddy_msg_to_db(M);
2594 tgl_peer_t* chat_UC = tgl_peer_get(TLS, M->to_id);
2595 chat_UC->chat.date = M->date;
2596 insert_chat_info_to_db(&(chat_UC->chat), NULL);
2598 insert_peer_into_database(chat_UC, 0, 0, 0);
2600 if (tg_data->new_group_icon) {
2601 tgl_peer_t* UC = tgl_peer_get(TLS, M->to_id);
2602 struct tgl_chat *chat_info = &(UC->chat);
2603 tgl_do_set_chat_photo(TLS, chat_info->id, tg_data->new_group_icon, on_new_group_icon_loaded, chat_info);
2607 } else if (M->action.type == tgl_message_action_chat_edit_title) {
2609 } else if (M->action.type == tgl_message_action_chat_edit_photo) {
2611 } else if (M->action.type == tgl_message_action_chat_delete_photo) {
2613 } else if (M->action.type == tgl_message_action_chat_add_user) {
2615 } else if (M->action.type == tgl_message_action_chat_delete_user) {
2618 send_new_group_added_response(tg_data, M->to_id.id);
2623 void on_set_profile_picture_response_received(struct tgl_state *TLS, void *callback_extra, int success)
2625 tg_engine_data_s *tg_data = TLS->callback_data;
2626 char *file_path = callback_extra;
2629 update_buddy_pic_db(file_path, USER_INFO_TABLE_NAME, tg_data->id.id);
2630 update_buddy_pic_db(file_path, BUDDY_INFO_TABLE_NAME, tg_data->id.id);
2631 send_self_profile_picture_updated_response(tg_data, file_path, EINA_TRUE);
2633 send_self_profile_picture_updated_response(tg_data, file_path, EINA_FALSE);
2639 void set_profile_picture(tg_engine_data_s *tg_data, int buddy_id, const char *file_path)
2642 char *org_path = strdup(file_path);
2643 tgl_do_set_profile_photo(tgl_engine_get_TLS(), (char*)file_path, on_set_profile_picture_response_received, org_path);
2647 void on_set_new_chat_title_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2650 char *type_of_change = NULL;
2651 if (M && M->action.type == tgl_message_action_chat_edit_title) {
2652 type_of_change = strdup("edit_title");
2653 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2654 int msg_len = strlen(UC->user.first_name) + strlen(" changed the chat title") + 1;
2655 char* creator_name = (char*)malloc(msg_len);
2656 strcpy(creator_name, UC->user.first_name);
2657 strcat(creator_name, " changed the chat title");
2659 int cur_time = time(NULL);
2661 M->message = creator_name;
2662 M->message_len = msg_len;
2665 insert_buddy_msg_to_db(M);
2667 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2668 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
2671 tg_engine_data_s *tg_data = TLS->callback_data;
2672 struct tgl_chat *chat_info = (struct tgl_chat*)callback_extra;
2673 send_group_chat_rename_response(tg_data, chat_info->id.id, EINA_FALSE);
2677 void set_group_chat_new_title(tg_engine_data_s *tg_data, int buddy_id, const char *new_title)
2680 tgl_peer_id_t peer_id;
2681 peer_id.id = buddy_id;
2682 peer_id.type = TGL_PEER_CHAT;
2684 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), peer_id);
2685 struct tgl_chat *chat_info = &(UC->chat);
2686 tgl_do_rename_chat(tgl_engine_get_TLS(), chat_info->id, (char*)new_title, on_set_new_chat_title_response_received, chat_info);
2690 void on_new_buddy_added_to_chat_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2693 char *type_of_change = NULL;
2694 if (M && M->action.type == tgl_message_action_chat_add_user) {
2695 type_of_change = strdup("add_user");
2696 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2698 tgl_peer_id_t added_id;
2699 added_id.id = M->action.user;
2700 added_id.type = TGL_PEER_USER;
2702 tgl_peer_t* added_UC = tgl_peer_get(TLS, added_id);
2703 char* new_user_name = replace(added_UC->print_name, '_', " ");
2704 int msg_len = strlen(UC->user.first_name) + strlen(" added ") + strlen(new_user_name) + 1;
2705 char* creator_name = (char*)malloc(msg_len);
2706 strcpy(creator_name, UC->user.first_name);
2707 strcat(creator_name, " added ");
2708 strcat(creator_name, new_user_name);
2709 free(new_user_name);
2711 int cur_time = time(NULL);
2713 M->message = creator_name;
2714 M->message_len = msg_len;
2717 insert_buddy_msg_to_db(M);
2719 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2720 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
2723 tg_engine_data_s *tg_data = TLS->callback_data;
2724 struct tgl_chat *chat_info = (struct tgl_chat*)callback_extra;
2725 send_group_chat_new_buddy_response(tg_data, chat_info->id.id, EINA_FALSE);
2729 void set_group_chat_add_new_buddy(tg_engine_data_s *tg_data, int s_buddy_id, int s_chat_id)
2731 tgl_peer_id_t chat_id;
2732 chat_id.id = s_chat_id;
2733 chat_id.type = TGL_PEER_CHAT;
2735 tgl_peer_id_t buddy_id;
2736 buddy_id.id = s_buddy_id;
2737 buddy_id.type = TGL_PEER_USER;
2739 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), chat_id);
2740 struct tgl_chat *chat_info = &(UC->chat);
2741 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);
2745 void on_buddy_removed_from_chat_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
2748 char *type_of_change = NULL;
2749 if (M && M->action.type == tgl_message_action_chat_delete_user) {
2750 type_of_change = strdup("delete_user");
2751 tgl_peer_t* UC = tgl_peer_get(TLS, M->from_id);
2752 tgl_peer_id_t added_id;
2753 added_id.id = M->action.user;
2754 added_id.type = TGL_PEER_USER;
2756 tgl_peer_t* added_UC = tgl_peer_get(TLS, added_id);
2757 char* new_user_name = replace(added_UC->print_name, '_', " ");
2758 int msg_len = strlen(UC->user.first_name) + strlen(" removed ") + strlen(new_user_name) + 1;
2759 char* creator_name = (char*)malloc(msg_len);
2760 strcpy(creator_name, UC->user.first_name);
2761 strcat(creator_name, " removed ");
2762 strcat(creator_name, new_user_name);
2763 free(new_user_name);
2764 int cur_time = time(NULL);
2766 M->message = creator_name;
2767 M->message_len = msg_len;
2770 insert_buddy_msg_to_db(M);
2772 send_message_received_response(TLS->callback_data, M->from_id.id, M->to_id.id, M->id, tgl_get_peer_type(M->to_id));
2773 tgl_do_get_chat_info(TLS, M->to_id, 0, &on_group_chat_info_updated, type_of_change);
2776 tg_engine_data_s *tg_data = TLS->callback_data;
2777 struct tgl_chat *chat_info = (struct tgl_chat*)callback_extra;
2778 send_group_chat_delete_buddy_response(tg_data, chat_info->id.id, EINA_FALSE);
2782 void set_group_chat_remove_buddy(tg_engine_data_s *tg_data, int s_buddy_id, int s_chat_id)
2784 tgl_peer_id_t chat_id;
2785 chat_id.id = s_chat_id;
2786 chat_id.type = TGL_PEER_CHAT;
2788 tgl_peer_id_t buddy_id;
2789 buddy_id.id = s_buddy_id;
2790 buddy_id.type = TGL_PEER_USER;
2792 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), chat_id);
2793 struct tgl_chat *chat_info = &(UC->chat);
2794 tgl_do_del_user_from_chat(tgl_engine_get_TLS(), chat_id, buddy_id, on_buddy_removed_from_chat_response_received, chat_info);
2797 void set_group_chat_profile_picture(tg_engine_data_s *tg_data, int buddy_id, const char *file_path)
2800 tgl_peer_id_t peer_id;
2801 peer_id.id = buddy_id;
2802 peer_id.type = TGL_PEER_CHAT;
2804 tgl_peer_t* UC = tgl_peer_get(tgl_engine_get_TLS(), peer_id);
2805 struct tgl_chat *chat_info = &(UC->chat);
2806 tgl_do_set_chat_photo(tgl_engine_get_TLS(), chat_info->id, (char*)file_path, on_new_group_icon_loaded, chat_info);
2810 void on_set_username_response_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *buddy)
2812 tg_engine_data_s *tg_data = TLS->callback_data;
2813 char *org_username = callback_extra;
2816 update_buddy_into_db(USER_INFO_TABLE_NAME, buddy);
2817 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2818 send_self_user_name_updated_response(tg_data, org_username, EINA_TRUE);
2820 send_self_user_name_updated_response(tg_data, org_username, EINA_FALSE);
2827 void set_user_name(tg_engine_data_s *tg_data, int buddy_id, const char *username)
2830 char *org_username = strdup(username);
2831 tgl_do_set_username(tgl_engine_get_TLS(), username, on_set_username_response_received, org_username);
2835 void on_profile_name_changed(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_user *buddy)
2837 tg_engine_data_s *tg_data = callback_extra;
2840 update_buddy_into_db(USER_INFO_TABLE_NAME, buddy);
2841 update_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
2842 send_self_profile_name_updated_response(tg_data, buddy->first_name, buddy->last_name, EINA_TRUE);
2844 send_self_profile_name_updated_response(tg_data, "", "", EINA_FALSE);
2848 void update_user_display_name(tg_engine_data_s *tg_data, int buddy_id, const char *first_name, const char *last_name)
2850 if (first_name && last_name) {
2851 tgl_do_set_profile_name(tgl_engine_get_TLS(), first_name, last_name, on_profile_name_changed, tg_data);
2855 void create_new_group(tg_engine_data_s *tg_data, Eina_List* buddy_ids, const char *group_name, const char *group_icon)
2857 if (!buddy_ids || ! group_name) {
2860 int users_num = eina_list_count(buddy_ids);
2861 static tgl_peer_id_t ids[1024];
2862 static char _group_icon[1024];
2864 for (i = 0; i < users_num; i++) {
2865 char *buddy_id_str = (char *)eina_list_nth(buddy_ids, i);
2866 int buddy_id = atoi(buddy_id_str);
2867 ids[i].id = buddy_id;
2868 ids[i].type = TGL_PEER_USER;
2871 strncpy(_group_icon, group_icon, sizeof(_group_icon));
2873 tgl_do_create_group_chat_ex(tgl_engine_get_TLS(), users_num, ids, group_name, on_new_group_created, (void *)_group_icon);
2874 tg_data->is_group_creation_requested = EINA_TRUE;
2876 if (tg_data->new_group_icon) {
2877 free(tg_data->new_group_icon);
2880 if (group_icon && strlen(group_icon) > 0) {
2881 tg_data->new_group_icon = strdup(group_icon);
2883 tg_data->new_group_icon = NULL;
2888 void add_contacts_to_user(tg_engine_data_s *tg_data, int size, Eina_List* contact_list)
2890 tg_data->contact_list_to_add = contact_list;
2891 contact_data_s* contact = eina_list_nth(contact_list, 0);
2893 char *first_name = contact->first_name;
2894 char *last_name = contact->last_name;
2895 char *phone_number = contact->phone_number;
2897 tg_data->current_index = 0;
2900 first_name = contact->display_name;
2910 if (first_name && last_name && phone_number) {
2911 tgl_do_add_contact(tgl_engine_get_TLS(), phone_number, first_name, last_name, 0, on_contact_added, tg_data);
2913 on_contact_added(tgl_engine_get_TLS(), tg_data, 0, 0, NULL);
2918 void media_download_request(tg_engine_data_s *tg_data, int buddy_id, long long media_id)
2920 // get media details by mediaid
2921 struct tgl_media* img_details = get_media_details_from_db(media_id);
2924 send_media_download_completed_response(tg_data, -1, buddy_id, media_id, NULL, NULL);
2928 if (img_details->media_type == tgl_message_media_none) {
2930 } else if (img_details->media_type == tgl_message_media_photo) {
2932 struct tgl_photo* photo_prop = (struct tgl_photo*)malloc(sizeof(struct tgl_photo));
2933 photo_prop->id = img_details->media_id;
2934 photo_prop->access_hash = img_details->access_hash;
2935 photo_prop->user_id = img_details->user_id;
2936 photo_prop->date = img_details->date;
2937 photo_prop->caption = img_details->caption;
2938 photo_prop->geo.latitude = atof(img_details->latitude);
2939 photo_prop->geo.longitude = atof(img_details->longitude);
2940 photo_prop->sizes_num = img_details->sizes;
2942 photo_prop->sizes = talloc(sizeof(struct tgl_photo_size) * photo_prop->sizes_num);
2944 for (i = 0; i < photo_prop->sizes_num; i++) {
2947 photo_prop->sizes[i].w = img_details->photo_width1;
2948 photo_prop->sizes[i].h = img_details->photo_height1;
2949 photo_prop->sizes[i].size = img_details->photo_size1;
2950 if(img_details->photo_data1) {
2951 photo_prop->sizes[i].data = strdup(img_details->photo_data1);
2953 if(img_details->photo_type1) {
2954 photo_prop->sizes[i].type = strdup(img_details->photo_type1);
2956 photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc1;
2957 photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id1;
2958 photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec1;
2959 photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol1;
2960 } else if (i == 1) {
2962 photo_prop->sizes[i].w = img_details->photo_width2;
2963 photo_prop->sizes[i].h = img_details->photo_height2;
2964 photo_prop->sizes[i].size = img_details->photo_size2;
2965 if(img_details->photo_data2) {
2966 photo_prop->sizes[i].data = strdup(img_details->photo_data2);
2968 if(img_details->photo_type2) {
2969 photo_prop->sizes[i].type = strdup(img_details->photo_type2);
2971 photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc2;
2972 photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id2;
2973 photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec2;
2974 photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol2;
2976 } else if (i == 2) {
2978 photo_prop->sizes[i].w = img_details->photo_width3;
2979 photo_prop->sizes[i].h = img_details->photo_height3;
2980 photo_prop->sizes[i].size = img_details->photo_size3;
2981 if(img_details->photo_data3) {
2982 photo_prop->sizes[i].data = strdup(img_details->photo_data3);
2984 if(img_details->photo_type3) {
2985 photo_prop->sizes[i].type = strdup(img_details->photo_type3);
2987 photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc3;
2988 photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id3;
2989 photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec3;
2990 photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol3;
2992 } else if (i == 3) {
2994 photo_prop->sizes[i].w = img_details->photo_width4;
2995 photo_prop->sizes[i].h = img_details->photo_height4;
2996 photo_prop->sizes[i].size = img_details->photo_size4;
2997 if(img_details->photo_data4) {
2998 photo_prop->sizes[i].data = strdup(img_details->photo_data4);
3000 if(img_details->photo_type4) {
3001 photo_prop->sizes[i].type = strdup(img_details->photo_type4);
3003 photo_prop->sizes[i].loc.dc = img_details->photo_loc_dc4;
3004 photo_prop->sizes[i].loc.local_id = img_details->photo_loc_id4;
3005 photo_prop->sizes[i].loc.secret = img_details->photo_loc_sec4;
3006 photo_prop->sizes[i].loc.volume = img_details->photo_loc_vol4;
3012 photo_prop->to_peer_id = buddy_id;
3013 tgl_do_load_photo(s_info.TLS, photo_prop ,&on_image_download_completed, photo_prop);
3015 } else if (img_details->media_type == tgl_message_media_document) {
3016 struct tgl_document* doc_prop = (struct tgl_document*)malloc(sizeof(struct tgl_document));
3017 doc_prop->id = img_details->media_id;;
3018 doc_prop->access_hash = img_details->access_hash;
3019 doc_prop->user_id = img_details->user_id;
3020 doc_prop->date = img_details->date;
3021 doc_prop->size = img_details->sizes;
3022 doc_prop->mime_type = NULL;
3023 doc_prop->dc_id = img_details->doc_dc;
3024 doc_prop->to_peer_id = buddy_id;
3026 if (img_details->caption) {
3027 doc_prop->caption = strdup(img_details->caption);
3029 doc_prop->caption = NULL;
3033 if (!(img_details->mime_type) || strlen(img_details->mime_type) <= 0) {
3035 if (img_details->doc_type && strlen(img_details->doc_type) > 0) {
3036 if (strstr(img_details->doc_type, "video") != NULL) {
3037 doc_prop->mime_type = strdup("video/mp4");
3038 } else if (strstr(img_details->doc_type, "audio") != NULL) {
3039 doc_prop->mime_type = strdup("audio/wav");
3040 } else if (strstr(img_details->doc_type, "image/gif") != NULL) {
3041 doc_prop->mime_type = strdup("image/gif");
3045 doc_prop->mime_type = img_details->mime_type;
3048 if (strstr(img_details->doc_type, "video") != NULL) {
3049 doc_prop->flags = FLAG_DOCUMENT_VIDEO;
3050 } else if (strstr(img_details->doc_type, "audio") != NULL) {
3051 doc_prop->flags = FLAG_DOCUMENT_AUDIO;
3052 } else if (strstr(img_details->doc_type, "image") != NULL) {
3053 doc_prop->flags = FLAG_DOCUMENT_ANIMATED;
3056 tgl_do_load_document(s_info.TLS, doc_prop ,on_document_download_completed, doc_prop);
3063 // delete image details
3065 if (img_details->caption) {
3066 free(img_details->caption);
3068 if (img_details->longitude) {
3069 free(img_details->longitude);
3071 if (img_details->latitude) {
3072 free(img_details->latitude);
3074 if (img_details->phone_no) {
3075 free(img_details->phone_no);
3077 if (img_details->first_name) {
3078 free(img_details->first_name);
3080 if (img_details->last_name) {
3081 free(img_details->last_name);
3083 if (img_details->file_path) {
3084 free(img_details->file_path);
3086 if (img_details->photo_type1) {
3087 free(img_details->photo_type1);
3089 if (img_details->photo_data1) {
3090 free(img_details->photo_data1);
3092 if (img_details->photo_type2) {
3093 free(img_details->photo_type2);
3095 if (img_details->photo_data2) {
3096 free(img_details->photo_data2);
3098 if (img_details->photo_type3) {
3099 free(img_details->photo_type3);
3101 if (img_details->photo_data3) {
3102 free(img_details->photo_data3);
3104 if (img_details->photo_type4) {
3105 free(img_details->photo_type4);
3107 if (img_details->photo_data4) {
3108 free(img_details->photo_data4);
3110 if (img_details->mime_type) {
3111 free(img_details->mime_type);
3113 if (img_details->doc_type) {
3114 free(img_details->doc_type);
3116 if (img_details->doc_thumb_path) {
3117 free(img_details->doc_thumb_path);
3123 void on_mark_read_callback(struct tgl_state *TLS, void *callback_extra, int success)
3125 // message read sent successfully. update to UI if needed.
3129 void on_message_deleted_from_message_list(struct tgl_state *TLS, void *callback_extra, int success)
3131 msg_list_container_s *msg_list_container = (msg_list_container_s*)callback_extra;
3132 tg_engine_data_s *tg_data = TLS->callback_data;
3134 if (success && msg_list_container) {
3135 // delete message from message table
3136 char* tb_name = get_table_name_from_number(msg_list_container->buddy_id);
3137 delete_message_from_table(tb_name, msg_list_container->current_message_id);
3141 if (msg_list_container && msg_list_container->message_ids) {
3142 if (msg_list_container->current_index < eina_list_count(msg_list_container->message_ids)) {
3143 msg_list_container->current_index = msg_list_container->current_index + 1;
3144 msg_list_container->current_message_id = (int)eina_list_nth(msg_list_container->message_ids, msg_list_container->current_index);
3145 tgl_do_delete_msg(s_info.TLS, msg_list_container->current_message_id, &on_message_deleted_from_message_list , (void*)(msg_list_container));
3147 eina_list_free(msg_list_container->message_ids);
3148 free(msg_list_container);
3153 void delete_all_messages_from_chat(int buddy_id, int type_of_chat)
3155 tgl_peer_id_t chat_id;
3156 chat_id.id = buddy_id;
3157 chat_id.type = type_of_chat;
3159 char* tb_name = get_table_name_from_number(buddy_id);
3160 //get all message ids from table.
3161 Eina_List *msg_ids = get_all_message_ids_from_table(tb_name);
3164 if (msg_ids && eina_list_count(msg_ids) > 0) {
3165 msg_list_container_s *msg_list_container = (msg_list_container_s*)malloc(sizeof(msg_list_container_s));
3166 msg_list_container->message_ids = msg_ids;
3167 msg_list_container->buddy_id = buddy_id;
3168 msg_list_container->current_index = 0;
3169 msg_list_container->current_message_id = (int)eina_list_nth(msg_list_container->message_ids, msg_list_container->current_index);
3171 tgl_do_delete_msg(s_info.TLS, msg_list_container->current_message_id, &on_message_deleted_from_message_list , (void*)(msg_list_container));
3177 void send_do_mark_read_messages(int buddy_id, int type_of_chat)
3179 tgl_peer_id_t chat_id;
3180 chat_id.id = buddy_id;
3181 chat_id.type = type_of_chat;
3183 tgl_do_mark_read(s_info.TLS, chat_id, &on_mark_read_callback , (void*)(&chat_id));
3187 void on_user_block_response(struct tgl_state *TLS, void *callback_extra, int success)
3189 int buddy_id = (int)callback_extra;
3190 tg_engine_data_s *tg_data = TLS->callback_data;
3194 update_buddy_block_db(BUDDY_INFO_TABLE_NAME, buddy_id, blocked);
3195 send_buddy_blocked_response(tg_data, buddy_id, EINA_TRUE);
3197 send_buddy_blocked_response(tg_data, buddy_id, EINA_FALSE);
3201 void on_user_unblock_response(struct tgl_state *TLS, void *callback_extra, int success)
3203 int buddy_id = (int)callback_extra;
3204 tg_engine_data_s *tg_data = TLS->callback_data;
3207 update_buddy_block_db(BUDDY_INFO_TABLE_NAME, buddy_id, blocked);
3208 send_buddy_unblocked_response(tg_data, buddy_id, EINA_TRUE);
3210 send_buddy_unblocked_response(tg_data, buddy_id, EINA_FALSE);
3214 void on_user_delete_response(struct tgl_state *TLS, void *callback_extra, int success)
3216 int buddy_id = (int)callback_extra;
3217 tg_engine_data_s *tg_data = TLS->callback_data;
3220 // delete from peer table
3221 // delete from buddy table
3222 // delete chat items
3224 //delete_chat_from_db(buddy_id);
3225 //delete_buddy_from_db(buddy_id);
3226 //char* msg_table = get_table_name_from_number(buddy_id);
3227 //drop_table(msg_table);
3231 update_buddy_delete_db(BUDDY_INFO_TABLE_NAME, buddy_id, deleted);
3232 send_buddy_deleted_response(tg_data, buddy_id, EINA_TRUE);
3234 send_buddy_deleted_response(tg_data, buddy_id, EINA_FALSE);
3239 void on_buddy_readded(struct tgl_state *TLS,void *callback_extra, int success, int size, struct tgl_user *users[])
3241 int buddy_id = (int)callback_extra;
3242 tg_engine_data_s *tg_data = TLS->callback_data;
3245 update_buddy_delete_db(BUDDY_INFO_TABLE_NAME, buddy_id, deleted);
3246 send_buddy_readded_response(tg_data, buddy_id, EINA_TRUE);
3248 send_buddy_readded_response(tg_data, buddy_id, EINA_FALSE);
3252 void on_new_buddy_added(struct tgl_state *TLS,void *callback_extra, int success, int size, struct tgl_user *users[])
3254 tg_engine_data_s *tg_data = TLS->callback_data;
3256 struct tgl_user *buddy = users[0];
3258 char* msg_table = get_table_name_from_number(buddy->id.id);
3259 create_buddy_msg_table(msg_table);
3262 if (buddy->id.id == 333000 || buddy->id.id == 777000) {
3263 buddy->is_unknown = 1;
3265 buddy->is_unknown = 0;
3267 init_insert_buddy_into_db(BUDDY_INFO_TABLE_NAME, buddy);
3268 tgl_peer_t* UC = tgl_peer_get(TLS, buddy->id);
3270 insert_peer_into_database(UC, 0, 0, 0);
3272 tgl_do_get_user_info(TLS, buddy->id, 0, on_buddy_info_loaded, NULL);
3274 // send response to application
3275 send_new_contact_added_response(tg_data, buddy->id.id, EINA_TRUE);
3277 send_new_contact_added_response(tg_data, -1, EINA_FALSE);
3281 send_new_contact_added_response(tg_data, -1, EINA_TRUE);
3285 void do_add_buddy(int buddy_id, char *first_name, char *last_name, char *phone_num)
3297 if (first_name && last_name && phone_num) {
3298 if (buddy_id == -1) {
3299 tgl_do_add_contact(s_info.TLS, phone_num, first_name, last_name, 0, on_new_buddy_added, (void*)(buddy_id));
3301 tgl_do_add_contact(s_info.TLS, phone_num, first_name, last_name, 0, on_buddy_readded, (void*)(buddy_id));
3307 void logout_telegram(tg_engine_data_s *tg_data)
3312 void on_secret_chat_request_sent(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_secret_chat *E)
3314 int buddy_id = (int)callback_extra;
3315 tg_engine_data_s *tg_data = TLS->callback_data;
3323 void request_for_secret_chat(int buddy_id)
3325 tgl_peer_id_t peer_id;
3326 peer_id.id = buddy_id;
3327 peer_id.type = TGL_PEER_USER;
3328 tgl_do_create_secret_chat(s_info.TLS, peer_id, on_secret_chat_request_sent, (void*)(buddy_id));
3331 void do_delete_buddy(int buddy_id)
3333 tgl_peer_id_t peer_id;
3334 peer_id.id = buddy_id;
3335 peer_id.type = TGL_PEER_USER;
3336 tgl_do_del_contact(s_info.TLS, peer_id, &on_user_delete_response , (void*)(buddy_id));
3339 void on_message_deleted(struct tgl_state *TLS, void *callback_extra, int success)
3341 msg_container_s *msg_details = (msg_container_s*)callback_extra;
3342 tg_engine_data_s *tg_data = TLS->callback_data;
3345 send_message_deleted_response(tg_data, msg_details->buddy_id, msg_details->message_id, EINA_TRUE);
3347 send_message_deleted_response(tg_data, msg_details->buddy_id, msg_details->message_id, EINA_FALSE);
3351 void do_delete_message(int buddy_id, int message_id)
3353 msg_container_s *msg_details = (msg_container_s*)malloc(sizeof(msg_container_s));
3354 msg_details->buddy_id = buddy_id;
3355 msg_details->message_id = message_id;
3356 tgl_do_delete_msg(s_info.TLS, message_id, &on_message_deleted , (void*)(msg_details));
3360 void do_block_buddy(int buddy_id)
3362 tgl_peer_id_t peer_id;
3363 peer_id.id = buddy_id;
3364 peer_id.type = TGL_PEER_USER;
3365 tgl_do_block_user(s_info.TLS, peer_id, &on_user_block_response , (void*)(buddy_id));
3368 void do_unblock_buddy(int buddy_id)
3370 tgl_peer_id_t peer_id;
3371 peer_id.id = buddy_id;
3372 peer_id.type = TGL_PEER_USER;
3373 tgl_do_unblock_user(s_info.TLS, peer_id, &on_user_unblock_response , (void*)(buddy_id));
3376 extern void on_selected_group_chats_delete_reponse(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M);
3377 static Eina_Bool on_async_chat_deletion_requested(void *data)
3379 Eina_List *sel_grp_chats = data;
3380 if (sel_grp_chats) {
3381 tg_engine_data_s *tg_data = tgl_engine_get_TLS()->callback_data;
3382 tg_data->current_group_chat_index = tg_data->current_group_chat_index + 1;
3384 if (tg_data->current_group_chat_index < eina_list_count(sel_grp_chats)) {
3385 int group_chat_id = (int)eina_list_nth(sel_grp_chats, tg_data->current_group_chat_index);
3387 tgl_peer_id_t chat_id;
3388 chat_id.id = group_chat_id;
3389 chat_id.type = TGL_PEER_CHAT;
3391 tgl_peer_id_t self_id = tg_data->id;
3393 tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, on_selected_group_chats_delete_reponse, (void*)(sel_grp_chats));
3395 send_selected_group_chats_deleted_response(tg_data);
3398 return ECORE_CALLBACK_CANCEL;
3402 void on_selected_group_chats_delete_reponse(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
3404 Eina_List *sel_grp_chats = callback_extra;
3405 tg_engine_data_s *tg_data = TLS->callback_data;
3406 int chat_id = (int)eina_list_nth(sel_grp_chats, tg_data->current_group_chat_index);
3410 // delete from peer table
3411 delete_chat_from_db(chat_id);
3412 char* msg_table = get_table_name_from_number(chat_id);
3413 drop_table(msg_table);
3418 ecore_timer_add(3, on_async_chat_deletion_requested, sel_grp_chats);
3421 void delete_selected_group_chat(tg_engine_data_s *tg_data, Eina_List *sel_grp_chats)
3423 if (sel_grp_chats && eina_list_count(sel_grp_chats) > 0) {
3425 tg_data->current_group_chat_index = 0;
3426 int group_chat_id = (int)eina_list_nth(sel_grp_chats, tg_data->current_group_chat_index);
3428 tgl_peer_id_t chat_id;
3429 chat_id.id = group_chat_id;
3430 chat_id.type = TGL_PEER_CHAT;
3432 tgl_peer_id_t self_id = tg_data->id;
3434 tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, on_selected_group_chats_delete_reponse, (void*)(sel_grp_chats));
3438 void on_group_chat_delete_reponse(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M)
3440 int chat_id = (int)callback_extra;
3441 tg_engine_data_s *tg_data = TLS->callback_data;
3444 // delete from peer table
3445 delete_chat_from_db(chat_id);
3446 char* msg_table = get_table_name_from_number(chat_id);
3447 drop_table(msg_table);
3449 send_group_chat_deleted_response(tg_data, chat_id, EINA_TRUE);
3451 send_group_chat_deleted_response(tg_data, chat_id, EINA_FALSE);
3455 void leave_group_chat(tg_engine_data_s *tg_data, int group_chat_id)
3457 tgl_peer_id_t chat_id;
3458 chat_id.id = group_chat_id;
3459 chat_id.type = TGL_PEER_CHAT;
3461 tgl_peer_id_t self_id = tg_data->id;
3463 tgl_do_del_user_from_chat(s_info.TLS, chat_id, self_id, on_group_chat_delete_reponse, (void*)(group_chat_id));
3467 void on_new_msg_requested_chat_info_received(struct tgl_state *TLS, void *callback_extra, int success, struct tgl_chat *chat_info)
3469 tg_engine_data_s *tg_data;
3471 struct tgl_message *msg = callback_extra;
3478 if (!chat_info->user_list) {
3479 tgl_do_get_chat_info(TLS, chat_info->id, 0, &on_requested_chat_info_received, callback_extra);
3483 tg_data = TLS->callback_data;
3485 msg_table = get_table_name_from_number(chat_info->id.id);
3487 create_buddy_msg_table(msg_table);
3489 insert_chat_info_to_db(chat_info, NULL);
3490 struct tgl_photo *pic = &(chat_info->photo);
3492 tgl_do_load_photo(TLS, pic ,&on_chat_pic_loaded,chat_info);
3495 tgl_do_send_message(s_info.TLS, msg->to_id, msg->message, strlen(msg->message), &on_message_sent_to_buddy, (void*)(msg));
3497 char *type_of_change = strdup("add_user");
3498 tgl_do_get_chat_info(s_info.TLS, msg->to_id, 0, &on_group_chat_info_updated, type_of_change);
3504 void forward_message_to_buddy(int to_id, int type_of_chat, int from_id, int message_id, int temp_message_id)
3506 char *msg_table = get_table_name_from_number(from_id);
3507 struct tgl_message* msg = get_message_from_message_table(temp_message_id, msg_table);
3510 tgl_peer_id_t id_to_send;
3511 id_to_send.id = type_of_chat;
3512 tgl_do_forward_message(s_info.TLS, id_to_send, message_id, &on_message_sent_to_buddy, (void*)(msg));
3517 void send_typing_status_to_buddy(int buddy_id, int type_of_chat, int typing_status)
3519 tgl_peer_id_t id_to_send;
3520 id_to_send.id = type_of_chat;
3521 tgl_do_send_typing(s_info.TLS, id_to_send, typing_status, NULL, NULL);
3524 void send_message_to_buddy(int buddy_id, int message_id, int msg_type, char *msg_data, int type_of_chat)
3526 // get type of chat from buddy_id.
3527 char *msg_table = get_table_name_from_number(buddy_id);
3528 struct tgl_message* msg = get_message_from_message_table(message_id, msg_table);
3531 if (type_of_chat == TGL_PEER_USER) {
3532 msg->from_id.type = TGL_PEER_USER;
3533 msg->to_id.type = TGL_PEER_USER;
3534 tgl_do_send_message(s_info.TLS, msg->to_id, msg->message, strlen(msg->message), &on_message_sent_to_buddy, (void*)(msg));
3535 } else if (type_of_chat == TGL_PEER_CHAT) {
3536 msg->from_id.type = TGL_PEER_CHAT;
3537 msg->to_id.type = TGL_PEER_CHAT;
3539 Eina_Bool is_present_in_chat_db = is_user_present_chat_table(msg->to_id.id);
3540 if (!is_present_in_chat_db) {
3542 tgl_do_get_chat_info(s_info.TLS, msg->to_id, 0, &on_new_msg_requested_chat_info_received, msg);
3546 tgl_do_send_message(s_info.TLS, msg->to_id, msg->message, strlen(msg->message), &on_message_sent_to_buddy, (void*)(msg));
3547 } else if (type_of_chat == TGL_PEER_ENCR_CHAT) {
3556 void send_media_to_buddy(int buddy_id, int message_id, int media_id, int msg_type, char *file_path, int type_of_chat)
3558 char *msg_table = get_table_name_from_number(buddy_id);
3559 struct tgl_message* msg = get_message_from_message_table(message_id, msg_table);
3562 if (type_of_chat == TGL_PEER_USER) {
3564 msg->from_id.type = TGL_PEER_USER;
3565 msg->to_id.type = TGL_PEER_USER;
3567 if (msg->media.type == tgl_message_media_photo) {
3568 tgl_do_send_document(s_info.TLS, -1, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3569 } else if (msg->media.type == tgl_message_media_document) {
3570 char *extn = strrchr(file_path, '.');
3572 extn = replace(extn, '.', "");
3574 char *mime_type = NULL;;
3576 mime_type_get_mime_type(extn, &mime_type);
3579 if (strstr(mime_type, "video") != NULL) {
3581 char* thumb_path = get_video_thumb_path_from_db(media_id);
3582 tgl_do_send_video(s_info.TLS, -2, msg->to_id, file_path, thumb_path, &on_message_sent_to_buddy, (void*) (msg));
3587 } else if (strstr(mime_type, "audio") != NULL) {
3588 tgl_do_send_audio(s_info.TLS, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3592 } else if (msg->media.type == tgl_message_media_geo) {
3593 char *latitude = NULL;
3594 char *longitude = NULL;
3595 get_geo_location_from_db(media_id, &latitude, &longitude);
3596 if (latitude && longitude) {
3597 tgl_do_send_location(s_info.TLS, msg->to_id, strtod(latitude, NULL), strtod(longitude, NULL), &on_message_sent_to_buddy, (void*) (msg));
3599 } else if (msg->media.type == tgl_message_media_contact) {
3600 char *first_name = NULL;
3601 char *last_name = NULL;
3602 char *phone_num = NULL;
3603 get_contact_details_from_db(media_id, &first_name, &last_name, &phone_num);
3604 if (first_name && last_name && phone_num) {
3605 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));
3609 } else if (type_of_chat == TGL_PEER_CHAT) {
3610 msg->from_id.type = TGL_PEER_CHAT;
3611 msg->to_id.type = TGL_PEER_CHAT;
3613 if (msg->media.type == tgl_message_media_photo) {
3614 tgl_do_send_document(s_info.TLS, -1, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3615 } else if (msg->media.type == tgl_message_media_document) {
3618 char *extn = strrchr(file_path, '.');
3620 extn = replace(extn, '.', "");
3622 char *mime_type = NULL;;
3624 mime_type_get_mime_type(extn, &mime_type);
3627 if (strstr(mime_type, "video") != NULL) {
3629 char* thumb_path = get_video_thumb_path_from_db(media_id);
3630 tgl_do_send_video(s_info.TLS, -2, msg->to_id, file_path, thumb_path, &on_message_sent_to_buddy, (void*) (msg));
3635 } else if (strstr(mime_type, "audio") != NULL) {
3636 tgl_do_send_audio(s_info.TLS, msg->to_id, file_path, &on_message_sent_to_buddy, (void*) (msg));
3640 } else if (msg->media.type == tgl_message_media_geo) {
3641 char *latitude = NULL;
3642 char *longitude = NULL;
3643 get_geo_location_from_db(media_id, &latitude, &longitude);
3644 if (latitude && longitude) {
3645 tgl_do_send_location(s_info.TLS, msg->to_id, strtod(latitude, NULL), strtod(longitude, NULL), &on_message_sent_to_buddy, (void*) (msg));
3650 } else if (type_of_chat == TGL_PEER_ENCR_CHAT) {
3661 void check_type_sizes(void)
3663 if (sizeof(int) != 4u) {
3664 logprintf("sizeof(int) isn't equal 4.\n");
3667 if (sizeof(char) != 1u) {
3668 logprintf("sizeof(char) isn't equal 1.\n");
3673 int str_empty(char *str)
3675 return((str == NULL) ||(strlen(str) < 1));
3678 void parse_config(void)
3680 if (!s_info.disable_output) {
3681 //printf("libconfig not enabled\n");
3684 char *rsa_path = ui_utils_get_resource(DEFAULT_RSA_FILE_NAME);
3685 tasprintf(&s_info.rsa_file_name, "%s", rsa_path);
3686 tasprintf(&s_info.config_full_path, "%s%s", DEFAULT_TELEGRAM_PATH, CONFIG_DIRECTORY);
3687 struct stat st = { 0 };
3688 if (stat(s_info.config_full_path, &st) == -1) {
3689 mkdir(s_info.config_full_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
3692 if (remove(s_info.rsa_file_name) == 0) {
3693 //printf("File successfully deleted\n");
3696 tasprintf(&s_info.downloads_directory, "%s%s/%s", DEFAULT_TELEGRAM_PATH, CONFIG_DIRECTORY, DOWNLOADS_DIRECTORY);
3698 if (s_info.binlog_enabled) {
3699 tasprintf(&s_info.binlog_file_name, "%s%s/%s", DEFAULT_TELEGRAM_PATH, CONFIG_DIRECTORY, BINLOG_FILE);
3700 tgl_set_binlog_mode(s_info.TLS, 1);
3701 tgl_set_binlog_path(s_info.TLS, s_info.binlog_file_name);
3703 tgl_set_binlog_mode(s_info.TLS, 0);
3704 //tgl_set_auth_file_path(auth_file_name;
3705 tasprintf(&s_info.auth_file_name, "%s%s/%s", DEFAULT_TELEGRAM_PATH, CONFIG_DIRECTORY, AUTH_KEY_FILE);
3706 tasprintf(&s_info.state_file_name, "%s%s/%s", DEFAULT_TELEGRAM_PATH, CONFIG_DIRECTORY, STATE_FILE);
3707 tasprintf(&s_info.secret_chat_file_name, "%s%s/%s", DEFAULT_TELEGRAM_PATH, CONFIG_DIRECTORY, SECRET_CHAT_FILE);
3709 tgl_set_download_directory(s_info.TLS, s_info.downloads_directory);
3710 if (!mkdir(s_info.downloads_directory, CONFIG_DIRECTORY_MODE)) {
3711 if (!s_info.disable_output) {
3712 //printf("[%s] created\n", downloads_directory);
3717 void running_for_first_time(void)
3720 if (!str_empty(s_info.config_filename)) {
3721 return; // Do not create custom config file
3724 if (str_empty(s_info.config_directory)) {
3725 s_info.config_directory = strdup(DEFAULT_TELEGRAM_PATH); // specific path for tizen application.
3728 struct stat st = {0};
3729 if (stat(s_info.config_directory, &st) == -1) {
3730 mkdir(s_info.config_directory, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
3733 tasprintf(&s_info.config_filename, "%s%s", s_info.config_directory, CONFIG_FILE);
3736 // see if config file is there
3737 if (access(s_info.config_filename, R_OK) != 0) {
3738 // config file missing, so touch it
3739 config_file_fd = open(s_info.config_filename, O_CREAT | O_RDWR, 0600);
3740 if (config_file_fd == -1) {
3741 perror("open[config_file]");
3742 //printf("I: config_file=[%s]\n", config_filename);
3745 if (write(config_file_fd, DEFAULT_CONFIG_CONTENTS, strlen(DEFAULT_CONFIG_CONTENTS)) <= 0) {
3746 perror("write[config_file]");
3749 close(config_file_fd);
3753 void init_tl_engine(void *cbdata)
3755 s_info.TLS = tgl_state_alloc();
3759 * Unable to allocate the TGL State info.
3764 running_for_first_time();
3768 tgl_set_rsa_key(s_info.TLS, s_info.rsa_file_name);
3769 tgl_set_callback(s_info.TLS, &upd_cb, cbdata);
3770 tgl_set_net_methods(s_info.TLS, &tgl_conn_methods);
3771 tgl_set_timer_methods(s_info.TLS, &tgl_libevent_timers);
3772 assert(s_info.TLS->timer_methods);
3773 tgl_set_download_directory(s_info.TLS, tgl_engine_get_downloads_directory());
3774 tgl_register_app_id(s_info.TLS, TELEGRAM_CLI_APP_ID, TELEGRAM_CLI_APP_HASH);
3775 tgl_set_app_version(s_info.TLS, "Telegram-cli " TELEGRAM_CLI_VERSION);
3776 if (s_info.ipv6_enabled) {
3777 tgl_enable_ipv6(s_info.TLS);
3779 tgl_init(s_info.TLS);
3781 if (s_info.binlog_enabled) {
3782 double t = tglt_get_double_time();
3783 if (s_info.verbosity >= E_DEBUG) {
3784 logprintf("replay log start\n");
3786 tgl_replay_log(s_info.TLS);
3787 if (s_info.verbosity >= E_DEBUG) {
3788 logprintf("replay log end in %lf seconds\n", tglt_get_double_time() - t);
3790 tgl_reopen_binlog_for_writing(s_info.TLS);
3794 read_secret_chat_file();
3798 void tgl_engine_destroy_TLS(void)
3804 tgl_state_free(tgl_engine_get_TLS());
3808 struct tgl_state *tgl_engine_get_TLS(void)