Diff
Not logged in

Differences From Artifact [f8c8f60eb7]:

To Artifact [29803d5215]:


     1      1   // Copyright 2016 MaidSafe.net limited.
     2      2   //
     3      3   // This SAFE Network Software is licensed to you under (1) the MaidSafe.net Commercial License,
     4      4   // version 1.0 or later, or (2) The General Public License (GPL), version 3, depending on which
     5      5   // licence you accepted on initial access to the Software (the "Licences").
     6      6   //
     7      7   // By contributing code to the SAFE Network Software, or to this project generally, you agree to be
     8         -// bound by the terms of the MaidSafe Contributor Agreement, version 1.0.  This, along with the
     9         -// Licenses can be found in the root directory of this project at LICENSE, COPYING and CONTRIBUTOR.
            8  +// bound by the terms of the MaidSafe Contributor Agreement.  This, along with the Licenses can be
            9  +// found in the root directory of this project at LICENSE, COPYING and CONTRIBUTOR.
    10     10   //
    11     11   // Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed
    12     12   // under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    13     13   // KIND, either express or implied.
    14     14   //
    15     15   // Please review the Licences for the specific language governing permissions and limitations
    16     16   // relating to use of the SAFE Network Software.
    17     17   
    18     18   //! Session management
    19     19   
           20  +use super::errors::FfiError;
           21  +use super::helper;
    20     22   use core::client::Client;
    21     23   use core::translated_events::NetworkEvent;
    22     24   use libc::{int32_t, int64_t};
    23     25   use maidsafe_utilities::thread::{self, Joiner};
    24     26   use nfs::metadata::directory_key::DirectoryKey;
    25     27   use std::ptr;
    26     28   use std::sync::{Arc, Mutex};
    27     29   use std::sync::mpsc::{self, Sender};
    28         -use super::errors::FfiError;
    29         -use super::helper;
    30     30   
    31     31   /// Represents user session on the SAFE network. There should be one session per launcher.
           32  +#[cfg_attr(feature="cargo-clippy", allow(type_complexity))]
    32     33   pub struct Session {
    33     34       client: Arc<Mutex<Client>>,
    34     35       safe_drive_dir_key: Option<DirectoryKey>,
    35     36   
    36     37       network_event_observers: Arc<Mutex<Vec<extern "C" fn(i32)>>>,
    37     38       network_thread: Option<(Sender<NetworkEvent>, Joiner)>,
    38     39   }
    39     40   
    40     41   impl Session {
    41     42       /// Create unregistered client.
    42     43       pub fn create_unregistered_client() -> Result<Self, FfiError> {
    43         -        let client = try!(Client::create_unregistered_client());
           44  +        let client = Client::create_unregistered_client()?;
    44     45           let client = Arc::new(Mutex::new(client));
    45     46   
    46     47           Ok(Session {
    47         -            client: client,
    48         -            safe_drive_dir_key: None,
    49         -            network_event_observers: Default::default(),
    50         -            network_thread: None,
    51         -        })
           48  +               client: client,
           49  +               safe_drive_dir_key: None,
           50  +               network_event_observers: Default::default(),
           51  +               network_thread: None,
           52  +           })
    52     53       }
    53     54   
    54     55       /// Create new account.
    55         -    pub fn create_account(locator: &str, password: &str) -> Result<Self, FfiError> {
    56         -        let client = try!(Client::create_account(locator, password));
           56  +    pub fn create_account(locator: &str,
           57  +                          password: &str,
           58  +                          invitation: &str)
           59  +                          -> Result<Self, FfiError> {
           60  +        let client = Client::create_account(locator, password, invitation)?;
    57     61           let client = Arc::new(Mutex::new(client));
    58     62   
    59         -        let safe_drive_dir_key = try!(helper::get_safe_drive_key(client.clone()));
           63  +        let safe_drive_dir_key = helper::get_safe_drive_key(client.clone())?;
    60     64   
    61     65           Ok(Session {
    62         -            client: client,
    63         -            safe_drive_dir_key: Some(safe_drive_dir_key),
    64         -            network_event_observers: Default::default(),
    65         -            network_thread: None,
    66         -        })
           66  +               client: client,
           67  +               safe_drive_dir_key: Some(safe_drive_dir_key),
           68  +               network_event_observers: Default::default(),
           69  +               network_thread: None,
           70  +           })
    67     71       }
    68     72   
    69     73       /// Log in to existing account.
    70     74       pub fn log_in(locator: &str, password: &str) -> Result<Self, FfiError> {
    71         -        let client = try!(Client::log_in(locator, password));
           75  +        let client = Client::log_in(locator, password)?;
    72     76           let client = Arc::new(Mutex::new(client));
    73     77   
    74         -        let safe_drive_dir_key = try!(helper::get_safe_drive_key(client.clone()));
           78  +        let safe_drive_dir_key = helper::get_safe_drive_key(client.clone())?;
    75     79   
    76     80           Ok(Session {
    77         -            client: client,
    78         -            safe_drive_dir_key: Some(safe_drive_dir_key),
    79         -            network_event_observers: Default::default(),
    80         -            network_thread: None,
    81         -        })
           81  +               client: client,
           82  +               safe_drive_dir_key: Some(safe_drive_dir_key),
           83  +               network_event_observers: Default::default(),
           84  +               network_thread: None,
           85  +           })
    82     86       }
    83     87   
    84     88       /// Get the client.
    85     89       pub fn get_client(&self) -> Arc<Mutex<Client>> {
    86     90           self.client.clone()
    87     91       }
    88     92   
