Browse code

init repo MCOP CLient

Eduardo Zarate authored on 22/06/2018 14:02:04
Showing 94 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,10 @@
0
+*.iml
1
+.gradle
2
+/local.properties
3
+/.idea/workspace.xml
4
+/.idea/libraries
5
+.DS_Store
6
+/build
7
+/captures
8
+.externalNativeBuild
9
+*.apk
0 10
\ No newline at end of file
1 11
new file mode 100644
2 12
Binary files /dev/null and b/.idea/caches/build_file_checksums.ser differ
3 13
new file mode 100644
... ...
@@ -0,0 +1,29 @@
0
+<component name="ProjectCodeStyleConfiguration">
1
+  <code_scheme name="Project" version="173">
2
+    <Objective-C-extensions>
3
+      <file>
4
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
5
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
6
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
7
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
8
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
9
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
10
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
11
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
12
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
13
+      </file>
14
+      <class>
15
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
16
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
17
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
18
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
19
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
20
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
21
+      </class>
22
+      <extensions>
23
+        <pair source="cpp" header="h" fileNamingConvention="NONE" />
24
+        <pair source="c" header="h" fileNamingConvention="NONE" />
25
+      </extensions>
26
+    </Objective-C-extensions>
27
+  </code_scheme>
28
+</component>
0 29
\ No newline at end of file
1 30
new file mode 100644
... ...
@@ -0,0 +1,6 @@
0
+<?xml version="1.0" encoding="UTF-8"?>
1
+<project version="4">
2
+  <component name="Encoding">
3
+    <file url="PROJECT" charset="UTF-8" />
4
+  </component>
5
+</project>
0 6
\ No newline at end of file
1 7
new file mode 100644
... ...
@@ -0,0 +1,18 @@
0
+<?xml version="1.0" encoding="UTF-8"?>
1
+<project version="4">
2
+  <component name="GradleSettings">
3
+    <option name="linkedExternalProjectsSettings">
4
+      <GradleProjectSettings>
5
+        <option name="distributionType" value="DEFAULT_WRAPPED" />
6
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
7
+        <option name="modules">
8
+          <set>
9
+            <option value="$PROJECT_DIR$" />
10
+            <option value="$PROJECT_DIR$/app" />
11
+          </set>
12
+        </option>
13
+        <option name="resolveModulePerSourceSet" value="false" />
14
+      </GradleProjectSettings>
15
+    </option>
16
+  </component>
17
+</project>
0 18
\ No newline at end of file
1 19
new file mode 100644
... ...
@@ -0,0 +1,34 @@
0
+<?xml version="1.0" encoding="UTF-8"?>
1
+<project version="4">
2
+  <component name="NullableNotNullManager">
3
+    <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
4
+    <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
5
+    <option name="myNullables">
6
+      <value>
7
+        <list size="5">
8
+          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
9
+          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
10
+          <item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
11
+          <item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
12
+          <item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
13
+        </list>
14
+      </value>
15
+    </option>
16
+    <option name="myNotNulls">
17
+      <value>
18
+        <list size="4">
19
+          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
20
+          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
21
+          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
22
+          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
23
+        </list>
24
+      </value>
25
+    </option>
26
+  </component>
27
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
28
+    <output url="file://$PROJECT_DIR$/build/classes" />
29
+  </component>
30
+  <component name="ProjectType">
31
+    <option name="id" value="Android" />
32
+  </component>
33
+</project>
0 34
\ No newline at end of file
1 35
new file mode 100644
... ...
@@ -0,0 +1,9 @@
0
+<?xml version="1.0" encoding="UTF-8"?>
1
+<project version="4">
2
+  <component name="ProjectModuleManager">
3
+    <modules>
4
+      <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
5
+      <module fileurl="file://$PROJECT_DIR$/mcop-test-gui-GIT.iml" filepath="$PROJECT_DIR$/mcop-test-gui-GIT.iml" />
6
+    </modules>
7
+  </component>
8
+</project>
0 9
\ No newline at end of file
1 10
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+<?xml version="1.0" encoding="UTF-8"?>
1
+<project version="4">
2
+  <component name="RunConfigurationProducerService">
3
+    <option name="ignoredProducers">
4
+      <set>
5
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
6
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
7
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
8
+      </set>
9
+    </option>
10
+  </component>
11
+</project>
0 12
\ No newline at end of file
1 13
new file mode 100644
... ...
@@ -0,0 +1,6 @@
0
+<?xml version="1.0" encoding="UTF-8"?>
1
+<project version="4">
2
+  <component name="VcsDirectoryMappings">
3
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
4
+  </component>
5
+</project>
0 6
\ No newline at end of file
1 7
new file mode 100644
... ...
@@ -0,0 +1,10 @@
0
+<p align="center"><a href="https://mcopenplatform.org" target="_blank" rel="noopener noreferrer"><img src="https://demo.mcopenplatform.org/gitlist/mcop/MCOP-MCPTT-Client.git/raw/master/images/logoMCOP_MD_w400px.png" alt="MCOP logo"></a></p>
1
+
2
+# MCOP MCPTT Client

