@@ -9,14 +9,16 @@ use crate::config::Config;
99use crate :: constants:: Blocked ;
1010use crate :: contact:: ContactId ;
1111use crate :: context:: Context ;
12- use crate :: log:: LogExt ;
13- use crate :: log:: warn;
12+ use crate :: events:: EventType ;
13+ use crate :: log:: { LogExt as _, warn} ;
14+ use crate :: login_param:: EnteredLoginParam ;
1415use crate :: message:: { Message , MsgId , Viewtype } ;
1516use crate :: mimeparser:: SystemMessage ;
1617use crate :: param:: Param ;
1718use crate :: sync:: SyncData :: { AddQrToken , AlterChat , DeleteQrToken } ;
1819use crate :: token:: Namespace ;
1920use crate :: tools:: time;
21+ use crate :: transport:: { ConfiguredLoginParamJson , save_transport} ;
2022use crate :: { message, stock_str, token} ;
2123use std:: collections:: HashSet ;
2224
@@ -52,6 +54,29 @@ pub(crate) struct QrTokenData {
5254 pub ( crate ) grpid : Option < String > ,
5355}
5456
57+ #[ derive( Debug , Serialize , Deserialize ) ]
58+ pub ( crate ) struct TransportData {
59+ /// Configured login parameters.
60+ pub ( crate ) configured : ConfiguredLoginParamJson ,
61+
62+ /// Login parameters entered by the user.
63+ ///
64+ /// They can be used to reconfigure the transport.
65+ pub ( crate ) entered : EnteredLoginParam ,
66+
67+ /// Timestamp of when the transport was last time (re)configured.
68+ pub ( crate ) timestamp : i64 ,
69+ }
70+
71+ #[ derive( Debug , Serialize , Deserialize ) ]
72+ pub ( crate ) struct RemovedTransportData {
73+ /// Address of the removed transport.
74+ pub ( crate ) addr : String ,
75+
76+ /// Timestamp of when the transport was removed.
77+ pub ( crate ) timestamp : i64 ,
78+ }
79+
5580#[ derive( Debug , Serialize , Deserialize ) ]
5681pub ( crate ) enum SyncData {
5782 AddQrToken ( QrTokenData ) ,
@@ -71,6 +96,28 @@ pub(crate) enum SyncData {
7196 DeleteMessages {
7297 msgs : Vec < String > , // RFC724 id (i.e. "Message-Id" header)
7398 } ,
99+
100+ /// Update transport configuration.
101+ ///
102+ /// This message contains a list of all added transports
103+ /// together with their addition timestamp,
104+ /// and all removed transports together with
105+ /// the removal timestamp.
106+ ///
107+ /// In case of a tie, addition and removal timestamps
108+ /// being the same, removal wins.
109+ /// It is more likely that transport is added
110+ /// and then removed within a second,
111+ /// but unlikely the other way round
112+ /// as adding new transport takes time
113+ /// to run configuration.
114+ Transports {
115+ /// Active transports.
116+ transports : Vec < TransportData > ,
117+
118+ /// Removed transports with the timestamp of removal.
119+ removed_transports : Vec < RemovedTransportData > ,
120+ } ,
74121}
75122
76123#[ derive( Debug , Serialize , Deserialize ) ]
@@ -274,6 +321,10 @@ impl Context {
274321 SyncData :: Config { key, val } => self . sync_config ( key, val) . await ,
275322 SyncData :: SaveMessage { src, dest } => self . save_message ( src, dest) . await ,
276323 SyncData :: DeleteMessages { msgs } => self . sync_message_deletion ( msgs) . await ,
324+ SyncData :: Transports {
325+ transports,
326+ removed_transports,
327+ } => self . sync_transports ( transports, removed_transports) . await ,
277328 } ,
278329 SyncDataOrUnknown :: Unknown ( data) => {
279330 warn ! ( self , "Ignored unknown sync item: {data}." ) ;
@@ -347,6 +398,46 @@ impl Context {
347398 message:: delete_msgs_locally_done ( self , & msg_ids, modified_chat_ids) . await ?;
348399 Ok ( ( ) )
349400 }
401+
402+ /// Process received data for transport synchronization.
403+ async fn sync_transports (
404+ & self ,
405+ transports : & [ TransportData ] ,
406+ removed_transports : & [ RemovedTransportData ] ,
407+ ) -> Result < ( ) > {
408+ for TransportData {
409+ configured,
410+ entered,
411+ timestamp,
412+ } in transports
413+ {
414+ save_transport ( self , entered, configured, * timestamp) . await ?;
415+ }
416+
417+ self . sql
418+ . transaction ( |transaction| {
419+ for RemovedTransportData { addr, timestamp } in removed_transports {
420+ transaction. execute (
421+ "DELETE FROM transports
422+ WHERE addr=? AND add_timestamp<=?" ,
423+ ( addr, timestamp) ,
424+ ) ?;
425+ transaction. execute (
426+ "INSERT INTO removed_transports (addr, remove_timestamp)
427+ VALUES (?, ?)
428+ ON CONFLICT (addr) DO
429+ UPDATE SET remove_timestamp = excluded.remove_timestamp
430+ WHERE excluded.remove_timestamp > remove_timestamp" ,
431+ ( addr, timestamp) ,
432+ ) ?;
433+ }
434+ Ok ( ( ) )
435+ } )
436+ . await ?;
437+
438+ self . emit_event ( EventType :: TransportsModified ) ;
439+ Ok ( ( ) )
440+ }
350441}
351442
352443#[ cfg( test) ]
0 commit comments