From version 21.2
edited by Sylvain Berfini
on 2017/04/24 16:53
To version 22.1
edited by Benjamin REIS
on 2017/05/10 11:45
Change comment: There is no comment for this version

Summary

Details

Page properties
Author
... ... @@ -1,1 +1,1 @@
1 -xwiki:XWiki.sylvain
1 +xwiki:XWiki.BenjaminReis
Content
... ... @@ -4,7 +4,6 @@
4 4  
5 5  We provide a C# wrapper for LibLinphone that can be used in a Xamarin project.
6 6  
7 -
8 8  = Generating the C# wrapper =
9 9  
10 10  The C# wrapper is automatically generated from the documentation in the code (like the Python/C++ wrappers) which is created when Linphone is compiled.
... ... @@ -20,317 +20,23 @@
20 20  * If you use a Native Portable project (using Portable Class Library, PCL), LinphoneWrapper.cs can't go in it because DllImport ins't supported. This means you have to copy LinphoneWrapper.cs in each one of your target Projects (for example LinphoneXamarin.Droid, LinphoneXamarin.iOS, etc...) ;
21 21  * If you use a Native Shared project, LinphoneWrapper.cs can go in the shared project as long as each target project references the shared one.
22 22  
23 -= Xamarin Android =
22 += What about Xamarin ? =
24 24  
25 -== Setup ==
24 +The C# wrapper has been implemented to enable the development of Xamarin app based on LibLinphone.
26 26  
27 -For your Xamarin.Android project to be able to use Linphone, you also need our Android SDK. You can download the nightly snapshot from [[here>>http://linphone.org/snapshots/android/liblinphone-android-sdk-latest.zip]] or the latest stable release from [[there>>http://linphone.org/releases/android/liblinphone-android-sdk-latest.zip]].
26 +To obtain the SDK and wrapper you either :
28 28  
29 -In your Android project, create a folder for the Linphone libraries and copy into it the content of the libs directory from our SDK. Import the folders and their content inside your Visual Studio project.
28 +* download it [[here>>https://www.linphone.org/snapshots/xamarin/]] and unzip the precomiled SDK ;
29 +* clone the linphone-xamarin repo : git:~/~/git.linphone.org/linphone-xamarin.git and run the following commands :
30 30  
31 -{{warning}}
32 -Do not rename the folders that contains the libraries and keep their names as they are in Visual Studio so it uses the "Path Sniffing" feature to use the correct libraries depending on the device architecture.
33 -{{/warning}}
31 +{{code language="bash"}}
32 +./prepare.py -c
33 +./prepare.py
34 +make
35 +{{/code}}
34 34  
35 -For each library file (with .so extension), set the Build Action to AndroidNativeLibrary.
36 -
37 -For more information about this, you can check out the [[official documentation>>https://developer.xamarin.com/guides/android/advanced_topics/using_native_libraries/]].
38 -
39 39  {{info}}
40 -The wrapper needs to know the name of the Linphone library, but in our Android SDK the name depends on the architecture, so you must rename each .so file to remove the ABI suffix.
38 +If you only want to build the SDK for Android or iOS you can the following options to your prepare.py command : "-DENABLE_ANDROID=OFF" or "-DENABLE_IOS=OFF".
41 41  {{/info}}
42 42  
43 -
44 -You also need to copy the liblinphone.jar file from our SDK in your project (wherever you want, it doesn't matter) and set it's Build Action to AndroidJavaLibrary.
45 -
46 -Finally, in the Android project, in the Build section, under General, add "ANDROID" in the Conditional compilation symbols to have access to LinphoneAndroid class in the wrapper.
47 -
48 -== Getting started ==
49 -
50 -As a Java Android application that uses native libraries, you must load the library manually inside your application when it starts:
51 -
52 -{{code language="C#"}}
53 -Java.Lang.JavaSystem.LoadLibrary("bctoolbox");
54 -Java.Lang.JavaSystem.LoadLibrary("ortp");
55 -Java.Lang.JavaSystem.LoadLibrary("mediastreamer_base");
56 -Java.Lang.JavaSystem.LoadLibrary("mediastreamer_voip");
57 -Java.Lang.JavaSystem.LoadLibrary("linphone");
58 -{{/code}}
59 -
60 -For Android, there is one method you have to call before any other one (and after the LoadLibrary calls):
61 -
62 -{{code language="C#"}}
63 -LinphoneAndroid.setAndroidContext(Android.Runtime.JNIEnv.Handle, this.Handle);
64 -{{/code}}
65 -
66 -Optionnaly, you may want to add the Android native log handler so the LibLinphone logs are sent in logcat:
67 -
68 -{{code language="C#"}}
69 -LinphoneAndroid.setNativeLogHandler();
70 -{{/code}}
71 -
72 -{{warning}}
73 -If you don't find the LinphoneAndroid class, ensure you have added the ANDROID conditional compilation symbol in the Android project.
74 -{{/warning}}
75 -
76 -== Sample code ==
77 -
78 -Once these steps are done, you can use every class in the wrapper and build your application using LibLinphone.
79 -
80 -Here's a simple example that creates and starts a LinphoneCore:
81 -
82 -{{code language="C#"}}
83 -private Core core;
84 -private Call call;
85 -private CoreListener callListener;
86 -
87 -private void LinphoneCoreIterate()
88 -{
89 - while (true)
90 - {
91 - RunOnUiThread(() => core.Iterate());
92 - System.Threading.Thread.Sleep(50);
93 - }
94 -}
95 -
96 -private void OnGlobal(Core lc, GlobalState gstate, string message)
97 -{
98 - Console.WriteLine("Global state changed: " + gstate);
99 -}
100 -
101 -private void OnRegistration(Core lc, ProxyConfig config, RegistrationState state, string message)
102 -{
103 - Console.WriteLine("Registration state changed: " + state);
104 -}
105 -
106 -private void OnCall(Core lc, Call call, CallState state, string message)
107 -{
108 - Console.WriteLine("Call state changed: " + state);
109 - CallStats audio_stats = call.GetStats(StreamType.Audio);
110 - Console.WriteLine("Audio stats: " + audio_stats.DownloadBandwidth + " kbits/s / " + audio_stats.UploadBandwidth + " kbits/s");
111 -
112 - if (state == CallState.End)
113 - {
114 - core.RemoveListener(callListener);
115 - }
116 -}
117 -
118 -private void OnStats(Core lc, Call call, CallStats stats)
119 -{
120 - Console.WriteLine("Call stats: " + stats.DownloadBandwidth + " kbits/s / " + stats.UploadBandwidth + " kbits/s");
121 -}
122 -
123 -protected override void OnCreate(Bundle bundle)
124 -{
125 - base.OnCreate(bundle);
126 -
127 - // Copy the default_rc from the Assets to the device
128 - // The same can be done for the factory_rc
129 - AssetManager assets = this.Assets;
130 - string path = this.FilesDir.AbsolutePath;
131 - using (var br = new BinaryReader(Application.Context.Assets.Open("linphonerc_default")))
132 - {
133 - using (var bw = new BinaryWriter(new FileStream(path + "/default_rc", FileMode.Create)))
134 - {
135 - byte[] buffer = new byte[2048];
136 - int length = 0;
137 - while ((length = br.Read(buffer, 0, buffer.Length)) > 0)
138 - {
139 - bw.Write(buffer, 0, length);
140 - }
141 - }
142 - }
143 -
144 - // Load the libraries
145 - Java.Lang.JavaSystem.LoadLibrary("bctoolbox");
146 - Java.Lang.JavaSystem.LoadLibrary("ortp");
147 - Java.Lang.JavaSystem.LoadLibrary("mediastreamer_base");
148 - Java.Lang.JavaSystem.LoadLibrary("mediastreamer_voip");
149 - Java.Lang.JavaSystem.LoadLibrary("linphone");
150 -
151 - SetContentView(Resource.Layout.Main);
152 -
153 - Button button = FindViewById<Button>(Resource.Id.myButton);
154 -
155 - button.Click += delegate
156 - {
157 - if (callListener == null)
158 - {
159 - callListener = Factory.Instance.CreateCoreListener();
160 - callListener.OnCallStatsUpdated = OnStats;
161 - }
162 -
163 - if (call != null)
164 - {
165 - core.TerminateCall(call);
166 - call = null;
167 - }
168 - else
169 - {
170 - core.AddListener(callListener);
171 - call = core.InviteAddress(Factory.Instance.CreateAddress("sip:cotcot@sip.linphone.org"));
172 - }
173 - };
174 -
175 - // This is mandatory for Android
176 - LinphoneAndroid.setAndroidContext(JNIEnv.Handle, this.Handle);
177 - LinphoneAndroid.setNativeLogHandler();
178 -
179 - CoreListener listener = Factory.Instance.CreateCoreListener();
180 - listener.OnGlobalStateChanged = OnGlobal;
181 - listener.OnRegistrationStateChanged = OnRegistration;
182 - listener.OnCallStateChanged = OnCall;
183 - core = Factory.Instance.CreateCore(listener, path + "/default_rc", null);
184 -
185 - Thread coreIterate = new Thread(LinphoneCoreIterate);
186 - coreIterate.IsBackground = false;
187 - coreIterate.Start();
188 -}
189 -{{/code}}
190 -
191 -
192 -= Xamarin IOS =
193 -
194 -== Setup ==
195 -
196 -For your Xamarin.IOS project to be able to use Linphone, you also need our iOS SDK. You can download the nightly snapshot from[[ here>>http://www.linphone.org/snapshots/ios/liblinphone-iphone-sdk-latest.zip]] or the latest stable release from [[there>>http://linphone.org/releases/ios/liblinphone-iphone-sdk-latest.zip]].
197 -
198 -In your iOS project, create a folder for the Linphone libraries and copy into it the content of the libs directory from our SDK. Import the folders and their content inside your Xamarin Studio project.
199 -
200 -For each library file (with .a extension), set the Build Action to None.
201 -
202 -For more information about this, you can check out the [[official documentation>>https://developer.xamarin.com/guides/ios/advanced_topics/native_interop/]].
203 -
204 -Add the following line as a mTouch argument in your project build options :
205 -
206 -{{code}}
207 ---registrar:static -cxx -gcc_flags "-L${ProjectDir}/Libs -lantlr3c -lavcodec -lbcg729 -lbzrtp -lbctoolbox-tester -lbcunit -lspeex -lcorec -lcunit -lebml2 -lgsm -llinphone -llinphonetester -lmbedcrypto -lmbedtls -lmbedx509 -lopencore-amrnb -lopencore-amrwb -lopenh264 -lopus -lspeexdsp -lsrtp -lswresample -lswscale -ltunnel -lturbojpeg -lvo-amrwbenc -lvpx -lx264 -lbelr -lbellesip -lbelcard  -lbv16 -lmatroska2 -lbctoolbox -lortp -lmediastreamer_base -lmediastreamer_voip -lxml2 -lsqlite3 -lresolv.9 -framework AVFoundation -framework AudioToolbox -framework CoreMedia -framework CoreVideo -framework VideoToolbox -force_load ${ProjectDir}/Libs/liblinphone.a"
208 -{{/code}}
209 -
210 -== Getting started ==
211 -
212 -First you need to create a view. Here's a sample code to create a view with a button displaying the linphone version. The initialization of this view also initialize the linphone core.
213 -
214 -When the button is clicked a call to a SIP address is started.
215 -
216 -{{code language="C#"}}
217 -using System;
218 -using System.Threading;
219 -using CoreGraphics;
220 -using UIKit;
221 -using Linphone;
222 -using Foundation;
223 -
224 -namespace LinphoneXamarin.iOS
225 -{
226 - public class CustomViewController : UIViewController
227 - {
228 - public CustomViewController()
229 - {
230 - }
231 -
232 - private Core core;
233 - private CoreListener callListener;
234 -
235 - private void OnGlobal(Core lc, GlobalState gstate, string message)
236 - {
237 - Console.WriteLine("Global state changed " + gstate);
238 - }
239 -
240 - private void OnCall(Core lc, Call call, CallState gstate, string message)
241 - {
242 - Console.WriteLine("Call state changed " + gstate);
243 - if (gstate == CallState.End)
244 - {
245 - core.RemoveListener(callListener);
246 - }
247 - }
248 -
249 - public override void ViewDidLoad()
250 - {
251 - base.ViewDidLoad();
252 -
253 - View.BackgroundColor = UIColor.White;
254 - Title = "My Custom View Controller";
255 -
256 - var btn = UIButton.FromType(UIButtonType.System);
257 - btn.Frame = new CGRect(20, 200, 280, 44);
258 - string v = Core.Version;
259 - Console.WriteLine("Version : " + v);
260 - btn.SetTitle("Version : " + v, UIControlState.Normal);
261 -
262 - var user = new UIViewController();
263 - user.View.BackgroundColor = UIColor.Magenta;
264 -
265 - btn.TouchUpInside += (sender, e) =>
266 - {
267 - callListener = Factory.Instance.CreateCoreListener();
268 - callListener.OnCallStateChanged = OnCall;
269 - core.AddListener(callListener);
270 -
271 - Address addr = Factory.Instance.CreateAddress("sip:my.sip.address@sip.my.domain");
272 - core.InviteAddress(addr);
273 -
274 - };
275 -
276 - View.AddSubview(btn);
277 -
278 - CoreListener listener = Factory.Instance.CreateCoreListener();
279 - listener.OnGlobalStateChanged = OnGlobal;
280 - core = Factory.Instance.CreateCore(listener, "/Path/To/My/defaultrc", null);
281 -
282 - NSTimer mIterateTimer = NSTimer.CreateRepeatingScheduledTimer(0.02, (obj) => { core.Iterate(); });
283 - mIterateTimer.Fire();
284 - }
285 - }
286 -}
287 -{{/code}}
288 -
289 -And here is the code of the app delegate to launch the previsous view when the app is started :
290 -
291 -{{code language="C#"}}
292 -using System;
293 -using System.Collections.Generic;
294 -using System.Linq;
295 -using System.Threading;
296 -using System.Runtime.InteropServices;
297 -using Foundation;
298 -using UIKit;
299 -
300 -namespace LinphoneXamarin.iOS
301 -{
302 -
303 - // The UIApplicationDelegate for the application. This class is responsible for launching the
304 - // User Interface of the application, as well as listening (and optionally responding) to
305 - // application events from iOS.
306 - [Register("AppDelegate")]
307 - public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
308 - {
309 - //
310 - // This method is invoked when the application has loaded and is ready to run. In this
311 - // method you should instantiate the window, load the UI into it and then make the window
312 - // visible.
313 - //
314 - // You have 17 seconds to return from this method, or iOS will terminate your application.
315 -
316 - public override UIWindow Window
317 - {
318 - get;
319 - set;
320 - }
321 -
322 - public override bool FinishedLaunching(UIApplication appl, NSDictionary options)
323 - {
324 - // create a new window instance based on the screen size
325 - Window = new UIWindow(UIScreen.MainScreen.Bounds);
326 - var cvc = new CustomViewController();
327 - var navController = new UINavigationController(cvc);
328 - Window.RootViewController = navController;
329 - // make the window visible
330 - Window.MakeKeyAndVisible();
331 -
332 - return true;
333 - }
334 - }
335 -}
336 -{{/code}}
41 +You can, now, find [[here>>doc:Lib.Getting started.Xamarin.WebHome]] how to get started with a LibLinphone Xamarin project !