The **MCOP MCPTT Client** comprises different elements connected by Android’s binder mechanism including the **MCPTT Client GUI**, the **MCOP SDK** (responsible of MCPTT protocols) and **low level plugins** to access SIM card, eMBMS, connectivity and configuration-oam to be deployed to get access to Mission Critical capabilities.
3
+
4
+Check [**MCOP MCPTT Client Installation**](https://demo.mcopenplatform.org/gitlist/mcop/MCOP-MCPTT-Client.git/blob/master/docs/MCOP_MCPTT_Client_Installation.md) for instructions.
5
+
6
+License terms are defined in the [Licensing](https://demo.mcopenplatform.org/gitlist/mcop/MCOP-MCPTT-Client.git/blob/master/docs/Licensing.md) and [Doubango](https://demo.mcopenplatform.org/gitlist/mcop/MCOP-MCPTT-Client.git/blob/master/docs/Licensing_Doubango.md) files. 

* For testing purposes, the [**MCOP Demo Platform**](https://demo.mcopenplatform.org/) is also available. Check the [**profiles**](https://demo.mcopenplatform.org/gitlist/mcop/MCOP-MCPTT-Client.git/blob/master/docs/Profiles.md) documentation for information on how to request access to our platform and configure the application.
7
+
8
+* Refer to [**MCOP SDK** Installation](https://demo.mcopenplatform.org/gitlist/mcop/MCOP-SDK.git/blob/master/docs/MCOP_SDK_Installation.md) for detailed **MCOP SDK** installation and testing steps. The [MCOP MCPTT App Development](https://demo.mcopenplatform.org/gitlist/mcop/MCOP-MCPTT-Client.git/blob/master/docs/MCOP_App_developing_steps.md) guide provides more info on app development using the MCOP SDK.

This application uses [Doubango Framework](https://www.doubango.org/).
Refer to [Doubango IMSDroid README](https://demo.mcopenplatform.org/gitlist/mcop/MCOP-MCPTT-Client.git/blob/master/docs/imsdroid_README.md) for additional IMS/SIP compatibility statements.
9
+

**Copyright (C) 2018, University of the Basque Country (UPV/EHU)**

For more information, please visit [MCOP - Resources](https://www.mcopenplatform.org/mcop_resources/) or [MCOP webpage](https://www.mcopenplatform.org).



0 10
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+/build
0 1
new file mode 100644
... ...
@@ -0,0 +1,48 @@
0
+apply plugin: 'com.android.application'
1
+
2
+android {
3
+    compileSdkVersion 26
4
+    defaultConfig {
5
+        applicationId "org.test.client.mcopclient"
6
+        minSdkVersion 22
7
+        targetSdkVersion 26
8
+        versionCode 1
9
+        versionName "1.0"
10
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
11
+    }
12
+    /**
13
+     * This
14
+     */
15
+    packagingOptions{
16
+        doNotStrip "*/armeabi/*.so"
17
+        doNotStrip "*/armeabi-v7a/*.so"
18
+        doNotStrip "*/x86/*.so"
19
+    }
20
+
21
+    buildTypes {
22
+        release {
23
+            minifyEnabled false
24
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
25
+            buildConfigField "boolean", "LOG_SHOW", "true"
26
+        }
27
+        debug {
28
+            minifyEnabled false
29
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
30
+            buildConfigField "boolean", "LOG_SHOW", "true"
31
+        }
32
+    }
33
+}
34
+
35
+dependencies {
36
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
37
+    testImplementation 'junit:junit:4.12'
38
+    androidTestImplementation 'com.android.support.test:runner:1.0.1'
39
+    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
40
+    compile 'com.android.support.constraint:constraint-layout:1.0.2'
41
+    compile 'com.android.support:support-annotations:' + rootProject.supportLibVersion
42
+    compile 'com.android.support:appcompat-v7:' + rootProject.supportLibVersion
43
+    compile 'com.android.support:design:' + rootProject.supportLibVersion
44
+    compile 'com.android.support:cardview-v7:' + rootProject.supportLibVersion
45
+    compile 'com.android.support:support-v4:' + rootProject.supportLibVersion
46
+    compile 'com.android.support:recyclerview-v7:' + rootProject.supportLibVersion
47
+}
0 48
new file mode 100644
... ...
@@ -0,0 +1,21 @@
0
+# Add project specific ProGuard rules here.
1
+# You can control the set of applied configuration files using the
2
+# proguardFiles setting in build.gradle.
3
+#
4
+# For more details, see
5
+#   http://developer.android.com/guide/developing/tools/proguard.html
6
+
7
+# If your project uses WebView with JS, uncomment the following
8
+# and specify the fully qualified class name to the JavaScript interface
9
+# class:
10
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
11
+#   public *;
12
+#}
13
+
14
+# Uncomment this to preserve the line number information for
15
+# debugging stack traces.
16
+#-keepattributes SourceFile,LineNumberTable
17
+
18
+# If you keep the line number information, uncomment this to
19
+# hide the original source file name.
20
+#-renamesourcefileattribute SourceFile
0 21
new file mode 100644
... ...
@@ -0,0 +1,26 @@
0
+package org.test.client.mcopclient;
1
+
2
+import android.content.Context;
3
+import android.support.test.InstrumentationRegistry;
4
+import android.support.test.runner.AndroidJUnit4;
5
+
6
+import org.junit.Test;
7
+import org.junit.runner.RunWith;
8
+
9
+import static org.junit.Assert.*;
10
+
11
+/**
12
+ * Instrumented test, which will execute on an Android device.
13
+ *
14
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
15
+ */
16
+@RunWith(AndroidJUnit4.class)
17
+public class ExampleInstrumentedTest {
18
+    @Test
19
+    public void useAppContext() throws Exception {
20
+        // Context of the app under test.
21
+        Context appContext = InstrumentationRegistry.getTargetContext();
22
+
23
+        assertEquals("org.test.client.mcopclient", appContext.getPackageName());
24
+    }
25
+}
0 26
new file mode 100644
... ...
@@ -0,0 +1,46 @@
0
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
1
+    package="org.test.client.mcopclient">
2
+
3
+    <uses-permission android:name="android.permission.INTERNET" />
4
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
5
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
6
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
7
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
8
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
9
+    <uses-permission android:name="android.permission.CAMERA" />
10
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
11
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
12
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
13
+    <uses-permission android:name="android.permission.VIBRATE" />
14
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
15
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
16
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
17
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
18
+    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
19
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
20
+    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
21
+    <uses-permission android:name="android.permission.CALL_PHONE" />
22
+    <uses-permission android:name="android.permission.RAISED_THREAD_PRIORITY" />
23
+
24
+    <!-- Location permission -->
25
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
26
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
27
+
28
+    <application
29
+        android:allowBackup="true"
30
+        android:icon="@mipmap/ic_launcher"
31
+        android:label="@string/app_name"
32
+        android:roundIcon="@mipmap/ic_launcher_round"
33
+        android:supportsRtl="true"
34
+        android:theme="@style/AppTheme" >
35
+        <activity android:name=".MainActivity"
36
+            android:screenOrientation="portrait">
37
+            <intent-filter>
38
+                <action android:name="android.intent.action.MAIN" />
39
+
40
+                <category android:name="android.intent.category.LAUNCHER" />
41
+            </intent-filter>
42
+        </activity>
43
+    </application>
44
+
45
+</manifest>
0 46
new file mode 100644
... ...
@@ -0,0 +1,40 @@
0
+/*
1
+*  Copyright (C) 2018 Eduardo Zarate Lasurtegui
2
+*  Copyright (C) 2018, University of the Basque Country (UPV/EHU)
3
+*
4
+* Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
5
+*
6
+* This file is part of MCOP MCPTT Client
7
+*
8
+* This is free software: you can redistribute it and/or modify it under the terms of
9
+* the GNU General Public License as published by the Free Software Foundation, either version 3
10
+* of the License, or (at your option) any later version.
11
+*
12
+* This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13
+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
+* See the GNU General Public License for more details.
15
+*
16
+* You should have received a copy of the GNU General Public License along
17
+* with this program; if not, write to the Free Software Foundation, Inc.,
18
+* 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
+*/
20
+package org.mcopenplatform.muoapi;
21
+
22
+/**
23
+* AIDL definition {@link https://developer.android.com/guide/components/aidl.html}
24
+* Used as a callback for MCOP SDK server-client communication, and for MCPTT (Mission Critical Push to Talk) Services.
25
+* @author Eduardo Zarate Lasurtegui
26
+* @version 0.1
27
+*/
28
+interface IMCOPCallback {
29
+    /**
30
+     *
31
+     * Callback to be listened to by the client. It provides active events, responses to methods
32
+     * executed by the client, asynchronous events from the MCPTT system, and errors produced.
33
+     *
34
+     * @return
35
+     * @see org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack (Types of actions that each of the callback events can have)
36
+     * @param actionList Intent list. Each component in the list contains an event.
37
+    */
38
+    void handleOnEvent(in List<Intent> actionList);
39
+}
0 40
\ No newline at end of file
1 41
new file mode 100644
... ...
@@ -0,0 +1,162 @@
0
+/*
1
+ *  Copyright (C) 2018 Eduardo Zarate Lasurtegui
2
+ *  Copyright (C) 2018, University of the Basque Country (UPV/EHU)
3
+ *
4
+ * Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
5
+ *
6
+ * This file is part of MCOP MCPTT Client
7
+ *
8
+ * This is free software: you can redistribute it and/or modify it under the terms of
9
+ * the GNU General Public License as published by the Free Software Foundation, either version 3
10
+ * of the License, or (at your option) any later version.
11
+ *
12
+ * This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
+ * See the GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License along
17
+ * with this program; if not, write to the Free Software Foundation, Inc.,
18
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
+ */
20
+package org.mcopenplatform.muoapi;
21
+
22
+import org.mcopenplatform.muoapi.IMCOPCallback;
23
+
24
+/**
25
+ * AIDL definition {@link https://developer.android.com/guide/components/aidl.html}
26
+ * Used as a callback for MCOP SDK server-client communication, and for MCPTT (Mission Critical Push to Talk) Services.
27
+ * @author Eduardo Zarate Lasurtegui
28
+ * @version 0.1
29
+ */
30
+interface IMCOPsdk {
31
+    /**
32
+     * Allows to synchronously get the capabilities from the different MCPTT SDK plugins.
33
+     * @return Returns an structure with all the capabilities.
34
+     * @throws android.os.RemoteException
35
+     */
36
+    String getMCOPCapabilities();
37
+
38
+
39
+    boolean loginMCOP();
40
+
41
+    /**
42
+     * This method starts the MCPTT System unLogin procedure.
43
+     * No input parameters.
44
+     * In case of re-execution it restarts the unlogin procedure.
45
+     *
46
+     * @return  Indicates if the unLogin procedure can be started.
47
+     * @see org.mcopenplatform.muoapi.ConstantsMCOP.AuthorizationRequestExtras org.mcopenplatform.muoapi.ConstantsMCOP.AuthorizationRequestExtras (Definition of all the asynchronous response values of this method)
48
+     * @see org.mcopenplatform.muoapi.ConstantsMCOP.AuthorizationRequestExtras org.mcopenplatform.muoapi.ConstantsMCOP.LoginEventExtras (Definition of all the asynchronous response values of this method and the errors)
49
+     *
50
+     */
51
+     boolean unLoginMCOP();
52
+
53
+     /**
54
+     * Once the authentication procedure has been carried out against a third party,
55
+     * this method must be called to continue with the Login process started
56
+     * with loginMCOP() method, defined in this AIDL.
57
+     *
58
+     * Before making the call to this method, the client must use the "request uri", obtained in the callback "org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack.authorizationRequestEvent",
59
+     * to authenticate against a third party, so that the SDK can verify the authentication with the "url" input parameter.
60
+     *
61
+     * @return  Indicates if the Login procedure can be started.
62
+     * @see org.mcopenplatform.muoapi.ConstantsMCOP.AuthorizationRequestExtras org.mcopenplatform.muoapi.ConstantsMCOP.AuthorizationRequestExtras (Definition of all the asynchronous response values of this method and the errors)
63
+     * @see org.mcopenplatform.muoapi.ConstantsMCOP.AuthorizationRequestExtras org.mcopenplatform.muoapi.ConstantsMCOP.LoginEventExtras (Definition of all the asynchronous response values of this method and the errors)
64
+     * @param url. String with URL format where the parameters are indicated so that the SDK can authenticate the user.
65
+     */
66
+    boolean authorizeUser(String url);
67
+
68
+    /**
69
+     *
70
+     * Method to make MCPTT type calls. Allowed call types are limited.
71
+     * MCPTT services that a call can contain are listed in {@link org.mcopenplatform.muoapi.ConstantsMCOP.CallTypeEnum}
72
+     *
73
+     * @return Indicates whether the make call procedure could be started. In case of invalid MCPTT session, FALSE is returned.
74
+     * @see org.mcopenplatform.muoapi.ConstantsMCOP.CallTypeEnum org.mcopenplatform.muoapi.ConstantsMCOP.CallTypeEnum (Definition of the MCPTT Services a call may contain)
75
+     * @see org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras (Definition of the different asynchronous responses this method can have through the callback)
76
+     * @param userID. String to identify the MCOP system user or group to call. If no identity is indicated, the selected contact will be called.
77
+     * @param callType. Integer that contains a series of FLAGs indicating the services for the new MCPTT session.
78
+     */
79
+    boolean makeCall(String userID, int callType);
80
+
81
+    /**
82
+     * Hang up an incoming, established or initiated MCPTT session.
83
+     * @param sessionID. Identifier of the specific MCPTT session where the specific action is carried out.
84
+     * @return Indicates whether the desired operation can be started.
85
+     * @throws android.os.RemoteException
86
+     */
87
+    boolean hangUpCall(String sessionID);
88
+
89
+    /**
90
+     * Accept an incoming MCPTT sesion.
91
+     * @param sessionID. Identifier of the specific MCPTT session where the specific action is carried out.
92
+     * @return Indicates whether the desired operation can be started.
93
+     * @throws android.os.RemoteException
94
+     */
95
+    boolean acceptCall(String sessionID);
96
+
97
+    /**
98
+     * Update the emergency state of a particular session.
99
+     * @param sessionID. Identifier of the specific MCPTT session to be updated.
100
+     * @param emergencyType. New emergency state of the session. It must be type {@link org.mcopenplatform.muoapi.ConstantsMCOP.EmergencyTypeEnum}
101
+     * @return Indicates whether the desired operation can be started.
102
+     * @see org.mcopenplatform.muoapi.ConstantsMCOP.EmergencyTypeEnum
103
+     * @throws android.os.RemoteException
104
+     */
105
+    boolean updateEmergencyState(String sessionID, int emergencyType);
106
+
107
+    /**
108
+     * Perform floor control operations over MCPTT sessions.
109
+     * @param sessionID Identifier of the specific MCPTT session where the specific action is carried out.
110
+     * @param requestType Type of action to be performed. It must be type {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlOperationTypeEnum}
111
+     * @param UserID To be used in Video sessions, indicating the specific user to receive video from.
112
+     * @return Indicates whether the desired operation can be started.
113
+     * @throws android.os.RemoteException
114
+     */
115
+    boolean floorControlOperation(String sessionID, int requestType, String UserID);
116
+
117
+    /**
118
+     * Requests group information to the SDK,
119
+     * generating a type {@link org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack#groupInfoEvent} event callback.
120
+     * @return Indicates whether the desired operation can be started.
121
+     * @throws android.os.RemoteException
122
+     */
123
+    boolean updateGroupsInfo();
124
+
125
+    /**
126
+     * Requests group affiliation information to the SDK,
127
+     * generating a type {@link org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack#groupAffiliationEvent} event callback.
128
+     * @return Indicates whether the desired operation can be started.
129
+     * @throws android.os.RemoteException
130
+     */
131
+    boolean updateGroupsAffiliation();
132
+
133
+    /**
134
+     * Perform a group affiliation operation.
135
+     * @param groupMcpttId. Unequivocally identifies the group on which the operation is carried out. The group list will be received in the event {@link ConstantsMCOP.ActionsCallBack#groupAffiliationEvent}
136
+     * @param affiliationOperation. Operation to perform on the indicated group. Allowed actions: {@link org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras.AffiliationOperationTypeEnum}.
137
+     * @return Indicates whether the desired operation can be started.
138
+     * @See org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras
139
+     * @throws android.os.RemoteException
140
+     */
141
+    boolean groupAffiliationOperation(String groupMcpttId, int affiliationOperation);
142
+
143
+    /**
144
+     * Select default contact (user or group).
145
+     * @param groupID. Unequivocal identifier of the MCPTT group defined for default MCPTT sessions.
146
+     * @return Indicates whether the desired operation can be started.
147
+     * @See org.mcopenplatform.muoapi.ConstantsMCOP.SelectedContactChangeEventExtras
148
+     * @throws android.os.RemoteException
149
+     */
150
+    boolean changeSelectedContact(String groupID);
151
+
152
+     /**
153
+     * Register the callback defined by AIDL so that the SDK can send asynchronous events to the user.
154
+     * @param mcopCallBack. Callback where the different events are sent.
155
+     * @return Indicates whether the desired operation can be started.
156
+     * @see org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack
157
+     * @throws android.os.RemoteException
158
+     */
159
+    boolean registerCallback(IMCOPCallback mcopCallBack);
160
+}
161
+
0 162
new file mode 100644
1 163
Binary files /dev/null and b/app/src/main/ic_launcher-web.png differ
2 164
new file mode 100644
... ...
@@ -0,0 +1,1267 @@
0
+/*
1
+ *
2
+ *  Copyright (C) 2018 Eduardo Zarate Lasurtegui
3
+ *   Copyright (C) 2018, University of the Basque Country (UPV/EHU)
4
+ *
5
+ *  Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
6
+ *
7
+ *  This file is part of MCOP MCPTT Client
8
+ *
9
+ *  This is free software: you can redistribute it and/or modify it under the terms of
10
+ *  the GNU General Public License as published by the Free Software Foundation, either version 3
11
+ *  of the License, or (at your option) any later version.
12
+ *
13
+ *  This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14
+ *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
+ *  See the GNU General Public License for more details.
16
+ *
17
+ *  You should have received a copy of the GNU General Public License along
18
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
19
+ *  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
+ */
21
+
22
+package org.test.client.mcopclient;
23
+
24
+
25
+import java.util.ArrayList;
26
+import java.util.HashMap;
27
+import java.util.List;
28
+import java.util.Map;
29
+
30
+/**
31
+ * MCOP MCPTT SDK
32
+ * Constants used on AIDLs
33
+ * @author Eduardo Zarate Lasurtegui
34
+ * @version 0.1
35
+ */
36
+public class ConstantsMCOP {
37
+
38
+    public static final int NO_ERROR=0;
39
+
40
+
41
+
42
+    /**
43
+     *
44
+     * Access keys to the values of event types {@link org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack#unLoginEvent}
45
+     * <p>This class contains all the answers to the actions of methods {@link IMCOPsdk#unLoginMCOP()} </p>
46
+     *
47
+     */
48
+    public static class UnLoginEventExtras{
49
+        /**
50
+         * <h2>Access key to the response to method {@link IMCOPsdk#unLoginMCOP()}}:</h2>
51
+         * <p>Response: boolean, indicates whether the unlogin procedure was successful or not.</p>
52
+         */
53
+        public static final String SUCCESS="org.mcopenplatform.muoapi.ConstantsMCOP.UnLoginEventExtras"+".SUCCESS";
54
+
55
+        /**
56
+         * <h2>Access key to the error codes of the login and authentication methods.</h2>
57
+         * <p>Response: Integer indicating the error code.</p>
58
+         * <p>Values:</p>
59
+         * <p>  205 It is not possible to unregister because the customer is not registered right now</p>
60
+         * <p>  207 There was an error in the unregistration process</p>
61
+         * <p>0 means no errors.</p>
62
+         * <p></p>
63
+         */
64
+        public static final String ERROR_CODE="org.mcopenplatform.muoapi.ConstantsMCOP.UnLoginEventExtras"+".ERROR_CODE";
65
+        /**
66
+         * <h2>Access key to error string for the login and authentication methods.</h2>
67
+         * <p>Resputa: String describing the error.</p>
68
+         */
69
+        public static final String ERROR_STRING="org.mcopenplatform.muoapi.ConstantsMCOP.UnLoginEventExtras"+".ERROR_STRING";
70
+    }
71
+
72
+    /**
73
+     *
74
+     * Access keys to the values of event types {@link org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack#loginEvent}
75
+     * <p>This class contains all the answers to the actions of methods {@link IMCOPsdk#loginMCOP()} and {@link IMCOPsdk#authorizeUser(String)} ()}</p>
76
+     *
77
+     */
78
+    public static class LoginEventExtras{
79
+        /**
80
+         * <h2>Access key to the response to method {@link IMCOPsdk#authorizeUser(String)}:</h2>
81
+         * <p>Response: boolean, indicates whether the login procedure was successful or not.</p>
82
+         */
83
+        public static final String SUCCESS="org.mcopenplatform.muoapi.ConstantsMCOP.LoginEventExtras"+".SUCCESS";
84
+        /**
85
+         * <h2>Access key to the MCPTT ID of the client once authenticated.</h2>
86
+         * <p>Response: String with URI format that unequivocally identifies the user in the MCPTT system.</p>
87
+         */
88
+        public static final String MCPTT_ID="org.mcopenplatform.muoapi.ConstantsMCOP.LoginEventExtras"+".MCPTT_ID";
89
+        /**
90
+         * <h2>Access key to the DISPLAY NAME of the client once authenticated.</h2>
91
+         * <p>Response: String that identifies the user with a human-readable alias, more pleasant than a MCPTT identifier.</p>
92
+         */
93
+        public static final String DISPLAY_NAME="org.mcopenplatform.muoapi.ConstantsMCOP.LoginEventExtras"+".DISPLAY_NAME";
94
+        /**
95
+         * <h2>Access key to the error codes of the login and authentication methods.</h2>
96
+         * <p>Response: Integer indicating the error code.</p>
97
+         * <p>Values:</p>
98
+         * <p>0 means no errors.</p>
99
+         * <p>1XX: xMS Errors:</p>
100
+         * <p>  101 Unknown GMS address</p>
101
+         * <p>  102 Unknown CMS address</p>
102
+         * <p>  103 Unknown KMS address</p>
103
+         * <p>  104 Incorrect answer from GMS</p>
104
+         * <p>  105 Incorrect answer from CMS</p>
105
+         * <p>  106 Incorrect answer from KMS</p>
106
+         * <p>  107 There was error with CMS</p>
107
+         * <p>2XX: IMS or SIM Authentication Errors:</p>
108
+         * <p>  201 IMS registration error</p>
109
+         * <p>  202 IMS authentication error</p>
110
+         * <p>  203 Synchronization error between SIM and IMS</p>
111
+         * <p>  204 SIM access error</p>
112
+         * <p>  205 It is not possible to register because the customer is registered right now</p>
113
+         * <p>  206 the URL for the authentication is not valid</p>
114
+         * <p>  207 There was an error in the registration process</p>
115
+         * <p>  208 Error in the authentication process</p>
116
+         * <p>3XX: IDMS Errors:</p>
117
+         */
118
+        public static final String ERROR_CODE="org.mcopenplatform.muoapi.ConstantsMCOP.LoginEventExtras"+".ERROR_CODE";
119
+        /**
120
+         * <h2>Access key to error string for the login and authentication methods.</h2>
121
+         * <p>Resputa: String describing the error.</p>
122
+         */
123
+        public static final String ERROR_STRING="org.mcopenplatform.muoapi.ConstantsMCOP.LoginEventExtras"+".ERROR_STRING";
124
+    }
125
+
126
+    /**
127
+     *
128
+     * <h1>Keys to access the values of authentication events by methods:</h1>
129
+     * <h2>     {@link IMCOPsdk#loginMCOP()}</h2>
130
+     * <h2>     {@link IMCOPsdk#authorizeUser(String)}</h2>
131
+     */
132
+    public static class AuthorizationRequestExtras{
133
+        /**
134
+         * <h2>Access key to the uri to request the user authentication to a third party.</h2>
135
+         * <p>This data is received once the call to the method {@link IMCOPsdk#loginMCOP()} is made.</p>
136
+         * <p>Response: URI format string</p>
137
+         */
138
+        public static final String REQUEST_URI="org.mcopenplatform.muoapi.ConstantsMCOP.AuthorizationRequestActions"+".REQUEST_URI";
139
+        /**
140
+         * <h2>Access key to the uri answered by the third party authentication agent.</h2>
141
+         * <h3>Indicates when the third party authentication ends, and the method {@link IMCOPsdk#authorizeUser(String)} can be called with the authentication response.</h3>
142
+         * <p>This data is received once the call to the method {@link IMCOPsdk#loginMCOP()} is made.</p>
143
+         * <p>Response: URI format string</p>
144
+         */
145
+        public static final String REDIRECT_URI="org.mcopenplatform.muoapi.ConstantsMCOP.AuthorizationRequestActions"+".REDIRECT_URI";
146
+        /**
147
+         * <h2>Access key to authentication error codes.</h2>
148
+         * <p>Response: Integer indicating the error code.</p>
149
+         * <p>Values:</p>
150
+         * <p></p>
151
+         * <p>0 indicates no errors</p>
152
+         */
153
+        public static final String ERROR_CODE="org.mcopenplatform.muoapi.ConstantsMCOP.AuthorizationRequestActions"+".ERROR_CODE";
154
+        /**
155
+         * <h2>Access key to error codes string.</h2>
156
+         */
157
+        public static final String ERROR_STRING="org.mcopenplatform.muoapi.ConstantsMCOP.AuthorizationRequestActions"+".ERROR_STRING";
158
+    }
159
+
160
+
161
+    /**
162
+     *
163
+     * <h1>Access key to the values of all the configuration events of all the MCPTT services.</h1>
164
+     *
165
+     */
166
+    public static class ConfigurationUpdateEventExtras{
167
+
168
+        /**
169
+         * <h2>Access key to the organization that the user belongs to.</h2>
170
+         * <p>This data will be received once logged into the system.</p>
171
+         * <p>Response: String.</p>
172
+         */
173
+        public static final String ORGANIZATION="org.mcopenplatform.muoapi.ConstantsMCOP.LoginSuccessExtras"+".ORGANIZATION";
174
+
175
+        /**
176
+         * <h2>Access key to default emergency contact identifier that must be called in case of an emergency call with no destination specified.</h2>
177
+         * <p>This data will be received once logged in and each time the system changes the value or the user manually changes it with the method {@link IMCOPsdk#changeSelectedContact}</p>
178
+         * <p>Response: String with UserID format</p>
179
+         */
180
+        public static final String DEFAULT_EMERGERCY_CONTACT="org.mcopenplatform.muoapi.ConstantsMCOP.LoginSuccessExtras"+".DEFAULT_EMERGERCY_CONTACT";
181
+
182
+        /**
183
+         * <h2>Access key to ParticipantType, indicating the position of the user in the organization. Not defined in the 3GPP.</h2>
184
+         * <p>This data will be received once logged into the system or whenever the user receives a new configuration.</p>
185
+         * <p>Response: String.</p>
186
+         */
187
+        public static final String PARTICIPANT_TYPE="org.mcopenplatform.muoapi.ConstantsMCOP.LoginSuccessExtras"+".PARTICIPANT_TYPE";
188
+
189
+        /**
190
+         * <h2>Access key to the list of user granted permissions.</h2>
191
+         * <p>This data will be received once logged into the system or whenever the user receives a new configuration.</p>
192
+         * <p>Response: Integer with values of all the FLAGs that identify user allowed services</p>
193
+         * <p>Values: Sum of {@link AllowTypeEnum}</p>
194
+         * <p>  private_call (Private calls allowed) {@link AllowTypeEnum#private_call}</p>
195
+         * <p>  emergency_group_call (Emergency group calls allowed) {@link AllowTypeEnum#emergency_group_call}</p>
196
+         * <p>  emergency_private_call (Private emergency calls allowed){@link AllowTypeEnum#emergency_private_call}</p>
197
+         * <p>  imminent_peril_call (Imminent peril calls allowed){@link AllowTypeEnum#imminent_peril_call}</p>
198
+         * <p>  activate_emergency_alert (Alert calls allowed){@link AllowTypeEnum#activate_emergency_alert}</p>
199
+         * <p>NOTE: The absence of permissions in this list indicates that it is not allowed to make such type of calls, and any attempt will give an error in {@link CallEventExtras#ERROR_CODE}.</p>
200
+         */
201
+
202
+        public static final String ALLOWS_LIST="org.mcopenplatform.muoapi.ConstantsMCOP.ConfigurationUpdateEventExtras"+".ALLOWS_LIST";
203
+
204
+
205
+        /**
206
+         * <h2>Access key to configuration error codes.</h2>
207
+         * <p>Response: Integer indicating the error code.</p>
208
+         * <p>Values:</p>
209
+         *<p>Code	Explanatory text	Description</p>
210
+         *<p>101	It has been impossible to obtain authentication data</p>
211
+         * <p>0 means no errors</p>
212
+         */
213
+        public static final String ERROR_CODE="org.mcopenplatform.muoapi.ConstantsMCOP.ConfigurationUpdateEventExtras"+".ERROR_CODE";
214
+        /**
215
+         * <h2>Access key to the string of error codes</h2>
216
+         */
217
+        public static final String ERROR_STRING="org.mcopenplatform.muoapi.ConstantsMCOP.ConfigurationUpdateEventExtras"+".ERROR_STRING";
218
+
219
+        /**
220
+         * <h2>Type of permissions that the user obtains when receiving the data from key {@link ConfigurationUpdateEventExtras#ALLOWS_LIST}</h2>
221
+         */
222
+        public enum AllowTypeEnum {
223
+            none(0x00),
224
+            private_call (0x01),
225
+            emergency_group_call (0x01 << 1),
226
+            emergency_private_call (0x01 << 2),
227
+            imminent_peril_call (0x01 << 3),
228
+            activate_emergency_alert (0x01 << 4);
229
+            private int code;
230
+
231
+            AllowTypeEnum(int code) {
232
+                this.code = code;
233
+            }
234
+
235
+
236
+            public int getValue() {
237
+                return code;
238
+            }
239
+
240
+            public static List<AllowTypeEnum> getListAllowType(int num){
241
+                ArrayList<AllowTypeEnum> allowTypeEnums=new ArrayList<>();
242
+                for (ConstantsMCOP.ConfigurationUpdateEventExtras.AllowTypeEnum allowTypeEnum : ConstantsMCOP.ConfigurationUpdateEventExtras.AllowTypeEnum.values())
243
+                    if((num & allowTypeEnum.getValue())==allowTypeEnum.getValue())
244
+                        allowTypeEnums.add(allowTypeEnum);
245
+
246
+                return allowTypeEnums;
247
+            }
248
+
249
+            public static int getValue(List<AllowTypeEnum> allowTypeEnums){
250
+                int value=none.getValue();
251
+                for (ConstantsMCOP.ConfigurationUpdateEventExtras.AllowTypeEnum allowTypeEnum : allowTypeEnums)
252
+                    if(allowTypeEnum!=null)
253
+                        value+=allowTypeEnum.getValue();
254
+
255
+                return value;
256
+            }
257
+
258
+
259
+        }
260
+
261
+    }
262
+
263
+    /**
264
+     *
265
+     * Access keys to the values of type {@link org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack#callEvent} events.
266
+     *
267
+     */
268
+    public static class CallEventExtras{
269
+
270
+        /**
271
+         * <h2>Access key to event type:</h2>
272
+         * <p>Integer type values</p>
273
+         * <p>Possible event types:</p>
274
+         * <p>     INCOMING    (Incoming call of any MCPTT type) {@link org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras.CallEventEventTypeEnum#INCOMING}</p>
275
+         * <p>     RINGING     (Destination of the call is ringing) {@link org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras.CallEventEventTypeEnum#RINGING}</p>
276
+         * <p>     INPROGRESS  (MCPTT call in progress) {@link org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras.CallEventEventTypeEnum#INPROGRESS}</p>
277
+         * <p>     CONNECTED   (Established call) {@link org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras.CallEventEventTypeEnum#CONNECTED}</p>
278
+         * <p>     ERROR       (Any error in MCPTT calls) {@link org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras.CallEventEventTypeEnum#ERROR}</p>
279
+         * <p>     UPDATE       (Any Change in Call) {@link org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras.CallEventEventTypeEnum#UPDATE}</p>
280
+         */
281
+        public static final String EVENT_TYPE="org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras"+".EVENT_TYPE";
282
+
283
+
284
+        /**
285
+         *  <h2>Access key to MCPTT call session ID. This identifier is unique for each call.</h2>
286
+         *  <p>Present in all types of events {@link org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras.CallEventEventTypeEnum}</p>
287
+         */
288
+        public static final String SESSION_ID="org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras"+".SESSION_ID";
289
+
290
+        /**
291
+         *  <h2>Access key to MCPTT call type.</h2>
292
+         *  <p>Present in event type {@link org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras.CallEventEventTypeEnum#INCOMING} and {@link org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras.CallEventEventTypeEnum#UPDATE}</p>
293
+         */
294
+        public static final String CALL_TYPE="org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras"+".CALL_TYPE";
295
+
296
+
297
+        /**
298
+         *  Access key to the caller UserID
299
+         *  Present in event type {@link org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras.CallEventEventTypeEnum#INCOMING}
300
+         */
301
+        public static final String CALLER_USERID="org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras"+".CALLER_USERID";
302
+
303
+        /**
304
+         *<p> Access key to Error Codes</p>
305
+         *<p> All error codes are integers:</p>
306
+         *<p>Code	Explanatory text	Description</p>
307
+         *<p>103	maximum simultaneous MCPTT group calls reached	The number of maximum simultaneous MCPTT group calls supported for the MCPTT user has been exceeded.</p>
308
+         *<p>104	isfocus not assigned	A controlling MCPTT function has not been assigned to the MCPTT session.</p>
309
+         *<p>105	subscription not allowed in a broadcast group call	Subscription to the conference event package rejected during a group call initiated as a broadcast group call.</p>
310
+         *<p>106	user not authorised to join chat group	The MCPTT user is not authorised to join this chat group.</p>
311
+         *<p>107	user not authorised to make private calls	The MCPTT user is not authorised to make private calls.</p>
312
+         *<p>108	user not authorised to make chat group calls	The MCPTT user is not authorised to make chat group calls.</p>
313
+         *<p>109	user not authorised to make prearranged group calls	The MCPTT user is not authorised to make group calls to a prearranged group.</p>
314
+         *<p>110	user declined the call invitation	The MCPTT user declined to accept the call.</p>
315
+         *<p>111	group call proceeded without all required group members	The required members of the group did not respond within the acknowledged call time, but the call still went ahead.</p>
316
+         *<p>112	group call abandoned due to required group members not part of the group session	The group call was abandoned, as the required members of the group did not respond within the acknowledged call time.</p>
317
+         *<p>116	user is not part of the MCPTT group	The group exists on the group management server but the requesting user is not part of this group.</p>
318
+         *<p>117	the group identity indicated in the request is a prearranged group	The group id that is indicated in the request is for a prearranged group, but did not match the request from the MCPTT user.</p>
319
+         *<p>118	the group identity indicated in the request is a chat group	The group id that is indicated in the request is for a chat group, but did not match the request from the MCPTT user.</p>
320
+         *<p>119	user is not authorised to initiate the group call	The MCPTT user identified by the MCPTT ID is not authorised to initiate the group call.</p>
321
+         *<p>120	user is not affiliated to this group	The MCPTT user is not affiliated to the group.</p>
322
+         *<p>121	user is not authorised to join the group call	The MCPTT user identified by the MCPTT ID is not authorised to join the group call.</p>
323
+         *<p>122	too many participants	The group call has reached its maximum number of participants.</p>
324
+         *<p>123(INFO)	MCPTT session already exists	Inform the MCPTT user that the group call is currently ongoing.</p>
325
+         *<p>124	maximum number of private calls reached	The maximum number of private calls allowed at the MCPTT server for the MCPTT user has been reached.</p>
326
+         *<p>127	user not authorised to be called in private call	The called MCPTT user is not allowed to be part of a private call.</p>
327
+         *<p>144	user not authorised to call this particular user	The calling user is not authorised to call this particular called user.</p>
328
+         *<p>145	unable to determine called party	The participating function was unable to determine the called party from the information received in the SIP request.</p>
329
+         *<p>147(INFO)	user is authorized to initiate a temporary group call	The non-controlling MCPTT function has authorized a request from the controlling MCPTT function to authorize a user to initiate an temporary group session.</p>
330
+         *<p>148(INFO)	MCPTT group is regrouped	The MCPTT group hosted by a non-controlling MCPTT function is part of a temporary group session as the result of the group regroup function.</p>
331
+         *<p>151	user not authorised to make a private call call-back request	The MCPTT user is not authorised to make a private call call-back request.</p>
332
+         *<p>152	user not authorised to make a private call call-back cancel request	The MCPTT user is not authorised to make a private call call-back cancel request.</p>
333
+         *<p>153	user not authorised to call any of the users requested in the first-to-answer call	All users that were invited in the first-to-answer call cannot be involved in a private call with the inviting user.</p>
334
+         *<p>154	user not authorised to make ambient listening call	The MCPTT user is not authorised to make an ambient listening call.</p>
335
+         *<p>156	user not authorised to originate a first-to-answer call	The MCPTT user is not authorised to make a first-to-answer call.</p>
336
+         *
337
+         *<p>401   Invalid call type.</p>
338
+         *<p>402   Invalid action.</p>
339
+         *<p>403   in MakeCall the UserID is not valid. the UserID is empty, or don´t have URI format</p>
340
+         *<p>404   The call can not be hung because is not made</p>
341
+         *<p>405   The call cannot be accepted because it has not received any call for that sessionID</p>
342
+         *<p>406   The sessionID could not be created</p>
343
+         *<p>407   The call cannot be made because this unregistered</p>
344
+         *<p>408   User destination is not available at the moment</p>
345
+         *<p>409   Undefined signal error</p>
346
+         *<p>410   The destination is busy</p>
347
+         */
348
+        public static final String ERROR_CODE="org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras"+".ERROR_CODE";
349
+        /**
350
+         * Access key to Error Codes string.
351
+         */
352
+        public static final String ERROR_STRING="org.mcopenplatform.muoapi.ConstantsMCOP.CallEventExtras"+".ERROR_STRING";
353
+
354
+
355
+        /**
356
+         * Types of CallEvent events.
357
+         */
358
+        public enum CallEventEventTypeEnum{
359
+            NONE (0x00),
360
+            INCOMING(0x01),
361
+            RINGING(0x02),
362
+            INPROGRESS(0x03),
363
+            CONNECTED(0x04),
364
+            TERMINATED(0x05),
365
+            ERROR(0x06),
366
+            UPDATE(0x07);
367
+
368
+            private int code;
369
+            CallEventEventTypeEnum(int code) {
370
+                this.code = code;
371
+            }
372
+            public int getValue() {
373
+                return code;
374
+            }
375
+
376
+
377
+            private static Map map = new HashMap<>();
378
+
379
+
380
+            static {
381
+                for (CallEventEventTypeEnum pageType : CallEventEventTypeEnum.values()) {
382
+                    map.put(pageType.code, pageType);
383
+                }
384
+            }
385
+
386
+            public static CallEventEventTypeEnum fromInt(int pageType) {
387
+                return (CallEventEventTypeEnum) map.get(pageType);
388
+            }
389
+
390
+        }
391
+        /**
392
+         * <h2>Individual call types than can be combined and used in {@link IMCOPsdk#makeCall(String, int)} or received in type {@link ConstantsMCOP.CallEventExtras.CallEventEventTypeEnum#INCOMING} events</h2>
393
+         */
394
+        public enum CallTypeEnum {
395
+
396
+            None(0x00),
397
+            Audio (0x01),
398
+            Video (0x01 << 1),
399
+            Data (0x01 << 2),
400
+            WithFloorCtrl (0x01 << 3),
401
+            WithoutFloorCtrl (0x01 << 4),
402
+            Private (0x01 << 5),
403
+            Broadcast (0x01 << 6),
404
+            PrearrangedGroup (0x01 << 7),
405
+            ChatGroup (0x01 << 8),
406
+            FirstToAnswer (0x01 << 9), //REL 14
407
+            PrivateCallCallback (0x01 << 10), //REL 14
408
+            RemoteAmbientListening (0x01 << 11), //REL 14
409
+            LocalAmbientListening (0x01 << 12), //REL 14
410
+            Emergency (0x01 << 13),
411
+            ImminentPeril (0x01 << 14),
412
+            EmergencyAlert (0x01 << 15);
413
+
414
+            private int code;
415
+
416
+            CallTypeEnum(int code) {
417
+                this.code = code;
418
+            }
419
+
420
+
421
+            public int getValue() {
422
+                return code;
423
+            }
424
+
425
+            public static List<CallTypeEnum> getListCallType(int num){
426
+                ArrayList<CallTypeEnum> callTypesEnum=new ArrayList<>();
427
+                for (CallTypeEnum callTypeEnum : CallTypeEnum.values())
428
+                    if((num & callTypeEnum.getValue())==callTypeEnum.getValue())
429
+                        callTypesEnum.add(callTypeEnum);
430
+
431
+                return callTypesEnum;
432
+            }
433
+
434
+            public static Map<CallTypeEnum,Integer> getMapCallType(int num){
435
+                Map<CallTypeEnum,Integer> callTypesEnum=new HashMap<>();
436
+                for (CallTypeEnum callTypeEnum : CallTypeEnum.values())
437
+                    if((num & callTypeEnum.getValue())==callTypeEnum.getValue())
438
+                        callTypesEnum.put(callTypeEnum,callTypeEnum.getValue());
439
+                return callTypesEnum;
440
+            }
441
+
442
+            public static int getValue(List<CallTypeEnum> callTypeEnums){
443
+                int value=None.getValue();
444
+                for (CallTypeEnum callTypeEnum : callTypeEnums)
445
+                    if(callTypeEnum!=null)
446
+                        value+=callTypeEnum.getValue();
447
+
448
+                return value;
449
+            }
450
+
451
+
452
+        }
453
+    }
454
+
455
+
456
+
457
+    //Pending more definitions
458
+    public static class ConfigurationUpdateExtras{
459
+        //GROUPS_LIST-> returns list String (URI String)
460
+        public static final String GROUPS_LIST="org.mcopenplatform.muoapi.ConstantsMCOP.ConfigurationUpdateExtras"+".SUCCESS";
461
+        //ERROR_CODE-> returns int!=0 if the configurationUpdate fails. 0 if Successful
462
+        public static final String ERROR_CODE="org.mcopenplatform.muoapi.ConstantsMCOP.ConfigurationUpdateExtras"+".ERROR_CODE";
463
+        //ERROR_STRING-> returns String (define the error) if the configurationUpdate fails.
464
+        public static final String ERROR_STRING="org.mcopenplatform.muoapi.ConstantsMCOP.ConfigurationUpdateExtras"+".ERROR_STRING";
465
+    }
466
+
467
+
468
+    /**
469
+     *
470
+     * <h1>Access keys to the values of the floor control events in any MCPTT session.</h1>
471
+     *
472
+     */
473
+    public static class FloorControlEventExtras{
474
+
475
+        /**
476
+         * <h2>Access key to the list of floor control events.</h2>
477
+         * <p>This event is received every time an action is generated on any floor control of any MCPTT session.</p>
478
+         * <p>Response: String</p>
479
+         * <p>Values:
480
+         * <p>     granted      (Session control granted) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#granted}</p>
481
+         * <p>     idle         (Nobody has control of the session) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#idle}</p>
482
+         * <p>     taken         (Other session participant has control) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#taken}</p>
483
+         * <p>     request_sent  (Session control request sent) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#request_sent}</p>
484
+         * <p>     release_sent   (Session control release sent) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#idle}</p>
485
+         * <p>     denied         (Session control denied) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#denied}</p>
486
+         * <p>     revoked         (Session control revoked) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#revoked}</p>
487
+         * <p>     queued         (Session control request queued) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#queued}</p>
488
+         * <p>     queued_timeout         (Queued request timed out) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#queued_timeout}</p>
489
+         * <p>     transmission_granted         (Transmission granted) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#transmission_granted}</p>
490
+         * <p>     reception_granted         (Reception granted) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#reception_granted}</p>
491
+         * <p>     transmission_rejection         (Transmission rejected) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#transmission_rejection}</p>
492
+         * <p>     reception_rejection         (Reception rejected) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#reception_rejection}</p>
493
+         * <p>     transmission_revoke         (Transmission revoked) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#transmission_revoke}</p>
494
+         * <p>     reception_revoke         (Reception revoked) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#reception_revoke}</p>
495
+         * <p>     transmission_notification         (Transmission notification) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#transmission_notification}</p>
496
+         * <p>     transmission_end_notification         (Transmission notification end) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#transmission_end_notification}</p>
497
+         * <p>     transmission_end_response         (Transmission end response) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#transmission_end_response}</p>
498
+         * <p>     reception_end_response         (Reception end response) {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#reception_end_response}</p>
499
+         */
500
+        public static final String FLOOR_CONTROL_EVENT="org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras"+".FLOOR_CONTROL_EVENT";
501
+
502
+
503
+        /**
504
+         * <h2>Access key to DISPLAY NAME of the client linked to one of the events in {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum}</h2>
505
+         * <p>It is usually used with the event {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#taken} to know who is talking at each moment.</p>
506
+         * <p>Response: String that identifies the user with a human-readable alias, more pleasant than a MCPTT identifier.</p>
507
+         */
508
+        public static final String DISPLAY_NAME="org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras"+".DISPLAY_NAME";
509
+
510
+        /**
511
+         * <h2>Access key to DURATION TOKEN of Number of seconds that a client can speak {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum}</h2>
512
+         * <p>It is usually used with the event {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#granted} to know who is talking at each moment.</p>
513
+         * <p>Response: Number of seconds that a client can speak.</p>
514
+         */
515
+        public static final String DURATION_TOKEN="org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras"+".DURATION_TOKEN";
516
+
517
+        /**
518
+         * <h2>Access key to User ID that univocally distinguishes the MCPTT user causing the event {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum}</h2>
519
+         * <p>Usually used with events:</p>
520
+         * <p>      {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#taken} to know who is talking at each moment.</p>
521
+         * <p>      {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#reception_granted}</p>
522
+         * <p>      {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#transmission_end_response}</p>
523
+         * <p>      {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#reception_end_response}</p>
524
+         * <p>Response: String with URI format that identifies the MCPTT user.</p>
525
+         */
526
+        public static final String USER_ID="org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras"+".USER_ID";
527
+
528
+
529
+        /**
530
+         * <h2>Access key to ALLOW REQUEST that indicates whether a call can be made to {@link org.mcopenplatform.muoapi.IMCOPsdk#floorControlOperation(String, int, String)} to request the token despite being in a {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#taken} state</h2>
531
+         * <p>This data will be obtained every time a {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#taken} event is received.</p>
532
+         * <p>Response: boolean</p>
533
+         */
534
+        public static final String ALLOW_REQUEST="org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras"+".ALLOW_REQUEST";
535
+
536
+        /**
537
+         *  Access key to MCPTT calls Session ID. This identifier is unique for each call.
538
+         *  It occurs in all types of {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum} events.
539
+         */
540
+        public static final String SESSION_ID="org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras"+".SESSION_ID";
541
+
542
+
543
+        /**
544
+         * <h2>Access key to the numbering of a specific MCPTT session control denial or revocation event.</h2>
545
+         * <p>Response: Integer indicating the code of the cause.</p>
546
+         * <p>Values:</p>
547
+         * <p>  Event  {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#denied}:</p>
548
+         * <p> 101     Cause #1 - Another MCPTT client has permission The <Reject cause> value set to '1' indicates that another MCPTT user has permission to send a media.</p>
549
+         * <p> 102     Cause #2 - Internal floor control server error The <Reject cause> value set to '2' indicates that the floor control server cannot grant the floor request due to an internal error.</p>
550
+         * <p> 103     Cause #3 - Only one participant The <Reject cause> value set to '3' indicates that the floor control server cannot grant the floor request, because the requesting party is the only participant in the MCPTT session.</p>
551
+         * <p> 104     Cause #4 - Retry-after timer has not expired The <Reject cause> value set to '4' indicates that the floor control server cannot grant the floor request, because timer T9 (Retry-after) has not expired after permission to send media has been revoked.</p>
552
+         * <p> 105     Cause #5 - Receive only The <Reject cause> value set to '5' indicates that the floor control server cannot grant the floor request, because the requesting party only has receive privilege.</p>
553
+         * <p> 106     Cause #6 - No resources available The <Reject cause> value set to '6' indicates that the floor control server cannot grant the floor request due to congestion.</p>
554
+         * <p> 107     Cause #7 – Queue full The <Reject cause> value set to 7 indicates that the floor control server cannot queue the floor request, because the queue is full.</p>
555
+         * <p> 108     Cause #255 - Other reason The <Reject cause> value set to '255' indicates that the floor control server does not grant the floor request due to the floor control server local policy.</p>
556
+         * <p>  Event  {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#revoked}:</p>
557
+         * <p> 201     Cause #1 – Only one MCPTT client The <Reject Cause> value set to '1' indicates that the MCPTT client is the only MCPTT client in the MCPTT session or the only participant connected to a floor control server. No additional information included.</p>
558
+         * <p> 202     Cause #2 – Media burst too long The <Reject Cause> value set to '2' indicates that the MCPTT User has talked too long (e.g., the stop-talking timer has expired). No additional information included.</p>
559
+         * <p> 203     Cause #3 - No permission to send a Media Burst The <Reject Cause> value set to '3' indicates that the MCPTT client does not have permission to send media. No additional information is included.</p>
560
+         * <p> 204     Cause #4 - Media Burst pre-empted The <Reject Cause> value set to '4' indicates that the MCPTT client 's permission to send a media is being pre-empted. No additional information is included.</p>
561
+         * <p> 205     Cause #6 - No resources available The <Reject Cause> value set to '6' indicates that the floor control server can no longer grant MCPTT client to send media due to congestion. No additional information is included.</p>
562
+         * <p> 206     Cause #255 – Other reason The <Reject Cause> value set to '255' indicates that the floor control server can no longer grant MCPTT client to send media due to the floor control server local policy. No additional information is included.</p>
563
+         * <p>  Event  {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#transmission_rejection}:</p>
564
+         * <p> 301     Cause #1 - Transmission limit reached The <Reject cause> value set to '1' indicates that the number of transmitters have reached maximum.</p>
565
+         * <p> 302     Cause #2 - Internal transmission control server error The <Reject cause> value set to '2' indicates that the transmission control server cannot grant the transmission request due to an internal error.</p>
566
+         * <p> 303     Cause #3 - Only one participant The <Reject cause> value set to '3' indicates that the transmission control server cannot grant the transmission request, because the requesting party is the only participant in the MCVideo session.</p>
567
+         * <p> 304     Cause #4 - Retry-after timer has not expired The <Reject cause> value set to '4' indicates that the transmission control server cannot grant the transmission request, because timer T9 (Retry-after) has not expired after permission to send media has been revoked.</p>
568
+         * <p> 305     Cause #5 - Receive only The <Reject cause> value set to '5' indicates that the transmission control server cannot grant the transmission request, because the requesting party only has receive privilege.</p>
569
+         * <p> 306     Cause #6 - No resources available The <Reject cause> value set to '6' indicates that the transmission control server cannot grant the transmission request due to congestion.</p>
570
+         * <p> 307     Cause #255 - Other reason The <Reject cause> value set to '255' indicates that the transmission control server does not grant the transmission request due to the transmission control server local policy.</p>
571
+         * <p>  Event  {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#transmission_revoke}:</p>
572
+         * <p> 401     Cause #1 – Only one MCVideo client The <Reject Cause> value set to '1' indicates that the MCVideo client is the only MCVideo client in the MCVideo session or the only participant connected to a transmission control server. No additional information included.</p>
573
+         * <p> 402     Cause #2 – Media burst too long The <Reject Cause> value set to '2' indicates that the MCVideo User has transmitted too long (e.g., the stop-transmission timer has expired). No additional information included.</p>
574
+         * <p> 403     Cause #3 - No permission to send a Media Burst The <Reject Cause> value set to '3' indicates that the MCVideo client does not have permission to send media. No additional information is included.</p>
575
+         * <p> 404     Cause #4 - Media Burst pre-empted The <Reject Cause> value set to '4' indicates that the MCVideo client's permission to send a media is being pre-empted. No additional information is included.</p>
576
+         * <p> 405     Cause #6 - No resources available The <Reject Cause> value set to '6' indicates that the transmission control server can no longer grant MCVideo client to send media due to congestion. No additional information is included.</p>
577
+         * <p> 406     Cause #255 – Other reason The <Reject Cause> value set to '255' indicates that the transmission control server can no longer grant MCVideo client to send media due to the transmission control server local policy. No additional information is included.</p>
578
+         * <p>  Event  {@link org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum#reception_rejection}:</p>
579
+         * <p> 501     Cause #2 - Internal transmission control server error The <Reject cause> value set to '2' indicates that the transmission control server cannot grant the receive media request due to an internal error.</p>
580
+         * <p> 502     Cause #4 - Retry-after timer has not expired The <Reject cause> value set to '4' indicates that the transmission control server cannot grant the receive media request, because timer T9 (Retry-after) has not expired after permission to send media has been revoked.</p>
581
+         * <p> 503     Cause #5 - Send only The <Reject cause> value set to '5' indicates that the transmission control server cannot grant the receive media request, because the requesting party only has send privilege.</p>
582
+         * <p> 504     Cause #6 - No resources available The <Reject cause> value set to '6' indicates that the transmission control server cannot grant the receive media request due to congestion.</p>
583
+         * <p> 505     Cause #255 - Other reason The <Reject cause> value set to '255' indicates that the transmission control server does not grant the receive media request due to the transmission control server local policy.</p>
584
+         */
585
+        public static final String CAUSE_CODE="org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras"+".CAUSE_CODE";
586
+        /**
587
+         * <h2>Access key to the string of the cause codes.</h2>
588
+         */
589
+        public static final String CAUSE_STRING="org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras"+".CAUSE_STRING";
590
+        /**
591
+         *<p> Access key to Error Codes</p>
592
+         *<p> All error codes are integers:</p>
593
+         *<p>Code	Explanatory text	Description</p>
594
+         *<p>103	maximum simultaneous MCPTT group calls reached	The number of maximum simultaneous MCPTT group calls supported for the MCPTT user has been exceeded.</p>
595
+         *<p>104	isfocus not assigned	A controlling MCPTT function has not been assigned to the MCPTT session.</p>
596
+
597
+
598
+         /**
599
+         * <h2>Access key to the floor control error codes.</h2>
600
+         * <p>Response: Integer indicating the error code.</p>
601
+         * <p>Values:</p>
602
+         * <p>0 means no error.</p>
603
+         * <p>Code	Description</p>
604
+         * <p>101	The session cannot be accepted because it has not received any session for that sessionID</p>
605
+         * <p>102	Floor control invalid operation</p>
606
+         */
607
+        public static final String ERROR_CODE="org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras"+".ERROR_CODE";
608
+        /**
609
+         * <h2>Access key to the Error codes string.</h2>
610
+         */
611
+        public static final String ERROR_STRING="org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras"+".ERROR_STRING";
612
+
613
+
614
+        /**
615
+         * <h2>Operation types performed in method {@link IMCOPsdk#floorControlOperation(String, int, String)} for MCPTT session control management.</h2>
616
+         */
617
+        public enum FloorControlOperationTypeEnum{
618
+            none(0x00),
619
+            MCPTT_Request(0x01),
620
+            MCPTT_Release(0x02),
621
+            TRANSMISION_Request(0x03),
622
+            TRANSMISION_End_Request(0x04),
623
+            RECEPTION_Request(0x05),
624
+            RECEPTION_End_Request(0x06);
625
+            private int code;
626
+            FloorControlOperationTypeEnum(int code) {
627
+                this.code = code;
628
+            }
629
+            public int getValue() {
630
+                return code;
631
+            }
632
+
633
+            private static Map map = new HashMap<>();
634
+
635
+
636
+            static {
637
+                for (FloorControlOperationTypeEnum pageType : FloorControlOperationTypeEnum.values()) {
638
+                    map.put(pageType.code, pageType);
639
+                }
640
+            }
641
+
642
+            public static FloorControlOperationTypeEnum fromInt(int pageType) {
643
+                return (FloorControlOperationTypeEnum) map.get(pageType);
644
+            }
645
+        }
646
+
647
+        /**
648
+         * <h2>Types of event referred to the floor control of an MCPTT session and received on key {@link ConstantsMCOP.FloorControlEventExtras#FLOOR_CONTROL_EVENT} events.</h2>
649
+         */
650
+        public enum FloorControlEventTypeEnum{
651
+            none (""),
652
+            granted("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".granted"),
653
+            idle("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".idle"),
654
+            taken("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".taken"),
655
+            request_sent("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".request_sent"),
656
+            release_sent("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".release_sent"),
657
+            denied("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".denied"),
658
+            revoked("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".revoked"),
659
+            queued("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".queued"),
660
+            queued_timeout("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".queued_timeout"),
661
+            transmission_granted("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".transmission_granted"),
662
+            reception_granted("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".reception_granted"),
663
+            transmission_rejection("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".transmission_rejection"),
664
+            reception_rejection("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".reception_rejection"),
665
+            transmission_revoke("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".transmission_revoke"),
666
+            reception_revoke("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".reception_revoke"),
667
+            transmission_notification("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".transmission_notification"),
668
+            transmission_end_notification("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".transmission_end_notification"),
669
+            transmission_end_response("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".transmission_end_response"),
670
+            reception_end_response("org.mcopenplatform.muoapi.ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT"+".reception_end_response");
671
+
672
+            private final String text;
673
+
674
+            /**
675
+             * @param text
676
+             */
677
+            FloorControlEventTypeEnum(final String text) {
678
+                this.text = text;
679
+            }
680
+
681
+            /* (non-Javadoc)
682
+             * @see java.lang.Enum#toString()
683
+             */
684
+            @Override
685
+            public String toString() {
686
+                return text;
687
+            }
688
+
689
+            public static FloorControlEventTypeEnum fromString(String text) {
690
+                for (FloorControlEventTypeEnum value : FloorControlEventTypeEnum.values()) {
691
+                    if (value.text.equalsIgnoreCase(text)) {
692
+                        return value;
693
+                    }
694
+                }
695
+                return null;
696
+            }
697
+
698
+        }
699
+
700
+
701
+    }
702
+
703
+    /**
704
+     *
705
+     * <h1>Access key to event {@link ActionsCallBack#groupInfoEvent} values.</h1>
706
+     * <h2>For each group the user belongs to, an event with the different data that defines the group will be sent.</h2>
707
+     *
708
+     */
709
+    public static class GroupInfoEventExtras{
710
+
711
+
712
+
713
+        /**
714
+         * <h2>Access key to the Group ID that allows to univocally distinguish the MCPTT group causing the event.</h2>
715
+         * <p>Response: String with URI format that identifies the MCPTT group.</p>
716
+         */
717
+        public static final String GROUP_ID="org.mcopenplatform.muoapi.ConstantsMCOP.GroupInfoEventExtras"+".GROUP_ID";
718
+
719
+
720
+        /**
721
+         * <h2>Access key to the Display Name that allows to distinguish the MCPTT group causing the event.</h2>
722
+         * <p>Response: String that identifies the MCPTT group in a human-readable format.</p>
723
+         */
724
+        public static final String DISPLAY_NAME="org.mcopenplatform.muoapi.ConstantsMCOP.GroupInfoEventExtras"+".DISPLAY_NAME";
725
+
726
+        /**
727
+         * <h2>Access key to the permissions of the MCPTT group.</h2>
728
+         * <p>Response: Integer containing the different FLAGs of the user's permissions on the group.</p>
729
+         * <p>Values:</p>
730
+         * <p>0 means no permission.</p>
731
+         * <p>      invite_members                          ("exist" represents the pre-arranged group in on-network MCPTT procedures; "not exist" represents the chat group in on-network MCPTT procedures. This value is used when the element is not present.)   {@link AllowTypeEnum#invite_members}</p>
732
+         * <p>      recvonly                                (Receiving calls allowed, but not making them)   {@link AllowTypeEnum#recvonly}</p>
733
+         * <p>      emergency_call                          (Emergency group calls allowed)   {@link AllowTypeEnum#emergency_call}</p>
734
+         * <p>      imminent_peril_call                     (Imminent peril group calls allowed)   {@link AllowTypeEnum#imminent_peril_call}</p>
735
+         * <p>      emergency_alert_call                    (Emergency alert group calls allowed)   {@link AllowTypeEnum#emergency_alert_call}</p>
736
+         * <p>      video_invite_members                    ("exist" represents the pre-arranged group in on-network MCVideo procedures; "not exist" represents the chat group in on-network MCVideo procedures. This value is used when the element is not present)   {@link AllowTypeEnum#video_invite_members}</p>
737
+         * <p>      non_real_time_video_mode                ("exist" indicates that non real-time video mode is allowed for the MCVideo group. "not exist" indicates that non real-time video mode is not allowed for the MCVideo group. This value is used when the element is not present)   {@link AllowTypeEnum#non_real_time_video_mode}</p>
738
+         * <p>      non_urgent_real_time_video_mode         ("exist" indicates that non urgent real-time video mode is allowed for the MCVideo group. "not exist" indicates that non urgent real-time video mode is not allowed for the MCVideo group. This value is used when the element is not present)   {@link AllowTypeEnum#non_urgent_real_time_video_mode}</p>
739
+         * <p>      urgent_real_time_video_mode             ("exist" indicates that urgent real-time video mode is allowed for the MCVideo group. "not exist" indicates that urgent real-time video mode is not allowed for the MCVideo group. This value is used when the element is not present;)   {@link AllowTypeEnum#urgent_real_time_video_mode}</p>
740
+         * <p>      short_data_service                      (Short data allowed)   {@link AllowTypeEnum#short_data_service}</p>
741
+         * <p>      file_distribution                       (Distributed file sharing allowed)   {@link AllowTypeEnum#file_distribution}</p>
742
+         * <p>      conversation_management                 ("exist" indicates that conversation management is enabled for the MCData group. This value is used when the element is not present; "not exist" indicates that conversation management is disabled for the MCData group.)   {@link AllowTypeEnum#conversation_management}</p>
743
+         * <p>      tx_control                              ("exist" indicates that transmission control is enabled for the MCData group. This value is used when the element is not present; "not exist" indicates that transmission control is disabled for the MCData group.)   {@link AllowTypeEnum#tx_control}</p>
744
+         * <p>      rx_control                              ("exist" indicates that reception control is enabled for the MCData group. This value is used when the element is not present; "not exist" indicates that reception control is disabled for the MCData group.)   {@link AllowTypeEnum#rx_control}</p>
745
+         * <p>      enhanced_status                         ("exist" indicates that enhanced status is enabled for the MCData group. This value is used when the element is not present; "not exist" indicates that enhanced status is disabled for the MCData group.)   {@link AllowTypeEnum#enhanced_status}</p>
746
+         */
747
+        public static final String ALLOWS_GROUP="org.mcopenplatform.muoapi.ConstantsMCOP.GroupInfoEventExtras"+".ALLOWS_GROUP";
748
+
749
+
750
+        /**
751
+         * <h2>Access key to maximum allowed size for SDS data transmission.</h2>
752
+         * <p>Indicates the maximum size of data (in bytes) that the originating MCData client is allowed to send to the MCData server for on-network SDS communications.</p>
753
+         * <p>Response: Integer (in bytes)</p>
754
+         */
755
+        public static final String MAX_DATA_SIZE_FOR_SDS="org.mcopenplatform.muoapi.ConstantsMCOP.GroupInfoEventExtras"+".MAX_DATA_SIZE_FOR_SDS";
756
+
757
+        /**
758
+         * <h2>Access key to maximum allowed file size for FD data transmission.</h2>
759
+         * <p>Indicates the maximum size of data (in bytes) that the originating MCData client is allowed to send to the MCData server for on-network FD communications.</p>
760
+         * <p>Response: Integer (in bytes)</p>
761
+         */
762
+        public static final String MAX_DATA_SIZE_FOR_FD="org.mcopenplatform.muoapi.ConstantsMCOP.GroupInfoEventExtras"+".MAX_DATA_SIZE_FOR_FD";
763
+
764
+
765
+        /**
766
+         * <h2>Access key to maximum allowed file size for FD data transmission using HTTP.</h2>
767
+         * <p>Indicates the maximum size of data (in bytes) which the MCData server always requests the terminating MCData client to automatically download for on-network FD communications using HTTP.</p>
768
+         * <p>Response: Integer (in bytes)</p>
769
+         */
770
+        public static final String MAX_DATA_SIZE_AUTO_RECV="org.mcopenplatform.muoapi.ConstantsMCOP.GroupInfoEventExtras"+".MAX_DATA_SIZE_AUTO_RECV";
771
+
772
+        /**
773
+         * <h2>Access key to real-time video mode.</h2>
774
+         * <p>Response: String</p>
775
+         * <p>Values {@link ActionRealTimeVideoType}:</p>
776
+         * <p>      urgent_real_time                                ()   {@link ActionRealTimeVideoType#urgent_real_time}</p>
777
+         * <p>      non_urgent_real_time                            ()   {@link ActionRealTimeVideoType#non_urgent_real_time}</p>
778
+         * <p>      non_real_time                                   ()   {@link ActionRealTimeVideoType#non_real_time}</p>
779
+         *
780
+         */
781
+        public static final String ACTIVE_REAL_TIME_VIDEO_MODE="org.mcopenplatform.muoapi.ConstantsMCOP.GroupInfoEventExtras"+".ACTIVE_REAL_TIME_VIDEO_MODE";
782
+
783
+
784
+        /**
785
+         * <h2>Types of real-time video modes.</h2>
786
+         */
787
+        public enum ActionRealTimeVideoType{
788
+            none (""),
789
+            urgent_real_time("urgent-real-time"),
790
+            non_urgent_real_time("non-urgent-real-time"),
791
+            non_real_time("non-real-time");
792
+
793
+
794
+            private final String text;
795
+
796
+            /**
797
+             * @param text
798
+             */
799
+            ActionRealTimeVideoType(final String text) {
800
+                this.text = text;
801
+            }
802
+
803
+            /* (non-Javadoc)
804
+             * @see java.lang.Enum#toString()
805
+             */
806
+            @Override
807
+            public String toString() {
808
+                return text;
809
+            }
810
+        }
811
+
812
+        /**
813
+         * <h2>Access key to the group participants list.</h2>
814
+         * <p>Response: Array with 3 Strings:.</p>
815
+         * <p>      Component 0: UserID unequivocally identifies the user.</p>
816
+         * <p>      Component 1: ParticipantType indicates the user position in the organization. Not defined by 3GPP.</p>
817
+         * <p>      Component 2: DisplayName identifies the user.</p>
818
+         */
819
+        public static final String PARTICIPANTS_LIST="org.mcopenplatform.muoapi.ConstantsMCOP.GroupInfoEventExtras"+".PARTICIPANTS_LIST";
820
+
821
+        /**
822
+         * <h2>Access key to group info error codes.</h2>
823
+         * <p>Response: Integer indicating error codes.</p>
824
+         * <p>Values:</p>
825
+         * <p>0 means no errors.</p>
826
+         * <p> 101   Received data groups not valid</p>
827
+         */
828
+        public static final String ERROR_CODE="org.mcopenplatform.muoapi.ConstantsMCOP.GroupInfoEventExtras"+".ERROR_CODE";
829
+        /**
830
+         * <h2>Access key to the Error codes string.</h2>
831
+         */
832
+        public static final String ERROR_STRING="org.mcopenplatform.muoapi.ConstantsMCOP.GroupInfoEventExtras"+".ERROR_STRING";
833
+
834
+
835
+        /**
836
+         * <h2>Type of permission in a group.</h2>
837
+         *
838
+         */
839
+        public enum AllowTypeEnum{
840
+            none(0x00),
841
+            //MCPTT
842
+            invite_members(0x01),
843
+            recvonly(0x01 << 1),
844
+            emergency_call(0x01 << 2),
845
+            imminent_peril_call(0x01 << 3),
846
+            emergency_alert_call(0x01 << 4),
847
+            //MCVIDEO
848
+            video_invite_members(0x01 << 5),
849
+            non_real_time_video_mode(0x01 << 6),
850
+            non_urgent_real_time_video_mode(0x01 << 7),
851
+            urgent_real_time_video_mode(0x01 << 8),
852
+            //MCDATA
853
+            short_data_service(0x01 << 11),
854
+            file_distribution(0x01 << 12),
855
+            conversation_management(0x01 << 13),
856
+            tx_control(0x01 << 14),
857
+            rx_control(0x01 << 15),
858
+            enhanced_status(0x01 << 16);
859
+
860
+            private int code;
861
+
862
+            AllowTypeEnum(int code) {
863
+                this.code = code;
864
+            }
865
+
866
+
867
+            public int getValue() {
868
+                return code;
869
+            }
870
+
871
+            public static List<AllowTypeEnum> getListAllowType(int num){
872
+                ArrayList<AllowTypeEnum> allowTypeEnums=new ArrayList<>();
873
+                for (AllowTypeEnum allowTypeEnum : AllowTypeEnum.values())
874
+                    if((num & allowTypeEnum.getValue())==allowTypeEnum.getValue())
875
+                        allowTypeEnums.add(allowTypeEnum);
876
+
877
+                return allowTypeEnums;
878
+            }
879
+
880
+            public static int getValue(List<AllowTypeEnum> callTypeEnums){
881
+                int value=none.getValue();
882
+                for (AllowTypeEnum callTypeEnum : callTypeEnums)
883
+                    if(callTypeEnum!=null)
884
+                        value+=callTypeEnum.getValue();
885
+
886
+                return value;
887
+            }
888
+        }
889
+
890
+
891
+
892
+
893
+    }
894
+
895
+    /**
896
+     *
897
+     * <h1>Access key to values of {@link ActionsCallBack#groupAffiliationEvent} event.</h1>
898
+     *
899
+     */
900
+    public static class GroupAffiliationEventExtras{
901
+
902
+        /**
903
+         * <h2>Access key to MAP<String, Integer> of groups and the current group state.</h2>
904
+         * <p>This data is given in state {@link org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras.GroupAffiliationEventTypeEnum#GROUP_AFFILIATION_UPDATE}</p>
905
+         * <p>Response: MAP<String,Integer> being Group ID the key, and the type of affiliation status the value.</p>
906
+         * <p>      notaffiliated                                (Not affiliated, and therefore no action that requires being affiliated can be taken.)   {@link GroupAffiliationEventExtras.GroupAffiliationStateEnum#notaffiliated}</p>
907
+         * <p>      affiliating                                  (Affiliation procedure initiated.)   {@link GroupAffiliationEventExtras.GroupAffiliationStateEnum#affiliating}</p>
908
+         * <p>      affiliated                                   (Affiliated. All MCPTT procedures that require affiliation can be performed.)   {@link GroupAffiliationEventExtras.GroupAffiliationStateEnum#affiliated}</p>
909
+         * <p>      deaffiliating                                (Deaffiliation procedure started.)   {@link GroupAffiliationEventExtras.GroupAffiliationStateEnum#deaffiliating}</p>
910
+         */
911
+        public static final String GROUPS_LIST="org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras"+".GROUPS_LIST";
912
+
913
+        /**
914
+         * <h2>Access key to event type:</h2>
915
+         * <p>Value: Integer.</p>
916
+         * <p>Possible event types:</p>
917
+         * <p>     GROUP_AFFILIATION_UPDATE    (Event to update the status of the groups and user's affiliation to them.) {@link org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras.GroupAffiliationEventTypeEnum#GROUP_AFFILIATION_UPDATE}</p>
918
+         * <p>     GROUP_AFFILIATION_ERROR     (Error event in some affiliation procedure.) {@link org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras.GroupAffiliationEventTypeEnum#GROUP_AFFILIATION_ERROR}</p>
919
+         * <p>     REMOTE_AFFILIATION          (Remote affiliation request by another privileged user. It is mandatory to present the user the option to join or not. In case the user wants to be affiliated, the operation {@link IMCOPsdk#groupAffiliationOperation(String, String, int)} must be executed to affiliate the user to the group.) {@link org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras.GroupAffiliationEventTypeEnum#REMOTE_AFFILIATION}</p>
920
+         */
921
+        public static final String EVENT_TYPE="org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras"+".EVENT_TYPE";
922
+
923
+        /**
924
+         * <h2>Access key to the Group ID that univocally distinguishes the MCPTT group causing the event.</h2>
925
+         * <p>Response: String with URI format that identifies the MCPTT group.</p>
926
+         * <p>Event {@link org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras.GroupAffiliationEventTypeEnum#REMOTE_AFFILIATION} is used to request the group.</p>
927
+         */
928
+        public static final String REMOTE_GROUP_ID="org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras"+".REMOTE_GROUP_ID";
929
+
930
+
931
+        /**
932
+         * <h2>Access key to Group ID to know the group where the error occurred.</h2>
933
+         * <p>Response: String with URI format that identifies the MCPTT group.</p>
934
+         * <p>Event {@link org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras.GroupAffiliationEventTypeEnum#GROUP_AFFILIATION_ERROR} is used.</p>
935
+         */
936
+        public static final String GROUP_ID="org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras"+".GROUP_ID";
937
+
938
+        /**
939
+         * <h2>Access key to the User ID that univocally distinguishes the privileged MCPTT user making the explicit affiliation.</h2>
940
+         * <p>Response: String with URI format that identifies the MCPTT user.</p>
941
+         * <p>Event {@link org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras.GroupAffiliationEventTypeEnum#REMOTE_AFFILIATION} is used to know the remote user requesting the explicit affiliation.</p>
942
+         *
943
+         */
944
+        public static final String REMOTE_USER_ID="org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras"+".REMOTE_USER_ID";
945
+
946
+        /**
947
+         * <h2>Access key to the type of action that is remotely requested to be performed.</h2>
948
+         * <p>Response: {@link GroupAffiliationStateEnum}.</p>
949
+         * <p>Event {@link org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras.GroupAffiliationEventTypeEnum#REMOTE_AFFILIATION} is used to know the remote user requesting the explicit affiliation.</p>
950
+         * <p>      affiliating                                  (It must be asked whether the user accepts the affiliation or not.)   {@link GroupAffiliationEventExtras.GroupAffiliationStateEnum#affiliating}</p>
951
+         * <p>      deaffiliating                                (It must be asked whether the user accepts the de-affiliation or not.)   {@link GroupAffiliationEventExtras.GroupAffiliationStateEnum#deaffiliating}</p>
952
+         */
953
+        public static final String REMOTE_ACTION_TYPE="org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras"+".REMOTE_ACTION_TYPE";
954
+
955
+
956
+        /**
957
+         * <h2>Access key to the affiliation error codes.</h2>
958
+         * <p>Response: Integer indicating the error code.</p>
959
+         * <p>Values:</p>
960
+         * <p>0 means no errors.</p>
961
+         * <p>  101 Non-existent group</p>
962
+         * <p>  102 Action not allowed</p>
963
+         * <p>  103 The user is not a member of the group</p>
964
+         * <p>  104 The group is not currently affiliate</p>
965
+         * <p>  105 The group already is affiliated</p>
966
+         * <p>  106 The group already is not affiliated</p>
967
+         * <p>  107 The group does not belong to the list of existing groups</p>
968
+         * <p>  108 We don't have information of affiliation</p>
969
+         * <p>  109 The group already is affiliating or deaffiliating</p>
970
+         * @See IMCOPsdk#groupAffiliationOperation
971
+         */
972
+        public static final String ERROR_CODE="org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras"+".ERROR_CODE";
973
+        /**
974
+         * <h2>Access key to the error string of the affiliation methods.</h2>
975
+         * <p>Response: String describing the error.</p>
976
+         */
977
+        public static final String ERROR_STRING="org.mcopenplatform.muoapi.ConstantsMCOP.GroupAffiliationEventExtras"+".ERROR_STRING";
978
+
979
+        /**
980
+         * <h2>Status types of the referenced group.</h2>
981
+         */
982
+        public enum GroupAffiliationStateEnum{
983
+            none(0x00),
984
+            notaffiliated(0x01),
985
+            affiliating(0x02),
986
+            affiliated(0x03),
987
+            deaffiliating(0x04);
988
+            private int code;
989
+            GroupAffiliationStateEnum(int code) {
990
+                this.code = code;
991
+            }
992
+            public int getValue() {
993
+                return code;
994
+            }
995
+
996
+            private static Map map = new HashMap<>();
997
+
998
+
999
+            static {
1000
+                for (GroupAffiliationStateEnum pageType : GroupAffiliationStateEnum.values()) {
1001
+                    map.put(pageType.code, pageType);
1002
+                }
1003
+            }
1004
+
1005
+            public static GroupAffiliationStateEnum fromInt(int pageType) {
1006
+                return (GroupAffiliationStateEnum) map.get(pageType);
1007
+            }
1008
+
1009
+        }
1010
+
1011
+        /**
1012
+         * <h2>Event types of GroupAffiliationEventExtras</h2>
1013
+         */
1014
+        public enum GroupAffiliationEventTypeEnum{
1015
+            NONE (0x00),
1016
+            GROUP_AFFILIATION_UPDATE(0x01),
1017
+            GROUP_AFFILIATION_ERROR(0x02),
1018
+            REMOTE_AFFILIATION(0x03);
1019
+
1020
+
1021
+            private int code;
1022
+            GroupAffiliationEventTypeEnum(int code) {
1023
+                this.code = code;
1024
+            }
1025
+            public int getValue() {
1026
+                return code;
1027
+            }
1028
+
1029
+            private static Map map = new HashMap<>();
1030
+
1031
+
1032
+            static {
1033
+                for (GroupAffiliationEventTypeEnum pageType : GroupAffiliationEventTypeEnum.values()) {
1034
+                    map.put(pageType.code, pageType);
1035
+                }
1036
+            }
1037
+
1038
+            public static GroupAffiliationEventTypeEnum fromInt(int pageType) {
1039
+                return (GroupAffiliationEventTypeEnum) map.get(pageType);
1040
+            }
1041
+        }
1042
+
1043
+        /**
1044
+         *
1045
+         * <h1>Event used to indicate the affiliation action that must be used in method {@link IMCOPsdk#groupAffiliationOperation(String, String, int)}.</h1>
1046
+         * <p>Values:</p>
1047
+         * <p>Error Code 0 is not correct, and it will answer with an error.</p>
1048
+         * <p>     Affiliate            (Affiliation action over a groupID) {@link AffiliationOperationTypeEnum#Affiliate}</p>
1049
+         * <p>     Deaffiliate          (De-affiliation action over a groupID) {@link AffiliationOperationTypeEnum#Deaffiliate}</p>
1050
+         */
1051
+        public enum AffiliationOperationTypeEnum{
1052
+            none(0x00),
1053
+            Affiliate (0x01),
1054
+            Deaffiliate (0x02);
1055
+            private int code;
1056
+            AffiliationOperationTypeEnum(int code) {
1057
+                this.code = code;
1058
+            }
1059
+            public int getValue() {
1060
+                return code;
1061
+            }
1062
+            private static Map map = new HashMap<>();
1063
+
1064
+
1065
+            static {
1066
+                for (AffiliationOperationTypeEnum pageType : AffiliationOperationTypeEnum.values()) {
1067
+                    map.put(pageType.code, pageType);
1068
+                }
1069
+            }
1070
+
1071
+            public static AffiliationOperationTypeEnum fromInt(int pageType) {
1072
+                return (AffiliationOperationTypeEnum) map.get(pageType);
1073
+            }
1074
+        }
1075
+
1076
+    }
1077
+
1078
+    /**
1079
+     *
1080
+     * <h1>Access key to the values of event {@link ActionsCallBack#selectedContactChangeEvent}.</h1>
1081
+     *
1082
+     */
1083
+    public static class SelectedContactChangeEventExtras{
1084
+
1085
+        /**
1086
+         * <h2>Access key to Group ID to define the default call group.</h2>
1087
+         * <p>Response: String with URI format that identifies the MCPTT group.</p>
1088
+         * @See IMCOPsdk#makeCall
1089
+         */
1090
+        public static final String GROUP_ID="org.mcopenplatform.muoapi.ConstantsMCOP.SelectedContactChangeEventExtras"+".GROUP_ID";
1091
+
1092
+        /**
1093
+         * <h2>Access key to the error codes of default group selection.</h2>
1094
+         * <p>Response: Integer indicating the error code.</p>
1095
+         * <p>Values:</p>
1096
+         * <p>0 means no errors.</p>
1097
+         * <p>  101 Non-existent group</p>
1098
+         * <p>  102 Action not allowed</p>
1099
+         * <p>  103 The user is not a member of that group</p>
1100
+         * @See IMCOPsdk#changeSelectedContact
1101
+         */
1102
+        public static final String ERROR_CODE="org.mcopenplatform.muoapi.ConstantsMCOP.SelectedContactChangeEventExtras"+".ERROR_CODE";
1103
+        /**
1104
+         * <h2>Access key to the error strings.</h2>
1105
+         * <p>Response: String describing the error.</p>
1106
+         */
1107
+        public static final String ERROR_STRING="org.mcopenplatform.muoapi.ConstantsMCOP.SelectedContactChangeEventExtras"+".ERROR_STRING";
1108
+
1109
+    }
1110
+
1111
+
1112
+    /**
1113
+     *
1114
+     * <h1>Access key to the values of event {@link ActionsCallBack#eMBMSNotificationEvent}.</h1>
1115
+     *
1116
+     */
1117
+    public static class EMBMSNotificationEventExtras{
1118
+
1119
+        /**
1120
+         * <h2>Access key to the Temporary Mobile Group Identity (TMGI) identifying the eMBMS bearer.</h2>
1121
+         * <p>Response: String</p>
1122
+         * <p>Used in events:</p>
1123
+         * <p>      {@link EMBMSNotificationEventEventTypeEnum#UndereMBMSCoverage}</p>
1124
+         * <p>      {@link EMBMSNotificationEventEventTypeEnum#eMBMSBearerInUse}</p>
1125
+         * <p>      {@link EMBMSNotificationEventEventTypeEnum#eMBMSBearerNotInUse}</p>
1126
+         * <p>      {@link EMBMSNotificationEventEventTypeEnum#NoeMBMSCoverage}</p>
1127
+         */
1128
+        public static final String TMGI="org.mcopenplatform.muoapi.ConstantsMCOP.EMBMSNotificationEventExtras"+".TMGI";
1129
+
1130
+
1131
+        /**
1132
+         *  <h2>Access key to the MCPTT session ID. This identifier is unique for each call.</h2>
1133
+         *  <p>Response: String</p>
1134
+         * <p>Used in events:</p>
1135
+         * <p>      {@link EMBMSNotificationEventEventTypeEnum#UndereMBMSCoverage}</p>
1136
+         * <p>      {@link EMBMSNotificationEventEventTypeEnum#eMBMSBearerInUse}</p>
1137
+         * <p>      {@link EMBMSNotificationEventEventTypeEnum#eMBMSBearerNotInUse}</p>
1138
+         * <p>      {@link EMBMSNotificationEventEventTypeEnum#NoeMBMSCoverage}</p>
1139
+         */
1140
+        public static final String SESSION_ID="org.mcopenplatform.muoapi.ConstantsMCOP.EMBMSNotificationEventExtras"+".SESSION_ID";
1141
+
1142
+        /**
1143
+         *  <h2>Access key to the list of eMBMS service areas.</h2>
1144
+         *  <p>Response: String containing all the eMBMS service area identifiers consecutively.</p>
1145
+         * <p>Used in events:</p>
1146
+         * <p>      {@link EMBMSNotificationEventEventTypeEnum#UndereMBMSCoverage}</p>
1147
+         * <p>      {@link EMBMSNotificationEventEventTypeEnum#eMBMSBearerInUse}</p>
1148
+         * <p>      {@link EMBMSNotificationEventEventTypeEnum#eMBMSBearerNotInUse}</p>
1149
+         * <p>      {@link EMBMSNotificationEventEventTypeEnum#NoeMBMSCoverage}</p>
1150
+         */
1151
+        public static final String AREA_LIST="org.mcopenplatform.muoapi.ConstantsMCOP.EMBMSNotificationEventExtras"+".AREA_LIST";
1152
+
1153
+
1154
+        /**
1155
+         * Access key to event type:
1156
+         * Value: Integer.
1157
+         * <p>Possible event types:</p>
1158
+         * <p>     eMBMSAvailable           (eMBMS available) {@link org.mcopenplatform.muoapi.ConstantsMCOP.EMBMSNotificationEventExtras.EMBMSNotificationEventEventTypeEnum#eMBMSAvailable}</p>
1159
+         * <p>     UndereMBMSCoverage       (Under eMBMS coverage for a specific TMGI) {@link org.mcopenplatform.muoapi.ConstantsMCOP.EMBMSNotificationEventExtras.EMBMSNotificationEventEventTypeEnum#UndereMBMSCoverage}</p>
1160
+         * <p>     eMBMSBearerInUse         (Particular eMBMS bearer in use) {@link org.mcopenplatform.muoapi.ConstantsMCOP.EMBMSNotificationEventExtras.EMBMSNotificationEventEventTypeEnum#eMBMSBearerInUse}</p>
1161
+         * <p>     eMBMSBearerNotInUse      (Particular eMBMS bearer not in use) {@link org.mcopenplatform.muoapi.ConstantsMCOP.EMBMSNotificationEventExtras.EMBMSNotificationEventEventTypeEnum#eMBMSBearerNotInUse}</p>
1162
+         * <p>     NoeMBMSCoverage          (Not under eMBMS coverage for a specific TMGI) org.mcopenplatform.muoapi.ConstantsMCOP.EMBMSNotificationEventExtras.EMBMSNotificationEventEventTypeEnum#NoeMBMSCoverage}</p>
1163
+         * <p>     eMBMSNotAvailable        (eMBMS not available) {@link org.mcopenplatform.muoapi.ConstantsMCOP.EMBMSNotificationEventExtras.EMBMSNotificationEventEventTypeEnum#eMBMSNotAvailable}</p>
1164
+         */
1165
+        public static final String EVENT_TYPE="org.mcopenplatform.muoapi.ConstantsMCOP.EMBMSNotificationEventExtras"+".EVENT_TYPE";
1166
+
1167
+
1168
+        /**
1169
+         * <h2>Access key to eMBMS error codes.</h2>
1170
+         * <p>Response: Integer indicating the error code.</p>
1171
+         * <p>Values:</p>
1172
+         * <p>0 means no errors.</p>
1173
+         */
1174
+        public static final String ERROR_CODE="org.mcopenplatform.muoapi.ConstantsMCOP.EMBMSNotificationEventExtras"+".ERROR_CODE";
1175
+        /**
1176
+         * <h2>Access key to error string.</h2>
1177
+         * <p>Response: String describing the error.</p>
1178
+         */
1179
+        public static final String ERROR_STRING="org.mcopenplatform.muoapi.ConstantsMCOP.EMBMSNotificationEventExtras"+".ERROR_STRING";
1180
+
1181
+        /**
1182
+         * CallEvent event types.
1183
+         */
1184
+        public enum EMBMSNotificationEventEventTypeEnum{
1185
+            none (0x00),
1186
+            eMBMSAvailable(0x01),
1187
+            UndereMBMSCoverage(0x02),
1188
+            eMBMSBearerInUse(0x03),
1189
+            eMBMSBearerNotInUse(0x04),
1190
+            NoeMBMSCoverage(0x05),
1191
+            eMBMSNotAvailable(0x06);
1192
+            private int code;
1193
+            EMBMSNotificationEventEventTypeEnum(int code) {
1194
+                this.code = code;
1195
+            }
1196
+            public int getValue() {
1197
+                return code;
1198
+            }
1199
+        }
1200
+    }
1201
+
1202
+
1203
+    /**
1204
+     * <h2>Different MCOP SDK event types for MCPTT services.</h2>
1205
+     */
1206
+    public enum ActionsCallBack{
1207
+        none(""),
1208
+        authorizationRequestEvent("org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack.authorizationRequestEvent"),
1209
+        unLoginEvent("org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack.unLoginEvent"),
1210
+        loginEvent("org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack.loginEvent"),
1211
+        configurationUpdateEvent("org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack.configurationUpdateEvent"),
1212
+        callEvent("org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack.callEvent"),
1213
+        floorControlEvent("org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack.floorControlEvent"),
1214
+        groupInfoEvent("org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack.groupInfoEvent"),
1215
+        groupAffiliationEvent("org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack.groupAffiliationEvent"),
1216
+        selectedContactChangeEvent("org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack.selectedContactChangeEvent"),
1217
+        eMBMSNotificationEvent("org.mcopenplatform.muoapi.ConstantsMCOP.ActionsCallBack.eMBMSNotificationEvent");
1218
+        private final String text;
1219
+
1220
+        /**
1221
+         * @param text
1222
+         */
1223
+        ActionsCallBack(final String text) {
1224
+            this.text = text;
1225
+        }
1226
+
1227
+        /* (non-Javadoc)
1228
+         * @see java.lang.Enum#toString()
1229
+         */
1230
+        @Override
1231
+        public String toString() {
1232
+            return text;
1233
+        }
1234
+
1235
+
1236
+        /**
1237
+         * @return the Enum representation for the given string.
1238
+         */
1239
+        public static ActionsCallBack fromString(String s) {
1240
+            for(ActionsCallBack actionsCallBack: ActionsCallBack.values()){
1241
+                if(actionsCallBack.toString().compareTo(s)==0)return actionsCallBack;
1242
+            }
1243
+            return null;
1244
+        }
1245
+
1246
+    }
1247
+
1248
+    /**
1249
+     * <h1>Event types for method {@link IMCOPsdk#updateEmergencyState(String, int)}.</h1>
1250
+     */
1251
+    public enum EmergencyTypeEnum{
1252
+        NONE (0x00),
1253
+        EMERGENCY(0x01),
1254
+        NO_EMERGENCY(0x02);
1255
+
1256
+        private int code;
1257
+        EmergencyTypeEnum(int code) {
1258
+            this.code = code;
1259
+        }
1260
+        public int getValue() {
1261
+            return code;
1262
+        }
1263
+    }
1264
+
1265
+
1266
+}
0 1267
\ No newline at end of file
1 1268
new file mode 100644
... ...
@@ -0,0 +1,109 @@
0
+/*
1
+ *
2
+ *  Copyright (C) 2018 Eduardo Zarate Lasurtegui
3
+ *   Copyright (C) 2018, University of the Basque Country (UPV/EHU)
4
+ *
5
+ *  Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
6
+ *
7
+ *  This file is part of MCOP MCPTT Client
8
+ *
9
+ *  This is free software: you can redistribute it and/or modify it under the terms of
10
+ *  the GNU General Public License as published by the Free Software Foundation, either version 3
11
+ *  of the License, or (at your option) any later version.
12
+ *
13
+ *  This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14
+ *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
+ *  See the GNU General Public License for more details.
16
+ *
17
+ *  You should have received a copy of the GNU General Public License along
18
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
19
+ *  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
+ */
21
+
22
+package org.test.client.mcopclient;
23
+
24
+import android.app.Dialog;
25
+import android.content.DialogInterface;
26
+import android.os.Bundle;
27
+import android.support.annotation.NonNull;
28
+import android.support.v4.app.DialogFragment;
29
+import android.support.v7.app.AlertDialog;
30
+import android.widget.EditText;
31
+import android.widget.Spinner;
32
+
33
+
34
+public class DialogMenu extends DialogFragment {
35
+    private final static String TAG = DialogMenu.class.getCanonicalName();
36
+    private EditText dialog_new_account_EditText_name;
37
+    private EditText dialog_new_account_EditText_UriSip;
38
+    private Spinner dialog_new_account_Spinner_type;
39
+
40
+    private static final String PARAMETER_MENU_ITEM=TAG+".PARAMETER_MENU_ITEM";
41
+    private static final String PARAMETER_MENU_TITLE=TAG+".PARAMETER_MENU_TITLE";
42
+
43
+
44
+    private String[] items;
45
+    private String title;
46
+
47
+    private OnClickListener onClickItemListener;
48
+
49
+    public DialogMenu() {
50
+    }
51
+
52
+    public static DialogMenu newInstance(String[] items, String title) {
53
+        DialogMenu f = new DialogMenu();
54
+
55
+        Bundle args = new Bundle();
56
+        args.putStringArray(PARAMETER_MENU_ITEM, items);
57
+        args.putString(PARAMETER_MENU_TITLE, title);
58
+        f.setArguments(args);
59
+
60
+        return f;
61
+    }
62
+
63
+    @Override
64
+    public void onCreate(Bundle savedInstanceState) {
65
+        super.onCreate(savedInstanceState);
66
+        this.items = getArguments().getStringArray(PARAMETER_MENU_ITEM);
67
+        this.title = getArguments().getString(PARAMETER_MENU_TITLE);
68
+
69
+    }
70
+
71
+
72
+    @NonNull
73
+    @Override
74
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
75
+        return createDialogNewAccount();
76
+    }
77
+
78
+    /**
79
+     * create new Dialog Fragment
80
+     * @return new Dialog Fragment
81
+     */
82
+    public AlertDialog createDialogNewAccount() {
83
+        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
84
+
85
+        String titleComplete="options";
86
+        if(title!=null){
87
+            titleComplete+="("+title+")";
88
+        }
89
+
90
+        builder.setTitle(titleComplete)
91
+                .setItems(items, new DialogInterface.OnClickListener() {
92
+                    public void onClick(DialogInterface dialog, int item) {
93
+                        if(onClickItemListener!=null)onClickItemListener.onClickItem(item);
94
+                    }
95
+                });
96
+
97
+        return builder.create();
98
+    }
99
+
100
+
101
+    public interface OnClickListener{
102
+        void onClickItem(int item);
103
+    }
104
+
105
+    public void setOnClickItemListener(OnClickListener onClickItemListener){
106
+        this.onClickItemListener=onClickItemListener;
107
+    }
108
+}
0 109
new file mode 100644
... ...
@@ -0,0 +1,1155 @@
0
+/*
1
+ *
2
+ *  Copyright (C) 2018 Ander Nieva Anza
3
+ *   Copyright (C) 2018, University of the Basque Country (UPV/EHU)
4
+ *
5
+ *  Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
6
+ *
7
+ *  This file is part of MCOP MCPTT Client
8
+ *
9
+ *  This is free software: you can redistribute it and/or modify it under the terms of
10
+ *  the GNU General Public License as published by the Free Software Foundation, either version 3
11
+ *  of the License, or (at your option) any later version.
12
+ *
13
+ *  This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14
+ *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
+ *  See the GNU General Public License for more details.
16
+ *
17
+ *  You should have received a copy of the GNU General Public License along
18
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
19
+ *  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
+ */
21
+
22
+package org.test.client.mcopclient;
23
+
24
+import android.Manifest;
25
+import android.annotation.TargetApi;
26
+import android.content.BroadcastReceiver;
27
+import android.content.ComponentName;
28
+import android.content.Context;
29
+import android.content.Intent;
30
+import android.content.IntentFilter;
31
+import android.content.ServiceConnection;
32
+import android.content.pm.PackageManager;
33
+import android.media.AudioManager;
34
+import android.net.Uri;
35
+import android.os.Build;
36
+import android.os.Bundle;
37
+import android.os.Handler;
38
+import android.os.IBinder;
39
+import android.os.RemoteException;
40
+import android.provider.Settings;
41
+import android.support.v4.app.ActivityCompat;
42
+import android.support.v4.content.ContextCompat;
43
+import android.support.v7.app.AppCompatActivity;
44
+import android.support.v7.widget.SwitchCompat;
45
+import android.telephony.TelephonyManager;
46
+import android.util.Log;
47
+import android.view.MotionEvent;
48
+import android.view.View;
49
+import android.widget.AdapterView;
50
+import android.widget.ArrayAdapter;
51
+import android.widget.Button;
52
+import android.widget.CompoundButton;
53
+import android.widget.Spinner;
54
+import android.widget.TextView;
55
+
56
+import org.mcopenplatform.muoapi.IMCOPCallback;
57
+import org.mcopenplatform.muoapi.IMCOPsdk;
58
+import org.test.client.mcopclient.datatype.UserData;
59
+import org.test.client.mcopclient.preference.PreferencesManagerDefault;
60
+
61
+import java.net.URI;
62
+import java.net.URISyntaxException;
63
+import java.util.ArrayList;
64
+import java.util.HashMap;
65
+import java.util.HashSet;
66
+import java.util.List;
67
+import java.util.Map;
68
+import java.util.Set;
69
+
70
+
71
+public class MainActivity extends AppCompatActivity {
72
+    private final static String TAG = MainActivity.class.getCanonicalName();
73
+
74
+    private ServiceConnection mConnection;
75
+    private IMCOPsdk mService;
76
+    private IMCOPCallback mMCOPCallback;
77
+    private boolean isConnect=false;
78
+    private static final int ERROR_CODE_DEFAULT=-1;
79
+    private static final int AUTHETICATION_RESULT=101;
80
+    private static final int GET_PERMISSION = 102;
81
+    private static final boolean VALUE_BOOLEAN_DEFAULT=false;
82
+    private static UserData userData;
83
+    private static final int DEFAULT_REGISTER_DELAY = 4000;
84
+
85
+    private static final String ACTION_BUTTON_PTT_DOWN_BITTIUM="com.elektrobit.pttbutton.PTTBUTTON_DOWN";
86
+    private static final String ACTION_BUTTON_PTT_UP_BITTIUM="com.elektrobit.pttbutton.PTTBUTTON_UP";
87
+    private static final String ACTION_BUTTON_PTT_LONG_PRESS_BITTIUM="com.elektrobit.pttbutton.PTTBUTTON_LONG_PRESS";
88
+    private BroadcastReceiver mButtonPTTBroadCastRecvMCPTT;
89
+
90
+
91
+    private Button btn_register;
92
+    private Button btn_unregister;
93
+    private TextView text_info;
94
+    private TextView text_error;
95
+    private TextView text_affiliation;
96
+    private TextView text_status;
97
+    private Button btn_hangup;
98
+    private DialogMenu mDialogIds;
99
+    private Button btn_accept;
100
+    private Button reg_status;
101
+    private Button btn_call;
102
+    private Button btn_speaker;
103
+    private Button btn_aux2;
104
+    private TextView text_talking;
105
+    private TextView text_callingid;
106
+    private TextView switch_private;
107
+    private TextView switch_group;
108
+    private PreferencesManagerDefault preferencesManager;
109
+    private static final String PARAMETER_PROFILE = "parameters";
110
+    private static final String PARAMETER_SAVE_PROFILE = TAG+".PARAMETER_SAVE_PROFILE";
111
+    private Map<String, String> clients;
112
+    private DialogMenu mDialogMenu;
113
+    private String currentProfile;
114
+    private SwitchCompat switchCompat;
115
+    private Spinner spinnerGroups;
116
+    private Spinner spinnerUsers;
117
+    private Boolean isSpeakerphoneOn;
118
+    private ArrayList<String> groupsCurrent;
119
+    private Intent serviceIntent;
120
+
121
+    private enum State {
122
+        GRANTED,
123
+        IDLE,
124
+        TAKEN,
125
+        NONE
126
+    }
127
+    private State mState = State.NONE;
128
+    private enum CallType {
129
+        PRIVATE,
130
+        GROUP
131
+    }
132
+    private CallType mCallType = CallType.GROUP;
133
+    private String selGroup = "sip:groupA@organization.org";
134
+    private String selUser = "sip:mcptt_id_clientA@organization.org";
135
+
136
+    @Override
137
+    protected void onCreate(Bundle savedInstanceState) {
138
+        super.onCreate(savedInstanceState);
139
+        setContentView(R.layout.activity_main);
140
+        setPermissions();
141
+        btn_register=(Button)findViewById(R.id.btn_register);
142
+        btn_unregister=(Button)findViewById(R.id.btn_unregister);
143
+        text_info=(TextView)findViewById(R.id.text_info);
144
+        text_error=(TextView)findViewById(R.id.text_error);
145
+        text_affiliation=(TextView)findViewById(R.id.text_affiliation);
146
+        text_status=(TextView)findViewById(R.id.text_status);
147
+
148
+        btn_hangup=(Button)findViewById(R.id.btn_hangup);
149
+        btn_accept=(Button)findViewById(R.id.btn_accept);
150
+        reg_status=(Button)findViewById(R.id.reg_status);
151
+        btn_call=(Button)findViewById(R.id.btn_call);
152
+        btn_speaker=(Button)findViewById(R.id.btn_speaker);
153
+        btn_aux2=(Button)findViewById(R.id.btn_aux2);
154
+        text_talking=(TextView)findViewById(R.id.text_talking);
155
+        text_callingid=(TextView)findViewById(R.id.text_callingid);
156
+        switch_private=(TextView)findViewById(R.id.switch_private);
157
+        switch_group=(TextView)findViewById(R.id.switch_group);
158
+        switchCompat=(SwitchCompat)findViewById(R.id.switch_call);
159
+        spinnerGroups=(Spinner)findViewById(R.id.spinnerGroups);
160
+        spinnerUsers=(Spinner)findViewById(R.id.spinnerUsers);
161
+
162
+        btn_unregister.setEnabled(false);
163
+        btn_call.setEnabled(false);
164
+        btn_call.setBackgroundResource(R.drawable.token_inactive);
165
+        btn_register.setEnabled(false);
166
+        btn_accept.setEnabled(false);
167
+        btn_hangup.setEnabled(false);
168
+        reg_status.setEnabled(false);
169
+        btn_speaker.setEnabled(false);
170
+        btn_aux2.setEnabled(false);
171
+        text_talking.setVisibility((View.INVISIBLE));
172
+        text_callingid.setVisibility((View.INVISIBLE));
173
+        switchCompat.setEnabled(false);
174
+        switch_group.setTextColor(ContextCompat.getColor(this, R.color.background));
175
+        switch_private.setTextColor(ContextCompat.getColor(this, R.color.background));
176
+        spinnerGroups.setEnabled(false);
177
+        spinnerGroups.setAdapter(null);
178
+        spinnerUsers.setEnabled(false);
179
+        spinnerUsers.setAdapter(null);
180
+        spinnerUsers.setVisibility((View.GONE));
181
+        spinnerGroups.setVisibility((View.VISIBLE));
182
+        isSpeakerphoneOn = false;
183
+        AudioManager mAudioManager;
184
+        mAudioManager =  (AudioManager)getSystemService(Context.AUDIO_SERVICE);
185
+        mAudioManager.setSpeakerphoneOn(isSpeakerphoneOn);
186
+
187
+        //Dissable logging messages. Enable just for debugging
188
+        text_info.setVisibility((View.GONE));
189
+        text_error.setVisibility((View.GONE));
190
+        text_affiliation.setVisibility((View.GONE));
191
+
192
+        preferencesManager=new PreferencesManagerDefault();
193
+
194
+        clients = new HashMap<>();
195
+
196
+        if(clients==null || clients.isEmpty()){
197
+            clients.put("TESTA", "TESTA");
198
+            clients.put("TESTB", "TESTB");
199
+            clients.put("TESTC", "TESTC");
200
+            clients.put("TESTD", "TESTD");
201
+            clients.put("TESTE", "TESTE");
202
+        }
203
+
204
+        List<String> usersCurrent = new ArrayList<String>();
205
+
206
+        if(usersCurrent.isEmpty()){
207
+            usersCurrent.add("sip:mcptt_id_test_A@organization.org");
208
+            usersCurrent.add("sip:mcptt_id_test_B@organization.org");
209
+            usersCurrent.add("sip:mcptt_id_test_C@organization.org");
210
+            usersCurrent.add("sip:mcptt_id_test_D@organization.org");
211
+            usersCurrent.add("sip:mcptt_id_test_E@organization.org");
212
+        }
213
+
214
+        //Group list
215
+        groupsCurrent = new ArrayList<String>();
216
+        groupsCurrent.add("sip:tets_group@organization.org");
217
+        groupsCurrent.add("sip:groupTest2@organization.org");
218
+
219
+        //Adapter por User Spinner
220
+        ArrayAdapter<String> userAdaptor = new ArrayAdapter<>(getApplicationContext(),
221
+                android.R.layout.simple_spinner_item, usersCurrent);
222
+        // Drop down layout style - list view with radio button
223
+        userAdaptor.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
224
+        spinnerUsers.setAdapter(userAdaptor);
225
+
226
+        loadGroups();
227
+
228
+
229
+        ArrayList<String> strings=getIntent().getStringArrayListExtra(PARAMETER_PROFILE);
230
+        Map<String, String> parameterClients= getProfilesParameters(strings);
231
+        if(parameterClients!=null && !parameterClients.isEmpty())
232
+            clients=parameterClients;
233
+
234
+        if(userData==null);
235
+        userData=new UserData();
236
+
237
+        mMCOPCallback=new IMCOPCallback.Stub() {
238
+            @Override
239
+            public void handleOnEvent(final List<Intent> actionList) throws RemoteException {
240
+                runOnUiThread(new Runnable() {
241
+                    @Override
242
+                    public void run() {
243
+                        for(Intent action:actionList){
244
+                            int codeError=-1;
245
+                            int eventTypeInt=-1;
246
+                            String stringError=null;
247
+                            String sessionID=null;
248
+                            if(action!=null && action.getAction()!=null && !action.getAction().trim().isEmpty())
249
+                                try {
250
+
251
+                                    switch (ConstantsMCOP.ActionsCallBack.fromString(action.getAction())){
252
+                                        case none:
253
+                                            break;
254
+                                        case authorizationRequestEvent:
255
+                                            codeError=-1;
256
+                                            if((codeError=action.getIntExtra(ConstantsMCOP.AuthorizationRequestExtras.ERROR_CODE,ERROR_CODE_DEFAULT))!=ERROR_CODE_DEFAULT){
257
+                                                //Error in authorizationRequestEvent
258
+                                                stringError=action.getStringExtra(ConstantsMCOP.AuthorizationRequestExtras.ERROR_STRING);
259
+                                                showLastError("authorizationRequestEvent",codeError,stringError);
260
+                                            }else  {
261
+                                                //No error
262
+                                                String requestUri=null;
263
+                                                String redirect=null;
264
+                                                if((requestUri=action.getStringExtra(ConstantsMCOP.AuthorizationRequestExtras.REQUEST_URI))!=null &&
265
+                                                        (redirect=action.getStringExtra(ConstantsMCOP.AuthorizationRequestExtras.REDIRECT_URI))!=null
266
+                                                        ){
267
+                                                    if(BuildConfig.DEBUG)Log.d(TAG,"onAuthentication URI: "+requestUri+ " redirectionURI: "+redirect);
268
+                                                }
269
+                                            }
270
+                                            break;
271
+                                        case loginEvent:
272
+                                            codeError=-1;
273
+                                            if((codeError=action.getIntExtra(ConstantsMCOP.LoginEventExtras.ERROR_CODE,ERROR_CODE_DEFAULT))!=ERROR_CODE_DEFAULT){
274
+                                                //Error in LoginEvent
275
+                                                stringError=action.getStringExtra(ConstantsMCOP.LoginEventExtras.ERROR_STRING);
276
+                                                showLastError("LoginEvent",codeError,stringError);
277
+                                            }else  {
278
+                                                //No error
279
+                                                boolean success=false;
280
+                                                String mcptt_id=null;
281
+                                                String displayName=null;
282
+                                                if((success=action.getBooleanExtra(ConstantsMCOP.LoginEventExtras.SUCCESS,VALUE_BOOLEAN_DEFAULT))==true &&
283
+                                                        (mcptt_id=action.getStringExtra(ConstantsMCOP.LoginEventExtras.MCPTT_ID))!=null
284
+                                                        ){
285
+                                                    if(BuildConfig.DEBUG)Log.d(TAG,"Login success: "+success+ " mcptt_id: "+mcptt_id);
286
+                                                    displayName=action.getStringExtra(ConstantsMCOP.LoginEventExtras.DISPLAY_NAME);
287
+                                                    isRegisted(success,mcptt_id,displayName);
288
+                                                }else{
289
+                                                    Log.e(TAG,"Error: Registration process");
290
+                                                }
291
+                                            }
292
+                                            break;
293
+                                        case unLoginEvent:
294
+                                            codeError=-1;
295
+                                            if((codeError=action.getIntExtra(ConstantsMCOP.UnLoginEventExtras.ERROR_CODE,ERROR_CODE_DEFAULT))!=ERROR_CODE_DEFAULT){
296
+                                                //Error in unLoginEvent
297
+                                                stringError=action.getStringExtra(ConstantsMCOP.UnLoginEventExtras.ERROR_STRING);
298
+                                                showLastError("unLoginEvent",codeError,stringError);
299
+                                            }else  {
300
+                                                //No error
301
+                                                boolean success=false;
302
+                                                if((success=action.getBooleanExtra(ConstantsMCOP.UnLoginEventExtras.SUCCESS,VALUE_BOOLEAN_DEFAULT))==true){
303
+                                                    unRegisted(success);
304
+                                                }else{
305
+                                                    Log.e(TAG,"Error: Unregistration process");
306
+                                                }
307
+                                            }
308
+                                            break;
309
+                                        case configurationUpdateEvent:
310
+                                            break;
311
+                                        case callEvent:
312
+                                            codeError=-1;
313
+                                            eventTypeInt=action.getIntExtra(ConstantsMCOP.CallEventExtras.EVENT_TYPE,ERROR_CODE_DEFAULT);
314
+                                            ConstantsMCOP.CallEventExtras.CallEventEventTypeEnum eventTypeCall=null;
315
+
316
+                                            if(eventTypeInt!=ERROR_CODE_DEFAULT &&
317
+                                                    (eventTypeCall=ConstantsMCOP.CallEventExtras.CallEventEventTypeEnum.fromInt(eventTypeInt))!=null ){
318
+                                                switch (eventTypeCall) {
319
+                                                    case NONE:
320
+                                                        break;
321
+                                                    case INCOMING:
322
+                                                        Log.e(TAG,"STATE: INCOMING");
323
+                                                        stringError=action.getStringExtra(ConstantsMCOP.CallEventExtras.ERROR_STRING);
324
+                                                        sessionID=action.getStringExtra(ConstantsMCOP.CallEventExtras.SESSION_ID);
325
+                                                        String callerID=action.getStringExtra(ConstantsMCOP.CallEventExtras.CALLER_USERID);
326
+                                                        if(sessionID!=null)userData.addSessionID(sessionID);
327
+                                                        showData("callEvent ("+sessionID+")","INCOMING "+"-> "+callerID);
328
+                                                        text_talking.setVisibility((View.VISIBLE));
329
+                                                        text_callingid.setVisibility((View.VISIBLE));
330
+                                                        text_callingid.setText(callerID);
331
+                                                        spinnerGroups.setEnabled(false);
332
+                                                        spinnerUsers.setEnabled(false);
333
+                                                        switchCompat.setEnabled(false);
334
+                                                        showIdsAcceptCall(getApplicationContext(), sessionID);
335
+                                                        break;
336
+                                                    case RINGING:
337
+                                                        Log.e(TAG,"STATE: RINGING");
338
+                                                        sessionID=action.getStringExtra(ConstantsMCOP.CallEventExtras.SESSION_ID);
339
+                                                        spinnerGroups.setEnabled(false);
340
+                                                        spinnerUsers.setEnabled(false);
341
+                                                        switchCompat.setEnabled(false);
342
+                                                        showData("callEvent ("+sessionID+")","RINGING");
343
+                                                        if(sessionID!=null)userData.addSessionID(sessionID);
344
+                                                        break;
345
+                                                    case INPROGRESS:
346
+                                                        Log.e(TAG,"STATE: INPROGRESS");
347
+                                                        sessionID=action.getStringExtra(ConstantsMCOP.CallEventExtras.SESSION_ID);
348
+                                                        spinnerGroups.setEnabled(false);
349
+                                                        spinnerUsers.setEnabled(false);
350
+                                                        switchCompat.setEnabled(false);
351
+                                                        showData("callEvent ("+sessionID+")","INPROGRESS");
352
+                                                        if(sessionID!=null)userData.addSessionID(sessionID);
353
+                                                        break;
354
+                                                    case CONNECTED:
355
+                                                        Log.e(TAG,"STATE: CONNECTED");
356
+                                                        sessionID=action.getStringExtra(ConstantsMCOP.CallEventExtras.SESSION_ID);
357
+                                                        showData("callEvent ("+sessionID+")","CONNECTED");
358
+                                                        break;
359
+                                                    case TERMINATED:
360
+                                                        Log.e(TAG,"STATE: TERMINATED");
361
+                                                        sessionID=action.getStringExtra(ConstantsMCOP.CallEventExtras.SESSION_ID);
362
+                                                        spinnerGroups.setEnabled(true);
363
+                                                        spinnerUsers.setEnabled(true);
364
+                                                        switchCompat.setEnabled(true);
365
+                                                        switch_group.setTextColor(ContextCompat.getColor(getBaseContext(), R.color.white));
366
+                                                        switch_private.setTextColor(ContextCompat.getColor(getBaseContext(), R.color.white));
367
+                                                        showData("callEvent ("+sessionID+")","TERMINATED");
368
+                                                        if(sessionID!=null)userData.removeSessionID(sessionID);
369
+                                                        btn_call.setBackgroundResource(R.drawable.token_default);
370
+                                                        mState = State.NONE;
371
+                                                        btn_call.setEnabled(true);
372
+                                                        btn_hangup.setEnabled(false);
373
+                                                        text_talking.setVisibility((View.INVISIBLE));
374
+                                                        text_callingid.setVisibility((View.INVISIBLE));
375
+                                                        break;
376
+                                                    case ERROR:
377
+                                                        Log.e(TAG,"STATE: ERROR");
378
+                                                        if((codeError=action.getIntExtra(ConstantsMCOP.CallEventExtras.ERROR_CODE,ERROR_CODE_DEFAULT))!=ERROR_CODE_DEFAULT){
379
+                                                            //Error in callEvent
380
+                                                            stringError=action.getStringExtra(ConstantsMCOP.CallEventExtras.ERROR_STRING);
381
+                                                            sessionID=action.getStringExtra(ConstantsMCOP.CallEventExtras.SESSION_ID);
382
+                                                            showLastError("callEvent ("+sessionID+")",codeError,stringError);
383
+                                                        }
384
+                                                        if(sessionID!=null)userData.addSessionID(sessionID);
385
+                                                        break;
386
+                                                    case UPDATE:
387
+                                                        Log.e(TAG,"STATE: UPDATE");
388
+                                                        sessionID=action.getStringExtra(ConstantsMCOP.CallEventExtras.SESSION_ID);
389
+                                                        int updateCallType=action.getIntExtra(ConstantsMCOP.CallEventExtras.CALL_TYPE,ERROR_CODE_DEFAULT);
390
+                                                        showData("callEvent ("+sessionID+")","UPDATE "+"-> CallType: "+updateCallType);
391
+                                                        if(sessionID!=null)userData.addSessionID(sessionID);
392
+                                                        break;
393
+                                                    default:
394
+                                                        showLastError("callEvent:",999,"RECEIVE EVENT NO VALID");
395
+                                                        break;
396
+                                                }
397
+                                            }else{
398
+                                                showLastError("callEvent:",999,"RECEIVE EVENT NO VALID");
399
+                                            }
400
+                                            break;
401
+                                        case floorControlEvent:
402
+                                            codeError=-1;
403
+                                            if((codeError=action.getIntExtra(ConstantsMCOP.FloorControlEventExtras.ERROR_CODE,ERROR_CODE_DEFAULT))!=ERROR_CODE_DEFAULT){
404
+                                                //Error in unLoginEvent
405
+                                                sessionID=action.getStringExtra(ConstantsMCOP.FloorControlEventExtras.SESSION_ID);
406
+                                                stringError=action.getStringExtra(ConstantsMCOP.UnLoginEventExtras.ERROR_STRING);
407
+                                                showLastError("floorControlEvent("+sessionID+")",codeError,stringError);
408
+                                            }else  {
409
+                                                //No error
410
+                                                boolean success=false;
411
+                                                String eventFloorControl=action.getStringExtra(ConstantsMCOP.FloorControlEventExtras.FLOOR_CONTROL_EVENT);
412
+                                                String causeString=null;
413
+                                                int causeInt=-1;
414
+                                                try{
415
+                                                    sessionID=action.getStringExtra(ConstantsMCOP.CallEventExtras.SESSION_ID);
416
+                                                    switch (ConstantsMCOP.FloorControlEventExtras.FloorControlEventTypeEnum.fromString(eventFloorControl)) {
417
+                                                        case none:
418
+                                                            break;
419
+                                                        case granted:
420
+                                                            Log.e(TAG,"TOKEN GRANTED");
421
+                                                            int durationGranted=action.getIntExtra(ConstantsMCOP.FloorControlEventExtras.DURATION_TOKEN,ERROR_CODE_DEFAULT);
422
+                                                            showData("floorControl ("+sessionID+")"," granted "+"-> Duration: "+durationGranted);
423
+                                                            btn_call.setBackgroundResource(R.drawable.token_green);
424
+                                                            mState = State.GRANTED;
425
+                                                            btn_call.setEnabled(true);
426
+                                                            btn_hangup.setEnabled(true);
427
+                                                            break;
428
+                                                        case idle:
429
+                                                            Log.e(TAG,"TOKEN IDLE");
430
+                                                            showData("floorControl ("+sessionID+")"," idle");
431
+                                                            btn_call.setBackgroundResource(R.drawable.token_gray);
432
+                                                            mState = State.IDLE;
433
+                                                            btn_call.setEnabled(true);
434
+                                                            btn_hangup.setEnabled(true);
435
+                                                            text_talking.setVisibility((View.INVISIBLE));
436
+                                                            text_callingid.setVisibility((View.INVISIBLE));
437
+                                                            break;
438
+                                                        case taken:
439
+                                                            Log.e(TAG,"TOKEN TAKEN");
440
+                                                            String userIDTaken=action.getStringExtra(ConstantsMCOP.FloorControlEventExtras.USER_ID);
441
+                                                            String displayNameTaken=action.getStringExtra(ConstantsMCOP.FloorControlEventExtras.DISPLAY_NAME);
442
+                                                            boolean allow_request=action.getBooleanExtra(ConstantsMCOP.FloorControlEventExtras.ALLOW_REQUEST,VALUE_BOOLEAN_DEFAULT);
443
+                                                            showData("floorControl ("+sessionID+")"," granted "+"-> userIDTaken(allowRequest="+allow_request+"):("+userIDTaken+":"+displayNameTaken+")");
444
+                                                            mState = State.TAKEN;
445
+                                                            btn_call.setEnabled(false);
446
+                                                            btn_hangup.setEnabled(true);
447
+                                                            btn_call.setBackgroundResource(R.drawable.token_red);
448
+                                                            text_talking.setVisibility((View.VISIBLE));
449
+                                                            text_callingid.setVisibility((View.VISIBLE));
450
+                                                            text_callingid.setText(userIDTaken);
451
+                                                            break;
452
+                                                        case denied:
453
+                                                            Log.e(TAG,"TOKEN DENIED");
454
+                                                            causeString=action.getStringExtra(ConstantsMCOP.FloorControlEventExtras.CAUSE_STRING);
455
+                                                            causeInt=action.getIntExtra(ConstantsMCOP.FloorControlEventExtras.CAUSE_CODE,ERROR_CODE_DEFAULT);
456
+                                                            showData("floorControl ("+sessionID+")"," denied "+"-> cause("+causeInt+":"+causeString+")");
457
+                                                            break;
458
+                                                        case revoked:
459
+                                                            Log.e(TAG,"TOKEN REVOKED");
460
+                                                            causeString=action.getStringExtra(ConstantsMCOP.FloorControlEventExtras.CAUSE_STRING);
461
+                                                            causeInt=action.getIntExtra(ConstantsMCOP.FloorControlEventExtras.CAUSE_CODE,ERROR_CODE_DEFAULT);
462
+                                                            showData("floorControl ("+sessionID+")"," revoked "+"-> cause("+causeInt+":"+causeString+")");
463
+                                                            break;
464
+                                                        default:
465
+                                                            break;
466
+                                                    }
467
+                                                }catch (Exception e){
468
+
469
+                                                }
470
+                                            }
471
+
472
+                                            break;
473
+                                        case groupInfoEvent:
474
+                                            break;
475
+                                        case groupAffiliationEvent:
476
+                                            codeError=-1;
477
+                                            eventTypeInt=action.getIntExtra(ConstantsMCOP.GroupAffiliationEventExtras.EVENT_TYPE,ERROR_CODE_DEFAULT);
478
+                                            ConstantsMCOP.GroupAffiliationEventExtras.GroupAffiliationEventTypeEnum eventTypeAffiliation=null;
479
+                                            if(eventTypeInt!=ERROR_CODE_DEFAULT &&
480
+                                                    (eventTypeAffiliation=ConstantsMCOP.GroupAffiliationEventExtras.GroupAffiliationEventTypeEnum.fromInt(eventTypeInt))!=null ){
481
+                                                switch (eventTypeAffiliation) {
482
+                                                    case GROUP_AFFILIATION_UPDATE:
483
+                                                        Map<String, Integer> groups=(HashMap<String, Integer>)action.getSerializableExtra(ConstantsMCOP.GroupAffiliationEventExtras.GROUPS_LIST);
484
+                                                        if(groups!=null)
485
+                                                            showGroups(groups);
486
+                                                        break;
487
+                                                    case GROUP_AFFILIATION_ERROR:
488
+                                                        if((codeError=action.getIntExtra(ConstantsMCOP.GroupAffiliationEventExtras.ERROR_CODE,ERROR_CODE_DEFAULT))!=ERROR_CODE_DEFAULT){
489
+                                                            //Error in unLoginEvent
490
+                                                            stringError=action.getStringExtra(ConstantsMCOP.GroupAffiliationEventExtras.ERROR_STRING);
491
+                                                            String groupID=action.getStringExtra(ConstantsMCOP.GroupAffiliationEventExtras.GROUP_ID);
492
+                                                            showLastError("groupAffiliationEvent ("+groupID+")",codeError,stringError);
493
+                                                        }
494
+                                                        break;
495
+                                                    case REMOTE_AFFILIATION:
496
+                                                        break;
497
+                                                    default:
498
+                                                        showLastError("groupAffiliationEvent:",999,"INVALID RECEIVE EVENT");
499
+                                                        break;
500
+                                                }
501
+                                            }else{
502
+                                                showLastError("groupAffiliationEvent:",999,"INVALID RECEIVE EVENT");
503
+                                            }
504
+
505
+                                            break;
506
+                                        case selectedContactChangeEvent:
507
+                                            break;
508
+                                        case eMBMSNotificationEvent:
509
+                                            break;
510
+                                    }
511
+                                }catch (Exception ex){
512
+                                    Log.e(TAG,"Event Action Error: "+action.getAction()+" error:"+ex.getMessage());
513
+                                }
514
+                        }
515
+                    }
516
+                });
517
+            }
518
+        };
519
+
520
+        btn_register.setOnClickListener(new View.OnClickListener() {
521
+            @Override
522
+            public void onClick(View view) {
523
+                //test
524
+                try {
525
+                    if(mService!=null)
526
+                        mService.authorizeUser(null);
527
+                } catch (RemoteException e) {
528
+                    e.printStackTrace();
529
+                }
530
+                /*try {
531
+                    if(mService!=null)
532
+                        mService.loginMCOP();
533
+                } catch (RemoteException e) {
534
+                    e.printStackTrace();
535
+                }*/
536
+            }
537
+        });
538
+
539
+        btn_unregister.setOnClickListener(new View.OnClickListener() {
540
+            @Override
541
+            public void onClick(View view) {
542
+                try {
543
+                    if(mService!=null)
544
+                        mService.unLoginMCOP();
545
+                } catch (RemoteException e) {
546
+                    e.printStackTrace();
547
+                }
548
+            }
549
+        });
550
+
551
+        btn_hangup.setOnClickListener(new View.OnClickListener() {
552
+            @Override
553
+            public void onClick(View view) {
554
+                showIds(getApplicationContext());
555
+            }
556
+        });
557
+
558
+        btn_accept.setOnClickListener(new View.OnClickListener() {
559
+            @Override
560
+            public void onClick(View view) {
561
+                //Auto-accept used
562
+                //showIdsAcceptCall(getApplicationContext());
563
+            }
564
+        });
565
+
566
+        btn_speaker.setOnClickListener(new View.OnClickListener() {
567
+            @Override
568
+            public void onClick(View view) {
569
+                AudioManager mAudioManager;
570
+                mAudioManager =  (AudioManager)getSystemService(Context.AUDIO_SERVICE);
571
+                if(isSpeakerphoneOn){
572
+                    isSpeakerphoneOn=false;
573
+                    Log.d(TAG, "Speaker false");
574
+                    btn_speaker.setText(R.string.btn_speaker_off);
575
+                }else{
576
+                    isSpeakerphoneOn=true;
577
+                    Log.d(TAG, "Speaker true");
578
+                    btn_speaker.setText(R.string.btn_speaker_on);
579
+                }
580
+                mAudioManager.setSpeakerphoneOn(isSpeakerphoneOn);
581
+            }
582
+        });
583
+
584
+        switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
585
+            @Override
586
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
587
+                if(isChecked){
588
+                    // Switch is on. Private Call
589
+                    mCallType = CallType.PRIVATE;
590
+                    //Toast.makeText(getBaseContext(), "Selected: " + mCallType, Toast.LENGTH_SHORT).show();
591
+                    spinnerGroups.setVisibility((View.GONE));
592
+                    spinnerUsers.setVisibility((View.VISIBLE));
593
+                    spinnerGroups.setEnabled(false);
594
+                    spinnerUsers.setEnabled(true);
595
+                }
596
+                else {
597
+                    // Switch is off. Group Call
598
+                    mCallType = CallType.GROUP;
599
+                    //Toast.makeText(getBaseContext(), "Selected: " + mCallType, Toast.LENGTH_SHORT).show();
600
+                    spinnerUsers.setVisibility((View.GONE));
601
+                    spinnerGroups.setVisibility((View.VISIBLE));
602
+                    spinnerUsers.setEnabled(false);
603
+                    spinnerGroups.setEnabled(true);
604
+                }
605
+            }
606
+        });
607
+
608
+        spinnerUsers.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
609
+            @Override
610
+            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
611
+                selUser = parent.getItemAtPosition(position).toString();
612
+                //Toast.makeText(parent.getContext(), "Selected: " + selUser, Toast.LENGTH_LONG).show();
613
+            }
614
+
615
+            @Override
616
+            public void onNothingSelected(AdapterView<?> parent) {
617
+
618
+            }
619
+        });
620
+
621
+        spinnerGroups.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
622
+            @Override
623
+            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
624
+                selGroup = parent.getItemAtPosition(position).toString();
625
+                //Toast.makeText(parent.getContext(), "Selected: " + selGroup, Toast.LENGTH_LONG).show();
626
+            }
627
+
628
+            @Override
629
+            public void onNothingSelected(AdapterView<?> parent) {
630
+
631
+            }
632
+        });
633
+
634
+        btn_call.setOnTouchListener(new View.OnTouchListener() {
635
+            @Override
636
+            public boolean onTouch(View v, MotionEvent event) {
637
+                if(mState != State.NONE && event.getAction() == MotionEvent.ACTION_DOWN) {
638
+                    if (mState == State.IDLE) {
639
+                        //Request token
640
+                        Log.e(TAG,"TOKEN REQUEST");
641
+                        showIdsOperationFloorControl(getApplicationContext(), true);
642
+                    }
643
+                }else if (mState != State.NONE && event.getAction() == MotionEvent.ACTION_UP) {
644
+                    if (mState == State.GRANTED) {
645
+                        //Release token
646
+                        Log.e(TAG,"TOKEN RELEASE");
647
+                        showIdsOperationFloorControl(getApplicationContext(),false);
648
+                    }
649
+                } else if (event.getAction() == MotionEvent.ACTION_DOWN){
650
+                    makeCall();
651
+                }
652
+                return true;
653
+            }
654
+        });
655
+
656
+
657
+
658
+
659
+        //PTT button on Bittium Devices
660
+        mButtonPTTBroadCastRecvMCPTT=new BroadcastReceiver() {
661
+            @Override
662
+            public void onReceive(Context context, Intent intent) {
663
+                Log.d(TAG,"PTT button");
664
+                final String action = intent.getAction();
665
+                if(action.compareTo(ACTION_BUTTON_PTT_DOWN_BITTIUM)==0
666
+                         ){
667
+
668
+                    Log.d(TAG,"PTT button Down");
669
+                    if(mState==State.IDLE && !showIdsOperationFloorControl(getApplicationContext(), true)){
670
+                        Log.e(TAG,"Error: the device can´t request the Token now");
671
+                    }else if(mState==null || mState==State.NONE){
672
+                        makeCall();
673
+                    }
674
+                }else if(action.compareTo(ACTION_BUTTON_PTT_UP_BITTIUM)==0 && mState==State.GRANTED){
675
+                    Log.d(TAG,"PTT button Up");
676
+                    if(!showIdsOperationFloorControl(getApplicationContext(), false)){
677
+                        Log.e(TAG,"Error: the device can´t release the Token now");
678
+                    }
679
+                }else if(action.compareTo(ACTION_BUTTON_PTT_LONG_PRESS_BITTIUM)==0){
680
+                    Log.d(TAG,"Long PTT button press");
681
+                }
682
+            }
683
+        };
684
+        final IntentFilter intentFilter2 = new IntentFilter();
685
+        intentFilter2.addAction(ACTION_BUTTON_PTT_DOWN_BITTIUM);
686
+        intentFilter2.addAction(ACTION_BUTTON_PTT_UP_BITTIUM);
687
+        intentFilter2.addAction(ACTION_BUTTON_PTT_LONG_PRESS_BITTIUM);
688
+
689
+        if(mConnection==null)
690
+            mConnection = new ServiceConnection() {
691
+
692
+                @Override
693
+                public void onServiceConnected(ComponentName className, IBinder service) {
694
+                    Log.e(TAG,"Service binded! "+className.getPackageName()+"\n");
695
+                    mService = IMCOPsdk.Stub.asInterface(service);
696
+
697
+                    try {
698
+                        Log.d(TAG,"execute "+"registerCallback"+mMCOPCallback);
699
+                        mService.registerCallback(mMCOPCallback);
700
+                    } catch (RemoteException e) {
701
+                        e.printStackTrace();
702
+                    }
703
+                    isConnect=true;
704
+
705
+                    //AUTO Register
706
+                    final Handler handler = new Handler();
707
+                    handler.postDelayed(new Runnable() {
708
+                        @Override
709
+                        public void run() {
710
+                            try {
711
+                                if(mService!=null)
712
+                                    mService.authorizeUser(null);
713
+                            } catch (RemoteException e) {
714
+                                e.printStackTrace();
715
+                            }
716
+                        }
717
+                    }, DEFAULT_REGISTER_DELAY);
718
+                }
719
+
720
+                @Override
721
+                public void onServiceDisconnected(ComponentName className) {
722
+                    mService = null;
723
+                    // This method is only invoked when the service quits from the other end or gets killed
724
+                    // Invoking exit() from the AIDL interface makes the Service kill itself, thus invoking this.
725
+                    Log.e(TAG,"Service disconnected.\n");
726
+                    isConnect=false;
727
+                }
728
+            };
729
+        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
730
+            TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
731
+            if(tm!=null) {
732
+                String imei = tm.getDeviceId();
733
+                String client=clients.get(imei);
734
+                if(client!=null){
735
+                    this.currentProfile=client;
736
+                    Log.i(TAG,"currentProfile: " +currentProfile);
737
+                    connectService(currentProfile);
738
+                }else{
739
+                    showOptionsProfiles(clients, this);
740
+                }
741
+            }
742
+        }else{
743
+            showOptionsProfiles(clients, this);
744
+        }
745
+    }
746
+
747
+    private void loadGroups(){
748
+        //Adapter por Group Spinner
749
+        ArrayAdapter<String> groupAdaptor = new ArrayAdapter<>(getApplicationContext(),
750
+                android.R.layout.simple_spinner_item, groupsCurrent);
751
+        // Drop down layout style - list view with radio button
752
+        groupAdaptor.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
753
+        spinnerGroups.setAdapter(groupAdaptor);
754
+    }
755
+
756
+    private void makeCall(){
757
+        if (mCallType == CallType.GROUP) {
758
+            //Group Call
759
+            try {
760
+                Log.e(TAG,"Call type: "+mCallType);
761
+                if(mService!=null)
762
+                    mService.makeCall(
763
+                            selGroup, //DEFAULT_GROUP,
764
+                            ConstantsMCOP.CallEventExtras.CallTypeEnum.Audio.getValue() |
765
+                                    ConstantsMCOP.CallEventExtras.CallTypeEnum.WithFloorCtrl.getValue() |
766
+                                    ConstantsMCOP.CallEventExtras.CallTypeEnum.PrearrangedGroup.getValue()
767
+                    );
768
+            } catch (RemoteException e) {
769
+                e.printStackTrace();
770
+            }
771
+        } else if (mCallType == CallType.PRIVATE) {
772
+            //Private Call
773
+            try {
774
+                Log.e(TAG,"Call type: "+mCallType);
775
+                if(mService!=null)
776
+                    mService.makeCall(
777
+                            selUser, //DEFAULT_PRIVATE_CALL,
778
+                            ConstantsMCOP.CallEventExtras.CallTypeEnum.Audio.getValue() |
779
+                                    ConstantsMCOP.CallEventExtras.CallTypeEnum.WithFloorCtrl.getValue() |
780
+                                    ConstantsMCOP.CallEventExtras.CallTypeEnum.Private.getValue()
781
+                    );
782
+            } catch (RemoteException e) {
783
+                e.printStackTrace();
784
+            }
785
+        }
786
+        btn_hangup.setEnabled(true);
787
+    }
788
+
789
+    private void showIds(final Context context){
790
+        if(userData.getSessionIDs()==null)return;
791
+        final String[] strings=userData.getSessionIDs().toArray(new String[userData.getSessionIDs().size()]);
792
+        if(strings==null || strings.length==0)return;
793
+        if(strings.length==1) {
794
+            try {
795
+                if (mService != null)
796
+                    mService.hangUpCall(strings[0]);
797
+            } catch (RemoteException e) {
798
+                e.printStackTrace();
799
+            }
800
+        } else {
801
+            mDialogIds = DialogMenu.newInstance(strings, null);
802
+            mDialogIds.setOnClickItemListener(new DialogMenu.OnClickListener() {
803
+                @Override
804
+                public void onClickItem(int item) {
805
+                    if (item >= 0 && strings.length > item) {
806
+                        try {
807
+                            if (mService != null)
808
+                                mService.hangUpCall(strings[item]);
809
+                        } catch (RemoteException e) {
810
+                            e.printStackTrace();
811
+                        }
812
+
813
+                    }
814
+                }
815
+            });
816
+            mDialogIds.show(getSupportFragmentManager(), "SimpleDialog");
817
+        }
818
+    }
819
+
820
+    private boolean showIdsOperationFloorControl(final Context context, final boolean request){
821
+        Log.i(TAG,"Send floor control operation : "+((request)?"request":"release"));
822
+        if(userData.getSessionIDs()==null)return false;
823
+        final String[] strings=userData.getSessionIDs().toArray(new String[userData.getSessionIDs().size()]);
824
+        if(strings==null || strings.length==0)return false;
825
+        if(strings.length==1) {
826
+            try {
827
+                if (mService != null){
828
+                    mService.floorControlOperation(
829
+                            strings[0],
830
+                            request ? ConstantsMCOP.FloorControlEventExtras.FloorControlOperationTypeEnum.MCPTT_Request.getValue() : ConstantsMCOP.FloorControlEventExtras.FloorControlOperationTypeEnum.MCPTT_Release.getValue(),
831
+                            null);
832
+                }
833
+                Log.i(TAG,"Send floor control operation 2: "+((request)?"request":"release"));
834
+
835
+            } catch (RemoteException e) {
836
+                e.printStackTrace();
837
+            }
838
+        } else {
839
+            mDialogIds = DialogMenu.newInstance(strings, null);
840
+            mDialogIds.setOnClickItemListener(new DialogMenu.OnClickListener() {
841
+                @Override
842
+                public void onClickItem(int item) {
843
+                    if (item >= 0 && strings.length > item) {
844
+                        try {
845
+                            if (mService != null){
846
+                                mService.floorControlOperation(
847
+                                        strings[item],
848
+                                        request ? ConstantsMCOP.FloorControlEventExtras.FloorControlOperationTypeEnum.MCPTT_Request.getValue() : ConstantsMCOP.FloorControlEventExtras.FloorControlOperationTypeEnum.MCPTT_Release.getValue(),
849
+                                        null);
850
+                                Log.i(TAG,"Send floor control operation 3: "+((request)?"request":"release"));
851
+                            }
852
+
853
+                        } catch (RemoteException e) {
854
+                            e.printStackTrace();
855
+                        }
856
+                    }
857
+                }
858
+            });
859
+            mDialogIds.show(getSupportFragmentManager(), "SimpleDialog");
860
+        }
861
+        return true;
862
+    }
863
+
864
+    private void showIdsAcceptCall(final Context context, String sessionID){
865
+        if(userData.getSessionIDs()==null)return;
866
+        final String[] strings=userData.getSessionIDs().toArray(new String[userData.getSessionIDs().size()]);
867
+        if(strings==null)return;
868
+        try {
869
+            if(mService!=null)
870
+                mService.acceptCall(sessionID);
871
+                btn_call.setBackgroundResource(R.drawable.token_red);
872
+        } catch (RemoteException e) {
873
+            e.printStackTrace();
874
+        }
875
+    }
876
+
877
+    @Override
878
+    protected void onDestroy(){
879
+        if(BuildConfig.DEBUG)Log.i(TAG,"onDestroy");
880
+        super.onDestroy();
881
+        isConnect=false;
882
+        if(mConnection!=null && isConnect)
883
+            try{
884
+                unbindService(mConnection);
885
+            }catch (Exception e){
886
+                Log.e(TAG,"Error in unbind Service");
887
+            }
888
+        if(serviceIntent!=null);
889
+        /*
890
+        try{
891
+            stopService(serviceIntent);
892
+        }catch (Exception e){
893
+            Log.e(TAG,"Error in stop Service");
894
+        }
895
+        */
896
+        mConnection=null;
897
+    }
898
+
899
+    @Override
900
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
901
+        switch (requestCode){
902
+        }
903
+    }
904
+
905
+    //START GUI
906
+    private void unRegisted(boolean success){
907
+        userData.setRegisted(false);
908
+        userData.setDisplayName(null);
909
+        userData.setMcpttID(null);
910
+        text_info.setText("UNREGISTEREDD");
911
+        text_status.setText(getString(R.string.text_status));
912
+        btn_call.setEnabled(false);
913
+        btn_call.setBackgroundResource(R.drawable.token_inactive);
914
+        btn_unregister.setEnabled(false);
915
+        btn_register.setEnabled(true);
916
+        reg_status.setEnabled(false);
917
+        switchCompat.setEnabled(false);
918
+        switch_group.setTextColor(ContextCompat.getColor(this, R.color.background));
919
+        switch_private.setTextColor(ContextCompat.getColor(this, R.color.background));
920
+        spinnerGroups.setEnabled(false);
921
+        spinnerUsers.setEnabled(false);
922
+        btn_speaker.setEnabled(false);
923
+        isSpeakerphoneOn=false;
924
+        btn_speaker.setText(R.string.btn_speaker_off);
925
+    }
926
+
927
+    private void isRegisted(boolean success,String mcpttID,String displayName){
928
+        userData.setRegisted(success);
929
+        if(mcpttID!=null)
930
+            userData.setMcpttID(mcpttID);
931
+        if(displayName!=null){
932
+            userData.setDisplayName(displayName);
933
+        }
934
+        text_info.setText("REGISTERED "+"MCPTT ID: "+mcpttID+" DISPLAY NAME: "+displayName);
935
+        text_status.setText(displayName);
936
+        btn_unregister.setEnabled(true);
937
+        btn_register.setEnabled(false);
938
+        btn_call.setBackgroundResource(R.drawable.token_default);
939
+        reg_status.setEnabled(true);
940
+        btn_call.setEnabled(true);
941
+        switchCompat.setEnabled(true);
942
+        switchCompat.setChecked(false);
943
+        switch_group.setTextColor(ContextCompat.getColor(this, R.color.white));
944
+        switch_private.setTextColor(ContextCompat.getColor(this, R.color.white));
945
+        spinnerGroups.setEnabled(true);
946
+        spinnerUsers.setEnabled(false);
947
+        spinnerUsers.setVisibility((View.GONE));
948
+        spinnerGroups.setVisibility((View.VISIBLE));
949
+        btn_speaker.setEnabled(true);
950
+    }
951
+
952
+    private void showData(String eventType,String data){
953
+        text_info.setText(eventType+": "+data);
954
+    }
955
+
956
+    private void showLastError(String from,int code,String errorString){
957
+        Log.e(TAG,"ERROR "+from+": "+code+" "+errorString);
958
+        text_info.setText("ERROR  "+from+": "+code+" "+errorString);
959
+    }
960
+
961
+    private void showGroups(Map<String, Integer> groups){
962
+        String result="";
963
+        if(groups!=null){
964
+            groupsCurrent=new ArrayList<>();
965
+            for (String groupID:groups.keySet()){
966
+                String type="";
967
+                switch (ConstantsMCOP.GroupAffiliationEventExtras.GroupAffiliationStateEnum.fromInt(groups.get(groupID))){
968
+                    case notaffiliated:
969
+                        type="notaffiliated";
970
+                        break;
971
+                    case affiliating:
972
+                        type="affiliating";
973
+                        break;
974
+                    case affiliated:
975
+                        type="affiliated";
976
+                        groupsCurrent.add(groupID);
977
+                        break;
978
+                    case deaffiliating:
979
+                        type="deaffiliating";
980
+                        break;
981
+                }
982
+                result=result+"groupID:"+groupID+":"+type+"\n";
983
+            }
984
+            loadGroups();
985
+        }
986
+
987
+        text_affiliation.setText("List Affiliation Groups: \n"+result);
988
+    }
989
+
990
+    /**
991
+     * Set permissions for Android 6.0 or above
992
+     */
993
+    protected void setPermissions(){
994
+        //Set permissions
995
+        //READ_PHONE_STATE
996
+        if (ContextCompat.checkSelfPermission(this,
997
+                Manifest.permission.RECORD_AUDIO)
998
+                != PackageManager.PERMISSION_GRANTED ||
999
+                ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
1000
+                ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED ||
1001
+                ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
1002
+                ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
1003
+                ) {
1004
+            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
1005
+                    Manifest.permission.RECORD_AUDIO)) {
1006
+                //Show an explanation to the user *asynchronously* -- don't block
1007
+                //this thread waiting for the user's response! After the user
1008
+                //sees the explanation, request the permission again.
1009
+                ActivityCompat.requestPermissions(this,
1010
+                        new String[]{Manifest.permission.RECORD_AUDIO,Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.CAMERA,Manifest.permission.READ_PHONE_STATE},
1011
+                        GET_PERMISSION);
1012
+            } else {
1013
+                //No explanation needed, we can request the permission.
1014
+                ActivityCompat.requestPermissions(this,
1015
+                        new String[]{Manifest.permission.RECORD_AUDIO,Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.CAMERA,Manifest.permission.READ_PHONE_STATE},
1016
+                        GET_PERMISSION);
1017
+
1018
+                //MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
1019
+                //app-defined int constant. The callback method gets the
1020
+                //result of the request.
1021
+            }
1022
+        }
1023
+    }
1024
+
1025
+    @Override
1026
+    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
1027
+        super.onRequestPermissionsResult(requestCode, permissions,grantResults);
1028
+        switch (requestCode) {
1029
+            case GET_PERMISSION: {
1030
+                //If request is cancelled, result arrays are empty.
1031
+                if (grantResults.length > 0
1032
+                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
1033
+                    //Permission was granted, yay! Do the
1034
+                    //contacts-related task you need to do.
1035
+                    //API>22
1036
+                    setPermissionsWriteSetting();
1037
+                } else {
1038
+                    setPermissions();
1039
+                    //Permission denied, boo! Disable the
1040
+                    //functionality that depends on this permission.
1041
+                }
1042
+                return;
1043
+            }
1044
+            default:
1045
+                break;
1046
+            //other 'case' lines to check for other
1047
+            //permissions this app might request
1048
+        }
1049
+    }
1050
+
1051
+    /**
1052
+     * API>22
1053
+     */
1054
+    @TargetApi(Build.VERSION_CODES.M)
1055
+    protected void setPermissionsWriteSetting(){
1056
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
1057
+            if (Settings.System.canWrite(this) ){
1058
+                //Do stuff here
1059
+            }
1060
+            else {
1061
+                Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);
1062
+                intent.setData(Uri.parse("package:" + this.getPackageName()));
1063
+                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1064
+                startActivity(intent);
1065
+            }
1066
+        }
1067
+    }
1068
+    //END GUI
1069
+
1070
+    private Map<String,String> getProfilesParameters(List<String> parameters){
1071
+        Map<String,String> parametersMap=new HashMap<>();
1072
+        if(parameters!=null && !parameters.isEmpty()){
1073
+            Log.i(TAG,"we external parameters");
1074
+        }else{
1075
+            Log.i(TAG,"we don´t have external parameters");
1076
+            parameters=loadParameters();
1077
+        }
1078
+
1079
+        if(parameters!=null && !parameters.isEmpty())
1080
+            for (String parameter:parameters){
1081
+                Log.i(TAG,"parameter: "+parameter);
1082
+                String[] parametersSplit=parameter.split(":");
1083
+                if(parametersSplit!=null && parametersSplit.length==2){
1084
+                    parametersMap.put(parametersSplit[0],parametersSplit[1]);
1085
+                }
1086
+            }
1087
+        if(parametersMap!=null && !parametersMap.isEmpty()){
1088
+            saveParameters(parameters);
1089
+        }
1090
+        return parametersMap;
1091
+    }
1092
+
1093
+    private boolean saveParameters(List<String> parameters){
1094
+        if(preferencesManager!=null){
1095
+            return preferencesManager.putStringSet(this,PARAMETER_SAVE_PROFILE,new HashSet<String>(parameters));
1096
+        }
1097
+        return false;
1098
+    }
1099
+
1100
+    private ArrayList<String> loadParameters(){
1101
+        if(preferencesManager!=null){
1102
+            Set<String> stringSet=preferencesManager.getStringSet(this,PARAMETER_SAVE_PROFILE);
1103
+            if(stringSet!=null){
1104
+                return (new ArrayList<String>(stringSet));
1105
+            }
1106
+        }
1107
+        return null;
1108
+    }
1109
+
1110
+    private void showOptionsProfiles(Map<String,String> stringsList,final Context context){
1111
+        if(stringsList==null)return;
1112
+        final String[] strings=stringsList.values().toArray(new String[stringsList.size()]);
1113
+        if(strings==null || strings.length==0)return;
1114
+        mDialogMenu = DialogMenu.newInstance(strings,null);
1115
+        mDialogMenu.setOnClickItemListener(new DialogMenu.OnClickListener() {
1116
+            @Override
1117
+            public void onClickItem(int item) {
1118
+                if(item>=0 && strings.length>item){
1119
+                    Log.d(TAG,"Select profile: "+strings[item]);
1120
+                    connectService(strings[item]);
1121
+                }
1122
+            }
1123
+        });
1124
+        mDialogMenu.show(getSupportFragmentManager(), "SimpleDialog");
1125
+    }
1126
+
1127
+    private void connectService(String client){
1128
+        if(!isConnect){
1129
+            serviceIntent = new Intent()
1130
+                    .setComponent(new ComponentName(
1131
+                            "org.mcopenplatform.muoapi",
1132
+                            "org.mcopenplatform.muoapi.MCOPsdk"));
1133
+
1134
+            Log.i(TAG,"Current profile: "+currentProfile);
1135
+            serviceIntent.putExtra("PROFILE_SELECT", currentProfile!=null?currentProfile:client);
1136
+
1137
+            try{
1138
+                ComponentName componentName=this.startService(serviceIntent);
1139
+                if(componentName==null){
1140
+                    Log.e(TAG,"Starting Error: "+componentName.getPackageName());
1141
+                }else if(serviceIntent==null){
1142
+                    Log.e(TAG,"serviceIntent Error: "+componentName.getPackageName());
1143
+                }else if(mConnection==null){
1144
+                    Log.e(TAG,"mConnection Error: "+componentName.getPackageName());
1145
+                }else{
1146
+
1147
+                }
1148
+            }catch (Exception e){
1149
+                if(BuildConfig.DEBUG)Log.w(TAG,"Error in start service: "+e.getMessage());
1150
+            }
1151
+            Log.i(TAG,"Bind Service: "+bindService(serviceIntent, mConnection, BIND_AUTO_CREATE));
1152
+        }
1153
+    }
1154
+}
0 1155
\ No newline at end of file
1 1156
new file mode 100644
... ...
@@ -0,0 +1,58 @@
0
+/*
1
+ *
2
+ *  Copyright (C) 2018 Eduardo Zarate Lasurtegui
3
+ *   Copyright (C) 2018, University of the Basque Country (UPV/EHU)
4
+ *
5
+ *  Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
6
+ *
7
+ *  This file is part of MCOP MCPTT Client
8
+ *
9
+ *  This is free software: you can redistribute it and/or modify it under the terms of
10
+ *  the GNU General Public License as published by the Free Software Foundation, either version 3
11
+ *  of the License, or (at your option) any later version.
12
+ *
13
+ *  This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14
+ *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
+ *  See the GNU General Public License for more details.
16
+ *
17
+ *  You should have received a copy of the GNU General Public License along
18
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
19
+ *  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
+ */
21
+
22
+package org.test.client.mcopclient;
23
+
24
+import android.content.Context;
25
+import android.telephony.TelephonyManager;
26
+import android.util.Log;
27
+
28
+import static android.content.ContentValues.TAG;
29
+
30
+
31
+public class Utils {
32
+
33
+
34
+
35
+    public static String getTAG(String tag){
36
+        if(BuildConfig.LOG_SHOW){
37
+            return tag;
38
+        }else{
39
+            return BuildConfig.APPLICATION_ID;
40
+        }
41
+
42
+    }
43
+
44
+    public static void testHasCarrierPrivileges(Context context) {
45
+        //if (!hasCellular) return;
46
+        if (!((TelephonyManager)
47
+                context.getSystemService(Context.TELEPHONY_SERVICE)).hasCarrierPrivileges()) {
48
+           Log.e(TAG,"No hasCarrierPrivileges");
49
+        }else{
50
+            Log.e(TAG,"HasCarrierPrivileges");
51
+        }
52
+
53
+    }
54
+
55
+
56
+
57
+}
0 58
new file mode 100644
... ...
@@ -0,0 +1,100 @@
0
+/*
1
+ *
2
+ *  Copyright (C) 2018 Eduardo Zarate Lasurtegui
3
+ *   Copyright (C) 2018, University of the Basque Country (UPV/EHU)
4
+ *
5
+ *  Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
6
+ *
7
+ *  This file is part of MCOP MCPTT Client
8
+ *
9
+ *  This is free software: you can redistribute it and/or modify it under the terms of
10
+ *  the GNU General Public License as published by the Free Software Foundation, either version 3
11
+ *  of the License, or (at your option) any later version.
12
+ *
13
+ *  This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14
+ *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
+ *  See the GNU General Public License for more details.
16
+ *
17
+ *  You should have received a copy of the GNU General Public License along
18
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
19
+ *  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
+ */
21
+
22
+package org.test.client.mcopclient.datatype;
23
+
24
+import java.util.ArrayList;
25
+import java.util.HashMap;
26
+import java.util.Iterator;
27
+import java.util.List;
28
+import java.util.Map;
29
+
30
+
31
+public class UserData {
32
+    private String mcpttID;
33
+    private String displayName;
34
+    private Map<String,String> sessionIDs;
35
+    private boolean isRegisted;
36
+
37
+
38
+    public UserData(String mcpttID, String displayName) {
39
+        this.mcpttID = mcpttID;
40
+        this.displayName = displayName;
41
+        sessionIDs=new HashMap<String,String>();
42
+    }
43
+
44
+
45
+    public UserData(String mcpttID, String displayName, boolean isRegisted) {
46
+        this.mcpttID = mcpttID;
47
+        this.displayName = displayName;
48
+        this.isRegisted = isRegisted;
49
+        sessionIDs=new HashMap<String,String>();
50
+    }
51
+
52
+
53
+    public UserData() {
54
+        sessionIDs=new HashMap<String,String>();
55
+    }
56
+
57
+
58
+    public String getMcpttID() {
59
+        return mcpttID;
60
+    }
61
+
62
+    public void setMcpttID(String mcpttID) {
63
+        this.mcpttID = mcpttID;
64
+    }
65
+
66
+    public String getDisplayName() {
67
+        return displayName;
68
+    }
69
+
70
+    public void setDisplayName(String displayName) {
71
+        this.displayName = displayName;
72
+    }
73
+
74
+    public boolean isRegisted() {
75
+        return isRegisted;
76
+    }
77
+
78
+    public void setRegisted(boolean registed) {
79
+        isRegisted = registed;
80
+    }
81
+
82
+    public List<String> getSessionIDs() {
83
+        if(sessionIDs==null || sessionIDs.keySet()==null)return null;
84
+        Iterator<String> interator=sessionIDs.keySet().iterator();
85
+        ArrayList<String> ids=new ArrayList<>();
86
+        while (interator.hasNext())
87
+            ids.add(interator.next());
88
+        return ids;
89
+    }
90
+
91
+    public void removeSessionID(String sessionIDs) {
92
+        this.sessionIDs.remove(sessionIDs);
93
+    }
94
+
95
+
96
+    public void addSessionID(String sessionIDs) {
97
+        this.sessionIDs.put(sessionIDs,sessionIDs);
98
+    }
99
+}
0 100
new file mode 100644
... ...
@@ -0,0 +1,181 @@
0
+/*
1
+ *
2
+ *  Copyright (C) 2018 Eduardo Zarate Lasurtegui
3
+ *   Copyright (C) 2018, University of the Basque Country (UPV/EHU)
4
+ *
5
+ *  Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
6
+ *
7
+ *  This file is part of MCOP MCPTT Client
8
+ *
9
+ *  This is free software: you can redistribute it and/or modify it under the terms of
10
+ *  the GNU General Public License as published by the Free Software Foundation, either version 3
11
+ *  of the License, or (at your option) any later version.
12
+ *
13
+ *  This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14
+ *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
+ *  See the GNU General Public License for more details.
16
+ *
17
+ *  You should have received a copy of the GNU General Public License along
18
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
19
+ *  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
+ */
21
+
22
+package org.test.client.mcopclient.preference;
23
+
24
+import android.content.Context;
25
+import android.content.SharedPreferences;
26
+import android.util.Log;
27
+
28
+import java.util.Set;
29
+
30
+
31
+public class PreferencesManager {
32
+    protected static String TAG = PreferencesManager.class.getCanonicalName();
33
+    protected static PreferencesManager mPreferencesManager=null;
34
+    private  String PREFERENCE_ID=TAG+"PREFERENCE_ID";
35
+    public static final String  STRING_DEFAULT=TAG+".STRING_DEFAULT";
36
+
37
+
38
+
39
+    SharedPreferences sharedPref;
40
+    public PreferencesManager(String preference_ID){
41
+        this();
42
+        this.PREFERENCE_ID=preference_ID;
43
+    }
44
+    public PreferencesManager(){
45
+        super();
46
+    }
47
+
48
+    protected SharedPreferences createSharedPreferences(Context context){
49
+        return createSharedPreferences(context, PREFERENCE_ID);
50
+    }
51
+
52
+    protected SharedPreferences createSharedPreferences(Context context,String preference_ID){
53
+        if(context==null){
54
+            Log.e(TAG,"Error save data 1");
55
+            return null;
56
+        }
57
+        this.PREFERENCE_ID=preference_ID;
58
+        sharedPref = context.getSharedPreferences(this.PREFERENCE_ID, Context.MODE_PRIVATE);
59
+        return sharedPref;
60
+    }
61
+
62
+    /*
63
+    public static PreferencesManager getInstance(){
64
+        if(mPreferencesManager==null){
65
+            mPreferencesManager=new PreferencesManager();
66
+        }
67
+        return mPreferencesManager;
68
+    }
69
+    */
70
+
71
+    public boolean putStringSet(Context context,String key,Set<String> data){
72
+        if(context==null || key==null || data==null){
73
+            Log.e(TAG, "Some parameter is null object in putString.");
74
+            return false;
75
+        }
76
+        SharedPreferences.Editor editor = createSharedPreferences(context).edit();
77
+        editor.putStringSet(key, data);
78
+        return editor.commit();
79
+    }
80
+
81
+    public Set<String> getStringSet(Context context,String key){
82
+        return getStringSet(context, key, STRING_DEFAULT);
83
+    }
84
+
85
+    public Set<String> getStringSet(Context context,String key,String defaultString){
86
+        if(context==null || key==null){
87
+            Log.e(TAG,"Some parameter is null object in getString.");
88
+            return null;
89
+        }
90
+        SharedPreferences  sharedPreferences= createSharedPreferences(context);
91
+        return sharedPreferences.getStringSet(key, null);
92
+
93
+    }
94
+
95
+    public boolean putString(Context context,String key,String data){
96
+        if(context==null || key==null || data==null){
97
+            Log.e(TAG, "Some parameter is null object in putString.");
98
+            return false;
99
+        }
100
+        SharedPreferences.Editor editor = createSharedPreferences(context).edit();
101
+        editor.putString(key, data);
102
+        return editor.commit();
103
+    }
104
+
105
+    public String getString(Context context,String key){
106
+        return getString(context, key, STRING_DEFAULT);
107
+
108
+    }
109
+
110
+    public String getString(Context context,String key,String defaultString){
111
+        if(context==null || key==null){
112
+            Log.e(TAG,"Some parameter is null object in getString.");
113
+            return null;
114
+        }
115
+        SharedPreferences  sharedPreferences= createSharedPreferences(context);
116
+        return sharedPreferences.getString(key, defaultString);
117
+
118
+    }
119
+
120
+    public boolean putInt(Context context,String key,int data){
121
+        if(context==null || key==null){
122
+            Log.e(TAG,"Some parameter is null object in putInt.");
123
+            return false;
124
+        }
125
+        SharedPreferences.Editor editor = createSharedPreferences(context).edit();
126
+        editor.putInt(key, data);
127
+        return editor.commit();
128
+    }
129
+
130
+    public int getInt(Context context,String key){
131
+        if(context==null || key==null){
132
+            Log.e(TAG,"Some parameter is null object in getInt.");
133
+            return -1;
134
+        }
135
+        SharedPreferences.Editor editor = createSharedPreferences(context).edit();
136
+        return createSharedPreferences(context).getInt(key, -1);
137
+
138
+    }
139
+
140
+    public boolean putLong(Context context,String key,long data){
141
+        if(context==null || key==null){
142
+            Log.e(TAG,"Some parameter is null object in putLong.");
143
+            return false;
144
+        }
145
+        SharedPreferences.Editor editor = createSharedPreferences(context).edit();
146
+        editor.putLong(key, data);
147
+        return editor.commit();
148
+    }
149
+
150
+    public long getLong(Context context,String key){
151
+        if(context==null || key==null){
152
+            Log.e(TAG,"Some parameter is null object in getLong.");
153
+            return -1;
154
+        }
155
+        SharedPreferences sharedPreferences= createSharedPreferences(context);
156
+        return sharedPreferences.getLong(key, -1);
157
+
158
+    }
159
+
160
+
161
+    public boolean putFloat(Context context,String key,float data){
162
+        if(context==null || key==null){
163
+            Log.e(TAG,"Some parameter is null object in putFloat.");
164
+            return false;
165
+        }
166
+        SharedPreferences.Editor editor = createSharedPreferences(context).edit();
167
+        editor.putFloat(key, data);
168
+        return editor.commit();
169
+    }
170
+
171
+    public float getFloat(Context context,String key){
172
+        if(context==null || key==null){
173
+            Log.e(TAG,"Some parameter is null object in getLong.");
174
+            return -1;
175
+        }
176
+        SharedPreferences sharedPreferences= createSharedPreferences(context);
177
+        return sharedPreferences.getFloat(key, -1);
178
+
179
+    }
180
+}
0 181
new file mode 100644
... ...
@@ -0,0 +1,47 @@
0
+/*
1
+ *
2
+ *  Copyright (C) 2018 Eduardo Zarate Lasurtegui
3
+ *   Copyright (C) 2018, University of the Basque Country (UPV/EHU)
4
+ *
5
+ *  Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
6
+ *
7
+ *  This file is part of MCOP MCPTT Client
8
+ *
9
+ *  This is free software: you can redistribute it and/or modify it under the terms of
10
+ *  the GNU General Public License as published by the Free Software Foundation, either version 3
11
+ *  of the License, or (at your option) any later version.
12
+ *
13
+ *  This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14
+ *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
+ *  See the GNU General Public License for more details.
16
+ *
17
+ *  You should have received a copy of the GNU General Public License along
18
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
19
+ *  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
+ */
21
+
22
+package org.test.client.mcopclient.preference;
23
+
24
+import android.content.Context;
25
+import android.content.SharedPreferences;
26
+import android.preference.PreferenceManager;
27
+
28
+
29
+public class PreferencesManagerDefault extends PreferencesManager {
30
+    private static String TAG = PreferencesManagerDefault.class.getCanonicalName();
31
+
32
+
33
+    protected SharedPreferences createSharedPreferences(Context context){
34
+        return createSharedPreferences(context, null);
35
+    }
36
+
37
+    protected SharedPreferences createSharedPreferences(Context context,String preference_ID){
38
+        if(context==null){
39
+            return null;
40
+        }
41
+        sharedPref = PreferenceManager
42
+                .getDefaultSharedPreferences(context);
43
+        return sharedPref;
44
+    }
45
+
46
+}
0 47
\ No newline at end of file
1 48
new file mode 100644
... ...
@@ -0,0 +1,34 @@
0
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
1
+    xmlns:aapt="http://schemas.android.com/aapt"
2
+    android:width="108dp"
3
+    android:height="108dp"
4
+    android:viewportHeight="108"
5
+    android:viewportWidth="108">
6
+    <path
7
+        android:fillType="evenOdd"
8
+        android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
9
+        android:strokeColor="#00000000"
10
+        android:strokeWidth="1">
11
+        <aapt:attr name="android:fillColor">
12
+            <gradient
13
+                android:endX="78.5885"
14
+                android:endY="90.9159"
15
+                android:startX="48.7653"
16
+                android:startY="61.0927"
17
+                android:type="linear">
18
+                <item
19
+                    android:color="#44000000"
20
+                    android:offset="0.0" />
21
+                <item
22
+                    android:color="#00000000"
23
+                    android:offset="1.0" />
24
+            </gradient>
25
+        </aapt:attr>
26
+    </path>
27
+    <path
28
+        android:fillColor="#FFFFFF"
29
+        android:fillType="nonZero"
30
+        android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
31
+        android:strokeColor="#00000000"
32
+        android:strokeWidth="1" />
33
+</vector>
0 34
new file mode 100644
... ...
@@ -0,0 +1,9 @@
0
+<?xml version="1.0" encoding="utf-8"?>
1
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
2
+    android:shape="rectangle">
3
+    <gradient
4
+        android:angle="90"
5
+        android:endColor="@color/colorPrimary"
6
+        android:startColor="@color/colorSecondary"
7
+        android:type="linear" />
8
+</shape>
0 9
\ No newline at end of file
1 10
new file mode 100644
... ...
@@ -0,0 +1,33 @@
0
+<?xml version="1.0" encoding="utf-8"?>
1
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
2
+<item android:state_enabled="false" android:color="@color/dark">
3
+    <shape xmlns:android="http://schemas.android.com/apk/res/android"
4
+        android:shape="oval">
5
+        <stroke android:color="@color/dark"
6
+            android:width="2dp"></stroke>
7
+        <gradient
8
+            android:angle="45"
9
+            android:endColor="@color/colorPrimaryLight"
10
+            android:gradientRadius="10"
11
+            android:startColor="@color/colorPrimaryDark"
12
+            android:type="linear" />
13
+        <size android:width="80dp"
14
+            android:height="80dp"></size>
15
+    </shape>
16
+</item>
17
+<item android:state_enabled="true" android:color="@color/white">
18
+    <shape xmlns:android="http://schemas.android.com/apk/res/android"
19
+        android:shape="oval">
20
+        <stroke android:color="@color/white"
21
+            android:width="2dp"></stroke>
22
+        <gradient
23
+            android:angle="45"
24
+            android:endColor="@color/colorPrimaryLight"
25
+            android:gradientRadius="10"
26
+            android:startColor="@color/colorPrimaryDark"
27
+            android:type="linear" />
28
+        <size android:width="80dp"
29
+            android:height="80dp"></size>
30
+    </shape>
31
+</item>
32
+</selector>
0 33
\ No newline at end of file
1 34
new file mode 100644
... ...
@@ -0,0 +1,170 @@
0
+<?xml version="1.0" encoding="utf-8"?>
1
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+    android:width="108dp"
3
+    android:height="108dp"
4
+    android:viewportHeight="108"
5
+    android:viewportWidth="108">
6
+    <path
7
+        android:fillColor="#26A69A"
8
+        android:pathData="M0,0h108v108h-108z" />
9
+    <path
10
+        android:fillColor="#00000000"
11
+        android:pathData="M9,0L9,108"
12
+        android:strokeColor="#33FFFFFF"
13
+        android:strokeWidth="0.8" />
14
+    <path
15
+        android:fillColor="#00000000"
16
+        android:pathData="M19,0L19,108"
17
+        android:strokeColor="#33FFFFFF"
18
+        android:strokeWidth="0.8" />
19
+    <path
20
+        android:fillColor="#00000000"
21
+        android:pathData="M29,0L29,108"
22
+        android:strokeColor="#33FFFFFF"
23
+        android:strokeWidth="0.8" />
24
+    <path
25
+        android:fillColor="#00000000"
26
+        android:pathData="M39,0L39,108"
27
+        android:strokeColor="#33FFFFFF"
28
+        android:strokeWidth="0.8" />
29
+    <path
30
+        android:fillColor="#00000000"
31
+        android:pathData="M49,0L49,108"
32
+        android:strokeColor="#33FFFFFF"
33
+        android:strokeWidth="0.8" />
34
+    <path
35
+        android:fillColor="#00000000"
36
+        android:pathData="M59,0L59,108"
37
+        android:strokeColor="#33FFFFFF"
38
+        android:strokeWidth="0.8" />
39
+    <path
40
+        android:fillColor="#00000000"
41
+        android:pathData="M69,0L69,108"
42
+        android:strokeColor="#33FFFFFF"
43
+        android:strokeWidth="0.8" />
44
+    <path
45
+        android:fillColor="#00000000"
46
+        android:pathData="M79,0L79,108"
47
+        android:strokeColor="#33FFFFFF"
48
+        android:strokeWidth="0.8" />
49
+    <path
50
+        android:fillColor="#00000000"
51
+        android:pathData="M89,0L89,108"
52
+        android:strokeColor="#33FFFFFF"
53
+        android:strokeWidth="0.8" />
54
+    <path
55
+        android:fillColor="#00000000"
56
+        android:pathData="M99,0L99,108"
57
+        android:strokeColor="#33FFFFFF"
58
+        android:strokeWidth="0.8" />
59
+    <path
60
+        android:fillColor="#00000000"
61
+        android:pathData="M0,9L108,9"
62
+        android:strokeColor="#33FFFFFF"
63
+        android:strokeWidth="0.8" />
64
+    <path
65
+        android:fillColor="#00000000"
66
+        android:pathData="M0,19L108,19"
67
+        android:strokeColor="#33FFFFFF"
68
+        android:strokeWidth="0.8" />
69
+    <path
70
+        android:fillColor="#00000000"
71
+        android:pathData="M0,29L108,29"
72
+        android:strokeColor="#33FFFFFF"
73
+        android:strokeWidth="0.8" />
74
+    <path
75
+        android:fillColor="#00000000"
76
+        android:pathData="M0,39L108,39"
77
+        android:strokeColor="#33FFFFFF"
78
+        android:strokeWidth="0.8" />
79
+    <path
80
+        android:fillColor="#00000000"
81
+        android:pathData="M0,49L108,49"
82
+        android:strokeColor="#33FFFFFF"
83
+        android:strokeWidth="0.8" />
84
+    <path
85
+        android:fillColor="#00000000"
86
+        android:pathData="M0,59L108,59"
87
+        android:strokeColor="#33FFFFFF"
88
+        android:strokeWidth="0.8" />
89
+    <path
90
+        android:fillColor="#00000000"
91
+        android:pathData="M0,69L108,69"
92
+        android:strokeColor="#33FFFFFF"
93
+        android:strokeWidth="0.8" />
94
+    <path
95
+        android:fillColor="#00000000"
96
+        android:pathData="M0,79L108,79"
97
+        android:strokeColor="#33FFFFFF"
98
+        android:strokeWidth="0.8" />
99
+    <path
100
+        android:fillColor="#00000000"
101
+        android:pathData="M0,89L108,89"
102
+        android:strokeColor="#33FFFFFF"
103
+        android:strokeWidth="0.8" />
104
+    <path
105
+        android:fillColor="#00000000"
106
+        android:pathData="M0,99L108,99"
107
+        android:strokeColor="#33FFFFFF"
108
+        android:strokeWidth="0.8" />
109
+    <path
110
+        android:fillColor="#00000000"
111
+        android:pathData="M19,29L89,29"
112
+        android:strokeColor="#33FFFFFF"
113
+        android:strokeWidth="0.8" />
114
+    <path
115
+        android:fillColor="#00000000"
116
+        android:pathData="M19,39L89,39"
117
+        android:strokeColor="#33FFFFFF"
118
+        android:strokeWidth="0.8" />
119
+    <path
120
+        android:fillColor="#00000000"
121
+        android:pathData="M19,49L89,49"
122
+        android:strokeColor="#33FFFFFF"
123
+        android:strokeWidth="0.8" />
124
+    <path
125
+        android:fillColor="#00000000"
126
+        android:pathData="M19,59L89,59"
127
+        android:strokeColor="#33FFFFFF"
128
+        android:strokeWidth="0.8" />
129
+    <path
130
+        android:fillColor="#00000000"
131
+        android:pathData="M19,69L89,69"
132
+        android:strokeColor="#33FFFFFF"
133
+        android:strokeWidth="0.8" />
134
+    <path
135
+        android:fillColor="#00000000"
136
+        android:pathData="M19,79L89,79"
137
+        android:strokeColor="#33FFFFFF"
138
+        android:strokeWidth="0.8" />
139
+    <path
140
+        android:fillColor="#00000000"
141
+        android:pathData="M29,19L29,89"
142
+        android:strokeColor="#33FFFFFF"
143
+        android:strokeWidth="0.8" />
144
+    <path
145
+        android:fillColor="#00000000"
146
+        android:pathData="M39,19L39,89"
147
+        android:strokeColor="#33FFFFFF"
148
+        android:strokeWidth="0.8" />
149
+    <path
150
+        android:fillColor="#00000000"
151
+        android:pathData="M49,19L49,89"
152
+        android:strokeColor="#33FFFFFF"
153
+        android:strokeWidth="0.8" />
154
+    <path
155
+        android:fillColor="#00000000"
156
+        android:pathData="M59,19L59,89"
157
+        android:strokeColor="#33FFFFFF"
158
+        android:strokeWidth="0.8" />
159
+    <path
160
+        android:fillColor="#00000000"
161
+        android:pathData="M69,19L69,89"
162
+        android:strokeColor="#33FFFFFF"
163
+        android:strokeWidth="0.8" />
164
+    <path
165
+        android:fillColor="#00000000"
166
+        android:pathData="M79,19L79,89"
167
+        android:strokeColor="#33FFFFFF"
168
+        android:strokeWidth="0.8" />
169
+</vector>
0 170
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+<?xml version="1.0" encoding="utf-8"?>
1
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
2
+    <item android:drawable="@drawable/token_default" android:state_enabled="true"></item>
3
+    <item android:drawable="@drawable/token_inactive" android:state_enabled="false"></item>
4
+    <item android:drawable="@drawable/token_green" android:state_pressed="true"></item>
5
+    <item android:drawable="@drawable/token_red" android:state_pressed="false"></item>
6
+</selector>
0 7
\ No newline at end of file
1 8
new file mode 100644
2 9
Binary files /dev/null and b/app/src/main/res/drawable/mcop_logo.png differ
3 10
new file mode 100644
... ...
@@ -0,0 +1,22 @@
0
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
1
+    <item android:state_enabled="false" android:color="@color/dark">
2
+        <shape xmlns:android="http://schemas.android.com/apk/res/android"
3
+            android:shape="oval">
4
+            <stroke android:color="@color/white"
5
+                android:width="1dp"></stroke>
6
+            <solid android:color="@color/unregistered"></solid>
7
+            <size android:width="21dp"
8
+                android:height="21dp"></size>
9
+        </shape>
10
+    </item>
11
+    <item android:state_enabled="true" android:color="@color/dark">
12
+        <shape xmlns:android="http://schemas.android.com/apk/res/android"
13
+            android:shape="oval">
14
+            <stroke android:color="@color/white"
15
+                android:width="1dp"></stroke>
16
+            <solid android:color="@color/registered"></solid>
17
+            <size android:width="21dp"
18
+                android:height="21dp"></size>
19
+        </shape>
20
+    </item>
21
+</selector>
0 22
\ No newline at end of file
1 23
new file mode 100644
... ...
@@ -0,0 +1,23 @@
0
+<resources>
1
+    <!-- For the resting Spinner style -->
2
+    <item name="android:spinnerItemStyle">
3
+        @style/spinnerItemStyle
4
+    </item>
5
+
6
+    <!-- For each individual Spinner list item once clicked on -->
7
+    <item name="android:spinnerDropDownItemStyle">
8
+        @style/spinnerDropDownItemStyle
9
+    </item>
10
+
11
+    <style name="spinnerItemStyle">
12
+        <item name="android:textSize">23sp</item>
13
+        <item name="android:textColor">#000000</item>
14
+        <item name="android:background">#008080</item>
15
+    </style>
16
+
17
+    <style name="spinnerDropDownItemStyle">
18
+        <item name="android:padding">5sp</item>
19
+        <item name="android:textSize">25sp</item>
20
+        <item name="android:textColor">#000000</item>
21
+    </style>
22
+</resources>
0 23
\ No newline at end of file
1 24
new file mode 100644
2 25
Binary files /dev/null and b/app/src/main/res/drawable/token_default.png differ
3 26
new file mode 100644
4 27
Binary files /dev/null and b/app/src/main/res/drawable/token_gray.png differ
5 28
new file mode 100644
6 29
Binary files /dev/null and b/app/src/main/res/drawable/token_green.png differ
7 30
new file mode 100644
8 31
Binary files /dev/null and b/app/src/main/res/drawable/token_inactive.png differ
9 32
new file mode 100644
10 33
Binary files /dev/null and b/app/src/main/res/drawable/token_red.png differ
11 34
new file mode 100644
... ...
@@ -0,0 +1,317 @@
0
+<?xml version="1.0" encoding="utf-8"?>
1
+<!--*
2
+    *
3
+    *  Copyright (C) 2018 Ander Nieva Anza
4
+    *   Copyright (C) 2018, University of the Basque Country (UPV/EHU)
5
+    *
6
+    *  Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
7
+    *
8
+    *  This file is part of MCOP MCPTT Client
9
+    *
10
+    *  This is free software: you can redistribute it and/or modify it under the terms of
11
+    *  the GNU General Public License as published by the Free Software Foundation, either version 3
12
+    *  of the License, or (at your option) any later version.
13
+    *
14
+    *  This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15
+    *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
+    *  See the GNU General Public License for more details.
17
+    *
18
+    *  You should have received a copy of the GNU General Public License along
19
+    *  with this program; if not, write to the Free Software Foundation, Inc.,
20
+    *  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
+    *
22
+    *-->
23
+
24
+<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
25
+    xmlns:app="http://schemas.android.com/apk/res-auto"
26
+    xmlns:tools="http://schemas.android.com/tools"
27
+    android:layout_width="match_parent"
28
+    android:layout_height="match_parent"
29
+    android:background="@color/background"
30
+    tools:context="org.test.client.mcopclient.MainActivity">
31
+
32
+    <LinearLayout
33
+        android:layout_width="wrap_content"
34
+        android:layout_height="wrap_content"
35
+        android:orientation="vertical">
36
+
37
+        <ImageView
38
+            android:id="@+id/logoMCOP"
39
+            android:layout_width="match_parent"
40
+            android:layout_height="56dp"
41
+            android:background="@color/colorPrimaryDark"
42
+            app:srcCompat="@drawable/mcop_logo" />
43
+    </LinearLayout>
44
+
45
+    <LinearLayout
46
+        android:layout_width="match_parent"
47
+        android:layout_height="wrap_content"
48
+        android:layout_marginTop="55dp"
49
+        android:gravity="center_horizontal"
50
+        android:orientation="vertical"
51
+        app:layout_constraintTop_toTopOf="parent"
52
+        tools:layout_editor_absoluteX="2dp">
53
+
54
+        <RelativeLayout
55
+            android:layout_width="fill_parent"
56
+            android:layout_height="wrap_content"
57
+            android:layout_marginTop="10dp"
58
+            android:layout_weight="1"
59
+            android:orientation="horizontal">
60
+
61
+            <TextView
62
+                android:id="@+id/text_status"
63
+                android:layout_width="wrap_content"
64
+                android:layout_height="wrap_content"
65
+                android:layout_alignParentRight="true"
66
+                android:layout_marginLeft="10dp"
67
+                android:layout_marginRight="40dp"
68
+                android:layout_weight="1"
69
+                android:text="@string/text_status"
70
+                android:textColor="@color/white"
71
+                android:textSize="14sp" />
72
+
73
+            <Button
74
+                android:id="@+id/reg_status"
75
+                android:layout_width="21dp"
76
+                android:layout_height="21dp"
77
+                android:layout_alignParentRight="true"
78
+                android:layout_marginLeft="10dp"
79
+                android:layout_marginRight="15dp"
80
+                android:layout_weight="1"
81
+                android:background="@drawable/reg_status"
82
+                tools:layout_editor_absoluteX="21dp"
83
+                tools:layout_editor_absoluteY="21dp" />
84
+        </RelativeLayout>
85
+
86
+        <LinearLayout
87
+            android:layout_width="wrap_content"
88
+            android:layout_height="match_parent"
89
+            android:layout_weight="1"
90
+            android:layout_marginTop="3dp"
91
+            android:orientation="vertical">
92
+
93
+            <TextView
94
+                android:id="@+id/text_talking"
95
+                android:layout_width="match_parent"
96
+                android:layout_height="wrap_content"
97
+                android:text="@string/text_talking"
98
+                android:textSize="15sp"
99
+                android:textColor="@color/white"/>
100
+            <TextView
101
+                android:id="@+id/text_callingid"
102
+                android:layout_width="match_parent"
103
+                android:layout_height="wrap_content"
104
+                android:textSize="18sp"
105
+                android:textColor="@color/white"/>
106
+        </LinearLayout>
107
+
108
+        <LinearLayout
109
+            android:layout_width="wrap_content"
110
+            android:layout_height="match_parent"
111
+            android:layout_marginTop="10dp"
112
+            android:layout_weight="1"
113
+            android:orientation="horizontal"
114
+            tools:layout_editor_absoluteX="8dp"
115
+            tools:layout_editor_absoluteY="8dp">
116
+
117
+            <Button
118
+                android:id="@+id/btn_register"
119
+                android:layout_width="85dp"
120
+                android:layout_height="85dp"
121
+                android:layout_marginLeft="10dp"
122
+                android:layout_marginRight="10dp"
123
+                android:layout_weight="1"
124
+                android:background="@drawable/circle_btn"
125
+                android:text="@string/btn_register"
126
+                android:textSize="10sp"
127
+                tools:layout_editor_absoluteX="85dp"
128
+                tools:layout_editor_absoluteY="85dp" />
129
+
130
+            <Button
131
+                android:id="@+id/btn_unregister"
132
+                android:layout_width="85dp"
133
+                android:layout_height="85dp"
134
+                android:layout_marginLeft="10dp"
135
+                android:layout_marginRight="10dp"
136
+                android:layout_weight="1"
137
+                android:background="@drawable/circle_btn"
138
+                android:text="@string/btn_unregister"
139
+                android:textSize="10sp"
140
+                tools:layout_editor_absoluteX="85dp"
141
+                tools:layout_editor_absoluteY="85dp" />
142
+        </LinearLayout>
143
+
144
+        <LinearLayout
145
+            android:layout_width="wrap_content"
146
+            android:layout_height="match_parent"
147
+            android:layout_weight="1"
148
+            android:orientation="horizontal"
149
+            tools:layout_editor_absoluteX="85dp">
150
+
151
+            <Button
152
+                android:id="@+id/btn_accept"
153
+                android:layout_width="85dp"
154
+                android:layout_height="85dp"
155
+                android:layout_weight="1"
156
+                android:background="@drawable/circle_btn"
157
+                android:text="@string/btn_accept"
158
+                android:textSize="10sp"
159
+                tools:layout_editor_absoluteX="85dp"
160
+                tools:layout_editor_absoluteY="85dp" />
161
+
162
+            <Button
163
+                android:id="@+id/btn_call"
164
+                android:layout_width="140dp"
165
+                android:layout_height="140dp"
166
+                android:layout_weight="1"
167
+                android:background="@drawable/token_inactive"
168
+                tools:layout_editor_absoluteX="85dp"
169
+                tools:layout_editor_absoluteY="85dp" />
170
+
171
+            <Button
172
+                android:id="@+id/btn_hangup"
173
+                android:layout_width="85dp"
174
+                android:layout_height="85dp"
175
+                android:layout_weight="1"
176
+                android:background="@drawable/circle_btn"
177
+                android:text="@string/btn_hangup"
178
+                android:textSize="10sp"
179
+                tools:layout_editor_absoluteX="85dp"
180
+                tools:layout_editor_absoluteY="85dp" />
181
+        </LinearLayout>
182
+
183
+        <LinearLayout
184
+            android:layout_width="wrap_content"
185
+            android:layout_height="match_parent"
186
+            android:layout_weight="1"
187
+            android:orientation="horizontal"
188
+            tools:layout_editor_absoluteX="8dp"
189
+            tools:layout_editor_absoluteY="8dp">
190
+
191
+            <Button
192
+                android:id="@+id/btn_speaker"
193
+                android:layout_width="85dp"
194
+                android:layout_height="85dp"
195
+                android:layout_marginLeft="10dp"
196
+                android:layout_marginRight="10dp"
197
+                android:layout_weight="1"
198
+                android:background="@drawable/circle_btn"
199
+                android:text="@string/btn_speaker_off"
200
+                android:textSize="10sp"
201
+                tools:layout_editor_absoluteX="85dp"
202
+                tools:layout_editor_absoluteY="85dp" />
203
+
204
+            <Button
205
+                android:id="@+id/btn_aux2"
206
+                android:layout_width="85dp"
207
+                android:layout_height="85dp"
208
+                android:layout_marginLeft="10dp"
209
+                android:layout_marginRight="10dp"
210
+                android:layout_weight="1"
211
+                android:background="@drawable/circle_btn"
212
+                android:text="@string/btn_aux2"
213
+                android:textSize="10sp"
214
+                tools:layout_editor_absoluteX="85dp"
215
+                tools:layout_editor_absoluteY="85dp" />
216
+        </LinearLayout>
217
+
218
+        <LinearLayout
219
+            android:layout_width="wrap_content"
220
+            android:layout_height="wrap_content"
221
+            android:layout_marginTop="15dp"
222
+            android:layout_weight="1"
223
+            android:gravity="bottom"
224
+            android:orientation="horizontal">
225
+
226
+            <TextView
227
+                android:id="@+id/switch_group"
228
+                android:layout_width="wrap_content"
229
+                android:layout_height="wrap_content"
230
+                android:layout_marginLeft="10dp"
231
+                android:layout_marginRight="10dp"
232
+                android:layout_weight="1"
233
+                android:text="@string/switch_group"
234
+                android:textColor="@color/white"
235
+                android:textSize="14sp" />
236
+
237
+            <android.support.v7.widget.SwitchCompat
238
+                android:id="@+id/switch_call"
239
+                style="@style/SwitchCompatTheme"
240
+                android:layout_width="wrap_content"
241
+                android:layout_height="wrap_content"
242
+                android:layout_marginTop="14dp"
243
+                android:layout_weight="1" />
244
+
245
+            <TextView
246
+                android:id="@+id/switch_private"
247
+                android:layout_width="wrap_content"
248
+                android:layout_height="wrap_content"
249
+                android:layout_marginLeft="10dp"
250
+                android:layout_marginRight="10dp"
251
+                android:layout_weight="1"
252
+                android:text="@string/switch_private"
253
+                android:textColor="@color/white"
254
+                android:textSize="14sp" />
255
+        </LinearLayout>
256
+
257
+        <LinearLayout
258
+            android:layout_width="wrap_content"
259
+            android:layout_height="match_parent"
260
+            android:layout_marginTop="10dp"
261
+            android:layout_weight="1"
262
+            android:gravity="bottom"
263
+            android:orientation="horizontal">
264
+
265
+            <Spinner
266
+                android:id="@+id/spinnerGroups"
267
+                android:layout_width="368dp"
268
+                android:layout_height="wrap_content"
269
+                android:layout_marginBottom="1dp"
270
+                android:layout_marginEnd="1dp"
271
+                android:layout_marginStart="5dp"
272
+                android:layout_marginTop="1dp"
273
+                android:enabled="false" />
274
+
275
+            <Spinner
276
+                android:id="@+id/spinnerUsers"
277
+                android:layout_width="368dp"
278
+                android:layout_height="wrap_content"
279
+                android:layout_marginBottom="1dp"
280
+                android:layout_marginEnd="1dp"
281
+                android:layout_marginStart="5dp"
282
+                android:layout_marginTop="1dp"
283
+                android:enabled="false" />
284
+        </LinearLayout>
285
+
286
+        <LinearLayout
287
+            android:layout_width="match_parent"
288
+            android:layout_height="match_parent"
289
+            android:layout_weight="1"
290
+            android:orientation="vertical">
291
+
292
+            <TextView
293
+                android:id="@+id/text_info"
294
+                android:layout_width="match_parent"
295
+                android:layout_height="wrap_content"
296
+                android:textSize="12sp"
297
+                android:textColor="#bebebe"/>
298
+
299
+            <TextView
300
+                android:id="@+id/text_error"
301
+                android:layout_width="match_parent"
302
+                android:layout_height="wrap_content"
303
+                android:textSize="12sp"
304
+                android:textColor="#bebebe"/>
305
+
306
+            <TextView
307
+                android:id="@+id/text_affiliation"
308
+                android:layout_width="match_parent"
309
+                android:layout_height="wrap_content"
310
+                android:textSize="12sp"
311
+                android:textColor="#bebebe"/>
312
+        </LinearLayout>
313
+
314
+    </LinearLayout>
315
+
316
+</android.support.constraint.ConstraintLayout>
0 317
\ No newline at end of file
1 318
new file mode 100644
... ...
@@ -0,0 +1,38 @@
0
+<?xml version="1.0" encoding="utf-8"?>
1
+<!--
2
+  ~
3
+  ~ * Copyright (C) 2018 Eduardo Zarate Lasurtegui
4
+  ~ *  Copyright (C) 2018, University of the Basque Country (UPV/EHU)
5
+  ~ *
6
+  ~ * Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
7
+  ~ *
8
+  ~ * This file is part of MCOP MCPTT Client
9
+  ~ *
10
+  ~ * This is free software: you can redistribute it and/or modify it under the terms of
11
+  ~ * the GNU General Public License as published by the Free Software Foundation, either version 3
12
+  ~ * of the License, or (at your option) any later version.
13
+  ~ *
14
+  ~ * This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15
+  ~ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
+  ~ * See the GNU General Public License for more details.
17
+  ~ *
18
+  ~ * You should have received a copy of the GNU General Public License along
19
+  ~ * with this program; if not, write to the Free Software Foundation, Inc.,
20
+  ~ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
+  -->
22
+
23
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
24
+    xmlns:tools="http://schemas.android.com/tools"
25
+    android:layout_width="match_parent"
26
+    android:layout_height="match_parent"
27
+    android:paddingBottom="@dimen/activity_vertical_margin"
28
+    android:paddingLeft="@dimen/activity_horizontal_margin"
29
+    android:paddingRight="@dimen/activity_horizontal_margin"
30
+    android:paddingTop="@dimen/activity_vertical_margin"
31
+    tools:context=".mcopsdk.ScreenAutheticationWebView">
32
+    <WebView
33
+        android:id="@+id/screen_authentication_WebView_info"
34
+        android:layout_width="match_parent"
35
+        android:layout_height="match_parent" />
36
+
37
+</RelativeLayout>
0 38
new file mode 100644
1 39
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
2 40
new file mode 100644
3 41
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
4 42
new file mode 100644
5 43
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
6 44
new file mode 100644
7 45
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
8 46
new file mode 100644
9 47
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
10 48
new file mode 100644
11 49
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
12 50
new file mode 100644
13 51
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
14 52
new file mode 100644
15 53
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
16 54
new file mode 100644
17 55
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
18 56
new file mode 100644
19 57
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
20 58
new file mode 100644
... ...
@@ -0,0 +1,15 @@
0
+<?xml version="1.0" encoding="utf-8"?>
1
+<resources>
2
+    <color name="colorPrimary">#f2912e</color>
3
+    <color name="colorPrimaryLight">#FCAE2E</color>
4
+    <color name="colorPrimaryDark">#F4792E</color>
5
+    <color name="colorSecondary">#2226AC</color>
6
+    <color name="colorAccent">#F1F047</color>
7
+    <color name="background_old">#353739</color>
8
+    <color name="background">#353739</color>
9
+    <color name="dark">#484a4f</color>
10
+    <color name="white">#FFFFFF</color>
11
+    <color name="unregistered">#ff0000</color>
12
+    <color name="processing">#ffdd00</color>
13
+    <color name="registered">#38aa00</color>
14
+</resources>
0 15
new file mode 100644
... ...
@@ -0,0 +1,41 @@
0
+<!--
1
+  ~
2
+  ~ * Copyright (C) 2018 Eduardo Zarate Lasurtegui
3
+  ~ *  Copyright (C) 2018, University of the Basque Country (UPV/EHU)
4
+  ~ *
5
+  ~ * Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
6
+  ~ *
7
+  ~ * This file is part of MCOP MCPTT Client
8
+  ~ *
9
+  ~ * This is free software: you can redistribute it and/or modify it under the terms of
10
+  ~ * the GNU General Public License as published by the Free Software Foundation, either version 3
11
+  ~ * of the License, or (at your option) any later version.
12
+  ~ *
13
+  ~ * This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14
+  ~ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
+  ~ * See the GNU General Public License for more details.
16
+  ~ *
17
+  ~ * You should have received a copy of the GNU General Public License along
18
+  ~ * with this program; if not, write to the Free Software Foundation, Inc.,
19
+  ~ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
+  -->
21
+
22
+<resources>
23
+    <!-- Default screen margins, per the Android Design guidelines. -->
24
+    <dimen name="activity_horizontal_margin">0dp</dimen>
25
+    <dimen name="activity_vertical_margin">0dp</dimen>
26
+
27
+    <!-- OLD
28
+    <dimen name="fab_margin">16dp</dimen>
29
+    <dimen name="button_padding">10dp</dimen>
30
+    <dimen name="padding_between">5dp</dimen>
31
+    <dimen name="dialog_body">5dp</dimen>
32
+    <dimen name="activity_horizontal_margin">16dp</dimen>
33
+    <dimen name="activity_vertical_margin">16dp</dimen>
34
+
35
+    <dimen name="cardview_bottom_margin">8dp</dimen>
36
+    <dimen name="cardview_top_margin">8dp</dimen>
37
+    <dimen name="cardview_left_margin">8dp</dimen>
38
+    <dimen name="cardview_right_margin">8dp</dimen>
39
+    -->
40
+</resources>
0 41
new file mode 100644
... ...
@@ -0,0 +1,4 @@
0
+<?xml version="1.0" encoding="utf-8"?>
1
+<resources>
2
+    <color name="ic_launcher_background">#FFFFFF</color>
3
+</resources>
0 4
\ No newline at end of file
1 5
new file mode 100644
... ...
@@ -0,0 +1,21 @@
0
+<resources>
1
+    <string name="app_name">MCOP MCPTT Client</string>
2
+
3
+    <!-- Buttons -->
4
+    <string name="btn_register">REGISTER</string>
5
+    <string name="btn_unregister">UNREGISTER</string>
6
+    <string name="btn_call">CALL</string>
7
+    <string name="btn_accept">ACCEPT</string>
8
+    <string name="btn_hangup">HANG UP</string>
9
+    <string name="btn_token">TOKEN</string>
10
+    <string name="btn_speaker_off">Speaker OFF</string>
11
+    <string name="btn_speaker_on">Speaker ON</string>
12
+    <string name="btn_aux2">AUX2</string>
13
+    <string name="switch_private">Private Call</string>
14
+    <string name="switch_group">Group Call</string>
15
+    <string name="text_status">Status: </string>
16
+
17
+    <!-- Messages -->
18
+    <string name="text_talking">Talking: </string>
19
+    <string name="Error_in_authetication">Authetication error</string>
20
+</resources>
0 21
new file mode 100644
... ...
@@ -0,0 +1,11 @@
0
+<resources>
1
+
2
+    <!-- Base application theme. -->
3
+    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
4
+        <!-- Customize your theme here. -->
5
+        <item name="colorPrimary">@color/colorPrimary</item>
6
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
7
+        <item name="colorAccent">@color/colorAccent</item>
8
+    </style>
9
+
10
+</resources>
0 11
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+<?xml version="1.0" encoding="utf-8"?>
1
+<resources>
2
+    <style name="SwitchCompatTheme" >
3
+        <item name="colorControlActivated">@color/colorPrimaryDark</item>
4
+        <item name="thumbTint">@color/colorPrimaryLight</item>
5
+    </style>
6
+</resources>
0 7
\ No newline at end of file
1 8
new file mode 100644
... ...
@@ -0,0 +1,17 @@
0
+package org.test.client.mcopclient;
1
+
2
+import org.junit.Test;
3
+
4
+import static org.junit.Assert.*;
5
+
6
+/**
7
+ * Example local unit test, which will execute on the development machine (host).
8
+ *
9
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
10
+ */
11
+public class ExampleUnitTest {
12
+    @Test
13
+    public void addition_isCorrect() throws Exception {
14
+        assertEquals(4, 2 + 2);
15
+    }
16
+}
0 17
\ No newline at end of file
1 18
new file mode 100644
... ...
@@ -0,0 +1,41 @@
0
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
1
+
2
+buildscript {
3
+    
4
+    repositories {
5
+        google()
6
+        jcenter()
7
+    }
8
+    dependencies {
9
+        classpath 'com.android.tools.build:gradle:3.0.1'
10
+        
11
+
12
+        // NOTE: Do not place your application dependencies here; they belong
13
+        // in the individual module build.gradle files
14
+    }
15
+}
16
+
17
+allprojects {
18
+    repositories {
19
+        jcenter()
20
+        repositories {
21
+            jcenter()
22
+        }
23
+        maven {
24
+            url 'https://maven.google.com/'
25
+            name 'Google'
26
+        }
27
+    }
28
+}
29
+ext {
30
+    gradleVersion="3.0.1"
31
+    buildToolsVersion = "25.0.3"
32
+    supportLibVersion = "25.4.0"
33
+    runnerVersion = "1.0.1"
34
+    rulesVersion = "1.0.1"
35
+    espressoVersion = "3.0.1"
36
+}
37
+
38
+task clean(type: Delete) {
39
+    delete rootProject.buildDir
40
+}
0 41
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+> *Refer to* [*README*](../README.md) *for main instruction file*
1
+
2
+[**MCOP SDK**](https://demo.mcopenplatform.org/gitlist/mcop/MCOP-SDK.git/blob/master/docs/MCOP_SDK_Installation.md) and [**MCOP MCPTT Client**](MCOP_MCPTT_Client_Installation.md) are part of the [MCOP Project](https://www.mcopenplatform.org/the-project/), and both free software licensed under the [GNU GPLv3](http://www.gnu.org/licenses/gpl.html) license terms based on [IMSDroid](http://code.google.com/p/imsdroid/) and [doubango](http://doubango.org). 
3
+
4
+As far as the commercial product, there is no license violation on using any MCOP component with **open-source** software, and it is compatible with [GNU GPL](http://www.gnu.org/licenses/gpl.html) terms. However, if your commercial product is a **proprietary software**, and you want to keep it closed, then you should get a non-GPL license both from the University of the Basque Country [UPV/EHU](mailto:licensing-mcpttclient@mcopenplatform.org) AND Doubango (check specific details of [Doubango](imsdroid_Commercial_License.md) or refer to the following single point of contact). <br />
5
+
6
+For more information, please [contact us](mailto:licensing-mcpttclient@mcopenplatform.org) <br />
0 7
new file mode 100644
... ...
@@ -0,0 +1,45 @@
0
+> *Refer to* [*README*](../README.md) *for main instruction file*
1
+
2
+This source code is **dual licensed (GPL/commercial)**, and contains third-party libraries compatible with commercial and proprietary applications.
3
+
4
+Refer to [Commercial License](Commercial_License.md) for commercial licensing.
5
+
6
+Regarding third-party libraries it depends on doubango framework and IMSDroid (also from Doubango), whose dependencies are collected in [Doubango Licensing](Licensing_Doubango.md).
7
+
8
+Additionally, in order to provide **AMR-WB** encoding capabilities needed by MCPTT, and XML parsing (libxml, now mandatory), the following additional libraries have been used. 
9
+
10
+Additionally, some versions of the libraries contained in the original [Doubango Licensing](Licensing_Doubango.md) file have been updated, so please check the changes in the following table:
11
+
12
+
13
+<table border='1' cellspacing='0' cellpadding='5'>
14
+<blockquote><tr>
15
+<blockquote><td>Name</td>
16
+<td>Version</td>
17
+<td>License</td>
18
+<td>Dependency</td>
19
+<td>Comments</td>
20
+</blockquote></tr>
21
+<tr>
22
+<blockquote><td><a href='https://sourceforge.net/projects/opencore-amr/vo-amrwbenc'>opencore-amr VisualON AMR-WB encoder</a></td>
23
+<td>0.1.2</td>
24
+<td>Apache license 2.0</td>
25
+<td><i>Needed for MCPTT compliance</i></td>
26
+<td>Needed for AMR encoding, included in opencore-amr, also used for decoding</td>
27
+</blockquote></tr>
28
+</blockquote><blockquote>
29
+<blockquote><td><a href='http://www.xmlsoft.org/'>libxml2</a></td>
30
+<td>2.9.1</td>
31
+<td>MIT</td>
32
+<td><i>Needed for MCPTT compliance</i></td>
33
+<td>Needed for XML</td>
34
+</blockquote></tr>
35
+</blockquote><blockquote></table>
36
+</br>
37
+
38
+Please, check the AMR-WB licensing and patents constraints in your development platform and Android device according to your national laws before using it even for research purposes. See for example the disclaimer in VisualON AMR-WB encoder library:
39
+
40
+*THIS IS NOT A GRANT OF PATENT RIGHTS.*
41
+
42
+*Google makes no representation or warranty that the codecs for which source code is made available hereunder are unencumbered by third-party patents.  Those intending to use this source code in hardware or software products are advised that implementations of these codecs, including in open source software or shareware, may require patent licenses from the relevant patent holders.*
43
+
44
+
0 45
new file mode 100644
... ...
@@ -0,0 +1,127 @@
0
+> *Refer to* [*README*](../README.md) *for main instruction file*
1
+
2
+The Doubango framework is **dual licensed (GPL/commercial)** and contains third-party libraries compatible with commercial and closed-source applications.
3
+
4
+The framework depends on:
5
+
6
+<table border='1' cellspacing='0' cellpadding='5'>
7
+<blockquote><tr>
8
+<blockquote><td>Name</td>
9
+<td>Version</td>
10
+<td>License</td>
11
+<td>Dependency</td>
12
+<td>Comments</td>
13
+</blockquote></tr>
14
+<tr>
15
+<blockquote><td><a href='http://www.ffmpeg.org/'>FFmpeg</a></td>
16
+<td>SVN <a href='https://code.google.com/p/doubango/source/detail?r=24652'>r24652</a></td>
17
+<td>GPL or LGPL</td>
18
+<td><i>optional</i></td>
19
+<td>The commercial version could be linked against the LGPL version as far as the FFmpeg's <a href='http://ffmpeg.org/legal.html'>License Compliance Checklist</a> is respected. <br /><b>We recommend not using FFmpeg</b></td>
20
+</blockquote></tr>
21
+<tr>
22
+<blockquote><td><a href='http://www.ilbcfreeware.org/'>iLBC</a></td>
23
+<td>1.0</td>
24
+<td>GIPS Public License</td>
25
+<td><i>optional</i></td>
26
+<td></td>
27
+</blockquote></tr>
28
+<tr>
29
+<blockquote><td><a href='https://launchpad.net/libgsm'>libgsm</a></td>
30
+<td>1.0-pl13</td>
31
+<td>BSD</td>
32
+<td><i>optional</i></td>
33
+<td></td>
34
+</blockquote></tr>
35
+<tr>
36
+<blockquote><td><a href='http://downloads.xiph.org/releases/ogg/libogg-1.1.4.tar.gz'>libogg</a></td>
37
+<td>1.1.4</td>
38
+<td>BSD</td>
39
+<td><i>optional</i></td>
40
+<td></td>
41
+</blockquote></tr>
42
+<tr>
43
+<blockquote><td><a href='http://code.google.com/p/libyuv/'>libyuv</a></td>
44
+<td>SVN <a href='https://code.google.com/p/doubango/source/detail?r=321'>r321</a></td>
45
+<td>BSD-style</td>
46
+<td><b>mandatory</b></td>
47
+<td></td>
48
+</blockquote></tr>
49
+<tr>
50
+<blockquote><td><a href='http://srtp.sourceforge.net/srtp.html'>libsrtp</a></td>
51
+<td>1.4.2</td>
52
+<td>BSD-based</td>
53
+<td><i>optional</i></td>
54
+<td></td>
55
+</blockquote></tr>
56
+<tr>
57
+<blockquote><td><a href='http://www.theora.org/'>libtheora</a></td>
58
+<td>1.1.1</td>
59
+<td>BSD</td>
60
+<td><i>optional</i></td>
61
+<td></td>
62
+</blockquote></tr>
63
+<tr>
64
+<blockquote><td><a href='http://downloads.xiph.org/releases/vorbis/libvorbis-1.2.3.tar.gz'>libvorbis</a></td>
65
+<td>1.2.3</td>
66
+<td>BSD</td>
67
+<td><i>optional</i></td>
68
+<td></td>
69
+</blockquote></tr>
70
+<tr>
71
+<blockquote><td><a href='https://sourceforge.net/projects/opencore-amr/'>opencore-amr</a></td>
72
+<td>0.1.2</td>
73
+<td>Apache license 2.0</td>
74
+<td><i>optional</i></td>
75
+<td></td>
76
+</blockquote></tr>
77
+<tr>
78
+<blockquote><td><a href='http://www.openssl.org/'>openssl</a></td>
79
+<td>0.9.8m</td>
80
+<td>Apache-style License</td>
81
+<td><i>optional</i></td>
82
+<td></td>
83
+</blockquote></tr>
84
+<tr>
85
+<blockquote><td><a href='http://www.complang.org/ragel/'>Ragel output</a></td>
86
+<td>6.7</td>
87
+<td>Doubango License</td>
88
+<td><b>mandatory</b></td>
89
+<td>No linking</td>
90
+</blockquote></tr>
91
+<tr>
92
+<blockquote><td><a href='http://simple.sourceforge.net/'>SimpleXML</a></td>
93
+<td>2.3.4</td>
94
+<td>Apache License 2.0</td>
95
+<td><b>mandatory</b></td>
96
+<td>Only on Android</td>
97
+</blockquote></tr>
98
+<tr>
99
+<blockquote><td><a href='http://www.swig.org/'>swig output</a></td>
100
+<td>SVN <a href='https://code.google.com/p/doubango/source/detail?r=12023'>r12023</a></td>
101
+<td>Doubango License</td>
102
+<td><b>mandatory</b></td>
103
+<td>No linking</td>
104
+</blockquote></tr>
105
+<tr>
106
+<blockquote><td><a href='http://www.speex.org/'>Speex</a></td>
107
+<td>1.2</td>
108
+<td>Revisited-BSD</td>
109
+<td><b>mandatory</b></td>
110
+<td></td>
111
+</blockquote></tr>
112
+<tr>
113
+<blockquote><td><a href='http://www.webrtc.org/'>WebRTC audio processing</a></td>
114
+<td>SVN <a href='https://code.google.com/p/doubango/source/detail?r=2512'>r2512</a></td>
115
+<td>BSD</td>
116
+<td>optional</td>
117
+<td>AEC, Noise suppression ...</td>
118
+</blockquote></tr>
119
+<tr>
120
+<blockquote><td><a href='http://www.videolan.org/developers/x264.html'>x264</a></td>
121
+<td>0.104</td>
122
+<td>GPL</td>
123
+<td><i>optional</i></td>
124
+<td><b>Must be disabled for commercial use</b></td>
125
+</blockquote></tr>
126
+</blockquote><blockquote></table>
0 127
new file mode 100644
... ...
@@ -0,0 +1,193 @@
0
+> *Refer to* [*README*](../README.md) *for main instruction file*
1
+
2
+# MCOP - MCPTT App Development
3
+
4
+## What is MCOP?
5
+
6
+**MCOP** (Mission Critical Open Platform) is a project that defines the first prototype of open source **MCPTT** (Mission Critical Push-To-Talk) client.
7
+
8
+This client allows the interoperability among different vendors thanks to a multilevel API.
9
+
10
+## Architecture
11
+
12
+Three main modules define the architecture: 
13
+
14
+* **MCOP SDK**:
15
+
16
+	This module contains all the MCPTT logic, and allows the use of other additional modules that increase its functionality. 
17
+
18
+* **MCOP Integration Plugins**:
19
+
20
+	Additional modules or Android services with their own API, known by the MCOP SDK module, offering device specific or MCPTT network required functionalities. 
21
+
22
+* **End User Interface**:
23
+
24
+	GUI (Graphical User Interface) that uses the MCOP SDK services without having to develop the whole MCPTT logic. *(Min. level of Android SDK: API 17)*.
25
+
26
+![ThreMainModules](../images/threemainmodules.png)
27
+
28
+## App Developing Steps
29
+
30
+* **0. MCOP SDK and AIDLs**: The SDK defines two AIDLs and one Constant class:
31
+
32
+	* **IMCOPsdk**: From Client to SDK.
33
+
34
+	* **IMCOPCallBack**: From SDK to Client.
35
+
36
+	* **ConstantsMCOP**: defines the constants to use in the AIDLs.
37
+
38
+* **1. Configure Manifest**: Indicate the necessary permissions for the application.
39
+
40
+		<uses-permission android:name="android.permission.INTERNET" />
41
+		<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
42
+		<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
43
+		<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
44
+		<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
45
+		<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
46
+		<uses-permission android:name="android.permission.CAMERA" />
47
+		<uses-permission android:name="android.permission.WAKE_LOCK" />
48
+		<uses-permission android:name="android.permission.RECORD_AUDIO" />
49
+		<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
50
+		<uses-permission android:name="android.permission.VIBRATE" />
51
+		<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
52
+		<uses-permission android:name="android.permission.WRITE_SETTINGS" />
53
+		<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
54
+		<uses-permission android:name="android.permission.READ_CONTACTS" />
55
+		<uses-permission android:name="android.permission.WRITE_CONTACTS" />
56
+		<uses-permission android:name="android.permission.READ_PHONE_STATE" />
57
+		<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
58
+		<uses-permission android:name="android.permission.CALL_PHONE" />
59
+		<uses-permission android:name="android.permission.RAISED_THREAD_PRIORITY" />
60
+		<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
61
+		<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
62
+
63
+	Define the activities to be used:
64
+
65
+		<application
66
+			android:allowBackup="true"
67
+			android:icon="@mipmap/ic_launcher"
68
+			android:label="@string/app_name"
69
+			android:roundIcon="@mipmap/ic_launcher_round"
70
+			android:supportsRtl="true"
71
+			android:theme="@style/AppTheme" >
72
+			<activity android:name=".MainActivity"
73
+				android:screenOrientation="portrait">
74
+				<intent-filter>
75
+					<action android:name="android.intent.action.MAIN" />
76
+					<category android:name="android.intent.category.LAUNCHER" />
77
+				</intent-filter>
78
+			</activity>
79
+		</application>
80
+
81
+* **2. Require the explicit acceptance of some of the permissions.**
82
+
83
+	The client should explicitly accept some permissions:
84
+
85
+	* Manifest.permission.ACCESS\_FINE\_LOCATION
86
+
87
+	* Manifest.permission.READ\_PHONE\_STATE
88
+
89
+	* Manifest.permission.ACCESS\_COARSE\_LOCATION
90
+
91
+	* Manifest.permission.CAMERA
92
+
93
+	* Manifest.permission.RECORD\_AUDIO
94
+
95
+		![Allow audio](../images/allow_audio.png)
96
+
97
+* **3. Bind to MCOP SDK**:
98
+
99
+	In this version of MCOP SDK, it is necessary to send **“currentProfile”** to the service:
100
+
101
+		Intent serviceIntent = new Intent()
102
+			.setComponent(new ComponentName(
103
+				"org.mcopenplatform.muoapi",
104
+				"org.mcopenplatform.muoapi.MCOPsdk"));

105
+		//This is only for tresting
106
+		serviceIntent.putExtra("PROFILE_SELECT",currentProfile);
107
+		
108
+		ComponentName componentName=startService(serviceIntent);
109
+		bindService(serviceIntent, mConnection, BIND_AUTO_CREATE);
110
+
111
+	Wait for the service to bind:
112
+
113
+	* Save the return value from the Service (this is the AIDL Interface to be used by the Client to communicate with the Service).
114
+
115
+	* Register the callback for asynchronous communication from the Service to the Client:
116
+
117
+			mConnection = new ServiceConnection() {
118
+			
119
+			@Override
120
+			public void onServiceConnected(ComponentName className, IBinder service) {			
121
+				mService = IMCOPsdk.Stub.asInterface(service);
122
+				try {
123
+					mService.registerCallback(mMCOPCallback);
124
+				} catch (RemoteException e) {
125
+					e.printStackTrace();
126
+				}
127
+				isConnect=true;
128
+				
129
+				//AUTO Register
130
+				final Handler handler = new Handler();
131
+				handler.postDelayed(new Runnable() {
132
+					@Override
133
+					public void run() {
134
+						try {
135
+							if(mService!=null)
136
+						mService.authorizeUser(null);
137
+						} catch (RemoteException e) {
138
+							e.printStackTrace();
139
+						}
140
+					}
141
+				}, DEFAULT_REGISTER_DELAY);
142
+			}
143
+
144
+	* Definition of the registered callback:
145
+
146
+		* This is the point where communications from the Server to the Client will be received:
147
+
148
+				mMCOPCallback=new IMCOPCallback.Stub() {
149
+					@Override
150
+					public void handleOnEvent(final List<Intent> actionList) throws RemoteException {
151
+						runOnUiThread(new Runnable() {
152
+							@Override
153
+							public void run() {
154
+								for(Intent action:actionList){
155
+									int codeError=-1;
156
+									int eventTypeInt=-1;
157
+									String stringError=null;
158
+									String sessionID=null;
159
+									if(action!=null &&
160
+										action.getAction()!=null &&
161
+										!action.getAction().trim().isEmpty())
162
+											try {
163
+												switch (ConstantsMCOP.ActionsCallBack.fromString(action.getAction())){
164
+												...
165
+												}
166
+											}catch (Exception ex){
167
+												Log.e(TAG,"Event Action Error: "+action.getAction()+" error:"+ex.getMessage());
168
+											}
169
+									}
170
+								}
171
+							});
172
+						}
173
+					};
174
+
175
+
176
+* **4. Perform any action in the MCOP SDK and receive the result**.
177
+
178
+	Example:
179
+
180
+		if(mService!=null)
181
+			mService.makeCall(
182
+				selGroup, //DEFAULT_GROUP,
183
+				ConstantsMCOP.CallEventExtras.CallTypeEnum.Audio.getValue()|
184
+				ConstantsMCOP.CallEventExtras.CallTypeEnum.WithFloorCtrl.getValue()| 
185
+				ConstantsMCOP.CallEventExtras.CallTypeEnum.PrearrangedGroup.getValue()
186
+			);
187
+			
188
+
189
+
190
+
191
+
192
+
0 193
new file mode 100644
... ...
@@ -0,0 +1,71 @@
0
+> *Refer to* [*README*](../README.md) *for main instruction file*
1
+
2
+# MCOP MCPTT Client
3
+
4
+## Installation
5
+
6
+### Requirements
7
+
8
+* [**MCOP SDK**](https://demo.mcopenplatform.org/gitlist/mcop/MCOP-SDK.git/blob/master/docs/MCOP_SDK_Installation.md) installed on the device.
9
+
10
+	* [**Profiles**](Profiles.md) with the network/user configuration.
11
+
12
+* [**Mock App**](Mock.md) to bypass the the SIM authentication.
13
+
14
+### Download the MCOP MCPTT Demo Client
15
+
16
+Clone or download the project:
17
+
18
+	$ git clone mcop@demo.mcopenplatform.org:mcop/MCOP-MCPTT-Client.git
19
+
20
+Enter the password: Iephieb8
21
+
22
+### Install Android Studio
23
+
24
+* Android Studio [User Guide](https://developer.android.com/studio/install).
25
+
26
+* Download [Android Studio](https://developer.android.com/studio/).
27
+
28
+### Install MCOP MCPTT Client
29
+
30
+Import the project in Android Studio by selecting **File --> Open:** Select the **MCOP-MCPTT-Client** project folder.
31
+
32
+Android **SKD Platform 27** is defined as compilation version. If not installed, a message is shown in Android Studio to *"Install missing platform(s) and sync project"*.
33
+
34
+Connect a phone to the computer via USB cable. **USB debugging** mode must be previously activated, on phone *Settings --> Developer Options*. Once connected, click OK on *"Allow USB debugging?"* message.
35
+
36
+![Allow USB Debugging](../images/images_allowUSBdebugging.png)
37
+
38
+Back on Android Studio, click on run ![Run](../images/images_run.png), select the device to install the app, and click on Install and Continue.
39
+
40
+Once installed, allow requested permissions:
41
+
42
+![Audio](../images/images_allow1RecordAudio.png) ![Location](../images/images_allow2AccessLocation.png)
43
+
44
+![Pictures and Video](../images/images_allow3PicturesVideo.png) ![Phone Calls](../images/images_allow4PhoneCalls.png)
45
+
46
+![Device Settings](../images/images_allow5SystemSettings.png)
47
+
48
+### Usage
49
+
50
+* Everytime the client app is started, a list of user profiles is displayed, in order to select the one to register with. By default some test profiles are loaded.
51
+
52
+* **IMPORTANT**: In order to test the MCOP MCPTT Client against our [demo.mcopenplatform.org](https://demo.mcopenplatform.org) testing platform, this profile files need to be configured in the **MCOP SDK** first, and then referenced in the Client. **Full detailed information is available in [Profiles](Profiles.md) documentation**.
53
+
54
+* After selecting the the initial configure profile, the client will try to automatically register.
55
+
56
+* Once registered, the rest of the button are enabled, and the client is ready to receive and make private or prearranged groups calls.
57
+
58
+* The swith button allows to select between private and. prearrange group calls. When pressing (or keeping it pressed) the middle MCOP logo button, a call will be made according to the selected option.
59
+
60
+* This middle MCOP logo button also works as push to talk button while on a call, changing the color to show whether the token is taken, granted or idle.
61
+
62
+* The spinner button below shows a list of clients or groups to call. The list changes depending on the switch button that activates private or group calls.
63
+
64
+* The speaker button allows to enable or dissable the speaker.
65
+
66
+* Check [MCOP MCPTT App Development](MCOP_App_developing_steps.md) guide for more info on app development using the MCOP SDK.
67
+
68
+### Possible Errors
69
+
70
+* If you have SIP related problems, maybe your carrier is SBC/filtering VoIP traffic. Please check the [Troubleshooting - Network Issues](Troubleshooting.md) section for more information.
0 71
new file mode 100644
... ...
@@ -0,0 +1,49 @@
0
+> *Refer to* [*README*](../README.md) *for main instruction file*
1
+
2
+# MCOP MOCK
3
+
4
+The MCOP Mock app is used to bypass the SIM authentication in order to test the **MCOP SDK** in those devices that don't have a proper SIM plugin due to privilege constraints.
5
+
6
+It uses **AKAv2** (*Authentication and Key Agreement*, [*RFC 3310*](https://tools.ietf.org/html/rfc3310)) for authentication. AKA is a challenge-response based mechanism that uses symmetric cryptography.
7
+
8
+## Parameters
9
+
10
+* **IMPI**: The IP Multimedia Private Identity used to authenticate.
11
+
12
+		e.g. mcptt-test-A@organization.org
13
+
14
+* **DOMAIN**: domain.
15
+
16
+		e.g. organization.org
17
+
18
+* **PASSWORD**: A shared secret key for the authentication process.
19
+
20
+		e.g. 0123456789
21
+
22
+## Usage
23
+
24
+Open the **Mock app** and enter the IMPI, DOMAIN and PASSWORD values. After that, it can be even closed.
25
+
26
+The **MCOP SDK** or **MCOP MCPTT** Client need to be opened after the data has been entered in the Mock App.
27
+
28
+## Installation
29
+
30
+Download the **Mock apk** from [here](https://demo.mcopenplatform.org/gitlist/mcop/MCOP-SDK.git/raw/master/mock/mockAPP.apk).
31
+
32
+It can be installed directly from an Android device, or using [Android ADB](https://developer.android.com/studio/command-line/adb) from a computer.
33
+
34
+## Screenshot
35
+		
36
+![MOCK](../images/images_mockAuth.png)
37
+
38
+## Response
39
+
40
+The Mock app provides a response according to the standard specified in [ETSI TS 131 102](http://www.etsi.org/deliver/etsi_ts/131100_131199/131102/14.04.00_60/ts_131102v140400p.pdf) on section *7.1.2.1 GSM/3G security context*, in base64 format.
41
+
42
+## Disclaimer
43
+
44
+The Mock App internally uses **amf = 0x0000 (hex)** and **OP = 0x00000000000000000000000000000000 (hex)**.
45
+
46
+
47
+
48
+
0 49
new file mode 100644
... ...
@@ -0,0 +1,65 @@
0
+> *Refer to* [*README*](../README.md) *for main instruction file*
1
+
2
+# Profiles
3
+
4
+The profiles *XML* file contains a list of *NgnSipPreferences* elements under main root *<Profiles>* tag. It can be found in **android-ngn-stak/res/raw/profiles/** folder on the **MCOP SDK** project. Each *NgnSipPreferences* element contains the configuration of a MCPTT user.

The configuration properties and their tags are described in the **Elements** section below. If a value isn't set, the application uses the default value stored in the code for that field.
5
+
6
+After defining a new NgnSipPreferences, it needs to be referenced in the application, adding its name to the **clients HasMap**.
7
+
8
+*e.g. for profile name:*
9
+
10
+	<NgnSipPrefrences name="MyProfile_UserA">
11
+	
12
+*add the following line to clients HasMap:*
13
+
14
+	clients.put("MyProfile_UserA", new String[]{"MyProfile_UserA","MyProfile_UserA","MyProfile_UserA"});
15
+
16
+The client HashMap is defined in the **MainActivity.java** file for both **MCOP SDK** and **MCOP MCPTT Client**. To quickly find it in Android Studio, go to *Edit --> Find --> Find in path* and search for **clients = new HashMap<>()**, and add the *clients.put* line after it.
17
+
18
+## demo.mcopenplatform.org
19
+
20
+The [**demo.mcopenplatform.org**](https://demo.mcopenplatform.org/) platform can be used for testing purposes. 
21
+
22
+Click on [**Request Access**](https://demo.mcopenplatform.org/reserve) and check the calendar there for an empty slot, and you'll receive credentials for five test users (with suffixes A to E).
23
+
24
+The **Name** field (max. 10 characters) in the form will determine the name of the client ID. Check the **Example** section below for a specific example.
25
+
26
+## Example

Example **profiles** file with just one user configuration.
27
+
28
+**For configuration from the [MCOP demo platform](https://demo.mcopenplatform.org/), replace "test" with the "Name" field submitted in the form.** The specific information is also provided by email after requesting a slot.

	<Profiles>
29
+   		<NgnSipPrefrences name="TEST_A">
30
+            <DisplayName>TEST A</DisplayName>
31
+            <IMPI>mcptt-test-A@organization.org</IMPI>
32
+            <IMPU>sip:mcptt-test-A@organization.org</IMPU>
33
+            <Password></Password>
34
+            <IPVersion>ipv4</IPVersion>
35
+            <Transport>UDP</Transport>
36
+            <IPsecSecAgree>false</IPsecSecAgree>
37
+            <McpttAnswerMode>true</McpttAnswerMode>
38
+            <McpttGranted>true</McpttGranted>
39
+            <McpttId>sip:mcptt_id_test_A@organization.org</McpttId>
40
+            <McpttClientId>sip:mcptt_id_test_A@organization.org</McpttClientId>
41
+            <McpttImplicit>true</McpttImplicit>
42
+            <McpttIsEnableAffiliation>true</McpttIsEnableAffiliation>
43
+            <McpttNameSpace>true</McpttNameSpace>
44
+            <McpttPriority>7</McpttPriority>
45
+            <McpttPrivAnswerMode>false</McpttPrivAnswerMode>
46
+            <McpttPsiAffiliation>sip:mcptt-server-orig-part.organization.org</McpttPsiAffiliation>
47
+            <McpttPsiCallGroup>sip:mcptt-server-orig-part.organization.org</McpttPsiCallGroup>
48
+            <McpttPsiCallPreestablished>sip:mcptt-server-orig-part.organization.org</McpttPsiCallPreestablished>
49
+            <McpttPsiCallPrivate>sip:mcptt-server-orig-part.organization.org</McpttPsiCallPrivate>
50
+            <McpttPsiAuthentication>sip:mcptt-server-orig-part.organization.org</McpttPsiAuthentication>
51
+            <Realm>organization.org</Realm>
52
+            <PcscfPort>5070</PcscfPort>
53
+            <PcscfHost>demo.mcopenplatform.org</PcscfHost>
54
+        </NgnSipPrefrences>
55
+	</Profiles>
56
+
57
+**Note: In case of any typo or error in the profile resulting in not being able to parse it, the SDK will use its default values instead**. 
58
+
59
+## Elements
60
+
61
+Brief description and example of the configuration elements:

* **DisplayName**: Display name.

		e.g. Test A

* **IMPI**: IP Multimedia Private Identity.

		e.g. mcptt-test-A@organization.org

* **IMPU**: IP Multimedia Public Identity.

		e.g. sip:mcptt-test-A@organization.org

* **Password**: Password.

		e.g. password

* **IPVersion**: IPV version.

		e.g. ipv4
62
+
63
+* **Transport**: Transport protocol.

		e.g. UDP

* **McpttAnswerMode**: "true" for auto answer mode, and "false" for manual answer mode.

		e.g. true

* **McpttGranted**: To insert GRANTED in the Invite message.

		e.g. true

* **McpttId**: MCPTT identifier.

		e.g. sip:mcptt_id_test_A@organization.org

* **McpttClientId**: MCPTT Client identifier.

		e.g. sip:mcptt_id_test_A@organization.org

* **McpttImplicit**: To insert IMPLICIT in the Invite message.

		e.g. true

* **McpttIsEnableAffiliation**: To enable MCPTT affiliation features.

		e.g. true

* **McpttPriority**: Priority level for Private or Group MCPTT calls. From 1 (lowest), to 15 (highest).

		e.g. 7

* **McpttPrivAnswerMode**: "true" for automatic answer mode, and "false" for manual answer mode.

		e.g. false

* **McpttPsiAffiliation**: Public Service Identity for Affiliations.

		e.g. sip:mcptt-server-orig-part.organization.org

* **McpttPsiCallGroup**: Public Service Identity for Group Calls.

		e.g. sip:mcptt-server-orig-part.organization.org

* **McpttPsiCallPreestablished**: Public Service Identity for Preestablished Calls.

		e.g. sip:mcptt-server-orig-part.organization.org

* **McpttPsiCallPrivate**: Public Service Identity for Private calls.

		e.g. sip:mcptt-server-orig-part.organization.org
		
* **McpttPsiAuthentication**: Public Service Identity for Authentication.

		e.g. sip:mcptt-server-orig-part.organization.org

* **Realm**: domain.

		e.g. organization.org

* **McpttEnableMbms**: To enable MBMS (Multimedia Broadcast Multicast Services).

		e.g. true

* **PcscfHost**: Host name or ip address of the P-CSCF (Proxy-Call Session Control Function).

		e.g. 192.168.16.193

* **PcscfPort**: Port number of the P-CSCF.

		e.g. 5060
64
+	
0 65
new file mode 100644
... ...
@@ -0,0 +1,33 @@
0
+> *Refer to* [*README*](../README.md) *for main instruction file*
1
+
2
+# Troubleshooting
3
+
4
+## General issues
5
+
6
+* If the [**MCOP MCPTT Client**](../README.md) app is closed without having deregistered, it might fail the next time is opened. To solve it, go to the device preferences, and under installed applications, Force Stop the **MCOPSDK** app.
7
+
8
+## Network issues
9
+
10
+Due to the fact that in most cases users and developers use access networks that work with NAT and Firewalls (e.g. business or university networks), there is some common functionality issues that may arise:
11
+
12
+* **Reception of modified SIP signalling messages**:
13
+
14
+	In some networks, Firewalls might be able to modify the content of the SIP messages, resulting in the destination not receiving the messages as they were sent.
15
+
16
+* **Deletion of SIP signalling messages**:
17
+	
18
+	Some Firewalls as able to delete specific SIP messaged to avoid stablishing the communication.
19
+
20
+* **Closed network ports**:
21
+
22
+	It is common for network operators to block most used ports in SIP communications, like port 5060.
23
+
24
+* **Change from private to public IPs**:
25
+
26
+	When behind a NAT network, the local IP of the device is not the public IP that messages reach the server with. This can cause errors processing the messages, specially on the server side.
27
+
28
+* **Non-reception of floor control and RTP messages at the beginning of the communication**:
29
+
30
+	MCPTT sessions need sending and receiving RTP and floor control data. In networks with NAT it is common not to receive data from a certain port until the device in that network sends a message using that port first. This causes not to receive data until communication in both directions has happened. Thus, granting and releasing the token from both communication sides might be needed one first time before any audio can be sent.
31
+
32
+For the moment, the MCOP SDK doesn't provide any solution for this type of situations, but will try to reduce their impact in the future.
0 33
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+> *Refer to* [*README*](../README.md) *for main instruction file*
1
+
2
+[IMSDroid](http://code.google.com/p/imsdroid/) is a free software licensed under the [GNU GPLv3](http://www.gnu.org/licenses/gpl.html) license terms. As far as the commercial product using [IMSDroid](http://code.google.com/p/imsdroid/) or [doubango](http://doubango.org) isn't a **closed-source** software and is compatible with [GNU GPL](http://www.gnu.org/licenses/gpl.html) terms, there is no license violation. However, if your commercial product is a **closed-source** software and you want to keep it closed, then you should get a non-GPL license.
3
+
4
+We can provide a non-GPL version of all components used in both [IMSDroid](http://code.google.com/p/imsdroid/) and [doubango](http://doubango.org) except for [x264](http://www.videolan.org/developers/x264.html) library.
5
+
6
+~~An alternative to x264 could be PacketVideo's H.264 implementation which is released under Apache License. ~~Starting Doubango **1220** we support [OpenH264](https://github.com/cisco/openh264) (BSD).
7
+
8
+Owners of [doubango](http://doubango.org) licenses can reuse part or whole
9
+[IMSDroid](http://code.google.com/p/imsdroid/) source code without any restriction.
10
+
11
+For more information, please [contact doubango](http://doubango.org/contact.html).
0 12
new file mode 100644
... ...
@@ -0,0 +1,130 @@
0
+> *Refer to* [*README*](../README.md) *for main instruction file*
1
+
2
+## IMSDROID README
3
+
4
+This application uses [Doubango Framework](https://www.doubango.org/).
5
+<br />
6
+
7
+<font color='green' size='2'>
8
+<strong>IMSDroid v2.x preview is now available for developers</strong><br />
9
+The source code is under <strong>branches/2.0</strong> and depends and <strong>doubango v2.x</strong><br />
10
+<br />
11
+New features: <br />
12
+- The SIP/IMS Stack is 7 times faster<br />
13
+- Full HD (1080p) video<br />
14
+- NAT Traversal using ICE<br />
15
+- Adds support for TLS, SRTP and RTCP<br />
16
+- NGN (Next Generation Network) stack for developers (<strong>android-ngn-stack</strong>)<br />
17
+- Better audio quality (Adaptive jitter buffer, noise suppression, automatic resampling, gain control, ...)<br />
18
+- Better video quality (low latency, low cpu usage, ...)<br />
19
+- VP8 video codec<br />
20
+- Multi-line<br />
21
+- MSRP chat<br />
22
+- Fix many issues<br />
23
+</font>
24
+
25
+
26
+[3GPP IMS](http://en.wikipedia.org/wiki/IP_Multimedia_Subsystem) (IP Multimedia Subsystem) is the next generation network for delivering IP multimedia services. IMS is standardized by the 3rd Generation Partnership Project (3GPP).
27
+IMS services could be used over any type of network, such as [3GPP LTE](http://en.wikipedia.org/wiki/3GPP_Long_Term_Evolution), GPRS, Wireless LAN, CDMA2000 or fixed line. <br />
28
+
29
+[IMSDroid](http://code.google.com/p/imsdroid/) is the first fully featured open source 3GPP IMS Client for Android devices (1.5 and later). The main purpose of the project is to exhibit [doubango](https://doubango.org)'s features and to offer an IMS client to the open source community. [doubango](https://doubango.org) is an experimental, open source, 3GPP IMS/LTE framework for both embedded (Android, Windows Mobile, Symbian, iPhone, iPad, ...) and desktop systems (Windows XP/Vista/7, MAC OS X, Linux, ...) and is written in ANSI-C to ease portability. The framework has been carefully designed to efficiently work on embedded systems with limited memory and low computing power. <br />
30
+As the SIP implementation follows [RFC 3261](http://www.ietf.org/rfc/rfc3261.txt) and [3GPP TS 24.229 Rel-9](http://www.3gpp.org/ftp/Specs/html-info/24229.htm) specifications, this will allow you to connect to any compliant SIP registrar. <br />
31
+<br />
32
+
33
+The current version of IMSDroid partially implements [GSMA Rich Communication Suite release 3](http://www.gsmworld.com/our-work/mobile_lifestyle/rcs/index.htm) and [The One Voice profile V1.0.0](http://news.vzw.com/OneVoiceProfile.pdf) (LTE/4G, also known as [GSMA VoLTE](http://www.gsmworld.com/our-work/mobile_broadband/VoLTE.htm)) specifications. Missing features will be implemented in the next releases. **Stay tuned**.<br /><br />
34
+**For newbies, here is a quick start guide:** [http://code.google.com/p/imsdroid/wiki/Quick\_Start](http://code.google.com/p/imsdroid/wiki/Quick_Start)
35
+<br /><br />
36
+
37
+<table cellpadding='3'>
38
+<tr>
39
+<td><img src='https://raw.githubusercontent.com/DoubangoTelecom/imsdroid/1.0/screenshots/visio.png' /></td>
40
+<td><img src='https://raw.githubusercontent.com/DoubangoTelecom/imsdroid/1.0/screenshots/visio_conf.png' /></td>
41
+</tr>
42
+<tr>
43
+<td align='center'><b>Video Call Screen (H.264 Base Profile 3.0)</b></td>
44
+<td align='center'><b>4-way video conference call using <a href='http://code.google.com/p/openvcs/'>OpenVCS</a></b></td>
45
+</tr>
46
+<tr>
47
+<td><img src='https://raw.githubusercontent.com/DoubangoTelecom/imsdroid/1.0/screenshots/screen_content_share.png' /></td>
48
+<td><img src='https://raw.githubusercontent.com/DoubangoTelecom/imsdroid/1.0/screenshots/screen_contacts.png' /></td>
49
+</tr>
50
+<tr>
51
+<td align='center'><b>GSMA Content Sharing</b></td>
52
+<td align='center'><b>Enhanced Address Book</b></td>
53
+</tr>
54
+</table>
55
+<br />
56
+
57
+## Quick Start ##
58
+  * Getting Started: [http://code.google.com/p/imsdroid/wiki/Quick\_Start](http://code.google.com/p/imsdroid/wiki/Quick_Start)
59
+  * Configure the client for:
60
+    1. [Freephonie](https://github.com/DoubangoTelecom/imsdroid/blob/master/Freephonie.md)
61
+    1. [iptel.org](https://github.com/DoubangoTelecom/imsdroid/blob/master/iptel_org.md)
62
+    1. [pbxes.org](https://github.com/DoubangoTelecom/imsdroid/blob/master/pbxes_org.md)
63
+    1. [sip2sip.info](https://github.com/DoubangoTelecom/imsdroid/blob/master/sip2sip_info.md)
64
+    1. [ekiga.net](https://github.com/DoubangoTelecom/imsdroid/blob/master/ekiga_org.md)
65
+    1. ... To be continued
66
+
67
+## Highlights ##
68
+  * SIP(RFC 3261, 3GPP TS 24.229 Rel-9)
69
+  * TCP and UDP over IPv4 or IPv6
70
+  * Signaling Compression, SigComp(RFC 3320, 3485, 4077, 4464, 4465, 4896, 5049, 5112 and 1951)
71
+  * 
72
+  * Enhanced Address Book (XCAP storage, authorizations, presence, ...)
73
+  * Partial supports for [GSMA Rich Communication Suite release 3](http://www.gsmworld.com/our-work/mobile_lifestyle/rcs/index.htm)
74
+  * Partial supports for [One Voice Profile V1.0.0 (GSMA VoLTE)](http://news.vzw.com/OneVoiceProfile.pdf)
75
+  * Partial supports for MMTel UNI (used by GSMA RCS and GSMA VoLTE)
76
+  * 
77
+  * IMS-AKA registration (both AKA-v1 and AKA-v2), Digest MD5, Basic
78
+  * 3GPP Early IMS Security (3GPP TS 33.978)
79
+  * Proxy-CSCF discovery using DNS NAPTR+SRV
80
+  * Private extension headers for 3GPP
81
+  * Service Route discovery
82
+  * Subscription to reg event package (Honoring network initiated (re/de/un)-registration events)
83
+  * 
84
+  * 3GPP SMS Over IP (3GPP TS 23.038, 24.040, 24.011, 24.341 and 24.451)
85
+  * Voice Call (G729AB<sup><a href='http://code.google.com/p/imsdroid/wiki/Building_Source#Building_libtinyWRAP.so_with_G729AB'>1</a></sup>, AMR-NB, iLBC, GSM, PCMA, PCMU, Speex-NB)
86
+  * Video Call (VP8, H264, MP4V-ES, Theora, H.263, H.263-1998, H.261)
87
+  * DTMF (RFC 4733)
88
+  * QoS negotiation using Preconditions (RFC 3312, 4032 and 5027)
89
+  * SIP Session Timers (RFC 4028)
90
+  * Provisional Response Acknowledgments (PRACK)
91
+  * Communication Hold (3GPP TS 24.610)
92
+  * Message Waiting Indication (3GPP TS 24.606)
93
+  * Calling E.164 numbers by using ENUM protocol (RFC 3761)
94
+  * NAT Traversal using STUN2 (RFC 5389) with possibilities to automatically discover the server by using DNS SRV (TURN already implemented and ICE is under tests)
95
+
96
+Many other features are supported by the underlying framework but not exposed to the user interface (in progress). For more information please refer to [doubango website](http://doubango.org). <br />These features include: OMA Large IM Message (MSRP), File Transfer (MSRP), Image Sharing (IR.79), Video Sharing (IR.74), TLS and IPSec Security Agreement (RFC 3329), Proxy-CSCF discovery using DHCPv4/v6, TURN, ...
97
+
98
+## Request for InterOperability Testing ##
99
+We have started to implement the features listed below and would like to make some IOT. So, if you have a client, IMS Core or Application Server supporting these features, then you are welcome. <br>
100
+<ul><li>Image Sharing (PRD IR.79 Image Share Interoperability Specification 1.0)<br>
101
+</li><li>Video Sharing (PRD IR.74 Video Share Interoperability Specification, 1.0)<br>
102
+</li><li>File Transfer (OMA SIMPLE IM 1.0)<br>
103
+</li><li>Explicit Communication Transfer (ECT) using IP Multimedia (IM) Core Network (CN) subsystem (3GPP TS 24.629)<br>
104
+</li><li>IP Multimedia Subsystem (IMS) emergency sessions (3GPP TS 23.167)</li></ul>
105
+
106
+<h2>GSMA RCS</h2>
107
+<a href='http://doubango.org'>doubango</a> partially support <a href='http://www.gsmworld.com/our-work/mobile_lifestyle/rcs/gsma_rcs_project.htm'>GSMA RCS</a> as defined in release 3. The core features will be fully implemented in the next major release.<br>
108
+<br>
109
+<h2>One Voice Profile (GSMA VoLTE)</h2>
110
+Some features of the <a href='http://news.vzw.com/OneVoiceProfile.pdf'>One Voice Profile</a> are implemented in this version (v1.0.0) and the other will be added in the coming releases.<br /><br />
111
+<img src='https://raw.githubusercontent.com/DoubangoTelecom/imsdroid/1.0/screenshots/LTE_Architecture.png' />
112
+<br /><br />
113
+Already implemented: <br />
114
+<ul><li>5.2.1 SIP Registration Procedures<br>
115
+</li><li>5.2.2 Authentication<br>
116
+</li><li>5.2.3 Addressing<br>
117
+</li><li>5.2.4 Call establishment and termination<br>
118
+</li><li>5.2.6 Tracing of Signalling<br>
119
+</li><li>5.2.7 The use of Signalling Compression<br>
120
+</li><li>5.3 Supplementary services (Communication Hold 3GPP TS 24.610, Message Waiting Indication 3GPP TS 24.606, Communication Barring 3GPP TS 24.611)<br>
121
+</li><li>5.4.1 SIP Precondition Considerations<br>
122
+</li><li>5.4.4 Multimedia Considerations<br>
123
+</li><li>5.5 SMS over IP<br>
124
+</li><li>6.2.1 Codecs<br>
125
+</li><li>6.2.5 AMR Payload Format Considerations</li></ul>
126
+
127
+<br />
128
+<b>© 2010-2015 Doubango Telecom</b> <br />
129
+<i>Inspiring the future</i>
0 130
new file mode 100644
... ...
@@ -0,0 +1,17 @@
0
+# Project-wide Gradle settings.
1
+
2
+# IDE (e.g. Android Studio) users:
3
+# Gradle settings configured through the IDE *will override*
4
+# any settings specified in this file.
5
+
6
+# For more details on how to configure your build environment visit
7
+# http://www.gradle.org/docs/current/userguide/build_environment.html
8
+
9
+# Specifies the JVM arguments used for the daemon process.
10
+# The setting is particularly useful for tweaking memory settings.
11
+org.gradle.jvmargs=-Xmx1536m
12
+
13
+# When configured, Gradle will run in incubating parallel mode.
14
+# This option should only be used with decoupled projects. More details, visit
15
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
16
+# org.gradle.parallel=true
0 17
new file mode 100644
1 18
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
2 19
new file mode 100644
... ...
@@ -0,0 +1,6 @@
0
+#Thu Apr 12 10:12:38 CEST 2018
1
+distributionBase=GRADLE_USER_HOME
2
+distributionPath=wrapper/dists
3
+zipStoreBase=GRADLE_USER_HOME
4
+zipStorePath=wrapper/dists
5
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
0 6
new file mode 100644
... ...
@@ -0,0 +1,160 @@
0
+#!/usr/bin/env bash
1
+
2
+##############################################################################
3
+##
4
+##  Gradle start up script for UN*X
5
+##
6
+##############################################################################
7
+
8
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
9
+DEFAULT_JVM_OPTS=""
10
+
11
+APP_NAME="Gradle"
12
+APP_BASE_NAME=`basename "$0"`
13
+
14
+# Use the maximum available, or set MAX_FD != -1 to use that value.
15
+MAX_FD="maximum"
16
+
17
+warn ( ) {
18
+    echo "$*"
19
+}
20
+
21
+die ( ) {
22
+    echo
23
+    echo "$*"
24
+    echo
25
+    exit 1
26
+}
27
+
28
+# OS specific support (must be 'true' or 'false').
29
+cygwin=false
30
+msys=false
31
+darwin=false
32
+case "`uname`" in
33
+  CYGWIN* )
34
+    cygwin=true
35
+    ;;
36
+  Darwin* )
37
+    darwin=true
38
+    ;;
39
+  MINGW* )
40
+    msys=true
41
+    ;;
42
+esac
43
+
44
+# Attempt to set APP_HOME
45
+# Resolve links: $0 may be a link
46
+PRG="$0"
47
+# Need this for relative symlinks.
48
+while [ -h "$PRG" ] ; do
49
+    ls=`ls -ld "$PRG"`
50
+    link=`expr "$ls" : '.*-> \(.*\)$'`
51
+    if expr "$link" : '/.*' > /dev/null; then
52
+        PRG="$link"
53
+    else
54
+        PRG=`dirname "$PRG"`"/$link"
55
+    fi
56
+done
57
+SAVED="`pwd`"
58
+cd "`dirname \"$PRG\"`/" >/dev/null
59
+APP_HOME="`pwd -P`"
60
+cd "$SAVED" >/dev/null
61
+
62
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
63
+
64
+# Determine the Java command to use to start the JVM.
65
+if [ -n "$JAVA_HOME" ] ; then
66
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
67
+        # IBM's JDK on AIX uses strange locations for the executables
68
+        JAVACMD="$JAVA_HOME/jre/sh/java"
69
+    else
70
+        JAVACMD="$JAVA_HOME/bin/java"
71
+    fi
72
+    if [ ! -x "$JAVACMD" ] ; then
73
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
74
+
75
+Please set the JAVA_HOME variable in your environment to match the
76
+location of your Java installation."
77
+    fi
78
+else
79
+    JAVACMD="java"
80
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
81
+
82
+Please set the JAVA_HOME variable in your environment to match the
83
+location of your Java installation."
84
+fi
85
+
86
+# Increase the maximum file descriptors if we can.
87
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
88
+    MAX_FD_LIMIT=`ulimit -H -n`
89
+    if [ $? -eq 0 ] ; then
90
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
91
+            MAX_FD="$MAX_FD_LIMIT"
92
+        fi
93
+        ulimit -n $MAX_FD
94
+        if [ $? -ne 0 ] ; then
95
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
96
+        fi
97
+    else
98
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
99
+    fi
100
+fi
101
+
102
+# For Darwin, add options to specify how the application appears in the dock
103
+if $darwin; then
104
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
105
+fi
106
+
107
+# For Cygwin, switch paths to Windows format before running java
108
+if $cygwin ; then
109
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
110
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
111
+    JAVACMD=`cygpath --unix "$JAVACMD"`
112
+
113
+    # We build the pattern for arguments to be converted via cygpath
114
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
115
+    SEP=""
116
+    for dir in $ROOTDIRSRAW ; do
117
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
118
+        SEP="|"
119
+    done
120
+    OURCYGPATTERN="(^($ROOTDIRS))"
121
+    # Add a user-defined pattern to the cygpath arguments
122
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
123
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
124
+    fi
125
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
126
+    i=0
127
+    for arg in "$@" ; do
128
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
129
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
130
+
131
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
132
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
133
+        else
134
+            eval `echo args$i`="\"$arg\""
135
+        fi
136
+        i=$((i+1))
137
+    done
138
+    case $i in
139
+        (0) set -- ;;
140
+        (1) set -- "$args0" ;;
141
+        (2) set -- "$args0" "$args1" ;;
142
+        (3) set -- "$args0" "$args1" "$args2" ;;
143
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
144
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
145
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
146
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
147
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
148
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
149
+    esac
150
+fi
151
+
152
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
153
+function splitJvmOpts() {
154
+    JVM_OPTS=("$@")
155
+}
156
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
157
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
158
+
159
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
0 160
new file mode 100644
... ...
@@ -0,0 +1,90 @@
0
+@if "%DEBUG%" == "" @echo off
1
+@rem ##########################################################################
2
+@rem
3
+@rem  Gradle startup script for Windows
4
+@rem
5
+@rem ##########################################################################
6
+
7
+@rem Set local scope for the variables with windows NT shell
8
+if "%OS%"=="Windows_NT" setlocal
9
+
10
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
11
+set DEFAULT_JVM_OPTS=
12
+
13
+set DIRNAME=%~dp0
14
+if "%DIRNAME%" == "" set DIRNAME=.
15
+set APP_BASE_NAME=%~n0
16
+set APP_HOME=%DIRNAME%
17
+
18
+@rem Find java.exe
19
+if defined JAVA_HOME goto findJavaFromJavaHome
20
+
21
+set JAVA_EXE=java.exe
22
+%JAVA_EXE% -version >NUL 2>&1
23
+if "%ERRORLEVEL%" == "0" goto init
24
+
25
+echo.
26
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
27
+echo.
28
+echo Please set the JAVA_HOME variable in your environment to match the
29
+echo location of your Java installation.
30
+
31
+goto fail
32
+
33
+:findJavaFromJavaHome
34
+set JAVA_HOME=%JAVA_HOME:"=%
35
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
36
+
37
+if exist "%JAVA_EXE%" goto init
38
+
39
+echo.
40
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
41
+echo.
42
+echo Please set the JAVA_HOME variable in your environment to match the
43
+echo location of your Java installation.
44
+
45
+goto fail
46
+
47
+:init
48
+@rem Get command-line arguments, handling Windowz variants
49
+
50
+if not "%OS%" == "Windows_NT" goto win9xME_args
51
+if "%@eval[2+2]" == "4" goto 4NT_args
52
+
53
+:win9xME_args
54
+@rem Slurp the command line arguments.
55
+set CMD_LINE_ARGS=
56
+set _SKIP=2
57
+
58
+:win9xME_args_slurp
59
+if "x%~1" == "x" goto execute
60
+
61
+set CMD_LINE_ARGS=%*
62
+goto execute
63
+
64
+:4NT_args
65
+@rem Get arguments from the 4NT Shell from JP Software
66
+set CMD_LINE_ARGS=%$
67
+
68
+:execute
69
+@rem Setup the command line
70
+
71
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72
+
73
+@rem Execute Gradle
74
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
75
+
76
+:end
77
+@rem End local scope for the variables with windows NT shell
78
+if "%ERRORLEVEL%"=="0" goto mainEnd
79
+
80
+:fail
81
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82
+rem the _cmd.exe /c_ return code!
83
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84
+exit /b 1
85
+
86
+:mainEnd
87
+if "%OS%"=="Windows_NT" endlocal
88
+
89
+:omega
0 90
new file mode 100644
1 91
Binary files /dev/null and b/images/MCOParchitecture.png differ
2 92
new file mode 100644
... ...
@@ -0,0 +1,99 @@
0
+<!DOCTYPE html>
1
+<html lang="en">
2
+    <head>
3
+        <meta charset="UTF-8" />
4
+        <title>GitList</title>
5
+        <link rel="stylesheet" type="text/css" href="/gitlist/themes/default/css/style.css">
6
+        <link rel="shortcut icon" type="image/png" href="/gitlist/themes/default/img/favicon.png" />
7
+        <!--[if lt IE 9]>
8
+        <script src="/gitlist/themes/default/js/html5.js"></script>
9
+        <![endif]-->
10
+    </head>
11
+
12
+    <body>
13
+            <div class="navbar navbar-scroll-top">
14
+    <div class="navbar-inner">
15
+        <div class="container">
16
+            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
17
+                <span class="icon-bar"></span>
18
+                <span class="icon-bar"></span>
19
+                <span class="icon-bar"></span>
20
+            </a>
21
+            <a class="brand" href="/gitlist/">MCOP Git Repo</a>
22
+            <div class="nav-collapse">
23
+                <ul class="nav pull-right">
24
+                </ul>
25
+            </div>
26
+        </div>
27
+    </div>
28
+</div>
29
+
30
+    <div class="container">
31
+        <div class="row">
32
+            <div class="span12">
33
+                                <form class="form-search pull-right" action="/gitlist/premcop/mcptt-client.git/tree/master/search" method="POST">
34
+                    <input type="text" name="query" class="input-medium search-query" placeholder="Search tree..." value="">
35
+                </form>
36
+                
37
+                                    <div class="btn-group pull-left space-right" id="branchList">
38
+    <button class="btn dropdown-toggle" data-toggle="dropdown">browsing: <strong>master</strong> <span class="caret"></span></button>
39
+
40
+    <div class="dropdown-menu">
41
+        <div class="search">
42
+            <input class="search" placeholder="Filter branch/tags" autofocus>
43
+        </div>
44
+    <ul class="unstyled list">
45
+    <li class="dropdown-header">Branches</li>
46
+            <li><a href="/gitlist/premcop/mcptt-client.git/master/"><span class="item">master</span></a></li>
47
+            </ul>
48
+    </div>
49
+</div>                
50
+                <ul class="nav nav-tabs">
51
+    <li class="active"><a href="/gitlist/premcop/mcptt-client.git/master/">Files</a></li>
52
+    <li><a href="/gitlist/premcop/mcptt-client.git/commits/master">Commits</a></li>
53
+    <li><a href="/gitlist/premcop/mcptt-client.git/stats/master">Stats</a></li>
54
+  	<li><a href="/gitlist/premcop/mcptt-client.git/network?branch=master">Network</a></li>
55
+</ul>
56
+            </div>
57
+        </div>
58
+
59
+            <ul class="breadcrumb">
60
+    <li><a href="/gitlist/premcop/mcptt-client.git/tree/master/">premcop/mcptt-client.git</a></li>
61
+            <span class="divider">/</span>
62
+        <li><a href="/gitlist/premcop/mcptt-client.git/tree/master/images/">images</a></li>
63
+            <span class="divider">/</span>
64
+        <li class="active">allow1RecordAudio.png</li>
65
+    
66
+    </ul>
67
+
68
+    <div class="source-view">
69
+        <div class="source-header">
70
+            <div class="meta"></div>
71
+
72
+            <div class="btn-group pull-right">
73
+                <a href="/gitlist/premcop/mcptt-client.git/raw/master/images/allow1RecordAudio.png" class="btn btn-small"><i class="icon-file"></i> Raw</a>
74
+                <a href="/gitlist/premcop/mcptt-client.git/blame/master/images/allow1RecordAudio.png" class="btn btn-small"><i class="icon-bullhorn"></i> Blame</a>
75
+                <a href="/gitlist/premcop/mcptt-client.git/commits/master/images/allow1RecordAudio.png" class="btn btn-small"><i class="icon-list-alt"></i> History</a>
76
+            </div>
77
+        </div>
78
+                <center><img src="/gitlist/premcop/mcptt-client.git/raw/master/images/allow1RecordAudio.png" alt="images/allow1RecordAudio.png" class="image-blob" /></center>
79
+
80
+            </div>
81
+
82
+    <hr />
83
+
84
+        <footer>
85
+    <p>Powered by <a href="https://github.com/klaussilveira/gitlist">GitList 0.4.0</a></p>
86
+</footer>
87
+    </div>
88
+        <script src="/gitlist/themes/default/js/jquery.js"></script>
89
+        <script src="/gitlist/themes/default/js/raphael.js"></script>
90
+        <script src="/gitlist/themes/default/js/bootstrap.js"></script>
91
+        <script src="/gitlist/themes/default/js/codemirror.js"></script>
92
+        <script src="/gitlist/themes/default/js/showdown.js"></script>
93
+        <script src="/gitlist/themes/default/js/table.js"></script>
94
+        <script src="/gitlist/themes/default/js/list.min.js"></script>
95
+        <script src="/gitlist/themes/default/js/main.js"></script>
96
+        <script src="/gitlist/themes/default/js/networkGraph.js"></script>
97
+    </body>
98
+</html>
0 99
new file mode 100644
... ...
@@ -0,0 +1,99 @@
0
+<!DOCTYPE html>
1
+<html lang="en">
2
+    <head>
3
+        <meta charset="UTF-8" />
4
+        <title>GitList</title>
5
+        <link rel="stylesheet" type="text/css" href="/gitlist/themes/default/css/style.css">
6
+        <link rel="shortcut icon" type="image/png" href="/gitlist/themes/default/img/favicon.png" />
7
+        <!--[if lt IE 9]>
8
+        <script src="/gitlist/themes/default/js/html5.js"></script>
9
+        <![endif]-->
10
+    </head>
11
+
12
+    <body>
13
+            <div class="navbar navbar-scroll-top">
14
+    <div class="navbar-inner">
15
+        <div class="container">
16
+            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
17
+                <span class="icon-bar"></span>
18
+                <span class="icon-bar"></span>
19
+                <span class="icon-bar"></span>
20
+            </a>
21
+            <a class="brand" href="/gitlist/">MCOP Git Repo</a>
22
+            <div class="nav-collapse">
23
+                <ul class="nav pull-right">
24
+                </ul>
25
+            </div>
26
+        </div>
27
+    </div>
28
+</div>
29
+
30
+    <div class="container">
31
+        <div class="row">
32
+            <div class="span12">
33
+                                <form class="form-search pull-right" action="/gitlist/premcop/mcptt-client.git/tree/master/search" method="POST">
34
+                    <input type="text" name="query" class="input-medium search-query" placeholder="Search tree..." value="">
35
+                </form>
36
+                
37
+                                    <div class="btn-group pull-left space-right" id="branchList">
38
+    <button class="btn dropdown-toggle" data-toggle="dropdown">browsing: <strong>master</strong> <span class="caret"></span></button>
39
+
40
+    <div class="dropdown-menu">
41
+        <div class="search">
42
+            <input class="search" placeholder="Filter branch/tags" autofocus>
43
+        </div>
44
+    <ul class="unstyled list">
45
+    <li class="dropdown-header">Branches</li>
46
+            <li><a href="/gitlist/premcop/mcptt-client.git/master/"><span class="item">master</span></a></li>
47
+            </ul>
48
+    </div>
49
+</div>                
50
+                <ul class="nav nav-tabs">
51
+    <li class="active"><a href="/gitlist/premcop/mcptt-client.git/master/">Files</a></li>
52
+    <li><a href="/gitlist/premcop/mcptt-client.git/commits/master">Commits</a></li>
53
+    <li><a href="/gitlist/premcop/mcptt-client.git/stats/master">Stats</a></li>
54
+  	<li><a href="/gitlist/premcop/mcptt-client.git/network?branch=master">Network</a></li>
55
+</ul>
56
+            </div>
57
+        </div>
58
+
59
+            <ul class="breadcrumb">
60
+    <li><a href="/gitlist/premcop/mcptt-client.git/tree/master/">premcop/mcptt-client.git</a></li>
61
+            <span class="divider">/</span>
62
+        <li><a href="/gitlist/premcop/mcptt-client.git/tree/master/images/">images</a></li>
63
+            <span class="divider">/</span>
64
+        <li class="active">allow2AccessLocation.png</li>
65
+    
66
+    </ul>
67
+
68
+    <div class="source-view">
69
+        <div class="source-header">
70
+            <div class="meta"></div>
71
+
72
+            <div class="btn-group pull-right">
73
+                <a href="/gitlist/premcop/mcptt-client.git/raw/master/images/allow2AccessLocation.png" class="btn btn-small"><i class="icon-file"></i> Raw</a>
74
+                <a href="/gitlist/premcop/mcptt-client.git/blame/master/images/allow2AccessLocation.png" class="btn btn-small"><i class="icon-bullhorn"></i> Blame</a>
75
+                <a href="/gitlist/premcop/mcptt-client.git/commits/master/images/allow2AccessLocation.png" class="btn btn-small"><i class="icon-list-alt"></i> History</a>
76
+            </div>
77
+        </div>
78
+                <center><img src="/gitlist/premcop/mcptt-client.git/raw/master/images/allow2AccessLocation.png" alt="images/allow2AccessLocation.png" class="image-blob" /></center>
79
+
80
+            </div>
81
+
82
+    <hr />
83
+
84
+        <footer>
85
+    <p>Powered by <a href="https://github.com/klaussilveira/gitlist">GitList 0.4.0</a></p>
86
+</footer>
87
+    </div>
88
+        <script src="/gitlist/themes/default/js/jquery.js"></script>
89
+        <script src="/gitlist/themes/default/js/raphael.js"></script>
90
+        <script src="/gitlist/themes/default/js/bootstrap.js"></script>
91
+        <script src="/gitlist/themes/default/js/codemirror.js"></script>
92
+        <script src="/gitlist/themes/default/js/showdown.js"></script>
93
+        <script src="/gitlist/themes/default/js/table.js"></script>
94
+        <script src="/gitlist/themes/default/js/list.min.js"></script>
95
+        <script src="/gitlist/themes/default/js/main.js"></script>
96
+        <script src="/gitlist/themes/default/js/networkGraph.js"></script>
97
+    </body>
98
+</html>
0 99
new file mode 100644
... ...
@@ -0,0 +1,99 @@
0
+<!DOCTYPE html>
1
+<html lang="en">
2
+    <head>
3
+        <meta charset="UTF-8" />
4
+        <title>GitList</title>
5
+        <link rel="stylesheet" type="text/css" href="/gitlist/themes/default/css/style.css">
6
+        <link rel="shortcut icon" type="image/png" href="/gitlist/themes/default/img/favicon.png" />
7
+        <!--[if lt IE 9]>
8
+        <script src="/gitlist/themes/default/js/html5.js"></script>
9
+        <![endif]-->
10
+    </head>
11
+
12
+    <body>
13
+            <div class="navbar navbar-scroll-top">
14
+    <div class="navbar-inner">
15
+        <div class="container">
16
+            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
17
+                <span class="icon-bar"></span>
18
+                <span class="icon-bar"></span>
19
+                <span class="icon-bar"></span>
20
+            </a>
21
+            <a class="brand" href="/gitlist/">MCOP Git Repo</a>
22
+            <div class="nav-collapse">
23
+                <ul class="nav pull-right">
24
+                </ul>
25
+            </div>
26
+        </div>
27
+    </div>
28
+</div>
29
+
30
+    <div class="container">
31
+        <div class="row">
32
+            <div class="span12">
33
+                                <form class="form-search pull-right" action="/gitlist/premcop/mcptt-client.git/tree/master/search" method="POST">
34
+                    <input type="text" name="query" class="input-medium search-query" placeholder="Search tree..." value="">
35
+                </form>
36
+                
37
+                                    <div class="btn-group pull-left space-right" id="branchList">
38
+    <button class="btn dropdown-toggle" data-toggle="dropdown">browsing: <strong>master</strong> <span class="caret"></span></button>
39
+
40
+    <div class="dropdown-menu">
41
+        <div class="search">
42
+            <input class="search" placeholder="Filter branch/tags" autofocus>
43
+        </div>
44
+    <ul class="unstyled list">
45
+    <li class="dropdown-header">Branches</li>
46
+            <li><a href="/gitlist/premcop/mcptt-client.git/master/"><span class="item">master</span></a></li>
47
+            </ul>
48
+    </div>
49
+</div>                
50
+                <ul class="nav nav-tabs">
51
+    <li class="active"><a href="/gitlist/premcop/mcptt-client.git/master/">Files</a></li>
52
+    <li><a href="/gitlist/premcop/mcptt-client.git/commits/master">Commits</a></li>
53
+    <li><a href="/gitlist/premcop/mcptt-client.git/stats/master">Stats</a></li>
54
+  	<li><a href="/gitlist/premcop/mcptt-client.git/network?branch=master">Network</a></li>
55
+</ul>
56
+            </div>
57
+        </div>
58
+
59
+            <ul class="breadcrumb">
60
+    <li><a href="/gitlist/premcop/mcptt-client.git/tree/master/">premcop/mcptt-client.git</a></li>
61
+            <span class="divider">/</span>
62
+        <li><a href="/gitlist/premcop/mcptt-client.git/tree/master/images/">images</a></li>
63
+            <span class="divider">/</span>
64
+        <li class="active">allow3PicturesVideo.png</li>
65
+    
66
+    </ul>
67
+
68
+    <div class="source-view">
69
+        <div class="source-header">
70
+            <div class="meta"></div>
71
+
72
+            <div class="btn-group pull-right">
73
+                <a href="/gitlist/premcop/mcptt-client.git/raw/master/images/allow3PicturesVideo.png" class="btn btn-small"><i class="icon-file"></i> Raw</a>
74
+                <a href="/gitlist/premcop/mcptt-client.git/blame/master/images/allow3PicturesVideo.png" class="btn btn-small"><i class="icon-bullhorn"></i> Blame</a>
75
+                <a href="/gitlist/premcop/mcptt-client.git/commits/master/images/allow3PicturesVideo.png" class="btn btn-small"><i class="icon-list-alt"></i> History</a>
76
+            </div>
77
+        </div>
78
+                <center><img src="/gitlist/premcop/mcptt-client.git/raw/master/images/allow3PicturesVideo.png" alt="images/allow3PicturesVideo.png" class="image-blob" /></center>
79
+
80
+            </div>
81
+
82
+    <hr />
83
+
84
+        <footer>
85
+    <p>Powered by <a href="https://github.com/klaussilveira/gitlist">GitList 0.4.0</a></p>
86
+</footer>
87
+    </div>
88
+        <script src="/gitlist/themes/default/js/jquery.js"></script>
89
+        <script src="/gitlist/themes/default/js/raphael.js"></script>
90
+        <script src="/gitlist/themes/default/js/bootstrap.js"></script>
91
+        <script src="/gitlist/themes/default/js/codemirror.js"></script>
92
+        <script src="/gitlist/themes/default/js/showdown.js"></script>
93
+        <script src="/gitlist/themes/default/js/table.js"></script>
94
+        <script src="/gitlist/themes/default/js/list.min.js"></script>
95
+        <script src="/gitlist/themes/default/js/main.js"></script>
96
+        <script src="/gitlist/themes/default/js/networkGraph.js"></script>
97
+    </body>
98
+</html>
0 99
new file mode 100644
... ...
@@ -0,0 +1,99 @@
0
+<!DOCTYPE html>
1
+<html lang="en">
2
+    <head>
3
+        <meta charset="UTF-8" />
4
+        <title>GitList</title>
5
+        <link rel="stylesheet" type="text/css" href="/gitlist/themes/default/css/style.css">
6
+        <link rel="shortcut icon" type="image/png" href="/gitlist/themes/default/img/favicon.png" />
7
+        <!--[if lt IE 9]>
8
+        <script src="/gitlist/themes/default/js/html5.js"></script>
9
+        <![endif]-->
10
+    </head>
11
+
12
+    <body>
13
+            <div class="navbar navbar-scroll-top">
14
+    <div class="navbar-inner">
15
+        <div class="container">
16
+            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
17
+                <span class="icon-bar"></span>
18
+                <span class="icon-bar"></span>
19
+                <span class="icon-bar"></span>
20
+            </a>
21
+            <a class="brand" href="/gitlist/">MCOP Git Repo</a>
22
+            <div class="nav-collapse">
23
+                <ul class="nav pull-right">
24
+                </ul>
25
+            </div>
26
+        </div>
27
+    </div>
28
+</div>
29
+
30
+    <div class="container">
31
+        <div class="row">
32
+            <div class="span12">
33
+                                <form class="form-search pull-right" action="/gitlist/premcop/mcptt-client.git/tree/master/search" method="POST">
34
+                    <input type="text" name="query" class="input-medium search-query" placeholder="Search tree..." value="">
35
+                </form>
36
+                
37
+                                    <div class="btn-group pull-left space-right" id="branchList">
38
+    <button class="btn dropdown-toggle" data-toggle="dropdown">browsing: <strong>master</strong> <span class="caret"></span></button>
39
+
40
+    <div class="dropdown-menu">
41
+        <div class="search">
42
+            <input class="search" placeholder="Filter branch/tags" autofocus>
43
+        </div>
44
+    <ul class="unstyled list">
45
+    <li class="dropdown-header">Branches</li>
46
+            <li><a href="/gitlist/premcop/mcptt-client.git/master/"><span class="item">master</span></a></li>
47
+            </ul>
48
+    </div>
49
+</div>                
50
+                <ul class="nav nav-tabs">
51
+    <li class="active"><a href="/gitlist/premcop/mcptt-client.git/master/">Files</a></li>
52
+    <li><a href="/gitlist/premcop/mcptt-client.git/commits/master">Commits</a></li>
53
+    <li><a href="/gitlist/premcop/mcptt-client.git/stats/master">Stats</a></li>
54
+  	<li><a href="/gitlist/premcop/mcptt-client.git/network?branch=master">Network</a></li>
55
+</ul>
56
+            </div>
57
+        </div>
58
+
59
+            <ul class="breadcrumb">
60
+    <li><a href="/gitlist/premcop/mcptt-client.git/tree/master/">premcop/mcptt-client.git</a></li>
61
+            <span class="divider">/</span>
62
+        <li><a href="/gitlist/premcop/mcptt-client.git/tree/master/images/">images</a></li>
63
+            <span class="divider">/</span>
64
+        <li class="active">allow4PhoneCalls.png</li>
65
+    
66
+    </ul>
67
+
68
+    <div class="source-view">
69
+        <div class="source-header">
70
+            <div class="meta"></div>
71
+
72
+            <div class="btn-group pull-right">
73
+                <a href="/gitlist/premcop/mcptt-client.git/raw/master/images/allow4PhoneCalls.png" class="btn btn-small"><i class="icon-file"></i> Raw</a>
74
+                <a href="/gitlist/premcop/mcptt-client.git/blame/master/images/allow4PhoneCalls.png" class="btn btn-small"><i class="icon-bullhorn"></i> Blame</a>
75
+                <a href="/gitlist/premcop/mcptt-client.git/commits/master/images/allow4PhoneCalls.png" class="btn btn-small"><i class="icon-list-alt"></i> History</a>
76
+            </div>
77
+        </div>
78
+                <center><img src="/gitlist/premcop/mcptt-client.git/raw/master/images/allow4PhoneCalls.png" alt="images/allow4PhoneCalls.png" class="image-blob" /></center>
79
+
80
+            </div>
81
+
82
+    <hr />
83
+
84
+        <footer>
85
+    <p>Powered by <a href="https://github.com/klaussilveira/gitlist">GitList 0.4.0</a></p>
86
+</footer>
87
+    </div>
88
+        <script src="/gitlist/themes/default/js/jquery.js"></script>
89
+        <script src="/gitlist/themes/default/js/raphael.js"></script>
90
+        <script src="/gitlist/themes/default/js/bootstrap.js"></script>
91
+        <script src="/gitlist/themes/default/js/codemirror.js"></script>
92
+        <script src="/gitlist/themes/default/js/showdown.js"></script>
93
+        <script src="/gitlist/themes/default/js/table.js"></script>
94
+        <script src="/gitlist/themes/default/js/list.min.js"></script>
95
+        <script src="/gitlist/themes/default/js/main.js"></script>
96
+        <script src="/gitlist/themes/default/js/networkGraph.js"></script>
97
+    </body>
98
+</html>
0 99
new file mode 100644
... ...
@@ -0,0 +1,99 @@
0
+<!DOCTYPE html>
1
+<html lang="en">
2
+    <head>
3
+        <meta charset="UTF-8" />
4
+        <title>GitList</title>
5
+        <link rel="stylesheet" type="text/css" href="/gitlist/themes/default/css/style.css">
6
+        <link rel="shortcut icon" type="image/png" href="/gitlist/themes/default/img/favicon.png" />
7
+        <!--[if lt IE 9]>
8
+        <script src="/gitlist/themes/default/js/html5.js"></script>
9
+        <![endif]-->
10
+    </head>
11
+
12
+    <body>
13
+            <div class="navbar navbar-scroll-top">
14
+    <div class="navbar-inner">
15
+        <div class="container">
16
+            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
17
+                <span class="icon-bar"></span>
18
+                <span class="icon-bar"></span>
19
+                <span class="icon-bar"></span>
20
+            </a>
21
+            <a class="brand" href="/gitlist/">MCOP Git Repo</a>
22
+            <div class="nav-collapse">
23
+                <ul class="nav pull-right">
24
+                </ul>
25
+            </div>
26
+        </div>
27
+    </div>
28
+</div>
29
+
30
+    <div class="container">
31
+        <div class="row">
32
+            <div class="span12">
33
+                                <form class="form-search pull-right" action="/gitlist/premcop/mcptt-client.git/tree/master/search" method="POST">
34
+                    <input type="text" name="query" class="input-medium search-query" placeholder="Search tree..." value="">
35
+                </form>
36
+                
37
+                                    <div class="btn-group pull-left space-right" id="branchList">
38
+    <button class="btn dropdown-toggle" data-toggle="dropdown">browsing: <strong>master</strong> <span class="caret"></span></button>
39
+
40
+    <div class="dropdown-menu">
41
+        <div class="search">
42
+            <input class="search" placeholder="Filter branch/tags" autofocus>
43
+        </div>
44
+    <ul class="unstyled list">
45
+    <li class="dropdown-header">Branches</li>
46
+            <li><a href="/gitlist/premcop/mcptt-client.git/master/"><span class="item">master</span></a></li>
47
+            </ul>
48
+    </div>
49
+</div>                
50
+                <ul class="nav nav-tabs">
51
+    <li class="active"><a href="/gitlist/premcop/mcptt-client.git/master/">Files</a></li>
52
+    <li><a href="/gitlist/premcop/mcptt-client.git/commits/master">Commits</a></li>
53
+    <li><a href="/gitlist/premcop/mcptt-client.git/stats/master">Stats</a></li>
54
+  	<li><a href="/gitlist/premcop/mcptt-client.git/network?branch=master">Network</a></li>
55
+</ul>
56
+            </div>
57
+        </div>
58
+
59
+            <ul class="breadcrumb">
60
+    <li><a href="/gitlist/premcop/mcptt-client.git/tree/master/">premcop/mcptt-client.git</a></li>
61
+            <span class="divider">/</span>
62
+        <li><a href="/gitlist/premcop/mcptt-client.git/tree/master/images/">images</a></li>
63
+            <span class="divider">/</span>
64
+        <li class="active">allow5SystemSettings.png</li>
65
+    
66
+    </ul>
67
+
68
+    <div class="source-view">
69
+        <div class="source-header">
70
+            <div class="meta"></div>
71
+
72
+            <div class="btn-group pull-right">
73
+                <a href="/gitlist/premcop/mcptt-client.git/raw/master/images/allow5SystemSettings.png" class="btn btn-small"><i class="icon-file"></i> Raw</a>
74
+                <a href="/gitlist/premcop/mcptt-client.git/blame/master/images/allow5SystemSettings.png" class="btn btn-small"><i class="icon-bullhorn"></i> Blame</a>
75
+                <a href="/gitlist/premcop/mcptt-client.git/commits/master/images/allow5SystemSettings.png" class="btn btn-small"><i class="icon-list-alt"></i> History</a>
76
+            </div>
77
+        </div>
78
+                <center><img src="/gitlist/premcop/mcptt-client.git/raw/master/images/allow5SystemSettings.png" alt="images/allow5SystemSettings.png" class="image-blob" /></center>
79
+
80
+            </div>
81
+
82
+    <hr />
83
+
84
+        <footer>
85
+    <p>Powered by <a href="https://github.com/klaussilveira/gitlist">GitList 0.4.0</a></p>
86
+</footer>
87
+    </div>
88
+        <script src="/gitlist/themes/default/js/jquery.js"></script>
89
+        <script src="/gitlist/themes/default/js/raphael.js"></script>
90
+        <script src="/gitlist/themes/default/js/bootstrap.js"></script>
91
+        <script src="/gitlist/themes/default/js/codemirror.js"></script>
92
+        <script src="/gitlist/themes/default/js/showdown.js"></script>
93
+        <script src="/gitlist/themes/default/js/table.js"></script>
94
+        <script src="/gitlist/themes/default/js/list.min.js"></script>
95
+        <script src="/gitlist/themes/default/js/main.js"></script>
96
+        <script src="/gitlist/themes/default/js/networkGraph.js"></script>
97
+    </body>
98
+</html>
0 99
new file mode 100644
1 100
Binary files /dev/null and b/images/allow_audio.png differ
2 101
new file mode 100644
3 102
Binary files /dev/null and b/images/images_DemoClient.png differ
4 103
new file mode 100644
5 104
Binary files /dev/null and b/images/images_DemoClient_Profiles.png differ
6 105
new file mode 100644
7 106
Binary files /dev/null and b/images/images_SDK_Manager.png differ
8 107
new file mode 100644
9 108
Binary files /dev/null and b/images/images_allow1RecordAudio.png differ
10 109
new file mode 100644
11 110
Binary files /dev/null and b/images/images_allow2AccessLocation.png differ
12 111
new file mode 100644
13 112
Binary files /dev/null and b/images/images_allow3PicturesVideo.png differ
14 113
new file mode 100644
15 114
Binary files /dev/null and b/images/images_allow4PhoneCalls.png differ
16 115
new file mode 100644
17 116
Binary files /dev/null and b/images/images_allow5SystemSettings.png differ
18 117
new file mode 100644
19 118
Binary files /dev/null and b/images/images_allowUSBdebugging.png differ
20 119
new file mode 100644
21 120
Binary files /dev/null and b/images/images_mockAuth.png differ
22 121
new file mode 100644
23 122
Binary files /dev/null and b/images/images_run.png differ
24 123
new file mode 100644
25 124
Binary files /dev/null and b/images/logoMCOP_MD_w400px.png differ
26 125
new file mode 100644
27 126
Binary files /dev/null and b/images/threemainmodules.png differ
28 127
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+include ':app'