diff --git a/README.md b/README.md
index 2b26e10e..11807a61 100644
--- a/README.md
+++ b/README.md
@@ -12,8 +12,8 @@ A [PJSIP](http://www.pjsip.org/) module for React Native.
## Installation
-- [iOS](https://github.com/datso/react-native-pjsip/blob/master/docs/installation_ios.md)
-- [Android](https://github.com/datso/react-native-pjsip/blob/master/docs/installation_android.md)
+- [iOS](/wiki/installation_ios.md)
+- [Android](/wiki/installation_android.md)
## Usage
@@ -92,10 +92,10 @@ endpoint.addListener("call_terminated", (newCall) => {
## API
-1. [Startup](https://github.com/datso/react-native-pjsip/blob/master/docs/startup.md)
-2. [Accounts](https://github.com/datso/react-native-pjsip/blob/master/docs/accounts.md)
-3. [Calls](https://github.com/datso/react-native-pjsip/blob/master/docs/calls.md)
-4. [Settings](https://github.com/datso/react-native-pjsip/blob/master/docs/settings.md)
+1. [Startup](/wiki/startup.md)
+2. [Accounts](/wiki/accounts.md)
+3. [Calls](/wiki/calls.md)
+4. [Settings](/wiki/settings.md)
## Demo
The demo project is https://github.com/datso/react-native-pjsip-app. And you will need a SIP server.
diff --git a/wiki/accounts.md b/wiki/accounts.md
new file mode 100644
index 00000000..d50b484f
--- /dev/null
+++ b/wiki/accounts.md
@@ -0,0 +1,80 @@
+
+# Events
+
+All interaction from javascript to pjsip module is asynchromius.
+So for each action, promise will be returned.
+
+# Create account
+
+```
+let configuration = {
+ "name": "John",
+ "username": "sip_username",
+ "domain": "pbx.carusto.com",
+ "password": "****",
+ "proxy": null,
+ "transport": null, // Default TCP
+ "regServer": null, // Default wildcard
+ "regTimeout": null // Default 3600
+ "regHeaders": {
+ "X-Custom-Header": "Value"
+ },
+ "regContactParams": ";unique-device-token-id=XXXXXXXXX",
+ "regOnAdd": false, // Default true, use false for manual REGISTRATION
+};
+
+let endpoint = new Endpoint();
+let state = await endpoint.start();
+let account = await endpoint.createAccont(configuration);
+
+// Do smth with account. For example wait until registration complete and make a call.
+```
+
+* There is no change account method. But this functionality is easy to implement by calling delete and create account methods.
+
+
+# Remove account
+
+TODO: Description
+
+```
+let account = ...;
+await endpoint.deleteAccont(account);
+
+await endpoint.deleteAccont(account); // There should be exception, bcs account already removed.
+```
+
+
+# Events
+
+
+## registration_changed
+
+TODO: Answer how much times it will be executed during lifetime, with examples.
+
+```
+
+```
+
+
+Example: Forbidden
+
+Example: Invalid host
+
+
+
+.then((account) => {
+ console.log("Account: ", account);
+
+ setTimeout(() => {
+ endpoint.registerAccount(account, true);
+ }, 10000);
+
+ setTimeout(() => {
+ endpoint.registerAccount(account, false);
+ }, 20000);
+ });
+
+
+
+
diff --git a/wiki/android_notification_example.png b/wiki/android_notification_example.png
new file mode 100644
index 00000000..77a3e29f
Binary files /dev/null and b/wiki/android_notification_example.png differ
diff --git a/wiki/android_sip_background.md b/wiki/android_sip_background.md
new file mode 100644
index 00000000..b3fa4f03
--- /dev/null
+++ b/wiki/android_sip_background.md
@@ -0,0 +1,79 @@
+# Android background service
+
+In order to accept incoming calls while applicaiton in background you should set `notifications` property to `true` (true by default).
+This will make PJSIP service run in the *foreground*, supplying the ongoing notification to be shown to the user while in this state.
+Without foreground notification, Android could kill PJSIP service to reclaim more memory.
+
+
+
+```javascript
+let configuration = {
+ service: {
+ ua: Platform.select({ios: "Reachify iOS", android: "Reachify Android"}), // Default: React Native PjSip (version)
+ notifications: true, // Creates peding notification that will allow service work while your app in background
+ notifications: false, // Disables pending notification
+ notifications: {
+ account: true,
+ call: false // Disables only call notification
+ },
+ notifications: {
+ account: {
+ title: "My cool react native app", // Default: account name
+ text: "Here we go", // Default: account registration status
+ info: null,
+ ticker: null,
+ smallIcon: null,
+ largeIcon: null
+ },
+ call: {
+ title: "Active call", // Default: "Call in Progress - %Account Name%"
+ text: "John Doe", // Default: "%Caller Name% (%Number%)"
+ info: null,
+ ticker: null, // Default: "Call in Progress"
+ smallIcon: "icon_call", // Default: R.drawable.stat_sys_phone_call
+ largeIcon: null
+ }
+ }
+ },
+ network: {
+ useAnyway: false, // Default: true
+ useWifi: true, // Default: true
+ use3g: true, // Default: false
+ useEdge: false, // Default: false
+ useGprs: false, // Default: false
+ useInRoaming: false, // Default: false
+ useOtherNetworks: true // Default: false
+ }
+};
+let endpoint = new Endpoint();
+let state = await endpoint.start(configuration);
+// ...
+```
+
+### smallIcon & largeIcon
+To use own images for nofitications, copy them into `android/app/src/main/res/mipmap-XXXX/` and set thier names into `smallIcon` and `largeIcon` without extension.
+For more info: [ui_guidelines/icon_design_status_bar](https://developer.android.com/guide/practices/ui_guidelines/icon_design_status_bar.html)
+
+### Handle clicks to call notifications
+
+Typically you should contain code that will change "route" in react-native app depending on result of `endpoint.start` command
+```javascript
+let state = await endpoint.start(configuration);
+let calls = state.calls; // A list of active calls
+
+if (state.hasOwnProperty("notificationCallId")) {
+ for (let c of calls) {
+ if (c.getId() == state['notificationCallId']) {
+ route = {name:'call', call: c};
+ break;
+ }
+ }
+}
+
+//...
+
+// If true you should use slider instead of buttons for incoming call, because device was in sleep when this call comes.
+if (state.notificationIsFromForeground) {
+ //...
+}
+```
diff --git a/wiki/calls.md b/wiki/calls.md
new file mode 100644
index 00000000..f7d54d67
--- /dev/null
+++ b/wiki/calls.md
@@ -0,0 +1,122 @@
+TODO: Introduction + links to other sections.
+
+# Events
+
+All interaction from javascript to pjsip module is asynchronous.
+So for each action, promise will be returned.
+
+## call_received
+
+TODO: Description
+
+## call_changed
+
+TODO: Description
+
+## call_terminated
+
+TODO: Description
+
+
+# Actions
+
+## Initiate a call
+To be able to make a call first of all you should createAccount, and pass account instance into Endpoint.makeCall function.
+This function will return a promise that will be resolved when PjSIP initializes the call.
+
+```
+let options = {
+ headers: {
+ "P-Assserted-Identity": "Header example",
+ "X-UA": "React native"
+ }
+}
+
+let call = await endpoint.makeCall(account, destination, options);
+call.getId() // Use this id to detect changes and make actions
+
+endpoint.addListener("call_changed", (newCall) => {
+ if (call.getId() === newCall.getId()) {
+ // Our call changed, do smth.
+ }
+}
+endpoint.addListener("call_terminated", (newCall) => {
+ if (call.getId() === newCall.getId()) {
+ // Our call terminated
+ }
+}
+```
+
+## Answer the call
+
+After answer there will be event "call_changed" that reflect the changes.
+If there is already active call, it will be placed on hold (so expect "call_changed" event)
+
+```
+let options = {};
+let call = ...;
+let promise = endpoint.answerCall(call, options);
+promise.then(() => {
+ // Answer complete, expect that "call_changed" will be fired.
+}));
+
+promise.catch(() => {
+ // Answer failed, show error
+});
+```
+
+## Hangup
+Use this function when you have active call, and Decline for unanswered incoming calls.
+After successul hangup, Endpoint should fire "call_terminated" event, use it to how final call duration and status.
+
+```
+let options = {};
+let call = ...;
+await endpoint.hangupCall(call, options);
+```
+
+## Decline
+Use this function when you have unanswered incoming call.
+After successul decline, Endpoint should fire "call_terminated" event.
+
+```
+let options = {};
+let call = ...;
+await endpoint.declineCall(call, options);
+```
+
+## Hold/Unhold
+
+TODO: Description
+After successul hold/unhold, Endpoint should fire "call_changed" event, where `isHeld` should be false or true.
+
+```
+let options = {};
+let call = ...;
+
+await endpoint.holdCall(call, options);
+await endpoint.unholdCall(call, options);
+```
+
+## Transfer
+
+TODO: Description
+
+```
+let options = {};
+let call = ...;
+
+await endpoint.xferCall(call, destination, options);
+```
+
+## DTMF
+
+TODO: Description
+
+```
+let options = {};
+let call = ...;
+let key = "3";
+
+await endpoint.dtmfCall(call, key, options);
+```
diff --git a/wiki/installation_android.md b/wiki/installation_android.md
new file mode 100644
index 00000000..ca9e94e4
--- /dev/null
+++ b/wiki/installation_android.md
@@ -0,0 +1,62 @@
+# Android installation
+
+## Step 1
+Add permissions & service to `android/app/src/main/AndroidManifest.xml`
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```xml
+
+ ...
+
+ ...
+
+```
+
+## Step 2
+```bash
+react-native link
+```
+
+## Additional step: Ability to answer incoming call without Lock Screen
+
+In `android/app/src/main/java/com/xxx/MainActivity.java`
+
+```java
+import android.view.Window;
+import android.view.WindowManager;
+import android.os.Bundle;
+...
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Window w = getWindow();
+ w.setFlags(
+ WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
+ WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+ );
+ }
+```
+
+## If Android targetSdk >= 23
+
+If your Android targetSdk is 23 or above you should grant `android.permission.RECORD_AUDIO` at runtime before making/receiving an audio call.
+
+To check and request Android permissions, please check out [react-native-android-permissions](https://github.com/lucasferreira/react-native-android-permissions).
diff --git a/wiki/installation_ios.md b/wiki/installation_ios.md
new file mode 100644
index 00000000..9269e1d4
--- /dev/null
+++ b/wiki/installation_ios.md
@@ -0,0 +1,66 @@
+# iOS installation
+
+## Step 1
+Link library
+
+```bash
+react-native link
+```
+
+## Step 2
+Open project in xcode.
+1. In the project build settings, make sure you have enabled All settings to be visible.
+2. The Build Options are the 4th section down. Select *No* for the Enable Bitcode option.
+
+## Step 3
+Add permissions and capabilities to use microphone and camera by adding following lines to `ios/%PROJECT_NAME%/Info.plist`
+
+```xml
+NSCameraUsageDescription
+Video calls
+NSMicrophoneUsageDescription
+Audio calls
+UIBackgroundModes
+
+ audio
+ fetch
+ voip
+
+```
+
+# PushNotifications
+
+To be able to receive incoming call when app in background you have to use PushKit.
+This is the only way to receive information and wake up application to perform some action like use CallKit to show incoming call dialog.
+
+## How it works
+1. Your application registers for receiving VoIP notifications
+2. After a successful registration your application adds *device token* to Contact header when REGISTER.
+3. Your SIP server should parse those headers and when someone calling to those user, server should also send push notification for those device(s).
+4. When iOS application receives this PushNotificaiton it should show incoming call dialog via callkit, and register on server.
+5. Server should send INVITE to new registration from this iOS device.
+6. When user press Answer button via callkit, iOS application answers those SIP call.
+
+## Client side
+When application starts, it should send REGISTER with additional attributes of `Contact` header and use a long term *registration timeout*.
+In example bellow we use one month as regTimeout to be sure that our registration will not be expired when application goes to background.
+
+Your configuration might looks like this
+```javascript
+endpoint.createAccount({
+ "username":"****",
+ "domain":"****",
+ "password":"****",
+ "regTimeout": 2592000, // one month
+ "regContactParams": ";app-id=****;pn-voip-tok=XXXXXXXXX;pn-im-tok=XXXXXXXXXX"
+})
+```
+
+## Server side
+Your SIP server should support ability to send PushNotifications and also have addtional logic that re-send's INVITE messages during calling to user when new registration is available.
+For example an working module for freeswitch consider using *mod_apn*.
+
+# CallKit
+
+Ensure that the Push Notification Capability is ON
+TODO: Example
\ No newline at end of file
diff --git a/wiki/ios_push_notifications_callkit.md b/wiki/ios_push_notifications_callkit.md
new file mode 100644
index 00000000..e425a159
--- /dev/null
+++ b/wiki/ios_push_notifications_callkit.md
@@ -0,0 +1,55 @@
+# PushNotifications
+
+To be able to receive incoming call when app in background you have to use PushKit.
+This is the only way to receive information and wake up application to perform some action like use CallKit to show incoming call dialog.
+
+PushNotifications didn't work inside emualtor.
+
+## How it works
+1. Your application registers for receiving VoIP notifications
+2. After a successful registration your application adds *device token* to Contact header when REGISTER.
+3. Your SIP server should parse those headers and when someone calling to those user, server should also send push notification for those device(s).
+4. When iOS application receives this PushNotificaiton it should show incoming call dialog via callkit, and register on server.
+5. Server should send INVITE to new registration from this iOS device.
+6. When user press Answer button via callkit, iOS application answers those SIP call.
+
+## Client side
+When application starts, it should send REGISTER with additional attributes of `Contact` header.
+
+Your configuration might looks like this
+```javascript
+endpoint.createAccount({
+ "username":"****",
+ "domain":"****",
+ "password":"****",
+ "regContactParams": ";app-id=****;pn-voip-tok=XXXXXXXXX;pn-im-tok=XXXXXXXXXX"
+})
+```
+
+By using react-native-voip-nitifications
+1. Register for *VoIP* notifications.
+2. Obtain `Device token`
+2. Send device token in `Contact` header options by using `contactUriParams` property of account configuration.
+
+Ensure that the Push Notification Capability is ON
+
+## Server side
+Your SIP server should support ability to send PushNotifications and also have addtional logic that re-send's INVITE messages during calling to user when new registration is available.
+For example an working module for freeswitch consider using *mod_apn*.
+
+## Background mode
+
+When your application goes to background mode it should send UNREGISTER to ensure that PJSIP will send NEW REGISTRATION when VoIP notification will be received from server.
+When new registration
+
+# CallKit
+
+
+
+
+CallKit app receives an incoming call while it is in the background, the system's native incoming call UI will be shown.
+
+
+
+
+TODO: Example
\ No newline at end of file
diff --git a/wiki/settings.md b/wiki/settings.md
new file mode 100644
index 00000000..6b2fb2e3
--- /dev/null
+++ b/wiki/settings.md
@@ -0,0 +1,32 @@
+# Settings
+
+
+# Connectivity settings
+TODO
+
+# Network settings
+TODO
+
+
+# Codecs settings
+Print codec settings
+```javascript
+let endpoint = new Endpoint();
+let state = await endpoint.start();
+let {accounts, calls, settings, connectivity} = state;
+
+console.log("codecs", settings.codecs); // Shows a list of available codecs with priority
+```
+
+Change codec configuration
+```javascript
+// Not listed codecs are automatically will have zero priority
+endpoint.changeCodecSettings({
+ "PCMA/8000/1": 0,
+ "G722/16000/1": 0, // Zero means to disable the codec.
+ "iLBC/8000/1": 210,
+ "speex/8000/1": 0,
+ "speex/16000/1": 0,
+ "speex/32000/1": 0
+})
+```
\ No newline at end of file
diff --git a/wiki/startup.md b/wiki/startup.md
new file mode 100644
index 00000000..39c3b240
--- /dev/null
+++ b/wiki/startup.md
@@ -0,0 +1,19 @@
+
+# Initialization
+
+First of all you have to initialize module to be able to work with it.
+
+There are some interesting moment in initialization.
+When application goes to background, PJSIP module is still working and able to receive calls, but your javascipt is totally suspended.
+When User open your application, javascript start to work and now your js application need to know what status have your account or may be you have pending incoming call.
+
+So thats why first step should call start method for pjsip module.
+
+```
+let endpoint = new Endpoint();
+let state = await endpoint.start();
+let {accounts, calls} = state;
+```
+
+It works in background because in Android where is a service PjSip service, that you included in AndroidManifest.xml.
+TODO: Describe how it works on iOS.