blob: 8397459af083b8bf3888ddcadc3f096333ad0510 [file] [log] [blame]
Neels Hofmeyrb52df172017-05-14 20:09:35 +02001== Installation on Main Unit
2
3The main unit is a general purpose computer that orchestrates the tests. It
4runs the core network components, controls the modems and so on. This can be
5anything from a dedicated production rack unit to your laptop at home.
6
Pau Espin Pedrolaccd74f2017-11-02 15:09:39 +01007This manual will assume that tests are run from a jenkins build slave, by a user
8named 'jenkins' that belong to group 'osmo-gsm-tester'. The user configuration
9for manual test runs and/or a different user name is identical, simply replace
10the user name or group.
Neels Hofmeyrb52df172017-05-14 20:09:35 +020011
12=== Dependencies
13
14On a Debian/Ubuntu based system, these commands install the packages needed to
15run the osmo-gsm-tester.py code, i.e. install these on your main unit:
16
17----
18apt-get install \
19 dbus \
20 tcpdump \
Neels Hofmeyr97110692017-06-03 15:20:28 +020021 sqlite3 \
Neels Hofmeyrb52df172017-05-14 20:09:35 +020022 python3 \
23 python3-yaml \
24 python3-mako \
25 python3-gi \
26 ofono \
27 python3-pip
28pip3 install pydbus
Pau Espin Pedrol8d72cd62017-06-14 16:02:34 +020029pip3 install git+git://github.com/podshumok/python-smpplib.git
Neels Hofmeyrb52df172017-05-14 20:09:35 +020030----
31
32IMPORTANT: ofono may need to be installed from source to contain the most
Neels Hofmeyr7b8dbd82017-05-15 15:28:34 +020033recent fixes needed to operate your modems. This depends on the modem hardware
Neels Hofmeyrb52df172017-05-14 20:09:35 +020034used and the tests run. Please see <<hardware_modems>>.
35
36To run osmo-bts-trx with a USRP attached, you may need to install a UHD driver.
37Please refer to http://osmocom.org/projects/osmotrx/wiki/OsmoTRX#UHD for
38details; the following is an example for the B200 family USRP devices:
39
40----
41apt-get install libuhd-dev uhd-host
42/usr/lib/uhd/utils/uhd_images_downloader.py
43----
44
45[[jenkins_deps]]
46==== Jenkins Build Dependencies
47
48Each of the jenkins builds requires individual dependencies. This is generally
49the same as for building the software outside of osmo-gsm-tester and will not
50be detailed here. For the Osmocom projects, refer to
51http://osmocom.org/projects/cellular-infrastructure/wiki/Build_from_Source . Be
52aware of specific requirements for BTS hardware: for example, the
53osmo-bts-sysmo build needs the sysmoBTS SDK installed on the build slave, which
54should match the installed sysmoBTS firmware.
55
56
57[[configure_build_slave]]
58=== Jenkins Build Slave
59
60==== Create 'jenkins' User on Main Unit
61
62On the main unit, create a jenkins user:
63
64----
65useradd -m jenkins
66----
67
Neels Hofmeyr3f596ed2017-07-14 00:04:40 +020068==== Install Java on Main Unit
69
70To be able to launch the Jenkins build slave, a Java RE must be available on
71the main unit. For example:
72
73----
74apt-get install default-jdk
75----
76
Neels Hofmeyrb52df172017-05-14 20:09:35 +020077==== Allow SSH Access from Jenkins Master
78
79Create an SSH keypair to be used for login on the osmo-gsm-tester. This may be
80entered on the jenkins web UI; alternatively, use the jenkins server's shell:
81
82Login on the main jenkins server shell and create an SSH keypair, for example:
83
84----
85# su jenkins
Neels Hofmeyr3f596ed2017-07-14 00:04:40 +020086$ mkdir -p /usr/local/jenkins/keys
Neels Hofmeyrb52df172017-05-14 20:09:35 +020087$ ssh-keygen
88Generating public/private rsa key pair.
89Enter file in which to save the key (/home/jenkins/.ssh/id_rsa): /usr/local/jenkins/keys/osmo-gsm-tester-rnd
90Enter passphrase (empty for no passphrase): <enter a passphrase>
91Enter same passphrase again: <enter a passphrase>
92Your identification has been saved in /usr/local/jenkins/keys/osmo-gsm-tester-rnd
93Your public key has been saved in /usr/local/jenkins/keys/osmo-gsm-tester-rnd.pub.
94The key fingerprint is:
95...
96----
97
98Copy the public key to the main unit, e.g. copy-paste:
99
100----
101cat /usr/local/jenkins/keys/osmo-gsm-tester-rnd.pub
102# copy this public key
103----
104
105On the main unit:
106
107----
108mkdir ~jenkins/.ssh
109cat > ~jenkins/.ssh/authorized_keys
110# paste above public key and hit Ctrl-D
111chown -R jenkins: ~jenkins/.ssh
112----
113
114Make sure that the user running the jenkins master accepts the main unit's host
115identification. There must be an actual RSA host key available in the
116known_hosts file for the jenkins master to be able to log in. Simply calling
117ssh and accepting the host key as usual is not enough. Jenkins may continue to
118say "Host key verification failed".
119
120To place an RSA host key in the jenkins' known_hosts file, you may do:
121
122On the Jenkins master:
123
124----
125main_unit_ip=10.9.8.7
126ssh-keyscan -H $main_unit_ip >> ~jenkins/.ssh/known_hosts
127chown jenkins: ~jenkins/.ssh/known_hosts
128----
129
130Verify that the jenkins user on the Jenkins master has SSH access to the main
131unit:
132
133----
134su jenkins
135main_unit_ip=10.9.8.7
Neels Hofmeyr3f596ed2017-07-14 00:04:40 +0200136ssh -i /usr/local/jenkins/keys/osmo-gsm-tester-rnd jenkins@$main_unit_ip
Neels Hofmeyrb52df172017-05-14 20:09:35 +0200137exit
138----
139
140[[install_add_build_slave]]
141==== Add Build Slave
142
143In the jenkins web UI, add a new build slave for the osmo-gsm-tester:
144
145* 'Manage Jenkins'
146** 'Manage Nodes'
147*** 'New Node'
148**** Enter a node name, e.g. "osmo-gsm-tester-1" +
149 (the "-1" is just some identification in case you'd like to add another
150 setup later).
151**** 'Permanent Agent'
152
153Configure the node as:
154
155* '# of executors': 1
156* 'Remote root directory': "/home/jenkins"
157* 'Labels': "osmo-gsm-tester" +
158 (This is a general label common to all osmo-gsm-tester build slaves you may set up in the future.)
159* 'Usage': 'Only build jobs with label expressions matching this node'
160* 'Launch method': 'Launch slave agents via SSH'
161** 'Host': your main unit's IP address
162** 'Credentials': choose 'Add' / 'Jenkins'
163*** 'Domain': 'Global credentials (unrestricted)'
164*** 'Kind': 'SSH Username with private key'
165*** 'Scope': 'Global'
166*** 'Username': "jenkins" +
167 (as created on the main unit above)
168*** 'Private Key': 'From a file on Jenkins master'
169**** 'File': "/usr/local/jenkins/keys/osmo-gsm-tester-rnd"
170*** 'Passphrase': enter same passphrase as above
171*** 'ID': "osmo-gsm-tester-1"
172*** 'Name': "jenkins for SSH to osmo-gsm-tester-1"
173
174The build slave should be able to start now.
175
176
177==== Add Build Jobs
178
179There are various jenkins-build-* scripts in osmo-gsm-tester/contrib/, which
180can be called as jenkins build jobs to build and bundle binaries as artifacts,
181to be run on the osmo-gsm-tester main unit and/or BTS hardware.
182
183Be aware of the dependencies, as hinted at in <<jenkins_deps>>.
184
185While the various binaries could technically be built on the osmo-gsm-tester
186main unit, it is recommended to use a separate build slave, to take load off
187of the main unit.
188
189On your jenkins master, set up build jobs to call these scripts -- typically
190one build job per script. Look in contrib/ and create one build job for each of
191the BTS types you would like to test, as well as one for the 'build-osmo-nitb'.
192
193These are generic steps to configure a jenkins build
194job for each of these build scripts, by example of the
195jenkins-build-osmo-nitb.sh script; all that differs to the other scripts is the
196"osmo-nitb" part:
197
198* 'Project name': "osmo-gsm-tester_build-osmo-nitb" +
199 (Replace 'osmo-nitb' according to which build script this is for)
200* 'Discard old builds' +
201 Configure this to taste, for example:
202** 'Max # of build to keep': "20"
203* 'Restrict where this project can be run': Choose a build slave label that
204 matches the main unit's architecture and distribution, typically a Debian
205 system, e.g.: "linux_amd64_debian8"
206* 'Source Code Management':
207** 'Git'
208*** 'Repository URL': "git://git.osmocom.org/osmo-gsm-tester"
209*** 'Branch Specifier': "*/master"
210*** 'Additional Behaviors'
211**** 'Check out to a sub-directory': "osmo-gsm-tester"
212* 'Build Triggers' +
213 The decision on when to build is complex. Here are some examples:
214** Once per day: +
215 'Build periodically': "H H * * *"
216** For the Osmocom project, the purpose is to verify our software changes.
217 Hence we would like to test every time our code has changed:
218*** We could add various git repositories to watch, and enable 'Poll SCM'.
219*** On jenkins.osmocom.org, we have various jobs that build the master branches
220 of their respective git repositories when a new change was merged. Here, we
221 can thus trigger e.g. an osmo-nitb build for osmo-gsm-tester everytime the
222 master build has run: +
223 'Build after other projects are built': "OpenBSC"
224*** Note that most of the Osmocom projects also need to be re-tested when their
225 dependencies like libosmo* have changed. Triggering on all those changes
226 typically causes more jenkins runs than necessary: for example, it rebuilds
227 once per each dependency that has rebuilt due to one libosmocore change.
228 There is so far no trivial way known to avoid this. It is indeed safest to
229 rebuild more often.
230* 'Build'
231** 'Execute Shell'
232+
233----
234#!/bin/sh
235set -e -x
236./osmo-gsm-tester/contrib/jenkins-build-osmo-nitb.sh
237----
238+
239(Replace 'osmo-nitb' according to which build script this is for)
240
241* 'Post-build Actions'
242** 'Archive the artifacts': "*.tgz, *.md5" +
243 (This step is important to be able to use the built binaries in the run job
244 below.)
245
246
247TIP: When you've created one build job, it is convenient to create further
248build jobs by copying the first and, e.g., simply replacing all "osmo-nitb"
249with "osmo-bts-trx".
250
251==== Add Run Job
252
253This is the build job that actually runs the tests on the GSM hardware:
254
255* It sources the artifacts from the build jobs.
256* It runs on the osmo-gsm-tester main unit's build slave.
257
258Here is the configuration for the run job:
259
260* 'Project name': "osmo-gsm-tester_run"
261* 'Discard old builds' +
262 Configure this to taste, for example:
263** 'Max # of build to keep': "20"
264* 'Restrict where this project can be run': "osmo-gsm-tester" +
265 (to match the 'Label' configured in <<install_add_build_slave>>).
266* 'Source Code Management':
267** 'Git'
268*** 'Repository URL': "git://git.osmocom.org/osmo-gsm-tester"
269*** 'Branch Specifier': "*/master"
270*** 'Additional Behaviors'
271**** 'Check out to a sub-directory': "osmo-gsm-tester"
272**** 'Clean before checkout'
273* 'Build Triggers' +
274 The decision on when to build is complex. For this run job, it is suggested
275 to rebuild:
276** after each of above build jobs that produced new artifacts: +
277 'Build after other projects are built': "osmo-gsm-tester_build-osmo-nitb,
278 osmo-gsm-tester_build-osmo-bts-sysmo, osmo-gsm-tester_build-osmo-bts-trx" +
279 (Add each build job name you configured above)
280** as well as once per day: +
281 'Build periodically': "H H * * *"
282** and, in addition, whenever the osmo-gsm-tester scripts have been modified: +
283 'Poll SCM': "H/5 * * * *" +
284 (i.e. look every five minutes whether the upstream git has changed)
285* 'Build'
286** Copy artifacts from each build job you have set up:
287*** 'Copy artifacts from another project'
288**** 'Project name': "osmo-gsm-tester_build-osmo-nitb"
289**** 'Which build': 'Latest successful build'
290**** enable 'Stable build only'
291**** 'Artifacts to copy': "*.tgz, *.md5"
292*** Add a separate similar 'Copy artifacts...' section for each build job you
293 have set up.
294** 'Execute Shell'
295+
296----
297#!/bin/sh
298set -e -x
299
300# debug: provoke a failure
301#export OSMO_GSM_TESTER_OPTS="-s debug -t fail"
302
303PATH="$PWD/osmo-gsm-tester/src:$PATH" \
304 ./osmo-gsm-tester/contrib/jenkins-run.sh
305----
306+
307Details:
308
309*** The 'jenkins-run.sh' script assumes to find the 'osmo-gsm-tester.py' in the
310 '$PATH'. To use the most recent osmo-gsm-tester code here, we direct
311 '$PATH' to the actual workspace checkout. This could also run from a sytem
312 wide install, in which case you could omit the explicit PATH to
313 "$PWD/osmo-gsm-tester/src".
314*** This assumes that there are configuration files for osmo-gsm-tester placed
315 on the system (see <<config_paths>>).
316*** If you'd like to check the behavior of test failures, you can uncomment the
317 line below "# debug" to produce a build failure on every run. Note that
318 this test typically produces a quite empty run result, since it launches no
319 NITB nor BTS.
320* 'Post-build Actions'
321** 'Archive the artifacts'
Neels Hofmeyr8d8a1362017-06-18 02:31:38 +0200322*** 'Files to archive': "*-run.tgz, *-bin.tgz" +
Neels Hofmeyrb52df172017-05-14 20:09:35 +0200323 This stores the complete test report with config files, logs, stdout/stderr
Neels Hofmeyr8d8a1362017-06-18 02:31:38 +0200324 output, pcaps as well as the binaries used for the test run in artifacts.
325 This allows analysis of older builds, instead of only the most recent build
326 (which cleans up the jenkins workspace every time). The 'trial-N-run.tgz'
327 and 'trial-N-bin.tgz' archives are produced by the 'jenkins-run.sh' script,
328 both for successful and failing runs.
Neels Hofmeyrb52df172017-05-14 20:09:35 +0200329
330=== Install osmo-gsm-tester on Main Unit
331
332This assumes you have already created the jenkins user (see <<configure_build_slave>>).
333
Neels Hofmeyrb52df172017-05-14 20:09:35 +0200334==== User Permissions
335
336On the main unit, create a group for all users that should be allowed to use
337the osmo-gsm-tester, and add users (here 'jenkins') to this group.
338
339----
340groupadd osmo-gsm-tester
341gpasswd -a jenkins osmo-gsm-tester
342----
343
344NOTE: you may also need to add users to the 'usrp' group, see
345<<user_config_uhd>>.
346
347A user added to a group needs to re-login for the group permissions to take
348effect.
349
350This group needs the following permissions:
351
352===== Paths
353
354Assuming that you are using the example config, prepare a system wide state
355location in '/var/tmp':
356
357----
358mkdir -p /var/tmp/osmo-gsm-tester/state
359chown -R :osmo-gsm-tester /var/tmp/osmo-gsm-tester
360chmod -R g+rwxs /var/tmp/osmo-gsm-tester
361setfacl -d -m group:osmo-gsm-tester:rwx /var/tmp/osmo-gsm-tester/state
362----
363
364IMPORTANT: the state directory needs to be shared between all users potentially
365running the osmo-gsm-tester to resolve resource allocations. Above 'setfacl'
366command sets the access control to keep all created files group writable.
367
368With the jenkins build as described here, the trials will live in the build
369slave's workspace. Other modes of operation (a daemon scheduling concurrent
370runs, *TODO*) may use a system wide directory to manage trials to run:
371
372----
373mkdir -p /var/tmp/osmo-gsm-tester/trials
374chown -R :osmo-gsm-tester /var/tmp/osmo-gsm-tester
375chmod -R g+rwxs /var/tmp/osmo-gsm-tester
376----
377
378===== Allow DBus Access to ofono
379
380Put a DBus configuration file in place that allows the 'osmo-gsm-tester' group
381to access the org.ofono DBus path:
382
383----
384cat > /etc/dbus-1/system.d/osmo-gsm-tester.conf <<END
385<!-- Additional rules for the osmo-gsm-tester to access org.ofono from user
386 land -->
387
388<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
389 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
390<busconfig>
391
392 <policy group="osmo-gsm-tester">
393 <allow send_destination="org.ofono"/>
394 </policy>
395
396</busconfig>
397END
398----
399
400(No restart of dbus nor ofono necessary.)
401
402[[install_capture_packets]]
403===== Capture Packets
404
405In order to allow collecting pcap traces of the network communication for later
406reference, allow the osmo-gsm-tester group to capture packets using the 'tcpdump'
407program:
408
409----
410chgrp osmo-gsm-tester /usr/sbin/tcpdump
411chmod 750 /usr/sbin/tcpdump
412setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump
413----
414
415Put 'tcpdump' in the '$PATH' -- assuming that 'tcpdump' is available for root:
416
417----
418ln -s `which tcpdump` /usr/local/bin/tcpdump
419----
420
421TIP: Why a symlink in '/usr/local/bin'? On Debian, 'tcpdump' lives in
422'/usr/sbin', which is not part of the '$PATH' for non-root users. To avoid
423hardcoding non-portable paths in the osmo-gsm-tester source, 'tcpdump' must be
424available in the '$PATH'. There are various trivial ways to modify '$PATH' for
425login shells, but the jenkins build slave typically runs in a *non-login*
426shell; modifying non-login shell enviroments is not trivially possible without
427also interfering with files installed from debian packages. Probably the
428easiest way to allow all users and all shells to find the 'tcpdump' binary is
429to actually place a symbolic link in a directory that is already part of the
430non-login shell's '$PATH'. Above example places such in '/usr/local/bin'.
431
432Verify that a non-login shell can find 'tcpdump':
433
434----
435su jenkins -c 'which tcpdump'
436# should print: "/usr/local/bin/tcpdump"
437----
438
439WARNING: When logged in via SSH on your main unit, running 'tcpdump' to capture
440packets may result in a feedback loop: SSH activity to send tcpdump's output to
441your terminal is in turn is picked up in the tcpdump trace, and so forth. When
442testing 'tcpdump' access, make sure to have proper filter expressions in place.
443
444TODO: allow skipping pcaps by configuration if access to tcpdump is not wanted
445
Pau Espin Pedrol018e1042017-08-28 11:58:25 +0200446==== Allow Core Files
447
448In case a binary run for the test crashes, a core file of the crash should be
449written. This requires a limit rule. Create a file with the required rule:
450
451----
452sudo -s
453echo "@osmo-gsm-tester - core unlimited" > /etc/security/limits.d/osmo-gsm-tester_allow-core.conf
454----
455
456Re-login the user to make these changes take effect.
457
458Set the *kernel.core_pattern* sysctl to *core* (usually the default). For each
459binary run by osmo-gsm-tester, a core file will then appear in the same dir that
460contains stdout and stderr for that process (because this dir is set as CWD).
461
462----
463sysctl -w kernel.core_pattern=core
464----
465
466==== Allow Realtime Priority
467
468Certain binaries should be run with real-time priority, like 'osmo-bts-trx'.
469Add this permission on the main unit:
470
471----
472sudo -s
473echo "@osmo-gsm-tester - rtprio 99" > /etc/security/limits.d/osmo-gsm-tester_allow-rtprio.conf
474----
475
476Re-login the user to make these changes take effect.
477
Neels Hofmeyrb52df172017-05-14 20:09:35 +0200478[[user_config_uhd]]
479==== UHD
480
481Grant permission to use the UHD driver to run USRP devices for osmo-bts-trx, by
482adding the jenkins user to the 'usrp' group:
483
484----
485gpasswd -a jenkins usrp
486----
487
Neels Hofmeyr74689532017-09-05 19:43:02 +0200488==== Log Rotation
489
490To avoid clogging up /var/log, it makes sense to choose a sane maximum log size:
491
492----
493echo maxsize 10M > /etc/logrotate.d/maxsize
494----
495
Neels Hofmeyrb52df172017-05-14 20:09:35 +0200496==== Install Scripts
497
498IMPORTANT: When using the jenkins build slave as configured above, *there is no
499need to install the osmo-gsm-tester sources on the main unit*. The jenkins job
500will do so implicitly by checking out the latest osmo-gsm-tester sources in the
501workspace for every run. If you're using only the jenkins build slave, you may
502skip this section.
503
504If you prefer to use a fixed installation of the osmo-gsm-tester sources
505instead of the jenkins workspace, you can:
506
507. From the run job configured above, remove the line that says
508+
509----
510PATH="$PWD/osmo-gsm-tester/src:$PATH" \
511----
512+
513so that this uses a system wide installation instead.
514
515. Install the sources e.g. in '/usr/local/src' as indicated below.
516
517On the main unit, to install the latest in '/usr/local/src':
518
519----
520apt-get install git
521mkdir -p /usr/local/src
522cd /usr/local/src
523git clone git://git.osmocom.org/osmo-gsm-tester
524----
525
526To allow all users to run 'osmo-gsm-tester.py', from login as well as non-login
527shells, the easiest solution is to place a symlink in '/usr/local/bin':
528
529----
530ln -s /usr/local/src/osmo-gsm-tester/src/osmo-gsm-tester.py /usr/local/bin/
531----
532
533(See also the tip in <<install_capture_packets>> for a more detailed
534explanation.)
535
536The example configuration provided in the source is suitable for running as-is,
537*if* your hardware setup matches (you could technically use that directly by a
538symlink e.g. from '/usr/local/etc/osmo-gsm-tester' to the 'example' dir). If in
539doubt, rather copy the example, point 'paths.conf' at the 'suites' dir, and
540adjust your own configuration as needed. For example:
541
542----
543cd /etc
544cp -R /usr/local/src/osmo-gsm-tester/example osmo-gsm-tester
545sed -i 's#\.\./suites#/usr/local/src/osmo-gsm-tester/suites#' osmo-gsm-tester/paths.conf
546----
547
548NOTE: The configuration will be looked up in various places, see
549<<config_paths>>.
550
551
552== Hardware Choice and Configuration
553
554=== SysmoBTS
555
556To use the SysmoBTS in the osmo-gsm-tester, the following systemd services must
557be disabled:
558
559----
Maxbe69b6b2017-07-03 19:03:25 +0200560systemctl mask osmo-nitb osmo-bts-sysmo osmo-pcu sysmobts-mgr
Neels Hofmeyrb52df172017-05-14 20:09:35 +0200561----
562
563This stops the stock setup keeping the BTS in operation and hence allows the
564osmo-gsm-tester to install and launch its own versions of the SysmoBTS
565software.
566
567==== IP Address
568
569To ensure that the SysmoBTS is always reachable at a fixed known IP address,
570configure the eth0 to use a static IP address:
571
572Adjust '/etc/network/interfaces' and replace the line
573
574----
575iface eth0 inet dhcp
576----
577
578with
579
580----
581iface eth0 inet static
582 address 10.42.42.114
583 netmask 255.255.255.0
584 gateway 10.42.42.1
585----
586
587You may set the name server in '/etc/resolve.conf' (most likely to the IP of
588the gateway), but this is not really needed by the osmo-gsm-tester.
589
Neels Hofmeyrb52df172017-05-14 20:09:35 +0200590==== Allow Core Files
591
592In case a binary run for the test crashes, a core file of the crash should be
Neels Hofmeyree57f092017-06-03 15:20:50 +0200593written. This requires a limits rule. Append a line to /etc/limits like:
Neels Hofmeyrb52df172017-05-14 20:09:35 +0200594
595----
Neels Hofmeyree57f092017-06-03 15:20:50 +0200596ssh root@10.42.42.114
597echo "* C16384" >> /etc/limits
Neels Hofmeyrb52df172017-05-14 20:09:35 +0200598----
599
Neels Hofmeyree57f092017-06-03 15:20:50 +0200600==== Reboot
601
602Reboot the BTS and make sure that the IP address for eth0 is now indeed
60310.42.42.114, and that no osmo* programs are running.
604
605----
606ip a
607ps w | grep osmo
608----
609
610==== SSH Access
611
612Make sure that the jenkins user on the main unit is able to login on the
613sysmoBTS, possibly erasing outdated host keys after a new rootfs was loaded:
614
615On the main unit, for example do:
616
617----
618su - jenkins
619ssh root@10.42.42.114
620----
621
622Fix any problems until you get a login on the sysmoBTS.
623
Neels Hofmeyrb52df172017-05-14 20:09:35 +0200624
625[[hardware_modems]]
626=== Modems
627
628TODO: describe modem choices and how to run ofono
629
630[[hardware_trx]]
631=== osmo-bts-trx
632
633TODO: describe B200 family