................................................................................
    97    101           if self.network_thread.is_none() {
    98    102               let callbacks = self.network_event_observers.clone();
    99    103   
   100    104               let (tx, rx) = mpsc::channel();
   101    105               let cloned_tx = tx.clone();
   102    106               unwrap!(self.client.lock()).add_network_event_observer(tx);
   103    107   
   104         -            let joiner = thread::named("FfiNetworkEventObserver", move || {
   105         -                while let Ok(event) = rx.recv() {
   106         -                    if let NetworkEvent::Terminated = event {
   107         -                        trace!("FFI exiting the network event notifier thread.");
   108         -                        break;
   109         -                    }
          108  +            let joiner = thread::named("FfiNetworkEventObserver",
          109  +                                       move || while let Ok(event) = rx.recv() {
          110  +                                           if let NetworkEvent::Terminated = event {
          111  +                                               trace!("FFI exiting the network event notifier /
          112  +                                                       thread.");
          113  +                                               break;
          114  +                                           }
   110    115   
   111         -                    let callbacks = &*unwrap!(callbacks.lock());
   112         -                    info!("Informing {:?} to {} FFI network event observers.",
   113         -                          event,
   114         -                          callbacks.len());
   115         -                    let event_ffi_val = event.into();
          116  +                                           let callbacks = &*unwrap!(callbacks.lock());
          117  +                                           info!("Informing {:?} to {} FFI network event /
          118  +                                                  observers.",
          119  +                                                 event,
          120  +                                                 callbacks.len());
          121  +                                           let event_ffi_val = event.into();
   116    122   
   117         -                    for cb in callbacks {
   118         -                        cb(event_ffi_val);
   119         -                    }
   120         -                }
   121         -            });
          123  +                                           for cb in callbacks {
          124  +                                               cb(event_ffi_val);
          125  +                                           }
          126  +                                       });
   122    127   
   123    128               self.network_thread = Some((cloned_tx, joiner));
   124    129           }
   125    130       }
   126    131   
   127    132       fn get_account_info(&self) -> Result<(u64, u64), FfiError> {
   128    133           let mut client = unwrap!(self.client.lock());
   129         -        let getter = try!(client.get_account_info(None));
   130         -        Ok(try!(getter.get()))
          134  +        let getter = client.get_account_info(None)?;
          135  +        Ok(getter.get()?)
   131    136       }
   132    137   }
   133    138   
   134    139   impl Drop for Session {
   135    140       fn drop(&mut self) {
   136    141           debug!("Session is now being dropped.");
   137    142   
................................................................................
   146    151   
   147    152   /// Create a session as an unregistered client. This or any one of the other companion functions to
   148    153   /// get a session must be called before initiating any operation allowed by this crate.
   149    154   #[no_mangle]
   150    155   pub unsafe extern "C" fn create_unregistered_client(session_handle: *mut *mut SessionHandle)
   151    156                                                       -> int32_t {
   152    157       helper::catch_unwind_i32(|| {
   153         -        trace!("FFI create unregistered client.");
          158  +                                 trace!("FFI create unregistered client.");
   154    159   
   155         -        let session = ffi_try!(Session::create_unregistered_client());
   156         -        *session_handle = allocate_handle(session);
   157         -        0
   158         -    })
          160  +                                 let session = ffi_try!(Session::create_unregistered_client());
          161  +                                 *session_handle = allocate_handle(session);
          162  +                                 0
          163  +                             })
   159    164   }
   160    165   
   161    166   /// Create a registered client. This or any one of the other companion functions to get a
   162    167   /// session must be called before initiating any operation allowed by this crate. `session_handle`
   163    168   /// is a pointer to a pointer and must point to a valid pointer not junk, else the consequences are
   164    169   /// undefined.
   165    170   #[no_mangle]
   166    171   pub unsafe extern "C" fn create_account(account_locator: *const u8,
   167    172                                           account_locator_len: usize,
   168    173                                           account_password: *const u8,
   169    174                                           account_password_len: usize,
          175  +                                        invitation: *const u8,
          176  +                                        invitation_len: usize,
   170    177                                           session_handle: *mut *mut SessionHandle)
   171    178                                           -> int32_t {
   172    179       helper::catch_unwind_i32(|| {
   173    180           trace!("FFI create a client account.");
   174    181   
   175    182           let acc_locator = ffi_try!(helper::c_utf8_to_str(account_locator, account_locator_len));
   176    183           let acc_password = ffi_try!(helper::c_utf8_to_str(account_password, account_password_len));
   177         -        let session = ffi_try!(Session::create_account(acc_locator, acc_password));
          184  +        let invitation = ffi_try!(helper::c_utf8_to_str(invitation, invitation_len));
          185  +        let session = ffi_try!(Session::create_account(acc_locator, acc_password, invitation));
   178    186   
   179    187           *session_handle = allocate_handle(session);
   180    188           0
   181    189       })
   182    190   }
   183    191   
   184    192   /// Log into a registered client. This or any one of the other companion functions to get a
................................................................................
   207    215   /// Register an observer to network events like Connected, Disconnected etc. as provided by the
   208    216   /// core module
   209    217   #[no_mangle]
   210    218   pub unsafe extern "C" fn register_network_event_observer(session_handle: *mut SessionHandle,
   211    219                                                            callback: extern "C" fn(i32))
   212    220                                                            -> int32_t {
   213    221       helper::catch_unwind_i32(|| {
   214         -        trace!("FFI register a network event observer.");
   215         -        unwrap!((*session_handle).lock()).register_network_event_observer(callback);
   216         -        0
   217         -    })
          222  +                                 trace!("FFI register a network event observer.");
          223  +                                 unwrap!((*session_handle).lock())
          224  +                                     .register_network_event_observer(callback);
          225  +                                 0
          226  +                             })
   218    227   }
   219    228   
   220    229   
   221    230   /// Return the amount of calls that were done to `get`
   222    231   #[no_mangle]
   223    232   pub unsafe extern "C" fn client_issued_gets(session_handle: *const SessionHandle) -> int64_t {
   224    233       helper::catch_unwind_i64(|| {
   225         -        trace!("FFI retrieve client issued GETs.");
   226         -        let session = unwrap!((*session_handle).lock());
   227         -        let client = unwrap!(session.client.lock());
   228         -        client.issued_gets() as int64_t
   229         -    })
          234  +                                 trace!("FFI retrieve client issued GETs.");
          235  +                                 let session = unwrap!((*session_handle).lock());
          236  +                                 let client = unwrap!(session.client.lock());
          237  +                                 client.issued_gets() as int64_t
          238  +                             })
   230    239   }
   231    240   
   232    241   /// Return the amount of calls that were done to `put`
   233    242   #[no_mangle]
   234    243   pub unsafe extern "C" fn client_issued_puts(session_handle: *const SessionHandle) -> int64_t {
   235    244       helper::catch_unwind_i64(|| {
   236         -        trace!("FFI retrieve client issued PUTs.");
   237         -        let session = unwrap!((*session_handle).lock());
   238         -        let client = unwrap!(session.client.lock());
   239         -        client.issued_puts() as int64_t
   240         -    })
          245  +                                 trace!("FFI retrieve client issued PUTs.");
          246  +                                 let session = unwrap!((*session_handle).lock());
          247  +                                 let client = unwrap!(session.client.lock());
          248  +                                 client.issued_puts() as int64_t
          249  +                             })
   241    250   }
   242    251   
   243    252   /// Return the amount of calls that were done to `post`
   244    253   #[no_mangle]
   245    254   pub unsafe extern "C" fn client_issued_posts(session_handle: *const SessionHandle) -> int64_t {
   246    255       helper::catch_unwind_i64(|| {
   247         -        trace!("FFI retrieve client issued POSTs.");
   248         -        let session = unwrap!((*session_handle).lock());
   249         -        let client = unwrap!(session.client.lock());
   250         -        client.issued_posts() as int64_t
   251         -    })
          256  +                                 trace!("FFI retrieve client issued POSTs.");
          257  +                                 let session = unwrap!((*session_handle).lock());
          258  +                                 let client = unwrap!(session.client.lock());
          259  +                                 client.issued_posts() as int64_t
          260  +                             })
   252    261   }
   253    262   
   254    263   /// Return the amount of calls that were done to `delete`
   255    264   #[no_mangle]
   256    265   pub unsafe extern "C" fn client_issued_deletes(session_handle: *const SessionHandle) -> int64_t {
   257    266       helper::catch_unwind_i64(|| {
   258         -        trace!("FFI retrieve client issued DELETEs.");
   259         -        let session = unwrap!((*session_handle).lock());
   260         -        let client = unwrap!(session.client.lock());
   261         -        client.issued_deletes() as int64_t
   262         -    })
          267  +                                 trace!("FFI retrieve client issued DELETEs.");
          268  +                                 let session = unwrap!((*session_handle).lock());
          269  +                                 let client = unwrap!(session.client.lock());
          270  +                                 client.issued_deletes() as int64_t
          271  +                             })
   263    272   }
   264    273   
   265    274   /// Return the amount of calls that were done to `append`
   266    275   #[no_mangle]
   267    276   pub unsafe extern "C" fn client_issued_appends(session_handle: *const SessionHandle) -> int64_t {
   268    277       helper::catch_unwind_i64(|| {
   269         -        trace!("FFI retrieve client issued APPENDs.");
   270         -        let session = unwrap!((*session_handle).lock());
   271         -        let client = unwrap!(session.client.lock());
   272         -        client.issued_appends() as int64_t
   273         -    })
          278  +                                 trace!("FFI retrieve client issued APPENDs.");
          279  +                                 let session = unwrap!((*session_handle).lock());
          280  +                                 let client = unwrap!(session.client.lock());
          281  +                                 client.issued_appends() as int64_t
          282  +                             })
   274    283   }
   275    284   
   276    285   /// Get data from the network. This is non-blocking. `data_stored` means number
   277    286   /// of chunks Put. `space_available` means number of chunks which can still be
   278    287   /// Put.
   279    288   #[no_mangle]
   280    289   pub unsafe extern "C" fn get_account_info(session_handle: *const SessionHandle,
................................................................................
   304    313   
   305    314   unsafe fn allocate_handle(session: Session) -> *mut SessionHandle {
   306    315       Box::into_raw(Box::new(Arc::new(Mutex::new(session))))
   307    316   }
   308    317   
   309    318   #[cfg(test)]
   310    319   mod test {
          320  +    use super::*;
   311    321       use ffi::test_utils;
   312    322       use std::ptr;
   313         -    use super::*;
   314    323   
   315    324       #[test]
   316    325       fn create_account_and_log_in() {
   317    326           let acc_locator = test_utils::generate_random_cstring(10);
   318    327           let acc_password = test_utils::generate_random_cstring(10);
          328  +        let invitation = test_utils::generate_random_cstring(10);
   319    329   
   320    330           {
   321    331               let mut session_handle: *mut SessionHandle = ptr::null_mut();
   322    332   
   323    333               unsafe {
   324    334                   let session_handle_ptr = &mut session_handle;
   325    335   
   326    336                   assert_eq!(create_account(acc_locator.as_ptr() as *const u8,
   327    337                                             10,
   328    338                                             acc_password.as_ptr() as *const u8,
          339  +                                          10,
          340  +                                          invitation.as_ptr() as *const u8,
   329    341                                             10,
   330    342                                             session_handle_ptr),
   331    343                              0);
   332    344               }
   333    345   
   334    346               assert!(!session_handle.is_null());
   335    347               unsafe { drop_session(session_handle) };